summaryrefslogtreecommitdiffstats
path: root/cddl/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib')
-rw-r--r--cddl/contrib/dtracetoolkit/Apps/Readme5
-rwxr-xr-xcddl/contrib/dtracetoolkit/Apps/httpdstat.d132
-rwxr-xr-xcddl/contrib/dtracetoolkit/Apps/nfswizard.d102
-rwxr-xr-xcddl/contrib/dtracetoolkit/Apps/shellsnoop268
-rwxr-xr-xcddl/contrib/dtracetoolkit/Apps/weblatency.d186
l---------cddl/contrib/dtracetoolkit/Bin/anonpgpid.d1
l---------cddl/contrib/dtracetoolkit/Bin/bitesize.d1
l---------cddl/contrib/dtracetoolkit/Bin/connections1
l---------cddl/contrib/dtracetoolkit/Bin/cpudists1
l---------cddl/contrib/dtracetoolkit/Bin/cputimes1
l---------cddl/contrib/dtracetoolkit/Bin/cputypes.d1
l---------cddl/contrib/dtracetoolkit/Bin/cpuwalk.d1
l---------cddl/contrib/dtracetoolkit/Bin/crash.d1
l---------cddl/contrib/dtracetoolkit/Bin/creatbyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/cswstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/dappprof1
l---------cddl/contrib/dtracetoolkit/Bin/dapptrace1
l---------cddl/contrib/dtracetoolkit/Bin/dexplorer1
l---------cddl/contrib/dtracetoolkit/Bin/diskhits1
l---------cddl/contrib/dtracetoolkit/Bin/dispqlen.d1
l---------cddl/contrib/dtracetoolkit/Bin/dnlcps.d1
l---------cddl/contrib/dtracetoolkit/Bin/dnlcsnoop.d1
l---------cddl/contrib/dtracetoolkit/Bin/dnlcstat1
l---------cddl/contrib/dtracetoolkit/Bin/dtruss1
l---------cddl/contrib/dtracetoolkit/Bin/dvmstat1
l---------cddl/contrib/dtracetoolkit/Bin/errinfo1
l---------cddl/contrib/dtracetoolkit/Bin/execsnoop1
l---------cddl/contrib/dtracetoolkit/Bin/fddist1
l---------cddl/contrib/dtracetoolkit/Bin/filebyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/fspaging.d1
l---------cddl/contrib/dtracetoolkit/Bin/fsrw.d1
l---------cddl/contrib/dtracetoolkit/Bin/guess.d1
l---------cddl/contrib/dtracetoolkit/Bin/hotkernel1
l---------cddl/contrib/dtracetoolkit/Bin/hotspot.d1
l---------cddl/contrib/dtracetoolkit/Bin/hotuser1
l---------cddl/contrib/dtracetoolkit/Bin/httpdstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/icmpstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/intbycpu.d1
l---------cddl/contrib/dtracetoolkit/Bin/intoncpu.d1
l---------cddl/contrib/dtracetoolkit/Bin/inttimes.d1
l---------cddl/contrib/dtracetoolkit/Bin/iofile.d1
l---------cddl/contrib/dtracetoolkit/Bin/iofileb.d1
l---------cddl/contrib/dtracetoolkit/Bin/iopattern1
l---------cddl/contrib/dtracetoolkit/Bin/iopending1
l---------cddl/contrib/dtracetoolkit/Bin/iosnoop1
l---------cddl/contrib/dtracetoolkit/Bin/iotop1
l---------cddl/contrib/dtracetoolkit/Bin/j_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_calls.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_classflow.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_events.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_methodcalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_objnew.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_package.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_profile.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_stat.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_thread.d1
l---------cddl/contrib/dtracetoolkit/Bin/j_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_calls.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_execs.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_objcpu.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_objgc.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_objnew.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_stat.d1
l---------cddl/contrib/dtracetoolkit/Bin/js_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/kill.d1
l---------cddl/contrib/dtracetoolkit/Bin/kstat_types.d1
l---------cddl/contrib/dtracetoolkit/Bin/lastwords1
l---------cddl/contrib/dtracetoolkit/Bin/loads.d1
l---------cddl/contrib/dtracetoolkit/Bin/lockbydist.d1
l---------cddl/contrib/dtracetoolkit/Bin/lockbyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/minfbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/minfbyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/mmapfiles.d1
l---------cddl/contrib/dtracetoolkit/Bin/modcalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/newproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/nfswizard.d1
l---------cddl/contrib/dtracetoolkit/Bin/opensnoop1
l---------cddl/contrib/dtracetoolkit/Bin/pathopens.d1
l---------cddl/contrib/dtracetoolkit/Bin/pfilestat1
l---------cddl/contrib/dtracetoolkit/Bin/pgpginbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/pgpginbyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_funccalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_malloc.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/php_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/pidpersec.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_malloc.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_subcalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/pl_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/priclass.d1
l---------cddl/contrib/dtracetoolkit/Bin/pridist.d1
l---------cddl/contrib/dtracetoolkit/Bin/procsystime1
l---------cddl/contrib/dtracetoolkit/Bin/putnexts.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_funccalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_malloc.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_mallocstk.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_profile.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/py_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_calls.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_funccalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_lines.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_malloc.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_objcpu.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_objnew.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_stat.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/rb_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/readbytes.d1
l---------cddl/contrib/dtracetoolkit/Bin/readdist.d1
l---------cddl/contrib/dtracetoolkit/Bin/rfileio.d1
l---------cddl/contrib/dtracetoolkit/Bin/rfsio.d1
l---------cddl/contrib/dtracetoolkit/Bin/runocc.d1
l---------cddl/contrib/dtracetoolkit/Bin/rwbbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/rwbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/rwbytype.d1
l---------cddl/contrib/dtracetoolkit/Bin/rwsnoop1
l---------cddl/contrib/dtracetoolkit/Bin/rwtop1
l---------cddl/contrib/dtracetoolkit/Bin/sampleproc1
l---------cddl/contrib/dtracetoolkit/Bin/sar-c.d1
l---------cddl/contrib/dtracetoolkit/Bin/seeksize.d1
l---------cddl/contrib/dtracetoolkit/Bin/setuids.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_calls.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_flowinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_lines.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_pidcolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_stat.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_wasted.d1
l---------cddl/contrib/dtracetoolkit/Bin/sh_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/shellsnoop1
l---------cddl/contrib/dtracetoolkit/Bin/shortlived.d1
l---------cddl/contrib/dtracetoolkit/Bin/sigdist.d1
l---------cddl/contrib/dtracetoolkit/Bin/stacksize.d1
l---------cddl/contrib/dtracetoolkit/Bin/statsnoop1
l---------cddl/contrib/dtracetoolkit/Bin/swapinfo.d1
l---------cddl/contrib/dtracetoolkit/Bin/sysbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/syscallbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/syscallbyproc.d1
l---------cddl/contrib/dtracetoolkit/Bin/syscallbysysc.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_calldist.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_calls.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_calltime.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_cpudist.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_cputime.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_flow.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_flowtime.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_ins.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_insflow.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_proccalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_procflow.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_stat.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_syscalls.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_syscolors.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcl_who.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcpsnoop1
l---------cddl/contrib/dtracetoolkit/Bin/tcpsnoop.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv1
l---------cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcpstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/tcptop1
l---------cddl/contrib/dtracetoolkit/Bin/tcptop_snv1
l---------cddl/contrib/dtracetoolkit/Bin/tcpwdist.d1
l---------cddl/contrib/dtracetoolkit/Bin/threaded.d1
l---------cddl/contrib/dtracetoolkit/Bin/topsyscall1
l---------cddl/contrib/dtracetoolkit/Bin/topsysproc1
l---------cddl/contrib/dtracetoolkit/Bin/udpstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/uname-a.d1
l---------cddl/contrib/dtracetoolkit/Bin/vmbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/vmstat-p.d1
l---------cddl/contrib/dtracetoolkit/Bin/vmstat.d1
l---------cddl/contrib/dtracetoolkit/Bin/vopstat1
l---------cddl/contrib/dtracetoolkit/Bin/weblatency.d1
l---------cddl/contrib/dtracetoolkit/Bin/whatexec.d1
l---------cddl/contrib/dtracetoolkit/Bin/woof.d1
l---------cddl/contrib/dtracetoolkit/Bin/wpm.d1
l---------cddl/contrib/dtracetoolkit/Bin/writebytes.d1
l---------cddl/contrib/dtracetoolkit/Bin/writedist.d1
l---------cddl/contrib/dtracetoolkit/Bin/xcallsbypid.d1
l---------cddl/contrib/dtracetoolkit/Bin/xvmstat1
l---------cddl/contrib/dtracetoolkit/Bin/zvmstat1
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Java/Func_abc.java26
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Java/Func_loop.java19
-rw-r--r--cddl/contrib/dtracetoolkit/Code/JavaScript/func_clock.html39
-rw-r--r--cddl/contrib/dtracetoolkit/Code/JavaScript/func_slow.html31
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Perl/func_abc.pl20
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Perl/func_malloc.pl18
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Perl/func_slow.pl20
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Perl/hello.pl3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Perl/hello_strict.pl5
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Php/func_abc.php23
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Python/func_abc.py19
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Python/func_slow.py26
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Readme16
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Ruby/func_abc.rb20
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Ruby/func_slow.rb32
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Shell/func_abc.sh23
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Shell/func_slow.sh35
-rwxr-xr-xcddl/contrib/dtracetoolkit/Code/Shell/func_waste.sh23
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Tcl/func_abc.tcl20
-rw-r--r--cddl/contrib/dtracetoolkit/Code/Tcl/func_slow.tcl29
-rw-r--r--cddl/contrib/dtracetoolkit/Cpu/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/cputypes.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/cpuwalk.d72
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/dispqlen.d52
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/intbycpu.d49
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/intoncpu.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/inttimes.d73
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/loads.d58
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/runocc.d56
-rwxr-xr-xcddl/contrib/dtracetoolkit/Cpu/xcallsbypid.d51
-rw-r--r--cddl/contrib/dtracetoolkit/Disk/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/bitesize.d81
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/diskhits113
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/hotspot.d71
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/iofile.d79
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/iofileb.d59
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/iopending261
-rwxr-xr-xcddl/contrib/dtracetoolkit/Disk/seeksize.d85
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Contents152
l---------cddl/contrib/dtracetoolkit/Docs/Examples1
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Faq126
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/History249
l---------cddl/contrib/dtracetoolkit/Docs/Index1
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Links30
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Maintainer6
l---------cddl/contrib/dtracetoolkit/Docs/Notes1
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Readme21
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/ToDo7
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/Who74
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/cddl1.txt385
-rw-r--r--cddl/contrib/dtracetoolkit/Docs/oneliners.txt81
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/Copyright1
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/Readme21
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/anonpgpid_example.txt73
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/bitesize_example.txt74
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/connections_example.txt23
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/cpudists_example.txt276
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/cputimes_example.txt210
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/cputypes_example.txt40
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/cpuwalk_example.txt85
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/crash_example.txt68
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/creatbyproc_example.txt23
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/cswstat_example.txt25
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dappprof_example.txt71
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dapptrace_example.txt215
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dexplorer_example.txt95
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/diskhits_example.txt107
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dispqlen_example.txt62
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dnlcps_example.txt47
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dnlcsnoop_example.txt88
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dnlcstat_example.txt40
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dtruss_example.txt120
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/dvmstat_example.txt91
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/errinfo_example.txt90
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/execsnoop_example.txt78
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/fddist_example.txt38
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/filebyproc_example.txt27
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/fspaging_example.txt32
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/fsrw_example.txt129
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/guess_example.txt39
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/hotkernel_example.txt153
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/hotspot_example.txt34
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/hotuser_example.txt107
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/httpdstat_example.txt36
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/icmpstat_example.txt29
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/intbycpu_example.txt11
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/intoncpu_example.txt93
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/inttimes_example.txt18
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iofile_example.txt35
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iofileb_example.txt23
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iopattern_example.txt57
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iopending_example.txt126
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iosnoop_example.txt39
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/iotop_example.txt142
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_calldist_example.txt247
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_calls_example.txt137
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_calltime_example.txt67
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_classflow_example.txt89
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_cpudist_example.txt252
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_cputime_example.txt75
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_events_example.txt134
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_flow_example.txt1292
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_flowtime_example.txt1287
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_methodcalls_example.txt999
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_objnew_example.txt1460
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_package_example.txt44
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_profile_example.txt209
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_stat_example.txt33
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_syscalls_example.txt165
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_syscolors_example.txt1550
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_thread_example.txt20
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/j_who_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_calldist_example.txt110
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_calls_example.txt312
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_calltime_example.txt60
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_cpudist_example.txt112
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_cputime_example.txt69
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_execs_example.txt15
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_flow_example.txt41
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_flowinfo_example.txt42
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_flowtime_example.txt42
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_objcpu_example.txt317
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_objgc_example.txt230
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_objnew_example.txt100
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_stat_example.txt35
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/js_who_example.txt59
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/kill_example.txt12
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/kstat_types_example.txt1358
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/lastwords_example.txt81
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/loads_example.txt19
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/lockbydist_example.txt114
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/lockbyproc_example.txt42
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/minfbypid_example.txt20
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/minfbyproc_example.txt14
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/mmapfiles_example.txt109
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/modcalls_example.txt47
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/newproc_example.txt19
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/nfswizard_example.txt67
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/oneliners_examples.txt307
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/opensnoop_example.txt110
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pathopens_example.txt32
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pfilestat_example.txt200
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pgpginbypid_example.txt14
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pgpginbyproc_example.txt13
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_calldist_example.txt84
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_calltime_example.txt51
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_cpudist_example.txt84
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_cputime_example.txt58
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_flow_example.txt36
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_flowinfo_example.txt40
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_flowtime_example.txt41
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_funccalls_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_malloc_example.txt23
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_syscalls_example.txt22
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_syscolors_example.txt63
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/php_who_example.txt10
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pidpersec_example.txt33
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_calldist_example.txt456
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_calltime_example.txt150
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_cpudist_example.txt470
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_cputime_example.txt151
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_flow_example.txt179
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_flowinfo_example.txt188
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_flowtime_example.txt199
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_malloc_example.txt79
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_subcalls_example.txt53
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_syscalls_example.txt50
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_syscolors_example.txt183
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pl_who_example.txt41
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/priclass_example.txt82
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/pridist_example.txt238
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/procsystime_example.txt149
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/putnexts_example.txt520
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_calldist_example.txt966
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_calltime_example.txt255
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_cpudist_example.txt966
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_cputime_example.txt262
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_flow_example.txt485
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_flowinfo_example.txt485
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_flowtime_example.txt487
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_funccalls_example.txt89
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_malloc_example.txt508
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_mallocstk_example.txt314
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_profile_example.txt399
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_syscalls_example.txt129
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_syscolors_example.txt584
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/py_who_example.txt34
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_calldist_example.txt153
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_calls_example.txt29
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_calltime_example.txt77
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_cpudist_example.txt199
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_cputime_example.txt81
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_flow_example.txt54
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_flowinfo_example.txt54
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_flowtime_example.txt56
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_funccalls_example.txt25
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_lines_example.txt30
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_malloc_example.txt120
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_objcpu_example.txt51
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_objnew_example.txt21
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_stat_example.txt22
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_syscalls_example.txt54
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_syscolors_example.txt331
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rb_who_example.txt20
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/readbytes_example.txt22
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/readdist_example.txt35
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rfileio_example.txt94
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rfsio_example.txt82
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/runocc_example.txt53
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rwbbypid_example.txt26
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rwbypid_example.txt19
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rwbytype_example.txt37
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rwsnoop_example.txt98
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/rwtop_example.txt59
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sampleproc_example.txt62
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sar-c_example.txt55
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/seeksize_example.txt197
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/setuids_example.txt28
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_calldist_example.txt309
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_calls_example.txt60
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_calltime_example.txt144
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_cpudist_example.txt92
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_cputime_example.txt131
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_flow_example.txt129
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_flowinfo_example.txt242
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_flowtime_example.txt131
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_lines_example.txt32
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_pidcolors_example.txt574
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_stat_example.txt44
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_syscalls_example.txt59
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_syscolors_example.txt328
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_wasted_example.txt45
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sh_who_example.txt45
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/shellsnoop_example.txt112
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/shortlived_example.txt57
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sigdist_example.txt18
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/stacksize_example.txt87
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/statsnoop_example.txt94
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/swapinfo_example.txt22
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/sysbypid_example.txt45
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/syscallbypid_example.txt50
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/syscallbyproc_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/syscallbysysc_example.txt24
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_calldist_example.txt166
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_calls_example.txt41
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_calltime_example.txt61
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_cpudist_example.txt164
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_cputime_example.txt67
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_flow_example.txt195
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_flowtime_example.txt197
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_ins_example.txt46
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_insflow_example.txt997
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_proccalls_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_procflow_example.txt29
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_stat_example.txt24
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_syscalls_example.txt66
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_syscolors_example.txt563
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcl_who_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcpsnoop_d_example.txt41
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcpsnoop_example.txt61
l---------cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_d_example.txt1
l---------cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_example.txt1
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcpstat_example.txt22
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcptop_example.txt28
l---------cddl/contrib/dtracetoolkit/Examples/tcptop_snv_example.txt1
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/tcpwdist_example.txt70
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/threaded_example.txt108
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/topsyscall_example.txt65
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/topsysproc_example.txt56
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/udpstat_example.txt39
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/uname-a_example.txt15
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/vmbypid_example.txt32
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/vmstat-p_example.txt51
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/vmstat_example.txt45
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/vopstat_example.txt89
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/weblatency_example.txt127
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/whatexec_example.txt18
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/woof_example.txt28
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/wpm_example.txt57
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/writebytes_example.txt26
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/writedist_example.txt38
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/xcallsbypid_example.txt17
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/xvmstat_example.txt44
-rw-r--r--cddl/contrib/dtracetoolkit/Examples/zvmstat_example.txt34
-rw-r--r--cddl/contrib/dtracetoolkit/FS/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/FS/fspaging.d154
-rwxr-xr-xcddl/contrib/dtracetoolkit/FS/fsrw.d149
-rwxr-xr-xcddl/contrib/dtracetoolkit/FS/rfileio.d91
-rwxr-xr-xcddl/contrib/dtracetoolkit/FS/rfsio.d98
-rwxr-xr-xcddl/contrib/dtracetoolkit/FS/vopstat304
-rw-r--r--cddl/contrib/dtracetoolkit/Guide91
-rw-r--r--cddl/contrib/dtracetoolkit/Include/Readme18
-rwxr-xr-xcddl/contrib/dtracetoolkit/Include/test.ksh68
-rw-r--r--cddl/contrib/dtracetoolkit/Include/time.h38
-rw-r--r--cddl/contrib/dtracetoolkit/Include/tostr.h89
-rw-r--r--cddl/contrib/dtracetoolkit/Java/Readme17
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_calldist.d116
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_calls.d113
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_calltime.d129
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_classflow.d100
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_cpudist.d116
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_cputime.d129
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_events.d56
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_flow.d87
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_flowtime.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_methodcalls.d60
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_objnew.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_package.d56
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_profile.d78
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_stat.d148
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_syscalls.d68
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_syscolors.d135
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_thread.d64
-rwxr-xr-xcddl/contrib/dtracetoolkit/Java/j_who.d58
-rw-r--r--cddl/contrib/dtracetoolkit/JavaScript/Readme54
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_calldist.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_calls.d76
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_calltime.d115
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_cpudist.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_cputime.d115
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_execs.d51
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_flow.d69
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_flowinfo.d86
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_flowtime.d84
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_objcpu.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_objgc.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_objnew.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_stat.d120
-rwxr-xr-xcddl/contrib/dtracetoolkit/JavaScript/js_who.d56
-rw-r--r--cddl/contrib/dtracetoolkit/Kernel/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/cpudists184
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/cputimes203
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/cswstat.d74
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/dnlcps.d68
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/dnlcsnoop.d92
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/dnlcstat162
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/kstat_types.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/modcalls.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/priclass.d67
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/pridist.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/putnexts.d38
-rwxr-xr-xcddl/contrib/dtracetoolkit/Kernel/whatexec.d79
l---------cddl/contrib/dtracetoolkit/License1
-rwxr-xr-xcddl/contrib/dtracetoolkit/Locks/lockbydist.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Locks/lockbyproc.d10
-rw-r--r--cddl/contrib/dtracetoolkit/Man/Readme40
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/anonpgpid.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/bitesize.d.1m57
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/connections.1m77
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/cpudists.1m86
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/cputimes.1m87
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/cputypes.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/cpuwalk.d.1m53
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/crash.d.1m81
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/creatbyproc.d.1m55
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/cswstat.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dappprof.1m98
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dapptrace.1m112
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dexplorer.1m64
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/diskhits.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dispqlen.d.1m36
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dnlcps.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dnlcsnoop.d.1m52
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dnlcstat.1m57
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dtruss.1m123
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/dvmstat.1m93
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/errinfo.1m85
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/execsnoop.1m108
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/fddist.1m63
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/filebyproc.d.1m56
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/fspaging.d.1m88
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/fsrw.d.1m80
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/guess.d.1m37
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/hotkernel.1m39
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/hotspot.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/hotuser.1m44
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/httpdstat.d.1m67
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/icmpstat.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/intbycpu.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/intoncpu.d.1m42
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/inttimes.d.1m43
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iofile.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iofileb.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iopattern.1m112
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iopending.1m89
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iosnoop.1m167
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/iotop.1m154
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_calldist.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_calls.d.1m57
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_calltime.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_classflow.d.1m63
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_cpudist.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_cputime.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_events.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_flow.d.1m63
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_flowtime.d.1m69
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_methodcalls.d.1m45
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_objnew.d.1m45
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_package.d.1m44
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_profile.d.1m52
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_stat.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_syscalls.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_syscolors.d.1m65
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_thread.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/j_who.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_calldist.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_calls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_cpudist.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_execs.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_flow.d.1m59
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_flowinfo.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_flowtime.d.1m62
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_objcpu.d.1m36
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_objgc.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_objnew.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_stat.d.1m52
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/js_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/kill.d.1m53
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/kstat_types.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/lastwords.1m56
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/loads.d.1m38
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/lockbydist.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/lockbyproc.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/minfbypid.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/minfbyproc.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/mmapfiles.d.1m42
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/modcalls.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/newproc.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/nfswizard.d.1m36
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/opensnoop.1m139
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pathopens.d.1m38
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pfilestat.1m87
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pgpginbypid.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pgpginbyproc.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_calldist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_cpudist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_flow.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_flowinfo.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_flowtime.d.1m65
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_funccalls.d.1m43
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_malloc.d.1m39
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_syscalls.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_syscolors.d.1m61
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/php_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pidpersec.d.1m42
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_calldist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_cpudist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_flow.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_flowinfo.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_flowtime.d.1m65
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_malloc.d.1m39
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_subcalls.d.1m43
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_syscalls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_syscolors.d.1m61
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pl_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/priclass.d.1m66
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/pridist.d.1m55
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/procsystime.1m108
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/putnexts.d.1m27
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_calldist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_cpudist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_flow.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_flowinfo.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_flowtime.d.1m65
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_funccalls.d.1m43
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_malloc.d.1m39
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_mallocstk.d.1m33
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_profile.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_syscalls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_syscolors.d.1m61
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/py_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_calldist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_calls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_cpudist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_flow.d.1m59
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_flowinfo.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_flowtime.d.1m62
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_funccalls.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_lines.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_malloc.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_objcpu.d.1m36
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_objnew.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_stat.d.1m66
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_syscalls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_syscolors.d.1m61
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rb_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/readbytes.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/readdist.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rfileio.d.1m41
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rfsio.d.1m41
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/runocc.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rwbbypid.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rwbypid.d.1m48
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rwbytype.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rwsnoop.1m104
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/rwtop.1m115
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sampleproc.1m55
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sar-c.d.1m62
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/seeksize.d.1m51
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/setuids.d.1m53
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_calldist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_calls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_calltime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_cpudist.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_cputime.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_flow.d.1m66
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_flowinfo.d.1m62
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_flowtime.d.1m76
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_lines.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_pidcolors.d.1m70
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_stat.d.1m59
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_syscalls.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_syscolors.d.1m63
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_wasted.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sh_who.d.1m49
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/shellsnoop.1m99
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/shortlived.d.1m37
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sigdist.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/stacksize.d.1m42
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/statsnoop.1m140
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/swapinfo.d.1m88
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/sysbypid.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/syscallbypid.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/syscallbyproc.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/syscallbysysc.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_calldist.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_calls.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_calltime.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_cpudist.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_cputime.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_flow.d.1m66
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_flowtime.d.1m69
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_ins.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_insflow.d.1m69
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_proccalls.d.1m44
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_procflow.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_stat.d.1m61
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscalls.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscolors.d.1m59
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcl_who.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.1m116
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.1m116
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.d.1m68
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpstat.d.1m58
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcptop.1m111
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcptop_snv.1m111
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/tcpwdist.d.1m60
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/threaded.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/topsyscall.1m73
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/topsysproc.1m75
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/udpstat.d.1m55
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/uname-a.d.1m35
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/vmbypid.d.1m50
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/vmstat-p.d.1m85
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/vmstat.d.1m79
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/vopstat.1m77
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/weblatency.d.1m63
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/whatexec.d.1m53
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/woof.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/wpm.d.1m34
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/writebytes.d.1m47
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/writedist.d.1m54
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/xcallsbypid.d.1m46
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/xvmstat.1m104
-rw-r--r--cddl/contrib/dtracetoolkit/Man/man1m/zvmstat.1m101
-rw-r--r--cddl/contrib/dtracetoolkit/Mem/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/anonpgpid.d75
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/minfbypid.d57
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/minfbyproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/pgpginbypid.d53
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/pgpginbyproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/swapinfo.d149
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/vmbypid.d54
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/vmstat-p.d155
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/vmstat.d137
-rwxr-xr-xcddl/contrib/dtracetoolkit/Mem/xvmstat217
-rw-r--r--cddl/contrib/dtracetoolkit/Misc/Readme5
-rwxr-xr-xcddl/contrib/dtracetoolkit/Misc/guess.d118
-rwxr-xr-xcddl/contrib/dtracetoolkit/Misc/woof.d63
-rwxr-xr-xcddl/contrib/dtracetoolkit/Misc/wpm.d143
-rw-r--r--cddl/contrib/dtracetoolkit/Net/Readme4
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/connections178
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/icmpstat.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpsnoop581
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpsnoop.d424
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpsnoop_snv583
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpsnoop_snv.d426
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpstat.d91
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcptop579
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcptop_snv581
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/tcpwdist.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Net/udpstat.d92
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLcolors_notes.txt127
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLelapsed_notes.txt46
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLexclusive_notes.txt78
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLfbt_notes.txt77
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLflow_notes.txt64
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLinclusive_notes.txt74
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLjava_notes.txt35
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLoncpu_notes.txt42
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLoverhead.txt96
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLperl_notes.txt44
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/ALLsnoop_notes.txt94
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/Readme21
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/cputimes_notes.txt138
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/dappprof_notes.txt14
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/dapptrace_notes.txt19
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/dtruss_notes.txt97
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/iosnoop_notes.txt99
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/iotop_notes.txt48
-rw-r--r--cddl/contrib/dtracetoolkit/Notes/procsystime_notes.txt14
-rw-r--r--cddl/contrib/dtracetoolkit/Perl/Readme38
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_calldist.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_calltime.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_cpudist.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_cputime.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_flow.d70
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_flowinfo.d86
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_flowtime.d88
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_malloc.d81
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_subcalls.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_syscalls.d65
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_syscolors.d119
-rwxr-xr-xcddl/contrib/dtracetoolkit/Perl/pl_who.d56
-rw-r--r--cddl/contrib/dtracetoolkit/Php/Readme39
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_calldist.d83
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_calltime.d90
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_cpudist.d83
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_cputime.d90
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_flow.d72
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_flowinfo.d88
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_flowtime.d91
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_funccalls.d56
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_malloc.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_syscalls.d75
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_syscolors.d116
-rwxr-xr-xcddl/contrib/dtracetoolkit/Php/php_who.d56
-rw-r--r--cddl/contrib/dtracetoolkit/Proc/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/crash.d181
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/creatbyproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/dappprof239
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/dapptrace259
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/fddist116
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/filebyproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/kill.d63
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/lastwords90
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/mmapfiles.d62
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/newproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/pathopens.d100
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/pfilestat282
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/pidpersec.d57
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/readbytes.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/readdist.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/rwbbypid.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/rwbypid.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/rwbytype.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/sampleproc105
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/shortlived.d118
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/sigdist.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/stacksize.d95
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/sysbypid.d53
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/syscallbypid.d54
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/syscallbyproc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/threaded.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/topsysproc121
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/writebytes.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/Proc/writedist.d10
-rw-r--r--cddl/contrib/dtracetoolkit/Python/Readme28
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_calldist.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_calltime.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_cpudist.d82
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_cputime.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_flow.d70
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_flowinfo.d86
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_flowtime.d89
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_funccalls.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_malloc.d81
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_mallocstk.d49
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_profile.d79
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_syscalls.d63
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_syscolors.d116
-rwxr-xr-xcddl/contrib/dtracetoolkit/Python/py_who.d56
l---------cddl/contrib/dtracetoolkit/README1
-rw-r--r--cddl/contrib/dtracetoolkit/Ruby/Readme31
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_calldist.d120
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_calls.d87
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_calltime.d129
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_cpudist.d120
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_cputime.d129
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_flow.d72
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_flowinfo.d88
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_flowtime.d84
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_funccalls.d57
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_lines.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_malloc.d80
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_objcpu.d61
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_objnew.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_stat.d146
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_syscalls.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_syscolors.d133
-rwxr-xr-xcddl/contrib/dtracetoolkit/Ruby/rb_who.d56
-rw-r--r--cddl/contrib/dtracetoolkit/Shell/Readme35
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_calldist.d119
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_calls.d72
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_calltime.d136
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_cpudist.d142
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_cputime.d158
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_flow.d85
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_flowinfo.d152
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_flowtime.d118
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_lines.d55
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_pidcolors.d203
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_stat.d133
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_syscalls.d83
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_syscolors.d169
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_wasted.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/Shell/sh_who.d56
-rw-r--r--cddl/contrib/dtracetoolkit/Snippits/Readme11
-rw-r--r--cddl/contrib/dtracetoolkit/Snippits/fd2pathname.txt32
-rw-r--r--cddl/contrib/dtracetoolkit/System/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/System/sar-c.d101
-rwxr-xr-xcddl/contrib/dtracetoolkit/System/syscallbysysc.d10
-rwxr-xr-xcddl/contrib/dtracetoolkit/System/topsyscall184
-rwxr-xr-xcddl/contrib/dtracetoolkit/System/uname-a.d53
-rw-r--r--cddl/contrib/dtracetoolkit/Tcl/Readme39
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_calldist.d111
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_calls.d63
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_calltime.d123
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_cpudist.d111
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_cputime.d123
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_flow.d86
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_flowtime.d105
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_ins.d57
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_insflow.d123
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_proccalls.d53
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_procflow.d70
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_stat.d137
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_syscalls.d66
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_syscolors.d139
-rwxr-xr-xcddl/contrib/dtracetoolkit/Tcl/tcl_who.d62
-rw-r--r--cddl/contrib/dtracetoolkit/User/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/User/setuids.d82
-rw-r--r--cddl/contrib/dtracetoolkit/Version1
-rw-r--r--cddl/contrib/dtracetoolkit/Zones/Readme3
-rwxr-xr-xcddl/contrib/dtracetoolkit/Zones/zvmstat277
-rwxr-xr-xcddl/contrib/dtracetoolkit/dexplorer547
-rwxr-xr-xcddl/contrib/dtracetoolkit/dtruss464
-rwxr-xr-xcddl/contrib/dtracetoolkit/dvmstat250
-rwxr-xr-xcddl/contrib/dtracetoolkit/errinfo180
-rwxr-xr-xcddl/contrib/dtracetoolkit/execsnoop167
-rwxr-xr-xcddl/contrib/dtracetoolkit/hotkernel125
-rwxr-xr-xcddl/contrib/dtracetoolkit/hotuser139
-rwxr-xr-xcddl/contrib/dtracetoolkit/install151
-rwxr-xr-xcddl/contrib/dtracetoolkit/iopattern277
-rwxr-xr-xcddl/contrib/dtracetoolkit/iosnoop367
-rwxr-xr-xcddl/contrib/dtracetoolkit/iotop422
-rwxr-xr-xcddl/contrib/dtracetoolkit/opensnoop244
-rwxr-xr-xcddl/contrib/dtracetoolkit/procsystime233
-rwxr-xr-xcddl/contrib/dtracetoolkit/rwsnoop234
-rwxr-xr-xcddl/contrib/dtracetoolkit/rwtop292
-rwxr-xr-xcddl/contrib/dtracetoolkit/statsnoop286
-rw-r--r--cddl/contrib/opensolaris/OPENSOLARIS.LICENSE384
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.1670
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.c1926
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/README32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c207
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/badioctl/badioctl.c145
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c149
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/Getopt.java453
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java1042
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/jdtrace.c60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/manifest/jdtrace.jar-manifest3
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl235
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl704
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_FUNC.bad.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_MDIM.bad.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_NULL.bad.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_REDEF.redef.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.avgtoofew.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.maxnoarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.mintoofew.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.quantizetoofew.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.sumtoofew.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_AGGARG.bad.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_PROTO.bad.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_IDENT.bad.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_UNDEF.badaggfunc.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badexpr.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badkey3.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.noeffect.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey1.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey2.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey4.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqbad1.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqshort.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASEVAL.bad.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMTYPE.lqbad1.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMVAL.bad.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.order.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.order.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHSTEP.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MISMATCH.lqbadarg.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPLARGE.lqtoofew.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPSMALL.bad.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPTYPE.lqbadinc.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPVAL.bad.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_AGGARG.bad.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_PROTO.bad.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_SCALAR.bad.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_ARG.lquantizetoofew.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgnoarg.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgtoomany.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.counttoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizenoarg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizetoomany.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxnoarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxtoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.minnoarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.mintoomany.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizenoarg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizetoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumnoarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumtoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_AGGARG.bad.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badmany.d34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badnone.d33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_SCALAR.bad.d34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d.out131
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d.out22
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d.out16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d.out22
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d.out94
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d.out22
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count3.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.goodkey.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d108
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d.out160
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d.out61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d.out16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d.out23
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d.out9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d96
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d.out910
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d.out15
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d150
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d.out64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d.out376
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d115
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d.out55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d.out46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d.out33
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d.out61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d.out1208
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d.out9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d.out146
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signature.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d120
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d.out44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d115
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d.out61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d111
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d.out46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_1.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_2.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.modby0.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.addmin.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.divmin.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muladd.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muldiv.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_ARR_BADREF.bad.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRBIG.toobig.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRNULL.bad.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRSUB.bad.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_PROTO_TYPE.badtuple.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_IDENT_UNDEF.badureg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic1.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic2.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic3.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic4.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic5.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic6.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.uregsarray.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupgtype.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupttype.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.this.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_ARG.badsig.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toofew.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toomany.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_SYNTAX.errassign.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.tupoflow.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.cpyarray.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.diffprofile.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.initialize.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.invalidref.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.misc.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.this.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.valassign.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.begin.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.tick.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_ADDROF_BITFIELD.BitfieldAddress.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.NegBitField.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.ZeroBitField.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.ExceedBaseType.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.GreaterThan64.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFTYPE.badtype.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_OFFSETOF_BITFIELD.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_SIZEOF_BITFIELD.SizeofBitfield.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.BitFieldPromotion.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.SizeofBitField.d109
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.end.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize1.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize2.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize3.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.zerobuf.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.alignring.d81
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.cputime.ksh90
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.dynvarsize.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d115
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d.out9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize3.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring1.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.smallring.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.cpuusage.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.nice.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.priority.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.prsize.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.rssize.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0clause.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8clause.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller1.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid1.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno1.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.execname.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.hpriority.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo1.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo1.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid1.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.timestamp.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.vtimestamp.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggfun.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggtup.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.arrtup.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.body.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.both.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.pred.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.nopred.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.pred.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predfirst.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predlast.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh107
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh81
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LOCASSC.NonLocalAssoc.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LONGINT.LongStruct.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PARMCLASS.BadStorageClass.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_NAME.VoidName.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_TYPE.Dyn.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VARARGS.VarLenArgs.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VOID.NonSoleVoid.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_SIGNINT.UnsignedStruct.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_VOIDATTR.ShortVoidDecl.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.arrays.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.basics.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.funcs.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.pointers.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.varargsfuncs.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/badptr.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/countdown.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/counter.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/errorpath.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/hello.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/kstat.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/ksyms.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/renormalize.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rtime.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rw.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwinfo.d74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwtime.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/specopen.d79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/truss.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/trussrw.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/userfunc.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_AGGREGATION.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DBLERROR.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DYNAMIC.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.end.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPEC.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPECUNAVAIL.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_STKSTROVERFLOW.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/err.D_PDESC_ZERO.InvalidDescription1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.APIVersion.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.AddSearchPath.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.CoalesceTrace.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ELFGeneration.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.IncludedFilePath.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithFunctions99
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithIDs77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithModules91
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithNames128
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithProviders82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ShowCompilerCode.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceFunctions115
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceIDs70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceModule114
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceNames129
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceProvider83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.VerboseStabilityReport.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeGiga.d.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeKilo.d.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeMega.d.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeTera.d.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel32.d.ksh73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel64.d.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithoutW.d.ksh55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus1.d.ksh56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus2.d.ksh55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExtraneousProbeIds.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName1.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName2.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId1.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId2.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId3.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule1.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule2.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule3.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule4.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProbeIdentifier.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider1.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider2.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider3.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider4.d.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc1.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc2.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc3.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc4.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc5.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc6.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc7.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc8.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc9.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID1.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID2.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID3.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID4.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID5.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID6.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID7.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule1.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule2.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule3.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule4.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule5.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule6.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule7.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule8.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName1.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName2.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName3.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName4.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName5.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName6.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName7.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName8.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName9.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider1.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider2.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider3.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider4.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider5.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.MultipleInvalidProbeId.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh.out0
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.UnDefineNameWithCPP.d.ksh71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbeIdentfier.d.ksh53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbesWithoutZ.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/err.D_IDENT_UNDEF.timespent.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.end.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.endwithoutbegin.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multibeginend.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multiend.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_DECL_IDRED.EnumSameName.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_UNKNOWN.RepeatIdentifiers.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumEquality.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumSameValue.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumValAssign.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_BADADDR.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_DIVZERO.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_UNKNOWN.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.error.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.errorend.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.D_PROTO_LEN.noarg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.exitarg1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/tst.basic1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/err.D_PDESC_ZERO.notreturn.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.basic.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_FUNC_UNDEF.progenyofbad1.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_OP_VFPTR.badop.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.chillbadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.copyoutbadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.mobadarg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.raisebadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.allocanoarg.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.badbreakpoint.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoofew.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoomany.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrbadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrtoofew.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoofew.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoomany.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtabadarg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.panicbadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.progenyofbad2.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.stopbadarg.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_STRINGOF_TYPE.badstringof.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_VAR_UNDEF.badvar.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca2.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy1.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy2.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy3.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy4.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy5.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy6.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badchill.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.chillbadarg.ksh69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyout.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutbadaddr.ksh71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutstrbadaddr.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoa6badaddr.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoabadaddr.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadaddr.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadarg.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.badfreopen.ksh102
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d87
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d.out163
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.bcopy.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.chill.ksh77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d.out22
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyin.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyinto.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ddi_pathname.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.default.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.freopen.ksh111
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.hton.d99
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d226
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d.out1126
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d95
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d138
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d.out13
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out302
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.progenyof.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.rand.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d89
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d.out10
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d146
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok_null.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d231
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out254
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_ADDROF_LVAL.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_EMPTY.empty.d34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.clauses.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.stmts.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef1.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef2.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_IDENT_UNDEF.recur.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef1.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef2.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.badxlate.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineDataAssign.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineExpression.d80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineTypedef.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineWritableAssign.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.c100
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d.out36
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl104
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl88
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out6
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh125
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out7
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh93
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out6
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh81
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out3
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh128
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out7
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out5
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out6
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh182
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out18
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh172
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out15
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/manifest/test.jar-manifest2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestAbort.java158
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestBean.java706
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestClose.java90
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java169
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestEnable.java151
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java114
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java252
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMaxConsumers.java97
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMultiAggPrinta.java144
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeData.java110
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeDescription.java55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStateMachine.java627
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStopLock.java67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh.out722
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.c51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh.out17
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh.out78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.c93
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh.out50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh.out70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d.out47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NL.char.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NULL.char.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_DIGIT.InvalidDigit.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_OFLOW.BigInt.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_STR_NL.string.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace1.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace2.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack1.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack2.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack3.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren1.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren2.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren3.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/tst.D_MACRO_OFLOW.ParIntOvflow.d.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.nodivide.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.notfactor.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORMATCH.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORNSTEPS.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORSMALL.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORTYPE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORVAL.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHMATCH.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHTYPE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHVAL.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWMATCH.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWTYPE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWVAL.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGRANGE.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGTOOBIG.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPMATCH.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPTYPE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPVAL.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d.out177
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d.out25
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d.out148
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d.out25
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d.out26
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d.out29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d.out2033
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d.out34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mdb/tst.dtracedcmd.ksh85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.icmp.ksh79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.tcp.ksh155
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.udp.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/err.D_PRAGMA_OPTSET.d34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.badopt.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d.out31
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.enablerace.ksh89
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.haslam.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh135
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out15
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.roch.d93
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGKEY.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGPROTO.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d311
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d.out265
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d.out201
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d.out1021
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d.out55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d.out72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.c120
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.c441
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.d91
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_BITFIELD.bitfield.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.badtype.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.notsou.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.OffsetofNULL.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.badmemb.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofAlias.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofArith.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofUnion.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badproc1.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_BADPID.badproc2.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.d36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.addprobes.ksh61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.c52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.c46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.d86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.main.ksh59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.manypids.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh93
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh131
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh102
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh154
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.c64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.c58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.c65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.c58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.d83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.c58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.d83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.ArrayVar.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.DynamicVar.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.agg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_NONPTR.noptr.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_VOID.VoidPointerDeref.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_ARRFUN.ArrayAssignment.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_INCOMPAT.VoidPointerArith.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_LVAL.AddressChange.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.NonPointerAccess.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.badpointer.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.BadPointerAccess.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.badpointer.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress1.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer1.d174
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer2.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer3.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.GlobalVar.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.IntegerArithmetic1.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic1.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic2.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic3.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerAssignment.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer1.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer2.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.VoidCast.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic1.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic2.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGERR.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_DEPEND.main.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_INVAL.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_MALFORM.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_UNUSED.UnusedPragma.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.circlibdep.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.invalidlibdep.ksh57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libchain.ksh58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdep.ksh66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepfullyconnected.ksh100
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_PRED_SCALAR.NonScalarPred.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.invalid.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.operr.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.argsnotcached.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d126
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d.out83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh197
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_IDENT_UNDEF.afterprobe.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_PRAGCTL_INVAL.tabdefine.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_SYNTAX.withoutpound.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.defincomp.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefelsenotendif.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefincomp.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefnotendif.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.incompelse.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.mulelse.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.predicatedeclare.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.withinprobe.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_DYN.bad.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out23
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out12
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badagg.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badfmt.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badval.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_PROTO.bad.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.jstack.d36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.stack.d36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.ustack.d36
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out19
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.many.d76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.stack.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d.out8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_AGG_CONV.aggfmt.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.toomany.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.widths.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_FMT.badfmt.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_PROTO.novalue.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.aggarg.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.recursive.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.noprec.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.nowidth.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badprec.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badwidth.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PROTO_LEN.toofew.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv1.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv2.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv3.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out26
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d.out7
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d87
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d.out14
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d.out16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d.out14
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths1.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d.out22
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.op_access.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.unpriv_funcs.ksh79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probeqtn.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probestar.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.tickstar.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.assign.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declare.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declarein.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.lbraces.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.probespec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.rbraces.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.recdec.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.basic1.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.check.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declare.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declareafter.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.emptyprobe.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragma.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaaftertab.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmainside.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaoutside.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.probestar.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.create.ksh67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.discard.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh92
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitexit.ksh67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitkilled.ksh75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.signal.ksh84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.c78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.startexit.ksh89
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZERO.profile.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonens.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonensec.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneus.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneusec.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.func.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.mod.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.sym.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.c78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh.out6
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_INVAL.wrongdec4.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.nonprofile.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec1.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec2.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec3.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginexit.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d.out1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d.out101
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.statusrate.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d.out101
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.basename.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.caller.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.cleanpath.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin2.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ddi_pathname.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.dirname.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.errno.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.execname.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.gid.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.hton.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.index.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgdsize.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgsize.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.null.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.pid.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ppid.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.progenyof.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.random.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.shortstr.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stack.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stackdepth.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stddev.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strchr.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strjoin.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strstr.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strtok.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.substr.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ucaller.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uid.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.unalign.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uregs.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustack.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustackdepth.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.vahole.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.violentdeath.ksh51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.zonename.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_ARR_LOCAL.thisarray.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.selfthis.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.thisself.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_IDRED.errval.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dec.err.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupgtype.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupltype.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupttype.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_SYNTAX.declare.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d57
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.localvar.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.misc.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.self.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray2.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfthis.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.this.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.thisself.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.enqueue.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.oncpu.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.stackdepth.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.concat.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.desc.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arg0.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh90
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.assign.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.basic.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh97
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pgid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.quite.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.trace.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_BADREF.SizeofAssoc.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_UNDEF.UnknownSymbol.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.badstruct.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SYNTAX.SizeofBadType.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofArray.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofDataTypes.d122
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofExpression.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofNULL.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d42
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/bug.1001148.SpecSizeVariations.d87
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_COMM.AggAftCommit.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithAvg.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithCount.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithLquant.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMax.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMin.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithQuant.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithSum.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.CommitAftCommit.d82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.DisjointCommit.d102
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_DREC.CommitAftDataRec.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.DataRecAftCommit.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.ExitAfterCommit.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_EXIT_SPEC.ExitAftSpec.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_MALFORM.NspecExpr.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.HugeNspecValue.d76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.InvalidSpecSize.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.NegSpecSize.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PROTO_LEN.SpecNoId.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_COMM.SpecAftCommit.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_DREC.SpecAftDataRec.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_SPEC.SpecAftSpec.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeBufSize.d88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeNspec.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeSpecSize.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations1.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations2.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitAfterDiscard.d86
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitWithZero.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DataRecAftDiscard.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftCommit.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDataRec.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDiscard.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardWithZero.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.ExitAftDiscard.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.NoSpecBuffer.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations1.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations2.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculateWithRandom.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationCommit.d75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationDiscard.d74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationID.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationWithZero.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.TwoSpecBuffers.d77
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negcommit.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negspec.d37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.zerosize.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stability/err.D_ATTR_MIN.MinAttributes.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_PROTO.bad.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_SIZE.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_FRAMES.bad.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_PROTO.bad.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_STRSIZE.bad.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/tst.default.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stackdepth/tst.default.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.c37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.c37
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strlen/tst.strlen1.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_ADDROF_VAR.StructPointer.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon.d74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon1.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.circular.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order2.d108
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.recursive.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.simple.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_VOIDOBJ.baddec.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_PROTO_ARG.DupStructAssoc.d80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructAssoc.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructDataTypes.d133
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructInside.d124
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.c41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.openret.ksh75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.c45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.d88
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.d87
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZERO.tick.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonens.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonensec.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneus.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneusec.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickarg0.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.misc.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.string.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_ARG.badsize.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toofew.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ADDR.badaddr.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d30
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.negsize.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.zerosize.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out1313
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.rootvp.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_DECL_TYPERED.BadTransDecl.d64
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_OP_INCOMPLETE.NonExistentInput1.d54
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl1.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl3.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl4.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_TYPE_MEMBER.NonExistentInput2.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_INCOMPAT.BadInputType1.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_MEMB.NonExistentOutput2.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_NONE.BadTransDecl6.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_REDECL.RepeatTransDecl.d67
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransDecl8.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransInt.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.NonExistentOutput1.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.CircularTransDecl.d100
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.EmptyTransDecl.d79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ForwardTag.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputAliasTrans.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputIntTrans.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialDereferencing.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialOutputTransDefn.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ProcModelTrans.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.RepeatDeclaration.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.SimultaneousTranslators.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.StructureAssignment.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransNonPointer.d84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransOutputPointer.d80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransPointer.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TranslateSelf.d76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionInputTrans.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionOutputTrans.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_DECL_IDRED.DupTypeDef.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.BadExistingTypedef.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.TypedefInClause.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.ChainTypedef.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.TypedefDataAssign.d118
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CAST_INVAL.badcast.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CG_DYN.ResultDynType.d47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CHR_OFLOW.charconst.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_BADCLASS.bad.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_CHARATTR.badtype3.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype4.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype5.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENCONST.badeval.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enoflow.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enuflow.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_SCOPE.scopeop.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_USELESS.baddec.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ACT.badcond.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ARITH.badoperand.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INCOMPAT.badassign.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badbitop.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badshift.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badcond.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badincop.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badlogop.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_PROTO_LEN.badcond1.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badenum.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badid.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badstruct.d38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype1.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype2.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupenum.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupstruct.d39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_XLATE_REDECL.ResultDynType.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.assignops.d82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.badshiftops.d49
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d.out16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.bitops.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.charconstants.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.complex.d74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.condexpr.d61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.constants.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.conv.d109
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.enum.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intincop.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intops.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.inttypes.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrincop.d72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrops.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relenum.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relstring.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.shiftops.d62
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.stringconstants.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.struct.d84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.typedef.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.unaryop.d50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_ADDROF_VAR.UnionPointer.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon1.d68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.circular.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.order.d69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.recursive.d59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.simple.d58
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_PROTO_ARG.DupUnionAssoc.d80
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionAssoc.d71
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionDataTypes.d132
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionInside.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile13
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/argmap.d31
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/args.d31
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/forker.d31
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.andpid.ksh46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.c39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.c39
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.d60
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh107
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh159
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh160
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh170
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh106
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh96
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh113
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh118
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh.out10
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh105
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.c47
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.ksh55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh96
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh100
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh84
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh99
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh90
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh98
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh98
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh108
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh.out5
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh96
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh.out2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.c61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.d45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.depth.ksh110
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.c61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.ksh139
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.gid.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.nullassign.d94
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ppid.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh.out3
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.uid.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.walltimestamp.d55
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/version/tst.1.0.d48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/arrays/tst.uregsarray.d63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyinstr.d52
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyout.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyoutstr.d56
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.s41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.s73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.s68
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.d76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.s114
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.ksh50
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.s51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/annotated_helper.d32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/helper_helper.d32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.c43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.s43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.c82
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d.out4
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh77
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh64
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh65
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh121
-rwxr-xr-xcddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh74
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/arrays/tst.uregsarray.d85
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.d40
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d.out23
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.s81
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.d78
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.s63
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.d73
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.s59
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh132
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/annotated_helper.d32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/helper_helper.d32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.c43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.s44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.c81
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.trapstat.ksh87
-rw-r--r--cddl/contrib/opensolaris/cmd/lockstat/lockstat.1875
-rw-r--r--cddl/contrib/opensolaris/cmd/lockstat/lockstat.c1921
-rw-r--r--cddl/contrib/opensolaris/cmd/lockstat/sym.c311
-rw-r--r--cddl/contrib/opensolaris/cmd/mdb/tools/common/die.c87
-rw-r--r--cddl/contrib/opensolaris/cmd/mdb/tools/common/util.h51
-rw-r--r--cddl/contrib/opensolaris/cmd/plockstat/plockstat.c1021
-rw-r--r--cddl/contrib/opensolaris/cmd/pyzfs/pyzfs.py79
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h126
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/include/alist.h280
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/include/debug.h1017
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/include/sgs.h296
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/include/string_table.h63
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident62
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c56
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c1210
-rw-r--r--cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c685
-rw-r--r--cddl/contrib/opensolaris/cmd/stat/common/statcommon.h50
-rw-r--r--cddl/contrib/opensolaris/cmd/stat/common/timestamp.c49
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.8306
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.c3299
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb_il.c384
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs.83322
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c490
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h58
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_main.c6758
-rw-r--r--cddl/contrib/opensolaris/cmd/zfs/zfs_util.h42
-rw-r--r--cddl/contrib/opensolaris/cmd/zhack/zhack.c541
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/translate.c492
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/zinject.c987
-rw-r--r--cddl/contrib/opensolaris/cmd/zinject/zinject.h70
-rw-r--r--cddl/contrib/opensolaris/cmd/zlook/zlook.c411
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool-features.7250
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool.81948
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_iter.c253
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c5351
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_util.c86
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_util.h72
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c1514
-rw-r--r--cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.167
-rw-r--r--cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c429
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c6228
-rw-r--r--cddl/contrib/opensolaris/common/avl/avl.c1030
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_create.c1366
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_decl.c184
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_error.c97
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_hash.c178
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_impl.h336
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_labels.c153
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_lookup.c313
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_open.c954
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_types.c845
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_util.c152
-rw-r--r--cddl/contrib/opensolaris/head/atomic.h34
-rw-r--r--cddl/contrib/opensolaris/head/libintl.h125
-rw-r--r--cddl/contrib/opensolaris/head/nlist.h54
-rw-r--r--cddl/contrib/opensolaris/head/note.h55
-rw-r--r--cddl/contrib/opensolaris/head/stdio_ext.h32
-rw-r--r--cddl/contrib/opensolaris/head/storclass.h79
-rw-r--r--cddl/contrib/opensolaris/head/syms.h230
-rw-r--r--cddl/contrib/opensolaris/head/synch.h277
-rw-r--r--cddl/contrib/opensolaris/head/thread.h104
-rw-r--r--cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c500
-rw-r--r--cddl/contrib/opensolaris/lib/libctf/common/ctf_subr.c83
-rw-r--r--cddl/contrib/opensolaris/lib/libctf/common/libctf.h60
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/drti.c361
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c1966
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c501
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.h64
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.c177
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.h69
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c2613
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c2006
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c2804
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c1127
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h126
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c511
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c974
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.h66
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c234
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h275
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y834
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_handle.c485
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c1047
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.h183
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h706
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.c115
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.h69
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l872
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c1972
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.c111
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.h53
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c492
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c1467
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h56
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c1674
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c1031
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c4900
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h285
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.c187
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.h103
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c829
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h64
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c531
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c648
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c2064
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.h135
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c1209
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h116
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c626
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.h63
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c883
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h118
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c107
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h53
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c309
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.h47
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c293
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h72
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c993
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_work.c319
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c383
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.h87
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h599
-rwxr-xr-xcddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh40
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh59
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh55
-rwxr-xr-xcddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh40
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c532
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in117
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in82
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c75
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c75
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c338
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d120
-rw-r--r--cddl/contrib/opensolaris/lib/libgen/common/gmatch.c174
-rw-r--r--cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c1273
-rw-r--r--cddl/contrib/opensolaris/lib/libnvpair/libnvpair.h194
-rw-r--r--cddl/contrib/opensolaris/lib/libnvpair/nvpair_alloc_system.c59
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/libuutil.h391
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/libuutil_common.h35
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/libuutil_impl.h181
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_alloc.c135
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c569
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_dprintf.c128
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_ident.c122
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_list.c718
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_misc.c277
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_open.c70
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_pname.c205
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_string.c56
-rw-r--r--cddl/contrib/opensolaris/lib/libuutil/common/uu_strtoint.c300
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h786
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c700
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c103
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h44
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c453
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c4597
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c834
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_fru.c452
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h221
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c1729
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c471
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c1323
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c4140
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c3241
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c449
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c1535
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c618
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h67
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c189
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h47
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/kernel.c1086
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h678
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/taskq.c303
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/util.c155
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/__init__.py27
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/allow.py396
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/dataset.py234
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/groupspace.py28
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/holds.py75
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/ioctl.c544
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/table.py70
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/unallow.py27
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/userspace.py246
-rw-r--r--cddl/contrib/opensolaris/lib/pyzfs/common/util.py141
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/ctf_headers.h72
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/list.c228
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/list.h58
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/memory.c103
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/memory.h52
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/symbol.c62
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/symbol.h44
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/utils.c104
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/utils.h53
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/alist.c215
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/alist.h57
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/barrier.c92
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/barrier.h62
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/compare.c92
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c1384
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctfconvert.c263
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c1024
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h90
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h454
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c1848
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/fifo.c153
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/fifo.h54
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/fixup_tdescs.c279
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/hash.c291
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/hash.h59
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/iidesc.c197
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/input.c419
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/merge.c1143
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/output.c777
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c1210
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/stabs.c381
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/stack.c112
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/stack.h53
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/strtab.c258
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/strtab.h69
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c487
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c226
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/traverse.h71
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/util.c283
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/dump/dump.c1028
2794 files changed, 311522 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/Apps/Readme b/cddl/contrib/dtracetoolkit/Apps/Readme
new file mode 100644
index 0000000..3a6812f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Apps/Readme
@@ -0,0 +1,5 @@
+Apps - Specific Application based analysis
+
+ These are DTrace scripts that are written to analyse a particular
+ application or applictaion layer protocol. For example, Apache or NFS
+ scripts would appear here.
diff --git a/cddl/contrib/dtracetoolkit/Apps/httpdstat.d b/cddl/contrib/dtracetoolkit/Apps/httpdstat.d
new file mode 100755
index 0000000..a053482
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Apps/httpdstat.d
@@ -0,0 +1,132 @@
+#!/usr/sbin/dtrace -s
+/*
+ * httpdstat.d - realtime httpd statistics. Uses DTrace.
+ *
+ * $Id: httpdstat.d 2 2007-08-01 10:01:43Z brendan $
+ *
+ * USAGE: httpdstat.d [interval [count]]
+ *
+ * interval seconds
+ * count number of samples
+ *
+ * FIELDS:
+ * TIME Time, string
+ * NUM Number of connections
+ * GET Number of "GET"s
+ * POST Number of "POST"s
+ * HEAD Number of "HEAD"s
+ * TRACE Number of "TRACE"s
+ *
+ * All of the statistics are printed as a value per interval (not per second).
+ *
+ * NOTE: This version does not process subsequent operations on keepalives.
+ *
+ * IDEA: Ryan Matteson (who first wrote a solution to this).
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 20-Nov-2005 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+/*
+ * Program Start
+ */
+dtrace:::BEGIN
+{
+ num = 0; get = 0; head = 0; post = 0; trac = 0;
+ lines = SCREEN + 1;
+ secs = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %6s %6s %5s %5s %5s\n", "TIME",
+ "NUM", "GET", "POST", "HEAD", "TRACE");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Track Accept Events
+ */
+syscall::accept:return
+/execname == "httpd"/
+{
+ self->buf = 1;
+}
+
+syscall::read:entry
+/self->buf/
+{
+ self->buf = arg1;
+}
+
+/*
+ * Tally Data
+ */
+syscall::read:return
+/self->buf && arg0/
+{
+ this->str = (char *)copyin(self->buf, arg0);
+ this->str[4] = '\0';
+ get += stringof(this->str) == "GET " ? 1 : 0;
+ post += stringof(this->str) == "POST" ? 1 : 0;
+ head += stringof(this->str) == "HEAD" ? 1 : 0;
+ trac += stringof(this->str) == "TRAC" ? 1 : 0;
+ num++;
+ self->buf = 0;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %6d %6d %5d %5d %5d\n", walltimestamp,
+ num, get, post, head, trac);
+ num = 0; get = 0; head = 0; post = 0; trac = 0;
+ secs = $1 ? $1 : 1;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Apps/nfswizard.d b/cddl/contrib/dtracetoolkit/Apps/nfswizard.d
new file mode 100755
index 0000000..c63bc33
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Apps/nfswizard.d
@@ -0,0 +1,102 @@
+#!/usr/sbin/dtrace -s
+/*
+ * nfswizard.d - nfs client activity wizard.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This examines activity caused by NFS client processes on the same server
+ * that you are running this script on. A detailed report is generated
+ * to explain various details of NFS client activity, including response
+ * times and file access.
+ *
+ * $Id: nfswizard.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: nfswizard.d # hit Ctrl-C to end sample
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 02-Dec-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ scriptstart = walltimestamp;
+ timestart = timestamp;
+}
+
+io:nfs::start
+{
+ /* tally file sizes */
+ @file[args[2]->fi_pathname] = sum(args[0]->b_bcount);
+
+ /* time response */
+ start[args[0]->b_addr] = timestamp;
+
+ /* overall stats */
+ @rbytes = sum(args[0]->b_flags & B_READ ? args[0]->b_bcount : 0);
+ @wbytes = sum(args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount);
+ @events = count();
+}
+
+io:nfs::done
+/start[args[0]->b_addr]/
+{
+ /* calculate and save response time stats */
+ this->elapsed = timestamp - start[args[0]->b_addr];
+ @maxtime = max(this->elapsed);
+ @avgtime = avg(this->elapsed);
+ @qnztime = quantize(this->elapsed / 1000);
+}
+
+dtrace:::END
+{
+ /* print header */
+ printf("NFS Client Wizard. %Y -> %Y\n\n", scriptstart, walltimestamp);
+
+ /* print read/write stats */
+ printa("Read: %@d bytes ", @rbytes);
+ normalize(@rbytes, 1000000);
+ printa("(%@d Mb)\n", @rbytes);
+ printa("Write: %@d bytes ", @wbytes);
+ normalize(@wbytes, 1000000);
+ printa("(%@d Mb)\n\n", @wbytes);
+
+ /* print throughput stats */
+ denormalize(@rbytes);
+ normalize(@rbytes, (timestamp - timestart) / 1000000);
+ printa("Read: %@d Kb/sec\n", @rbytes);
+ denormalize(@wbytes);
+ normalize(@wbytes, (timestamp - timestart) / 1000000);
+ printa("Write: %@d Kb/sec\n\n", @wbytes);
+
+ /* print time stats */
+ printa("NFS I/O events: %@d\n", @events);
+ normalize(@avgtime, 1000000);
+ printa("Avg response time: %@d ms\n", @avgtime);
+ normalize(@maxtime, 1000000);
+ printa("Max response time: %@d ms\n\n", @maxtime);
+ printa("Response times (us):%@d\n", @qnztime);
+
+ /* print file stats */
+ printf("Top 25 files accessed (bytes):\n");
+ printf(" %-64s %s\n", "PATHNAME", "BYTES");
+ trunc(@file, 25);
+ printa(" %-64s %@d\n", @file);
+}
diff --git a/cddl/contrib/dtracetoolkit/Apps/shellsnoop b/cddl/contrib/dtracetoolkit/Apps/shellsnoop
new file mode 100755
index 0000000..95f42c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Apps/shellsnoop
@@ -0,0 +1,268 @@
+#!/usr/bin/sh
+#
+# shellsnoop - A program to print read/write details from shells,
+# such as keystrokes and command outputs.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program sounds somewhat dangerous (snooping keystrokes), but is
+# no more so than /usr/bin/truss, and both need root or dtrace privileges to
+# run. In fact, less dangerous, as we only print visible text (not password
+# text, for example). Having said that, it goes without saying that this
+# program shouldn't be used for breeching privacy of other users.
+#
+# This was written as a tool to demonstrate the capabilities of DTrace.
+#
+# $Id: shellsnoop 19 2007-09-12 07:47:59Z brendan $
+#
+# USAGE: shellsnoop [-hqsv] [-p PID] [-u UID]
+#
+# -q # quiet, only print data
+# -s # include start time, us
+# -v # include start time, string
+# -p PID # process ID to snoop
+# -u UID # user ID to snoop
+# eg,
+# shellsnoop # default output
+# shellsnoop -v # human readable timestamps
+# shellsnoop -p 1892 # snoop this PID only
+# shellsnoop -qp 1892 # watch this PID data only
+#
+# FIELDS:
+# UID User ID
+# PID process ID
+# PPID parent process ID
+# COMM command name
+# DIR direction (R read, W write)
+# TEXT text contained in the read/write
+# TIME timestamp for the command, us
+# STRTIME timestamp for the command, string
+#
+# SEE ALSO: ttywatcher
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 28-Mar-2004 Brendan Gregg Created this.
+# 21-Jan-2005 " " Wrapped in sh to provide options.
+# 30-Nov-2005 " " Fixed trailing buffer text bug.
+# 30-Nov-2005 " " Fixed sh no keystroke text in quiet bug.
+# 30-Nov-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+opt_pid=0; opt_uid=0; opt_time=0; opt_timestr=0; opt_quiet=0; opt_debug=0
+filter=0; pid=0; uid=0
+
+while getopts dhp:qsu:v name
+do
+ case $name in
+ d) opt_debug=1 ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ q) opt_quiet=1 ;;
+ s) opt_time=1 ;;
+ u) opt_uid=1; uid=$OPTARG ;;
+ v) opt_timestr=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: shellsnoop [-hqsv] [-p PID] [-u UID]
+ shellsnoop # default output
+ -q # quiet, only print data
+ -s # include start time, us
+ -v # include start time, string
+ -p PID # process ID to snoop
+ -u UID # user ID to snoop
+ END
+ exit 1
+ esac
+done
+
+if [ $opt_quiet -eq 1 ]; then
+ opt_time=0; opt_timestr=0
+fi
+if [ $opt_pid -eq 1 -o $opt_uid -eq 1 ]; then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_debug = '$opt_debug';
+ inline int OPT_quiet = '$opt_quiet';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_uid = '$opt_uid';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int FILTER = '$filter';
+ inline int PID = '$pid';
+ inline int UID = '$uid';
+
+ #pragma D option quiet
+ #pragma D option switchrate=20hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN /OPT_time == 1/
+ {
+ printf("%-14s ","TIME");
+ }
+ dtrace:::BEGIN /OPT_timestr == 1/
+ {
+ printf("%-20s ","STRTIME");
+ }
+ dtrace:::BEGIN /OPT_quiet == 0/
+ {
+ printf("%5s %5s %8s %3s %s\n", "PID", "PPID", "CMD", "DIR", "TEXT");
+ }
+
+ /*
+ * Remember this PID is a shell child
+ */
+ syscall::exec:entry, syscall::exece:entry
+ /execname == "sh" || execname == "ksh" || execname == "csh" ||
+ execname == "tcsh" || execname == "zsh" || execname == "bash"/
+ {
+ child[pid] = 1;
+
+ /* debug */
+ this->parent = (char *)curthread->t_procp->p_parent->p_user.u_comm;
+ OPT_debug == 1 ? printf("PID %d CMD %s started. (%s)\n",
+ pid, execname, stringof(this->parent)) : 1;
+ }
+ syscall::exec:entry, syscall::exece:entry
+ /(OPT_pid == 1 && PID != ppid) || (OPT_uid == 1 && UID != uid)/
+ {
+ /* forget if filtered */
+ child[pid] = 0;
+ }
+
+ /*
+ * Print shell keystrokes
+ */
+ syscall::write:entry, syscall::read:entry
+ /(execname == "sh" || execname == "ksh" || execname == "csh" ||
+ execname == "tcsh" || execname == "zsh" || execname == "bash")
+ && (arg0 >= 0 && arg0 <= 2)/
+ {
+ self->buf = arg1;
+ }
+ syscall::write:entry, syscall::read:entry
+ /(OPT_pid == 1 && PID != pid) || (OPT_uid == 1 && UID != uid)/
+ {
+ self->buf = 0;
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && child[pid] == 0 && OPT_time == 1/
+ {
+ printf("%-14d ", timestamp/1000);
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && child[pid] == 0 && OPT_timestr == 1/
+ {
+ printf("%-20Y ", walltimestamp);
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && child[pid] == 0 && OPT_quiet == 0/
+ {
+ this->text = (char *)copyin(self->buf, arg0);
+ this->text[arg0] = '\'\\0\'';
+
+ printf("%5d %5d %8s %3s %s\n", pid, curpsinfo->pr_ppid, execname,
+ probefunc == "read" ? "R" : "W", stringof(this->text));
+ }
+ syscall::write:return
+ /self->buf && child[pid] == 0 && OPT_quiet == 1/
+ {
+ this->text = (char *)copyin(self->buf, arg0);
+ this->text[arg0] = '\'\\0\'';
+ printf("%s", stringof(this->text));
+ }
+ syscall::read:return
+ /self->buf && execname == "sh" && child[pid] == 0 && OPT_quiet == 1/
+ {
+ this->text = (char *)copyin(self->buf, arg0);
+ this->text[arg0] = '\'\\0\'';
+ printf("%s", stringof(this->text));
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && child[pid] == 0/
+ {
+ self->buf = 0;
+ }
+
+ /*
+ * Print command output
+ */
+ syscall::write:entry, syscall::read:entry
+ /child[pid] == 1 && (arg0 == 1 || arg0 == 2)/
+ {
+ self->buf = arg1;
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && OPT_time == 1/
+ {
+ printf("%-14d ", timestamp/1000);
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && OPT_timestr == 1/
+ {
+ printf("%-20Y ", walltimestamp);
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && OPT_quiet == 0/
+ {
+ this->text = (char *)copyin(self->buf, arg0);
+ this->text[arg0] = '\'\\0\'';
+
+ printf("%5d %5d %8s %3s %s", pid, curpsinfo->pr_ppid, execname,
+ probefunc == "read" ? "R" : "W", stringof(this->text));
+
+ /* here we check if a newline is needed */
+ this->length = strlen(this->text);
+ printf("%s", this->text[this->length - 1] == '\'\\n\'' ? "" : "\n");
+ self->buf = 0;
+ }
+ syscall::write:return, syscall::read:return
+ /self->buf && OPT_quiet == 1/
+ {
+ this->text = (char *)copyin(self->buf, arg0);
+ this->text[arg0] = '\'\\0\'';
+ printf("%s", stringof(this->text));
+ self->buf = 0;
+ }
+
+ /*
+ * Cleanup
+ */
+ syscall::rexit:entry
+ {
+ child[pid] = 0;
+
+ /* debug */
+ this->parent = (char *)curthread->t_procp->p_parent->p_user.u_comm;
+ OPT_debug == 1 ? printf("PID %d CMD %s exited. (%s)\n",
+ pid, execname, stringof(this->parent)) : 1;
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Apps/weblatency.d b/cddl/contrib/dtracetoolkit/Apps/weblatency.d
new file mode 100755
index 0000000..8d96d5c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Apps/weblatency.d
@@ -0,0 +1,186 @@
+#!/usr/sbin/dtrace -s
+/*
+ * weblatency.d - website latency statistics.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: weblatency.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: weblatency.d # hit Ctrl-C to end sample
+ *
+ * See the code below for the "BROWSER" variable, which sets the browser
+ * to trace (currently set to "mozilla-bin").
+ *
+ * This is written as an experimental tool, and may not work at all with
+ * your browser.
+ *
+ * FIELDS:
+ * HOST Hostname from URL
+ * NUM Number of GETs
+ * AVGTIME(ms) Average time for response, ms
+ * MAXTIME(ms) Maximum time for response, ms
+ *
+ * NOTE:
+ *
+ * The latency measured here is from the browser sending the GET
+ * request to when the browser begins to recieve the response. It
+ * is an overall response time for the client, and encompasses
+ * connection speed delays, DNS lookups, proxy delays, and web server
+ * response time.
+ *
+ * IDEA: Bryan Cantrill (who wrote an elegant version for Sol 10 update 1)
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * ToDo:
+ * Check write fd for socket, not file.
+ *
+ * 30-Nov-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/* browser's execname */
+inline string BROWSER = "mozilla-bin";
+
+/* maximum expected hostname length + "GET http://" */
+inline int MAX_REQ = 64;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/*
+ * Trace brower request
+ *
+ * This is achieved by matching writes for the browser's execname that
+ * start with "GET", and then timing from the return of the write to
+ * the return of the next read in the same thread. Various stateful flags
+ * are used: self->fd, self->read.
+ *
+ * For performance reasons, I'd like to only process writes that follow a
+ * connect(), however this approach fails to process keepalives.
+ */
+syscall::write:entry
+/execname == BROWSER/
+{
+ self->buf = arg1;
+ self->fd = arg0 + 1;
+ self->nam = "";
+}
+
+syscall::write:return
+/self->fd/
+{
+ this->str = (char *)copyin(self->buf, MAX_REQ);
+ this->str[4] = '\0';
+ self->fd = stringof(this->str) == "GET " ? self->fd : 0;
+}
+
+syscall::write:return
+/self->fd/
+{
+ /* fetch browser request */
+ this->str = (char *)copyin(self->buf, MAX_REQ);
+ this->str[MAX_REQ] = '\0';
+
+ /*
+ * This unrolled loop strips down a URL to it's hostname.
+ * We ought to use strtok(), but it's not available on Sol 10 3/05,
+ * so instead I used dirname(). It's not pretty - it's done so that
+ * this works on all Sol 10 versions.
+ */
+ self->req = stringof(this->str);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->req = dirname(self->req);
+ self->nam = strlen(self->req) > 15 ? self->req : self->nam;
+ self->nam = basename(self->nam);
+
+ /* start the timer */
+ start[pid, self->fd - 1] = timestamp;
+ host[pid, self->fd - 1] = self->nam;
+ self->buf = 0;
+ self->fd = 0;
+ self->req = 0;
+ self->nam = 0;
+}
+
+/* this one wasn't a GET */
+syscall::write:return
+/self->buf/
+{
+ self->buf = 0;
+ self->fd = 0;
+}
+
+syscall::read:entry
+/execname == BROWSER && start[pid, arg0]/
+{
+ self->fd = arg0 + 1;
+}
+
+/*
+ * Record host details
+ */
+syscall::read:return
+/self->fd/
+{
+ /* fetch details */
+ self->host = stringof(host[pid, self->fd - 1]);
+ this->start = start[pid, self->fd - 1];
+
+ /* save details */
+ @Avg[self->host] = avg((timestamp - this->start)/1000000);
+ @Max[self->host] = max((timestamp - this->start)/1000000);
+ @Num[self->host] = count();
+
+ /* clear vars */
+ start[pid, self->fd - 1] = 0;
+ host[pid, self->fd - 1] = 0;
+ self->host = 0;
+ self->fd = 0;
+}
+
+/*
+ * Output report
+ */
+dtrace:::END
+{
+ printf("%-32s %11s\n", "HOST", "NUM");
+ printa("%-32s %@11d\n", @Num);
+
+ printf("\n%-32s %11s\n", "HOST", "AVGTIME(ms)");
+ printa("%-32s %@11d\n", @Avg);
+
+ printf("\n%-32s %11s\n", "HOST", "MAXTIME(ms)");
+ printa("%-32s %@11d\n", @Max);
+}
diff --git a/cddl/contrib/dtracetoolkit/Bin/anonpgpid.d b/cddl/contrib/dtracetoolkit/Bin/anonpgpid.d
new file mode 120000
index 0000000..f48a510
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/anonpgpid.d
@@ -0,0 +1 @@
+../Mem/anonpgpid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/bitesize.d b/cddl/contrib/dtracetoolkit/Bin/bitesize.d
new file mode 120000
index 0000000..6f984e0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/bitesize.d
@@ -0,0 +1 @@
+../Disk/bitesize.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/connections b/cddl/contrib/dtracetoolkit/Bin/connections
new file mode 120000
index 0000000..1be9a64
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/connections
@@ -0,0 +1 @@
+../Net/connections \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/cpudists b/cddl/contrib/dtracetoolkit/Bin/cpudists
new file mode 120000
index 0000000..91f0d80
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/cpudists
@@ -0,0 +1 @@
+../Kernel/cpudists \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/cputimes b/cddl/contrib/dtracetoolkit/Bin/cputimes
new file mode 120000
index 0000000..219dbbc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/cputimes
@@ -0,0 +1 @@
+../Kernel/cputimes \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/cputypes.d b/cddl/contrib/dtracetoolkit/Bin/cputypes.d
new file mode 120000
index 0000000..da583fe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/cputypes.d
@@ -0,0 +1 @@
+../Cpu/cputypes.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/cpuwalk.d b/cddl/contrib/dtracetoolkit/Bin/cpuwalk.d
new file mode 120000
index 0000000..5a1c26e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/cpuwalk.d
@@ -0,0 +1 @@
+../Cpu/cpuwalk.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/crash.d b/cddl/contrib/dtracetoolkit/Bin/crash.d
new file mode 120000
index 0000000..d3a3cf8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/crash.d
@@ -0,0 +1 @@
+../Proc/crash.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/creatbyproc.d b/cddl/contrib/dtracetoolkit/Bin/creatbyproc.d
new file mode 120000
index 0000000..fecd0f3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/creatbyproc.d
@@ -0,0 +1 @@
+../Proc/creatbyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/cswstat.d b/cddl/contrib/dtracetoolkit/Bin/cswstat.d
new file mode 120000
index 0000000..ea54280
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/cswstat.d
@@ -0,0 +1 @@
+../Kernel/cswstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dappprof b/cddl/contrib/dtracetoolkit/Bin/dappprof
new file mode 120000
index 0000000..e4fc32e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dappprof
@@ -0,0 +1 @@
+../Proc/dappprof \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dapptrace b/cddl/contrib/dtracetoolkit/Bin/dapptrace
new file mode 120000
index 0000000..1d38cb5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dapptrace
@@ -0,0 +1 @@
+../Proc/dapptrace \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dexplorer b/cddl/contrib/dtracetoolkit/Bin/dexplorer
new file mode 120000
index 0000000..41c36e4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dexplorer
@@ -0,0 +1 @@
+../dexplorer \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/diskhits b/cddl/contrib/dtracetoolkit/Bin/diskhits
new file mode 120000
index 0000000..4a57310
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/diskhits
@@ -0,0 +1 @@
+../Disk/diskhits \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dispqlen.d b/cddl/contrib/dtracetoolkit/Bin/dispqlen.d
new file mode 120000
index 0000000..1073e0b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dispqlen.d
@@ -0,0 +1 @@
+../Cpu/dispqlen.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dnlcps.d b/cddl/contrib/dtracetoolkit/Bin/dnlcps.d
new file mode 120000
index 0000000..efca13c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dnlcps.d
@@ -0,0 +1 @@
+../Kernel/dnlcps.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dnlcsnoop.d b/cddl/contrib/dtracetoolkit/Bin/dnlcsnoop.d
new file mode 120000
index 0000000..2478687
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dnlcsnoop.d
@@ -0,0 +1 @@
+../Kernel/dnlcsnoop.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dnlcstat b/cddl/contrib/dtracetoolkit/Bin/dnlcstat
new file mode 120000
index 0000000..baec189
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dnlcstat
@@ -0,0 +1 @@
+../Kernel/dnlcstat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dtruss b/cddl/contrib/dtracetoolkit/Bin/dtruss
new file mode 120000
index 0000000..90c00c6f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dtruss
@@ -0,0 +1 @@
+../dtruss \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/dvmstat b/cddl/contrib/dtracetoolkit/Bin/dvmstat
new file mode 120000
index 0000000..1b92321
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/dvmstat
@@ -0,0 +1 @@
+../dvmstat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/errinfo b/cddl/contrib/dtracetoolkit/Bin/errinfo
new file mode 120000
index 0000000..fbecf4d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/errinfo
@@ -0,0 +1 @@
+../errinfo \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/execsnoop b/cddl/contrib/dtracetoolkit/Bin/execsnoop
new file mode 120000
index 0000000..3a0dde2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/execsnoop
@@ -0,0 +1 @@
+../execsnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/fddist b/cddl/contrib/dtracetoolkit/Bin/fddist
new file mode 120000
index 0000000..11d6e20f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/fddist
@@ -0,0 +1 @@
+../Proc/fddist \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/filebyproc.d b/cddl/contrib/dtracetoolkit/Bin/filebyproc.d
new file mode 120000
index 0000000..5c2b2c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/filebyproc.d
@@ -0,0 +1 @@
+../Proc/filebyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/fspaging.d b/cddl/contrib/dtracetoolkit/Bin/fspaging.d
new file mode 120000
index 0000000..54db157
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/fspaging.d
@@ -0,0 +1 @@
+../FS/fspaging.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/fsrw.d b/cddl/contrib/dtracetoolkit/Bin/fsrw.d
new file mode 120000
index 0000000..829e583
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/fsrw.d
@@ -0,0 +1 @@
+../FS/fsrw.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/guess.d b/cddl/contrib/dtracetoolkit/Bin/guess.d
new file mode 120000
index 0000000..b5a41fd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/guess.d
@@ -0,0 +1 @@
+../Misc/guess.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/hotkernel b/cddl/contrib/dtracetoolkit/Bin/hotkernel
new file mode 120000
index 0000000..0b872c3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/hotkernel
@@ -0,0 +1 @@
+../hotkernel \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/hotspot.d b/cddl/contrib/dtracetoolkit/Bin/hotspot.d
new file mode 120000
index 0000000..dad526a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/hotspot.d
@@ -0,0 +1 @@
+../Disk/hotspot.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/hotuser b/cddl/contrib/dtracetoolkit/Bin/hotuser
new file mode 120000
index 0000000..4ff615e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/hotuser
@@ -0,0 +1 @@
+../hotuser \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/httpdstat.d b/cddl/contrib/dtracetoolkit/Bin/httpdstat.d
new file mode 120000
index 0000000..5d8900d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/httpdstat.d
@@ -0,0 +1 @@
+../Apps/httpdstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/icmpstat.d b/cddl/contrib/dtracetoolkit/Bin/icmpstat.d
new file mode 120000
index 0000000..1d63bb7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/icmpstat.d
@@ -0,0 +1 @@
+../Net/icmpstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/intbycpu.d b/cddl/contrib/dtracetoolkit/Bin/intbycpu.d
new file mode 120000
index 0000000..4897057
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/intbycpu.d
@@ -0,0 +1 @@
+../Cpu/intbycpu.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/intoncpu.d b/cddl/contrib/dtracetoolkit/Bin/intoncpu.d
new file mode 120000
index 0000000..814c7be
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/intoncpu.d
@@ -0,0 +1 @@
+../Cpu/intoncpu.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/inttimes.d b/cddl/contrib/dtracetoolkit/Bin/inttimes.d
new file mode 120000
index 0000000..5b179ee
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/inttimes.d
@@ -0,0 +1 @@
+../Cpu/inttimes.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iofile.d b/cddl/contrib/dtracetoolkit/Bin/iofile.d
new file mode 120000
index 0000000..8c63c16
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iofile.d
@@ -0,0 +1 @@
+../Disk/iofile.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iofileb.d b/cddl/contrib/dtracetoolkit/Bin/iofileb.d
new file mode 120000
index 0000000..7d6d404
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iofileb.d
@@ -0,0 +1 @@
+../Disk/iofileb.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iopattern b/cddl/contrib/dtracetoolkit/Bin/iopattern
new file mode 120000
index 0000000..0257e0f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iopattern
@@ -0,0 +1 @@
+../iopattern \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iopending b/cddl/contrib/dtracetoolkit/Bin/iopending
new file mode 120000
index 0000000..6ba9328
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iopending
@@ -0,0 +1 @@
+../Disk/iopending \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iosnoop b/cddl/contrib/dtracetoolkit/Bin/iosnoop
new file mode 120000
index 0000000..2b86bcb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iosnoop
@@ -0,0 +1 @@
+../iosnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/iotop b/cddl/contrib/dtracetoolkit/Bin/iotop
new file mode 120000
index 0000000..14c124b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/iotop
@@ -0,0 +1 @@
+../iotop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_calldist.d b/cddl/contrib/dtracetoolkit/Bin/j_calldist.d
new file mode 120000
index 0000000..3d40bca
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_calldist.d
@@ -0,0 +1 @@
+../Java/j_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_calls.d b/cddl/contrib/dtracetoolkit/Bin/j_calls.d
new file mode 120000
index 0000000..81ddfc5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_calls.d
@@ -0,0 +1 @@
+../Java/j_calls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_calltime.d b/cddl/contrib/dtracetoolkit/Bin/j_calltime.d
new file mode 120000
index 0000000..5261cab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_calltime.d
@@ -0,0 +1 @@
+../Java/j_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_classflow.d b/cddl/contrib/dtracetoolkit/Bin/j_classflow.d
new file mode 120000
index 0000000..e6fb86a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_classflow.d
@@ -0,0 +1 @@
+../Java/j_classflow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/j_cpudist.d
new file mode 120000
index 0000000..22f9adf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_cpudist.d
@@ -0,0 +1 @@
+../Java/j_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_cputime.d b/cddl/contrib/dtracetoolkit/Bin/j_cputime.d
new file mode 120000
index 0000000..bfb6843
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_cputime.d
@@ -0,0 +1 @@
+../Java/j_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_events.d b/cddl/contrib/dtracetoolkit/Bin/j_events.d
new file mode 120000
index 0000000..3854561
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_events.d
@@ -0,0 +1 @@
+../Java/j_events.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_flow.d b/cddl/contrib/dtracetoolkit/Bin/j_flow.d
new file mode 120000
index 0000000..852a740
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_flow.d
@@ -0,0 +1 @@
+../Java/j_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/j_flowtime.d
new file mode 120000
index 0000000..c0f9fae
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_flowtime.d
@@ -0,0 +1 @@
+../Java/j_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_methodcalls.d b/cddl/contrib/dtracetoolkit/Bin/j_methodcalls.d
new file mode 120000
index 0000000..9e5e17f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_methodcalls.d
@@ -0,0 +1 @@
+../Java/j_methodcalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_objnew.d b/cddl/contrib/dtracetoolkit/Bin/j_objnew.d
new file mode 120000
index 0000000..b91ddaf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_objnew.d
@@ -0,0 +1 @@
+../Java/j_objnew.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_package.d b/cddl/contrib/dtracetoolkit/Bin/j_package.d
new file mode 120000
index 0000000..7627671
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_package.d
@@ -0,0 +1 @@
+../Java/j_package.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_profile.d b/cddl/contrib/dtracetoolkit/Bin/j_profile.d
new file mode 120000
index 0000000..270532c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_profile.d
@@ -0,0 +1 @@
+../Java/j_profile.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_stat.d b/cddl/contrib/dtracetoolkit/Bin/j_stat.d
new file mode 120000
index 0000000..128f913
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_stat.d
@@ -0,0 +1 @@
+../Java/j_stat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/j_syscalls.d
new file mode 120000
index 0000000..fae3968
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_syscalls.d
@@ -0,0 +1 @@
+../Java/j_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/j_syscolors.d
new file mode 120000
index 0000000..4acffad
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_syscolors.d
@@ -0,0 +1 @@
+../Java/j_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_thread.d b/cddl/contrib/dtracetoolkit/Bin/j_thread.d
new file mode 120000
index 0000000..f88296c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_thread.d
@@ -0,0 +1 @@
+../Java/j_thread.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/j_who.d b/cddl/contrib/dtracetoolkit/Bin/j_who.d
new file mode 120000
index 0000000..f2aba28
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/j_who.d
@@ -0,0 +1 @@
+../Java/j_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_calldist.d b/cddl/contrib/dtracetoolkit/Bin/js_calldist.d
new file mode 120000
index 0000000..93277b0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_calldist.d
@@ -0,0 +1 @@
+../JavaScript/js_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_calls.d b/cddl/contrib/dtracetoolkit/Bin/js_calls.d
new file mode 120000
index 0000000..9c27755
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_calls.d
@@ -0,0 +1 @@
+../JavaScript/js_calls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_calltime.d b/cddl/contrib/dtracetoolkit/Bin/js_calltime.d
new file mode 120000
index 0000000..6ec2eed
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_calltime.d
@@ -0,0 +1 @@
+../JavaScript/js_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/js_cpudist.d
new file mode 120000
index 0000000..2d0c07a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_cpudist.d
@@ -0,0 +1 @@
+../JavaScript/js_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_cputime.d b/cddl/contrib/dtracetoolkit/Bin/js_cputime.d
new file mode 120000
index 0000000..1c5c716
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_cputime.d
@@ -0,0 +1 @@
+../JavaScript/js_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_execs.d b/cddl/contrib/dtracetoolkit/Bin/js_execs.d
new file mode 120000
index 0000000..2f5c4a6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_execs.d
@@ -0,0 +1 @@
+../JavaScript/js_execs.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_flow.d b/cddl/contrib/dtracetoolkit/Bin/js_flow.d
new file mode 120000
index 0000000..ea2f3e7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_flow.d
@@ -0,0 +1 @@
+../JavaScript/js_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/js_flowinfo.d
new file mode 120000
index 0000000..0edb8bd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_flowinfo.d
@@ -0,0 +1 @@
+../JavaScript/js_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/js_flowtime.d
new file mode 120000
index 0000000..cec488c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_flowtime.d
@@ -0,0 +1 @@
+../JavaScript/js_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_objcpu.d b/cddl/contrib/dtracetoolkit/Bin/js_objcpu.d
new file mode 120000
index 0000000..51aacf5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_objcpu.d
@@ -0,0 +1 @@
+../JavaScript/js_objcpu.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_objgc.d b/cddl/contrib/dtracetoolkit/Bin/js_objgc.d
new file mode 120000
index 0000000..06f8460
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_objgc.d
@@ -0,0 +1 @@
+../JavaScript/js_objgc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_objnew.d b/cddl/contrib/dtracetoolkit/Bin/js_objnew.d
new file mode 120000
index 0000000..1a7fc16
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_objnew.d
@@ -0,0 +1 @@
+../JavaScript/js_objnew.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_stat.d b/cddl/contrib/dtracetoolkit/Bin/js_stat.d
new file mode 120000
index 0000000..b2bc6da
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_stat.d
@@ -0,0 +1 @@
+../JavaScript/js_stat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/js_who.d b/cddl/contrib/dtracetoolkit/Bin/js_who.d
new file mode 120000
index 0000000..40bea74
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/js_who.d
@@ -0,0 +1 @@
+../JavaScript/js_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/kill.d b/cddl/contrib/dtracetoolkit/Bin/kill.d
new file mode 120000
index 0000000..d8c4a73
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/kill.d
@@ -0,0 +1 @@
+../Proc/kill.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/kstat_types.d b/cddl/contrib/dtracetoolkit/Bin/kstat_types.d
new file mode 120000
index 0000000..156079c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/kstat_types.d
@@ -0,0 +1 @@
+../Kernel/kstat_types.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/lastwords b/cddl/contrib/dtracetoolkit/Bin/lastwords
new file mode 120000
index 0000000..54fc3ae
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/lastwords
@@ -0,0 +1 @@
+../Proc/lastwords \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/loads.d b/cddl/contrib/dtracetoolkit/Bin/loads.d
new file mode 120000
index 0000000..842dd94
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/loads.d
@@ -0,0 +1 @@
+../Cpu/loads.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/lockbydist.d b/cddl/contrib/dtracetoolkit/Bin/lockbydist.d
new file mode 120000
index 0000000..5e9b4a5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/lockbydist.d
@@ -0,0 +1 @@
+../Locks/lockbydist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/lockbyproc.d b/cddl/contrib/dtracetoolkit/Bin/lockbyproc.d
new file mode 120000
index 0000000..d16d941
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/lockbyproc.d
@@ -0,0 +1 @@
+../Locks/lockbyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/minfbypid.d b/cddl/contrib/dtracetoolkit/Bin/minfbypid.d
new file mode 120000
index 0000000..b8ccf80
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/minfbypid.d
@@ -0,0 +1 @@
+../Mem/minfbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/minfbyproc.d b/cddl/contrib/dtracetoolkit/Bin/minfbyproc.d
new file mode 120000
index 0000000..9553203
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/minfbyproc.d
@@ -0,0 +1 @@
+../Mem/minfbyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/mmapfiles.d b/cddl/contrib/dtracetoolkit/Bin/mmapfiles.d
new file mode 120000
index 0000000..728fd75
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/mmapfiles.d
@@ -0,0 +1 @@
+../Proc/mmapfiles.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/modcalls.d b/cddl/contrib/dtracetoolkit/Bin/modcalls.d
new file mode 120000
index 0000000..fe49549
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/modcalls.d
@@ -0,0 +1 @@
+../Kernel/modcalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/newproc.d b/cddl/contrib/dtracetoolkit/Bin/newproc.d
new file mode 120000
index 0000000..9387784
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/newproc.d
@@ -0,0 +1 @@
+../Proc/newproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/nfswizard.d b/cddl/contrib/dtracetoolkit/Bin/nfswizard.d
new file mode 120000
index 0000000..ddc19d2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/nfswizard.d
@@ -0,0 +1 @@
+../Apps/nfswizard.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/opensnoop b/cddl/contrib/dtracetoolkit/Bin/opensnoop
new file mode 120000
index 0000000..3fcae85
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/opensnoop
@@ -0,0 +1 @@
+../opensnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pathopens.d b/cddl/contrib/dtracetoolkit/Bin/pathopens.d
new file mode 120000
index 0000000..21c28a5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pathopens.d
@@ -0,0 +1 @@
+../Proc/pathopens.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pfilestat b/cddl/contrib/dtracetoolkit/Bin/pfilestat
new file mode 120000
index 0000000..333765f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pfilestat
@@ -0,0 +1 @@
+../Proc/pfilestat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pgpginbypid.d b/cddl/contrib/dtracetoolkit/Bin/pgpginbypid.d
new file mode 120000
index 0000000..cfa2d79
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pgpginbypid.d
@@ -0,0 +1 @@
+../Mem/pgpginbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pgpginbyproc.d b/cddl/contrib/dtracetoolkit/Bin/pgpginbyproc.d
new file mode 120000
index 0000000..4e9a8b7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pgpginbyproc.d
@@ -0,0 +1 @@
+../Mem/pgpginbyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_calldist.d b/cddl/contrib/dtracetoolkit/Bin/php_calldist.d
new file mode 120000
index 0000000..5ac4b43
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_calldist.d
@@ -0,0 +1 @@
+../Php/php_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_calltime.d b/cddl/contrib/dtracetoolkit/Bin/php_calltime.d
new file mode 120000
index 0000000..49fb14b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_calltime.d
@@ -0,0 +1 @@
+../Php/php_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/php_cpudist.d
new file mode 120000
index 0000000..6e6595e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_cpudist.d
@@ -0,0 +1 @@
+../Php/php_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_cputime.d b/cddl/contrib/dtracetoolkit/Bin/php_cputime.d
new file mode 120000
index 0000000..3e8ccb9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_cputime.d
@@ -0,0 +1 @@
+../Php/php_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_flow.d b/cddl/contrib/dtracetoolkit/Bin/php_flow.d
new file mode 120000
index 0000000..fa86f75
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_flow.d
@@ -0,0 +1 @@
+../Php/php_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/php_flowinfo.d
new file mode 120000
index 0000000..52ef64b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_flowinfo.d
@@ -0,0 +1 @@
+../Php/php_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/php_flowtime.d
new file mode 120000
index 0000000..67dbe84
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_flowtime.d
@@ -0,0 +1 @@
+../Php/php_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_funccalls.d b/cddl/contrib/dtracetoolkit/Bin/php_funccalls.d
new file mode 120000
index 0000000..2ba056b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_funccalls.d
@@ -0,0 +1 @@
+../Php/php_funccalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_malloc.d b/cddl/contrib/dtracetoolkit/Bin/php_malloc.d
new file mode 120000
index 0000000..9c51d83
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_malloc.d
@@ -0,0 +1 @@
+../Php/php_malloc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/php_syscalls.d
new file mode 120000
index 0000000..6587c4e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_syscalls.d
@@ -0,0 +1 @@
+../Php/php_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/php_syscolors.d
new file mode 120000
index 0000000..463f287
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_syscolors.d
@@ -0,0 +1 @@
+../Php/php_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/php_who.d b/cddl/contrib/dtracetoolkit/Bin/php_who.d
new file mode 120000
index 0000000..31d6acf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/php_who.d
@@ -0,0 +1 @@
+../Php/php_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pidpersec.d b/cddl/contrib/dtracetoolkit/Bin/pidpersec.d
new file mode 120000
index 0000000..2ec6eb1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pidpersec.d
@@ -0,0 +1 @@
+../Proc/pidpersec.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_calldist.d b/cddl/contrib/dtracetoolkit/Bin/pl_calldist.d
new file mode 120000
index 0000000..d5ef923
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_calldist.d
@@ -0,0 +1 @@
+../Perl/pl_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_calltime.d b/cddl/contrib/dtracetoolkit/Bin/pl_calltime.d
new file mode 120000
index 0000000..38986ec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_calltime.d
@@ -0,0 +1 @@
+../Perl/pl_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/pl_cpudist.d
new file mode 120000
index 0000000..ce47036
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_cpudist.d
@@ -0,0 +1 @@
+../Perl/pl_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_cputime.d b/cddl/contrib/dtracetoolkit/Bin/pl_cputime.d
new file mode 120000
index 0000000..66ea2f7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_cputime.d
@@ -0,0 +1 @@
+../Perl/pl_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_flow.d b/cddl/contrib/dtracetoolkit/Bin/pl_flow.d
new file mode 120000
index 0000000..b5d566e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_flow.d
@@ -0,0 +1 @@
+../Perl/pl_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/pl_flowinfo.d
new file mode 120000
index 0000000..ad53e51
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_flowinfo.d
@@ -0,0 +1 @@
+../Perl/pl_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/pl_flowtime.d
new file mode 120000
index 0000000..89bee37
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_flowtime.d
@@ -0,0 +1 @@
+../Perl/pl_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_malloc.d b/cddl/contrib/dtracetoolkit/Bin/pl_malloc.d
new file mode 120000
index 0000000..025e4ef
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_malloc.d
@@ -0,0 +1 @@
+../Perl/pl_malloc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_subcalls.d b/cddl/contrib/dtracetoolkit/Bin/pl_subcalls.d
new file mode 120000
index 0000000..350f8c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_subcalls.d
@@ -0,0 +1 @@
+../Perl/pl_subcalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/pl_syscalls.d
new file mode 120000
index 0000000..a1ab6e5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_syscalls.d
@@ -0,0 +1 @@
+../Perl/pl_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/pl_syscolors.d
new file mode 120000
index 0000000..ebc087f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_syscolors.d
@@ -0,0 +1 @@
+../Perl/pl_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pl_who.d b/cddl/contrib/dtracetoolkit/Bin/pl_who.d
new file mode 120000
index 0000000..398de67
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pl_who.d
@@ -0,0 +1 @@
+../Perl/pl_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/priclass.d b/cddl/contrib/dtracetoolkit/Bin/priclass.d
new file mode 120000
index 0000000..09cd160
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/priclass.d
@@ -0,0 +1 @@
+../Kernel/priclass.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/pridist.d b/cddl/contrib/dtracetoolkit/Bin/pridist.d
new file mode 120000
index 0000000..3c25cbd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/pridist.d
@@ -0,0 +1 @@
+../Kernel/pridist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/procsystime b/cddl/contrib/dtracetoolkit/Bin/procsystime
new file mode 120000
index 0000000..891c2a1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/procsystime
@@ -0,0 +1 @@
+../procsystime \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/putnexts.d b/cddl/contrib/dtracetoolkit/Bin/putnexts.d
new file mode 120000
index 0000000..23cba6e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/putnexts.d
@@ -0,0 +1 @@
+../Kernel/putnexts.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_calldist.d b/cddl/contrib/dtracetoolkit/Bin/py_calldist.d
new file mode 120000
index 0000000..4a007c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_calldist.d
@@ -0,0 +1 @@
+../Python/py_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_calltime.d b/cddl/contrib/dtracetoolkit/Bin/py_calltime.d
new file mode 120000
index 0000000..6f1c400
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_calltime.d
@@ -0,0 +1 @@
+../Python/py_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/py_cpudist.d
new file mode 120000
index 0000000..76ce8db
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_cpudist.d
@@ -0,0 +1 @@
+../Python/py_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_cputime.d b/cddl/contrib/dtracetoolkit/Bin/py_cputime.d
new file mode 120000
index 0000000..d11dd87
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_cputime.d
@@ -0,0 +1 @@
+../Python/py_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_flow.d b/cddl/contrib/dtracetoolkit/Bin/py_flow.d
new file mode 120000
index 0000000..bf1485a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_flow.d
@@ -0,0 +1 @@
+../Python/py_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/py_flowinfo.d
new file mode 120000
index 0000000..adc6114
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_flowinfo.d
@@ -0,0 +1 @@
+../Python/py_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/py_flowtime.d
new file mode 120000
index 0000000..1ae51db
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_flowtime.d
@@ -0,0 +1 @@
+../Python/py_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_funccalls.d b/cddl/contrib/dtracetoolkit/Bin/py_funccalls.d
new file mode 120000
index 0000000..8101512
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_funccalls.d
@@ -0,0 +1 @@
+../Python/py_funccalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_malloc.d b/cddl/contrib/dtracetoolkit/Bin/py_malloc.d
new file mode 120000
index 0000000..ed37a3b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_malloc.d
@@ -0,0 +1 @@
+../Python/py_malloc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_mallocstk.d b/cddl/contrib/dtracetoolkit/Bin/py_mallocstk.d
new file mode 120000
index 0000000..d2bb1bb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_mallocstk.d
@@ -0,0 +1 @@
+../Python/py_mallocstk.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_profile.d b/cddl/contrib/dtracetoolkit/Bin/py_profile.d
new file mode 120000
index 0000000..3eb7219
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_profile.d
@@ -0,0 +1 @@
+../Python/py_profile.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/py_syscalls.d
new file mode 120000
index 0000000..ecf137c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_syscalls.d
@@ -0,0 +1 @@
+../Python/py_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/py_syscolors.d
new file mode 120000
index 0000000..6781115
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_syscolors.d
@@ -0,0 +1 @@
+../Python/py_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/py_who.d b/cddl/contrib/dtracetoolkit/Bin/py_who.d
new file mode 120000
index 0000000..28db7e5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/py_who.d
@@ -0,0 +1 @@
+../Python/py_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_calldist.d b/cddl/contrib/dtracetoolkit/Bin/rb_calldist.d
new file mode 120000
index 0000000..8067860
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_calldist.d
@@ -0,0 +1 @@
+../Ruby/rb_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_calls.d b/cddl/contrib/dtracetoolkit/Bin/rb_calls.d
new file mode 120000
index 0000000..266bacb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_calls.d
@@ -0,0 +1 @@
+../Ruby/rb_calls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_calltime.d b/cddl/contrib/dtracetoolkit/Bin/rb_calltime.d
new file mode 120000
index 0000000..f00df1a6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_calltime.d
@@ -0,0 +1 @@
+../Ruby/rb_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/rb_cpudist.d
new file mode 120000
index 0000000..6e77cc3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_cpudist.d
@@ -0,0 +1 @@
+../Ruby/rb_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_cputime.d b/cddl/contrib/dtracetoolkit/Bin/rb_cputime.d
new file mode 120000
index 0000000..88d9138
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_cputime.d
@@ -0,0 +1 @@
+../Ruby/rb_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_flow.d b/cddl/contrib/dtracetoolkit/Bin/rb_flow.d
new file mode 120000
index 0000000..1a0f490
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_flow.d
@@ -0,0 +1 @@
+../Ruby/rb_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/rb_flowinfo.d
new file mode 120000
index 0000000..b813019
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_flowinfo.d
@@ -0,0 +1 @@
+../Ruby/rb_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/rb_flowtime.d
new file mode 120000
index 0000000..911ea08
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_flowtime.d
@@ -0,0 +1 @@
+../Ruby/rb_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_funccalls.d b/cddl/contrib/dtracetoolkit/Bin/rb_funccalls.d
new file mode 120000
index 0000000..2a3ac9a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_funccalls.d
@@ -0,0 +1 @@
+../Ruby/rb_funccalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_lines.d b/cddl/contrib/dtracetoolkit/Bin/rb_lines.d
new file mode 120000
index 0000000..3447ccf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_lines.d
@@ -0,0 +1 @@
+../Ruby/rb_lines.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_malloc.d b/cddl/contrib/dtracetoolkit/Bin/rb_malloc.d
new file mode 120000
index 0000000..b3e2ba7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_malloc.d
@@ -0,0 +1 @@
+../Ruby/rb_malloc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_objcpu.d b/cddl/contrib/dtracetoolkit/Bin/rb_objcpu.d
new file mode 120000
index 0000000..ac7d6a2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_objcpu.d
@@ -0,0 +1 @@
+../Ruby/rb_objcpu.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_objnew.d b/cddl/contrib/dtracetoolkit/Bin/rb_objnew.d
new file mode 120000
index 0000000..ca76898
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_objnew.d
@@ -0,0 +1 @@
+../Ruby/rb_objnew.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_stat.d b/cddl/contrib/dtracetoolkit/Bin/rb_stat.d
new file mode 120000
index 0000000..7a0e2ae
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_stat.d
@@ -0,0 +1 @@
+../Ruby/rb_stat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/rb_syscalls.d
new file mode 120000
index 0000000..1b15e57
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_syscalls.d
@@ -0,0 +1 @@
+../Ruby/rb_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/rb_syscolors.d
new file mode 120000
index 0000000..4fd3d6a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_syscolors.d
@@ -0,0 +1 @@
+../Ruby/rb_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rb_who.d b/cddl/contrib/dtracetoolkit/Bin/rb_who.d
new file mode 120000
index 0000000..effc0ce
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rb_who.d
@@ -0,0 +1 @@
+../Ruby/rb_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/readbytes.d b/cddl/contrib/dtracetoolkit/Bin/readbytes.d
new file mode 120000
index 0000000..4b82f0c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/readbytes.d
@@ -0,0 +1 @@
+../Proc/readbytes.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/readdist.d b/cddl/contrib/dtracetoolkit/Bin/readdist.d
new file mode 120000
index 0000000..d73e49c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/readdist.d
@@ -0,0 +1 @@
+../Proc/readdist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rfileio.d b/cddl/contrib/dtracetoolkit/Bin/rfileio.d
new file mode 120000
index 0000000..a73a1bc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rfileio.d
@@ -0,0 +1 @@
+../FS/rfileio.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rfsio.d b/cddl/contrib/dtracetoolkit/Bin/rfsio.d
new file mode 120000
index 0000000..2dcbe2c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rfsio.d
@@ -0,0 +1 @@
+../FS/rfsio.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/runocc.d b/cddl/contrib/dtracetoolkit/Bin/runocc.d
new file mode 120000
index 0000000..9b856b3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/runocc.d
@@ -0,0 +1 @@
+../Cpu/runocc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rwbbypid.d b/cddl/contrib/dtracetoolkit/Bin/rwbbypid.d
new file mode 120000
index 0000000..be65401
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rwbbypid.d
@@ -0,0 +1 @@
+../Proc/rwbbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rwbypid.d b/cddl/contrib/dtracetoolkit/Bin/rwbypid.d
new file mode 120000
index 0000000..9dcec04
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rwbypid.d
@@ -0,0 +1 @@
+../Proc/rwbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rwbytype.d b/cddl/contrib/dtracetoolkit/Bin/rwbytype.d
new file mode 120000
index 0000000..a02b48d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rwbytype.d
@@ -0,0 +1 @@
+../Proc/rwbytype.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rwsnoop b/cddl/contrib/dtracetoolkit/Bin/rwsnoop
new file mode 120000
index 0000000..3398d03
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rwsnoop
@@ -0,0 +1 @@
+../rwsnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/rwtop b/cddl/contrib/dtracetoolkit/Bin/rwtop
new file mode 120000
index 0000000..64e421b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/rwtop
@@ -0,0 +1 @@
+../rwtop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sampleproc b/cddl/contrib/dtracetoolkit/Bin/sampleproc
new file mode 120000
index 0000000..7bdd289
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sampleproc
@@ -0,0 +1 @@
+../Proc/sampleproc \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sar-c.d b/cddl/contrib/dtracetoolkit/Bin/sar-c.d
new file mode 120000
index 0000000..9a22210
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sar-c.d
@@ -0,0 +1 @@
+../System/sar-c.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/seeksize.d b/cddl/contrib/dtracetoolkit/Bin/seeksize.d
new file mode 120000
index 0000000..3f853d7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/seeksize.d
@@ -0,0 +1 @@
+../Disk/seeksize.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/setuids.d b/cddl/contrib/dtracetoolkit/Bin/setuids.d
new file mode 120000
index 0000000..43dbf8a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/setuids.d
@@ -0,0 +1 @@
+../User/setuids.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_calldist.d b/cddl/contrib/dtracetoolkit/Bin/sh_calldist.d
new file mode 120000
index 0000000..abc6928
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_calldist.d
@@ -0,0 +1 @@
+../Shell/sh_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_calls.d b/cddl/contrib/dtracetoolkit/Bin/sh_calls.d
new file mode 120000
index 0000000..2fa6131
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_calls.d
@@ -0,0 +1 @@
+../Shell/sh_calls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_calltime.d b/cddl/contrib/dtracetoolkit/Bin/sh_calltime.d
new file mode 120000
index 0000000..35331d3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_calltime.d
@@ -0,0 +1 @@
+../Shell/sh_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/sh_cpudist.d
new file mode 120000
index 0000000..d2fd1ce
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_cpudist.d
@@ -0,0 +1 @@
+../Shell/sh_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_cputime.d b/cddl/contrib/dtracetoolkit/Bin/sh_cputime.d
new file mode 120000
index 0000000..7188fc5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_cputime.d
@@ -0,0 +1 @@
+../Shell/sh_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_flow.d b/cddl/contrib/dtracetoolkit/Bin/sh_flow.d
new file mode 120000
index 0000000..fc02ecf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_flow.d
@@ -0,0 +1 @@
+../Shell/sh_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_flowinfo.d b/cddl/contrib/dtracetoolkit/Bin/sh_flowinfo.d
new file mode 120000
index 0000000..10da77a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_flowinfo.d
@@ -0,0 +1 @@
+../Shell/sh_flowinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/sh_flowtime.d
new file mode 120000
index 0000000..c3c3cb8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_flowtime.d
@@ -0,0 +1 @@
+../Shell/sh_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_lines.d b/cddl/contrib/dtracetoolkit/Bin/sh_lines.d
new file mode 120000
index 0000000..918890e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_lines.d
@@ -0,0 +1 @@
+../Shell/sh_lines.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_pidcolors.d b/cddl/contrib/dtracetoolkit/Bin/sh_pidcolors.d
new file mode 120000
index 0000000..24ae054
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_pidcolors.d
@@ -0,0 +1 @@
+../Shell/sh_pidcolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_stat.d b/cddl/contrib/dtracetoolkit/Bin/sh_stat.d
new file mode 120000
index 0000000..0dafd99
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_stat.d
@@ -0,0 +1 @@
+../Shell/sh_stat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/sh_syscalls.d
new file mode 120000
index 0000000..0402c76
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_syscalls.d
@@ -0,0 +1 @@
+../Shell/sh_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/sh_syscolors.d
new file mode 120000
index 0000000..c79f828
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_syscolors.d
@@ -0,0 +1 @@
+../Shell/sh_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_wasted.d b/cddl/contrib/dtracetoolkit/Bin/sh_wasted.d
new file mode 120000
index 0000000..564fc98
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_wasted.d
@@ -0,0 +1 @@
+../Shell/sh_wasted.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sh_who.d b/cddl/contrib/dtracetoolkit/Bin/sh_who.d
new file mode 120000
index 0000000..ca00fab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sh_who.d
@@ -0,0 +1 @@
+../Shell/sh_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/shellsnoop b/cddl/contrib/dtracetoolkit/Bin/shellsnoop
new file mode 120000
index 0000000..84169ab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/shellsnoop
@@ -0,0 +1 @@
+../Apps/shellsnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/shortlived.d b/cddl/contrib/dtracetoolkit/Bin/shortlived.d
new file mode 120000
index 0000000..6c234cf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/shortlived.d
@@ -0,0 +1 @@
+../Proc/shortlived.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sigdist.d b/cddl/contrib/dtracetoolkit/Bin/sigdist.d
new file mode 120000
index 0000000..838da26
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sigdist.d
@@ -0,0 +1 @@
+../Proc/sigdist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/stacksize.d b/cddl/contrib/dtracetoolkit/Bin/stacksize.d
new file mode 120000
index 0000000..cb6fec4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/stacksize.d
@@ -0,0 +1 @@
+../Proc/stacksize.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/statsnoop b/cddl/contrib/dtracetoolkit/Bin/statsnoop
new file mode 120000
index 0000000..445e361
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/statsnoop
@@ -0,0 +1 @@
+../statsnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/swapinfo.d b/cddl/contrib/dtracetoolkit/Bin/swapinfo.d
new file mode 120000
index 0000000..e5cd10f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/swapinfo.d
@@ -0,0 +1 @@
+../Mem/swapinfo.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/sysbypid.d b/cddl/contrib/dtracetoolkit/Bin/sysbypid.d
new file mode 120000
index 0000000..761ada9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/sysbypid.d
@@ -0,0 +1 @@
+../Proc/sysbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/syscallbypid.d b/cddl/contrib/dtracetoolkit/Bin/syscallbypid.d
new file mode 120000
index 0000000..eca83c7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/syscallbypid.d
@@ -0,0 +1 @@
+../Proc/syscallbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/syscallbyproc.d b/cddl/contrib/dtracetoolkit/Bin/syscallbyproc.d
new file mode 120000
index 0000000..0260655
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/syscallbyproc.d
@@ -0,0 +1 @@
+../Proc/syscallbyproc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/syscallbysysc.d b/cddl/contrib/dtracetoolkit/Bin/syscallbysysc.d
new file mode 120000
index 0000000..43258f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/syscallbysysc.d
@@ -0,0 +1 @@
+../System/syscallbysysc.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_calldist.d b/cddl/contrib/dtracetoolkit/Bin/tcl_calldist.d
new file mode 120000
index 0000000..6e3cf23
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_calldist.d
@@ -0,0 +1 @@
+../Tcl/tcl_calldist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_calls.d b/cddl/contrib/dtracetoolkit/Bin/tcl_calls.d
new file mode 120000
index 0000000..3a48d0b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_calls.d
@@ -0,0 +1 @@
+../Tcl/tcl_calls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_calltime.d b/cddl/contrib/dtracetoolkit/Bin/tcl_calltime.d
new file mode 120000
index 0000000..32cead5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_calltime.d
@@ -0,0 +1 @@
+../Tcl/tcl_calltime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_cpudist.d b/cddl/contrib/dtracetoolkit/Bin/tcl_cpudist.d
new file mode 120000
index 0000000..1724115
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_cpudist.d
@@ -0,0 +1 @@
+../Tcl/tcl_cpudist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_cputime.d b/cddl/contrib/dtracetoolkit/Bin/tcl_cputime.d
new file mode 120000
index 0000000..e8269db
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_cputime.d
@@ -0,0 +1 @@
+../Tcl/tcl_cputime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_flow.d b/cddl/contrib/dtracetoolkit/Bin/tcl_flow.d
new file mode 120000
index 0000000..4f3e01f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_flow.d
@@ -0,0 +1 @@
+../Tcl/tcl_flow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_flowtime.d b/cddl/contrib/dtracetoolkit/Bin/tcl_flowtime.d
new file mode 120000
index 0000000..3664f7a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_flowtime.d
@@ -0,0 +1 @@
+../Tcl/tcl_flowtime.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_ins.d b/cddl/contrib/dtracetoolkit/Bin/tcl_ins.d
new file mode 120000
index 0000000..d748034
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_ins.d
@@ -0,0 +1 @@
+../Tcl/tcl_ins.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_insflow.d b/cddl/contrib/dtracetoolkit/Bin/tcl_insflow.d
new file mode 120000
index 0000000..9f716bd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_insflow.d
@@ -0,0 +1 @@
+../Tcl/tcl_insflow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_proccalls.d b/cddl/contrib/dtracetoolkit/Bin/tcl_proccalls.d
new file mode 120000
index 0000000..704e0b5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_proccalls.d
@@ -0,0 +1 @@
+../Tcl/tcl_proccalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_procflow.d b/cddl/contrib/dtracetoolkit/Bin/tcl_procflow.d
new file mode 120000
index 0000000..51da9dc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_procflow.d
@@ -0,0 +1 @@
+../Tcl/tcl_procflow.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_stat.d b/cddl/contrib/dtracetoolkit/Bin/tcl_stat.d
new file mode 120000
index 0000000..7f9659a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_stat.d
@@ -0,0 +1 @@
+../Tcl/tcl_stat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_syscalls.d b/cddl/contrib/dtracetoolkit/Bin/tcl_syscalls.d
new file mode 120000
index 0000000..aec7673
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_syscalls.d
@@ -0,0 +1 @@
+../Tcl/tcl_syscalls.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_syscolors.d b/cddl/contrib/dtracetoolkit/Bin/tcl_syscolors.d
new file mode 120000
index 0000000..890ea5f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_syscolors.d
@@ -0,0 +1 @@
+../Tcl/tcl_syscolors.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcl_who.d b/cddl/contrib/dtracetoolkit/Bin/tcl_who.d
new file mode 120000
index 0000000..7917b5e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcl_who.d
@@ -0,0 +1 @@
+../Tcl/tcl_who.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpsnoop b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop
new file mode 120000
index 0000000..7f7b37d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop
@@ -0,0 +1 @@
+../Net/tcpsnoop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpsnoop.d b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop.d
new file mode 120000
index 0000000..ad9ccf9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop.d
@@ -0,0 +1 @@
+../Net/tcpsnoop.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv
new file mode 120000
index 0000000..7ea5a09
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv
@@ -0,0 +1 @@
+../Net/tcpsnoop_snv \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv.d b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv.d
new file mode 120000
index 0000000..a2321e0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpsnoop_snv.d
@@ -0,0 +1 @@
+../Net/tcpsnoop_snv.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpstat.d b/cddl/contrib/dtracetoolkit/Bin/tcpstat.d
new file mode 120000
index 0000000..176f0e3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpstat.d
@@ -0,0 +1 @@
+../Net/tcpstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcptop b/cddl/contrib/dtracetoolkit/Bin/tcptop
new file mode 120000
index 0000000..a97fec3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcptop
@@ -0,0 +1 @@
+../Net/tcptop \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcptop_snv b/cddl/contrib/dtracetoolkit/Bin/tcptop_snv
new file mode 120000
index 0000000..ad75a7b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcptop_snv
@@ -0,0 +1 @@
+../Net/tcptop_snv \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/tcpwdist.d b/cddl/contrib/dtracetoolkit/Bin/tcpwdist.d
new file mode 120000
index 0000000..0be2a41
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/tcpwdist.d
@@ -0,0 +1 @@
+../Net/tcpwdist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/threaded.d b/cddl/contrib/dtracetoolkit/Bin/threaded.d
new file mode 120000
index 0000000..b9febd8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/threaded.d
@@ -0,0 +1 @@
+../Proc/threaded.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/topsyscall b/cddl/contrib/dtracetoolkit/Bin/topsyscall
new file mode 120000
index 0000000..b9a2eec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/topsyscall
@@ -0,0 +1 @@
+../System/topsyscall \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/topsysproc b/cddl/contrib/dtracetoolkit/Bin/topsysproc
new file mode 120000
index 0000000..d523f50
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/topsysproc
@@ -0,0 +1 @@
+../Proc/topsysproc \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/udpstat.d b/cddl/contrib/dtracetoolkit/Bin/udpstat.d
new file mode 120000
index 0000000..11d0bca
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/udpstat.d
@@ -0,0 +1 @@
+../Net/udpstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/uname-a.d b/cddl/contrib/dtracetoolkit/Bin/uname-a.d
new file mode 120000
index 0000000..1125175
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/uname-a.d
@@ -0,0 +1 @@
+../System/uname-a.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/vmbypid.d b/cddl/contrib/dtracetoolkit/Bin/vmbypid.d
new file mode 120000
index 0000000..16e5ac4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/vmbypid.d
@@ -0,0 +1 @@
+../Mem/vmbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/vmstat-p.d b/cddl/contrib/dtracetoolkit/Bin/vmstat-p.d
new file mode 120000
index 0000000..a75e5a1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/vmstat-p.d
@@ -0,0 +1 @@
+../Mem/vmstat-p.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/vmstat.d b/cddl/contrib/dtracetoolkit/Bin/vmstat.d
new file mode 120000
index 0000000..395ba5f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/vmstat.d
@@ -0,0 +1 @@
+../Mem/vmstat.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/vopstat b/cddl/contrib/dtracetoolkit/Bin/vopstat
new file mode 120000
index 0000000..f38b579
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/vopstat
@@ -0,0 +1 @@
+../FS/vopstat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/weblatency.d b/cddl/contrib/dtracetoolkit/Bin/weblatency.d
new file mode 120000
index 0000000..c16bb2e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/weblatency.d
@@ -0,0 +1 @@
+../Apps/weblatency.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/whatexec.d b/cddl/contrib/dtracetoolkit/Bin/whatexec.d
new file mode 120000
index 0000000..660ff83
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/whatexec.d
@@ -0,0 +1 @@
+../Kernel/whatexec.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/woof.d b/cddl/contrib/dtracetoolkit/Bin/woof.d
new file mode 120000
index 0000000..a380d7c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/woof.d
@@ -0,0 +1 @@
+../Misc/woof.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/wpm.d b/cddl/contrib/dtracetoolkit/Bin/wpm.d
new file mode 120000
index 0000000..fee9c99
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/wpm.d
@@ -0,0 +1 @@
+../Misc/wpm.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/writebytes.d b/cddl/contrib/dtracetoolkit/Bin/writebytes.d
new file mode 120000
index 0000000..586cbd7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/writebytes.d
@@ -0,0 +1 @@
+../Proc/writebytes.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/writedist.d b/cddl/contrib/dtracetoolkit/Bin/writedist.d
new file mode 120000
index 0000000..3710f13
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/writedist.d
@@ -0,0 +1 @@
+../Proc/writedist.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/xcallsbypid.d b/cddl/contrib/dtracetoolkit/Bin/xcallsbypid.d
new file mode 120000
index 0000000..08c7fec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/xcallsbypid.d
@@ -0,0 +1 @@
+../Cpu/xcallsbypid.d \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/xvmstat b/cddl/contrib/dtracetoolkit/Bin/xvmstat
new file mode 120000
index 0000000..24008fb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/xvmstat
@@ -0,0 +1 @@
+../Mem/xvmstat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Bin/zvmstat b/cddl/contrib/dtracetoolkit/Bin/zvmstat
new file mode 120000
index 0000000..41c7dbb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Bin/zvmstat
@@ -0,0 +1 @@
+../Zones/zvmstat \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Code/Java/Func_abc.java b/cddl/contrib/dtracetoolkit/Code/Java/Func_abc.java
new file mode 100644
index 0000000..c14012e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Java/Func_abc.java
@@ -0,0 +1,26 @@
+public class Func_abc {
+ public static void func_c() {
+ System.out.println("Function C");
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (Exception e) { }
+ }
+ public static void func_b() {
+ System.out.println("Function B");
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (Exception e) { }
+ func_c();
+ }
+ public static void func_a() {
+ System.out.println("Function A");
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (Exception e) { }
+ func_b();
+ }
+
+ public static void main(String[] args) {
+ func_a();
+ }
+}
diff --git a/cddl/contrib/dtracetoolkit/Code/Java/Func_loop.java b/cddl/contrib/dtracetoolkit/Code/Java/Func_loop.java
new file mode 100644
index 0000000..81be852
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Java/Func_loop.java
@@ -0,0 +1,19 @@
+public class Func_loop {
+ public static void func_c() {
+ System.out.println("Function C");
+ while (true) {
+ }
+ }
+ public static void func_b() {
+ System.out.println("Function B");
+ func_c();
+ }
+ public static void func_a() {
+ System.out.println("Function A");
+ func_b();
+ }
+
+ public static void main(String[] args) {
+ func_a();
+ }
+}
diff --git a/cddl/contrib/dtracetoolkit/Code/JavaScript/func_clock.html b/cddl/contrib/dtracetoolkit/Code/JavaScript/func_clock.html
new file mode 100644
index 0000000..c25610b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/JavaScript/func_clock.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>func_clock, JavaScript</TITLE>
+<SCRIPT type="text/javascript">
+function func_c() {
+ document.getElementById('now').innerHTML += "Function C<br>"
+ for (i = 0; i < 30000; i++) {
+ j = i + 1
+ }
+}
+
+function func_b() {
+ document.getElementById('now').innerHTML += "Function B<br>"
+ for (i = 0; i < 20000; i++) {
+ j = i + 1
+ }
+ func_c()
+}
+
+function func_a() {
+ document.getElementById('now').innerHTML += "Function A<br>"
+ for (i = 0; i < 10000; i++) {
+ j = i + 1
+ }
+ func_b()
+}
+
+function start() {
+ now = new Date()
+ document.getElementById('now').innerHTML = now + "<br>"
+ func_a()
+ var timeout = setTimeout('start()', 1000)
+}
+</SCRIPT>
+</HEAD>
+<BODY onload="start()">
+<DIV id="now"></DIV>
+</BODY>
+</HTML>
diff --git a/cddl/contrib/dtracetoolkit/Code/JavaScript/func_slow.html b/cddl/contrib/dtracetoolkit/Code/JavaScript/func_slow.html
new file mode 100644
index 0000000..14fdfda
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/JavaScript/func_slow.html
@@ -0,0 +1,31 @@
+<HTML>
+<HEAD><TITLE>func_slow, JavaScript</TITLE></HEAD>
+<BODY>
+<SCRIPT type="text/javascript">
+function func_c() {
+ document.write("Function C<br>")
+ for (i = 0; i < 30000; i++) {
+ j = i + 1
+ }
+}
+
+function func_b() {
+ document.write("Function B<br>")
+ for (i = 0; i < 20000; i++) {
+ j = i + 1
+ }
+ func_c()
+}
+
+function func_a() {
+ document.write("Function A<br>")
+ for (i = 0; i < 10000; i++) {
+ j = i + 1
+ }
+ func_b()
+}
+
+func_a()
+</SCRIPT>
+</BODY>
+</HTML>
diff --git a/cddl/contrib/dtracetoolkit/Code/Perl/func_abc.pl b/cddl/contrib/dtracetoolkit/Code/Perl/func_abc.pl
new file mode 100755
index 0000000..394f1c2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Perl/func_abc.pl
@@ -0,0 +1,20 @@
+#!./perl -w
+
+sub func_c {
+ print "Function C\n";
+ sleep 1;
+}
+
+sub func_b {
+ print "Function B\n";
+ sleep 1;
+ func_c();
+}
+
+sub func_a {
+ print "Function A\n";
+ sleep 1;
+ func_b();
+}
+
+func_a();
diff --git a/cddl/contrib/dtracetoolkit/Code/Perl/func_malloc.pl b/cddl/contrib/dtracetoolkit/Code/Perl/func_malloc.pl
new file mode 100755
index 0000000..5340c82
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Perl/func_malloc.pl
@@ -0,0 +1,18 @@
+#!./perl -w
+
+sub func_c {
+ print "Function C\n";
+}
+
+sub func_b {
+ print "Function B\n";
+ my $b = "B" x 100_000;
+ func_c();
+}
+
+sub func_a {
+ print "Function A\n";
+ func_b();
+}
+
+func_a();
diff --git a/cddl/contrib/dtracetoolkit/Code/Perl/func_slow.pl b/cddl/contrib/dtracetoolkit/Code/Perl/func_slow.pl
new file mode 100755
index 0000000..f32d09e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Perl/func_slow.pl
@@ -0,0 +1,20 @@
+#!./perl -w
+
+sub func_c {
+ print "Function C\n";
+ for (my $i = 0; $i < 3000000; $i++) { my $j = $i + 1; }
+}
+
+sub func_b {
+ print "Function B\n";
+ for (my $i = 0; $i < 2000000; $i++) { my $j = $i + 1 ; }
+ func_c();
+}
+
+sub func_a {
+ print "Function A\n";
+ for (my $i = 0; $i < 1000000; $i++) { my $j = $i + 1; }
+ func_b();
+}
+
+func_a();
diff --git a/cddl/contrib/dtracetoolkit/Code/Perl/hello.pl b/cddl/contrib/dtracetoolkit/Code/Perl/hello.pl
new file mode 100755
index 0000000..3ca70a2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Perl/hello.pl
@@ -0,0 +1,3 @@
+#!./perl
+
+print "Hello World!\n";
diff --git a/cddl/contrib/dtracetoolkit/Code/Perl/hello_strict.pl b/cddl/contrib/dtracetoolkit/Code/Perl/hello_strict.pl
new file mode 100755
index 0000000..78003a9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Perl/hello_strict.pl
@@ -0,0 +1,5 @@
+#!./perl -w
+
+use strict;
+
+print "Hello World!\n";
diff --git a/cddl/contrib/dtracetoolkit/Code/Php/func_abc.php b/cddl/contrib/dtracetoolkit/Code/Php/func_abc.php
new file mode 100644
index 0000000..9165611
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Php/func_abc.php
@@ -0,0 +1,23 @@
+<?php
+function func_c()
+{
+ echo "Function C\n";
+ sleep(1);
+}
+
+function func_b()
+{
+ echo "Function B\n";
+ sleep(1);
+ func_c();
+}
+
+function func_a()
+{
+ echo "Function A\n";
+ sleep(1);
+ func_b();
+}
+
+func_a();
+?>
diff --git a/cddl/contrib/dtracetoolkit/Code/Python/func_abc.py b/cddl/contrib/dtracetoolkit/Code/Python/func_abc.py
new file mode 100755
index 0000000..0d4919f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Python/func_abc.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+import time
+
+def func_c():
+ print "Function C"
+ time.sleep(1)
+
+def func_b():
+ print "Function B"
+ time.sleep(1)
+ func_c()
+
+def func_a():
+ print "Function A"
+ time.sleep(1)
+ func_b()
+
+func_a()
diff --git a/cddl/contrib/dtracetoolkit/Code/Python/func_slow.py b/cddl/contrib/dtracetoolkit/Code/Python/func_slow.py
new file mode 100755
index 0000000..9cba9c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Python/func_slow.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+
+def func_c():
+ print "Function C"
+ i = 0
+ while (i < 3000000):
+ i = i + 1
+ j = i + 1
+
+def func_b():
+ print "Function B"
+ i = 0
+ while (i < 2000000):
+ i = i + 1
+ j = i + 1
+ func_c()
+
+def func_a():
+ print "Function A"
+ i = 0
+ while (i < 1000000):
+ i = i + 1
+ j = i + 1
+ func_b()
+
+func_a()
diff --git a/cddl/contrib/dtracetoolkit/Code/Readme b/cddl/contrib/dtracetoolkit/Code/Readme
new file mode 100644
index 0000000..f8b16d7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Readme
@@ -0,0 +1,16 @@
+Code - Example Programs
+
+ This directory contains example software sorted by language, which may
+ be used as the target for DTrace scripts. These examples are simple and
+ to the point, and are intended as example targets for when learing
+ DTrace.
+
+ Some people attempt to learn DTrace by tracing their complex real
+ world application first. That's the hard way. Try these programs instead,
+ and once you are confident here, move onto harder targets.
+
+ Some of these programs feature in the example files in the /Examples
+ directory.
+
+ This directory does not contain DTrace scripts.
+
diff --git a/cddl/contrib/dtracetoolkit/Code/Ruby/func_abc.rb b/cddl/contrib/dtracetoolkit/Code/Ruby/func_abc.rb
new file mode 100755
index 0000000..75adaf9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Ruby/func_abc.rb
@@ -0,0 +1,20 @@
+#!./ruby -w
+
+def func_c
+ print "Function C\n"
+ sleep 1
+end
+
+def func_b
+ print "Function B\n"
+ sleep 1
+ func_c
+end
+
+def func_a
+ print "Function A\n"
+ sleep 1
+ func_b
+end
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Ruby/func_slow.rb b/cddl/contrib/dtracetoolkit/Code/Ruby/func_slow.rb
new file mode 100755
index 0000000..87a498c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Ruby/func_slow.rb
@@ -0,0 +1,32 @@
+#!./ruby -w
+
+def func_c
+ print "Function C\n"
+ i = 0
+ while i < 300000
+ i = i + 1
+ j = i + 1
+ end
+end
+
+def func_b
+ print "Function B\n"
+ i = 0
+ while i < 200000
+ i = i + 1
+ j = i + 1
+ end
+ func_c
+end
+
+def func_a
+ print "Function A\n"
+ i = 0
+ while i < 100000
+ i = i + 1
+ j = i + 1
+ end
+ func_b
+end
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Shell/func_abc.sh b/cddl/contrib/dtracetoolkit/Code/Shell/func_abc.sh
new file mode 100755
index 0000000..b44ce57
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Shell/func_abc.sh
@@ -0,0 +1,23 @@
+#!./sh
+
+func_c()
+{
+ echo "Function C"
+ sleep 1
+}
+
+func_b()
+{
+ echo "Function B"
+ sleep 1
+ func_c
+}
+
+func_a()
+{
+ echo "Function A"
+ sleep 1
+ func_b
+}
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Shell/func_slow.sh b/cddl/contrib/dtracetoolkit/Code/Shell/func_slow.sh
new file mode 100755
index 0000000..3407646
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Shell/func_slow.sh
@@ -0,0 +1,35 @@
+#!./sh
+
+func_c()
+{
+ echo "Function C"
+ i=0
+ while [ $i -lt 300 ]
+ do
+ i=`expr $i + 1`
+ done
+}
+
+func_b()
+{
+ echo "Function B"
+ i=0
+ while [ $i -lt 200 ]
+ do
+ i=`expr $i + 1`
+ done
+ func_c
+}
+
+func_a()
+{
+ echo "Function A"
+ i=0
+ while [ $i -lt 100 ]
+ do
+ i=`expr $i + 1`
+ done
+ func_b
+}
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Shell/func_waste.sh b/cddl/contrib/dtracetoolkit/Code/Shell/func_waste.sh
new file mode 100755
index 0000000..bfeeecb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Shell/func_waste.sh
@@ -0,0 +1,23 @@
+#!./sh
+
+func_c()
+{
+ /usr/bin/echo "Function C"
+ sleep 1
+}
+
+func_b()
+{
+ /usr/bin/echo "Function B"
+ sleep 1
+ func_c
+}
+
+func_a()
+{
+ /usr/bin/echo "Function A"
+ sleep 1
+ func_b
+}
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Tcl/func_abc.tcl b/cddl/contrib/dtracetoolkit/Code/Tcl/func_abc.tcl
new file mode 100644
index 0000000..c84acb0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Tcl/func_abc.tcl
@@ -0,0 +1,20 @@
+#!./tclsh
+
+proc func_c {} {
+ puts "Function C"
+ after 1000
+}
+
+proc func_b {} {
+ puts "Function B"
+ after 1000
+ func_c
+}
+
+proc func_a {} {
+ puts "Function A"
+ after 1000
+ func_b
+}
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Code/Tcl/func_slow.tcl b/cddl/contrib/dtracetoolkit/Code/Tcl/func_slow.tcl
new file mode 100644
index 0000000..d4fc598
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Code/Tcl/func_slow.tcl
@@ -0,0 +1,29 @@
+#!./tclsh
+
+proc func_c {} {
+ puts "Function C"
+ set i 0
+ while {$i < 300000} {
+ set i [expr $i + 1]
+ }
+}
+
+proc func_b {} {
+ puts "Function B"
+ set i 0
+ while {$i < 200000} {
+ set i [expr $i + 1]
+ }
+ func_c
+}
+
+proc func_a {} {
+ puts "Function A"
+ set i 0
+ while {$i < 100000} {
+ set i [expr $i + 1]
+ }
+ func_b
+}
+
+func_a
diff --git a/cddl/contrib/dtracetoolkit/Cpu/Readme b/cddl/contrib/dtracetoolkit/Cpu/Readme
new file mode 100644
index 0000000..e0f8698
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/Readme
@@ -0,0 +1,3 @@
+Cpu - CPU based analysis
+
+ This would include activity by CPU.
diff --git a/cddl/contrib/dtracetoolkit/Cpu/cputypes.d b/cddl/contrib/dtracetoolkit/Cpu/cputypes.d
new file mode 100755
index 0000000..213af9e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/cputypes.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -s
+/*
+ * cputypes.d - list CPU type info.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: cputypes.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: cputypes.d
+ *
+ * FIELDS:
+ * CPU CPU ID
+ * CHIP chip ID
+ * PSET processor set ID
+ * LGRP latency group ID
+ * CLOCK clock speed, MHz
+ * TYPE CPU type
+ * FPU floating point identifier types
+ *
+ * SEE ALSO: psrinfo(1M)
+ * /usr/include/sys/processor.h
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 27-Jun-2005 Brendan Gregg Created this.
+ * 27-Jun-2005 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=64k
+
+dtrace:::BEGIN
+{
+ printf("%4s %4s %4s %4s %6s %-16s %s\n",
+ "CPU", "CHIP", "PSET", "LGRP", "CLOCK", "TYPE", "FPU");
+ done[0] = 0;
+}
+
+profile:::profile-10ms
+/done[cpu] == 0/
+{
+ printf("%4d %4d %4d %4d %6d %-16s %s\n",
+ cpu, curcpu->cpu_chip, curcpu->cpu_pset,
+ curcpu->cpu_lgrp, curcpu->cpu_info.pi_clock,
+ stringof(curcpu->cpu_info.pi_processor_type),
+ stringof(curcpu->cpu_info.pi_fputypes));
+ done[cpu]++;
+}
+
+profile:::tick-100ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/cpuwalk.d b/cddl/contrib/dtracetoolkit/Cpu/cpuwalk.d
new file mode 100755
index 0000000..495f64b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/cpuwalk.d
@@ -0,0 +1,72 @@
+#!/usr/sbin/dtrace -s
+/*
+ * cpuwalk.d - Measure which CPUs a process runs on.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This program is for multi-CPU servers, and can help identify if a process
+ * is running on multiple CPUs concurrently or not.
+ *
+ * $Id: cpuwalk.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: cpuwalk.d [duration]
+ * eg,
+ * cpuwalk.d 10 # sample for 10 seconds
+ * cpuwalk.d # sample until Ctrl-C is hit
+ *
+ * FIELDS:
+ * value CPU id
+ * count Number of 1000 hz samples on this CPU
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 22-Sep-2005 Brendan Gregg Created this.
+ * 14-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int MAXCPUID = 1024;
+
+dtrace:::BEGIN
+{
+ $1 ? printf("Sampling...\n") :
+ printf("Sampling... Hit Ctrl-C to end.\n");
+ seconds = 0;
+}
+
+profile:::profile-1000hz
+/pid/
+{
+ @sample[pid, execname] = lquantize(cpu, 0, MAXCPUID, 1);
+}
+
+profile:::tick-1sec
+{
+ seconds++;
+}
+
+profile:::tick-1sec
+/seconds == $1/
+{
+ exit(0);
+}
+
+dtrace:::END
+{
+ printa("\n PID: %-8d CMD: %s\n%@d", @sample);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/dispqlen.d b/cddl/contrib/dtracetoolkit/Cpu/dispqlen.d
new file mode 100755
index 0000000..46742c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/dispqlen.d
@@ -0,0 +1,52 @@
+#!/usr/sbin/dtrace -s
+/*
+ * dispqlen.d - dispatcher queue length by CPU.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: dispqlen.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: dispqlen.d # hit Ctrl-C to end sample
+ *
+ * NOTES: The dispatcher queue length is an indication of CPU saturation.
+ * It is not an indicatior of utilisation - the CPUs may or may not be
+ * utilised when the dispatcher queue reports a length of zero.
+ *
+ * SEE ALSO: uptime(1M)
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 27-Jun-2005 Brendan Gregg Created this.
+ * 14-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Sampling... Hit Ctrl-C to end.\n");
+}
+
+profile:::profile-1000hz
+{
+ @queue[cpu] =
+ lquantize(curthread->t_cpu->cpu_disp->disp_nrunnable, 0, 64, 1);
+}
+
+dtrace:::END
+{
+ printa(" CPU %d%@d\n", @queue);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/intbycpu.d b/cddl/contrib/dtracetoolkit/Cpu/intbycpu.d
new file mode 100755
index 0000000..606f402
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/intbycpu.d
@@ -0,0 +1,49 @@
+#!/usr/sbin/dtrace -s
+/*
+ * intbycpu.d - interrupts by CPU.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: intbycpu.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: intbycpu.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * CPU CPU number
+ * INTERRUPTS number of interrupts in sample
+ *
+ * This is based on a DTrace OneLiner from the DTraceToolkit.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 15-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sdt:::interrupt-start { @num[cpu] = count(); }
+
+dtrace:::END
+{
+ printf("%-16s %16s\n", "CPU", "INTERRUPTS");
+ printa("%-16d %@16d\n", @num);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/intoncpu.d b/cddl/contrib/dtracetoolkit/Cpu/intoncpu.d
new file mode 100755
index 0000000..b32685a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/intoncpu.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -s
+/*
+ * intoncpu.d - print interrupt on-cpu usage.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * $Id: intoncpu.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: intoncpu.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * value Time interrupt thread was on-cpu, ns
+ * count Number of occurrences of at least this time
+ *
+ * BASED ON: /usr/demo/dtrace/intr.d
+ *
+ * SEE ALSO: DTrace Guide "sdt Provider" chapter (docs.sun.com)
+ * intrstat(1M)
+ *
+ * PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sdt:::interrupt-start
+{
+ self->ts = vtimestamp;
+}
+
+sdt:::interrupt-complete
+/self->ts && arg0 != 0/
+{
+ this->devi = (struct dev_info *)arg0;
+ /* this checks the pointer is valid, */
+ self->name = this->devi != 0 ?
+ stringof(`devnamesp[this->devi->devi_major].dn_name) : "?";
+ this->inst = this->devi != 0 ? this->devi->devi_instance : 0;
+ @Time[self->name, this->inst] = quantize(vtimestamp - self->ts);
+ self->name = 0;
+}
+
+dtrace:::END
+{
+ printa("%s%d\n%@d", @Time);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/inttimes.d b/cddl/contrib/dtracetoolkit/Cpu/inttimes.d
new file mode 100755
index 0000000..926a566
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/inttimes.d
@@ -0,0 +1,73 @@
+#!/usr/sbin/dtrace -s
+/*
+ * inttimes.d - print interrupt on-cpu time.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * $Id: inttimes.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: inttimes.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * DEVICE instance name of device driver
+ * TIME (ns) sum of time spent servicing interrupt (ns)
+ *
+ * BASED ON: /usr/demo/dtrace/intr.d
+ *
+ * SEE ALSO:
+ * DTrace Guide "sdt Provider" chapter (docs.sun.com)
+ * intrstat(1M)
+ *
+ * PORTIONS: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sdt:::interrupt-start
+{
+ self->ts = vtimestamp;
+}
+
+sdt:::interrupt-complete
+/self->ts && arg0 != 0/
+{
+ this->devi = (struct dev_info *)arg0;
+ /* this checks the pointer is valid, */
+ self->name = this->devi != 0 ?
+ stringof(`devnamesp[this->devi->devi_major].dn_name) : "?";
+ this->inst = this->devi != 0 ? this->devi->devi_instance : 0;
+ @num[self->name, this->inst] = sum(vtimestamp - self->ts);
+ self->name = 0;
+}
+
+sdt:::interrupt-complete
+{
+ self->ts = 0;
+}
+
+dtrace:::END
+{
+ printf("%11s %16s\n", "DEVICE", "TIME (ns)");
+ printa("%10s%-3d %@16d\n", @num);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/loads.d b/cddl/contrib/dtracetoolkit/Cpu/loads.d
new file mode 100755
index 0000000..681e8f6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/loads.d
@@ -0,0 +1,58 @@
+#!/usr/sbin/dtrace -s
+/*
+ * loads.d - print load averages. Written using DTrace (Solaris 10 3/05).
+ *
+ * These are the same load averages that the "uptime" command prints.
+ * The purpose of this script is to demonstrate fetching these values
+ * from the DTrace language.
+ *
+ * $Id: loads.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: loads.d
+ *
+ * SEE ALSO: uptime(1)
+ *
+ * The first field is the 1 minute average, the second is the 5 minute,
+ * and the third is the 15 minute average. The value represents the average
+ * number of runnable threads in the system, a value higher than your
+ * CPU (core/hwthread) count may be a sign of CPU saturation.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 10-Jun-2005 Brendan Gregg Created this.
+ * 10-Jun-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ /* fetch load averages */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load5a = `hp_avenrun[1] / 65536;
+ this->load15a = `hp_avenrun[2] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+ this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536;
+ this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
+
+ /* print load average */
+ printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d\n",
+ walltimestamp, this->load1a, this->load1b, this->load5a,
+ this->load5b, this->load15a, this->load15b);
+
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/runocc.d b/cddl/contrib/dtracetoolkit/Cpu/runocc.d
new file mode 100755
index 0000000..a2b0469
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/runocc.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -s
+/*
+ * runocc.d - run queue occupancy by CPU.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This prints the dispatcher run queue occupancy by CPU each second.
+ * A consistant run queue occupancy is a sign of CPU saturation.
+ *
+ * The value is similar to that seen in "sar -q", however this is
+ * calculated in a more accurate manner - sampling at 1000 Hertz.
+ *
+ * $Id: runocc.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: runocc.d
+ *
+ * FIELDS:
+ * CPU cpu ID
+ * %runocc % run queue occupancy, sampled at 1000 Hertz
+ *
+ * SEE ALSO: Solaris Internals 2nd Ed, vol 2, CPU chapter.
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 02-Mar-2006 Brendan Gregg Created this.
+ * 24-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+profile-1000hz
+/curthread->t_cpu->cpu_disp->disp_nrunnable/
+{
+ @qocc[cpu] = count();
+}
+
+profile:::tick-1sec
+{
+ normalize(@qocc, 10);
+ printf("\n%8s %8s\n", "CPU", "%runocc");
+ printa("%8d %@8d\n", @qocc);
+ clear(@qocc);
+}
diff --git a/cddl/contrib/dtracetoolkit/Cpu/xcallsbypid.d b/cddl/contrib/dtracetoolkit/Cpu/xcallsbypid.d
new file mode 100755
index 0000000..b08027c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Cpu/xcallsbypid.d
@@ -0,0 +1,51 @@
+#!/usr/sbin/dtrace -s
+/*
+ * xcallsbypid.d - CPU cross calls by PID.
+ * Writen using DTrace (Solaris 10 3/05).
+ *
+ * $Id: xcallsbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: xcallsbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * XCALLS number of cross calls
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 17-Sep-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sysinfo:::xcalls
+{
+ @num[pid, execname] = count();
+}
+
+dtrace:::END
+{
+ printf("%6s %-16s %16s\n", "PID", "CMD", "XCALLS");
+ printa("%6d %-16s %@16d\n", @num);
+}
diff --git a/cddl/contrib/dtracetoolkit/Disk/Readme b/cddl/contrib/dtracetoolkit/Disk/Readme
new file mode 100644
index 0000000..37a5301
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/Readme
@@ -0,0 +1,3 @@
+Disk - Disk based analysis
+
+ These are scripts that analyse I/O activity that has made it to the disks.
diff --git a/cddl/contrib/dtracetoolkit/Disk/bitesize.d b/cddl/contrib/dtracetoolkit/Disk/bitesize.d
new file mode 100755
index 0000000..f2e8ea4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/bitesize.d
@@ -0,0 +1,81 @@
+#!/usr/sbin/dtrace -s
+/*
+ * bitesize.d - analyse disk I/O size by process.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This produces a report for the size of disk events caused by
+ * processes. These are the disk events sent by the block I/O driver.
+ *
+ * If applications must use the disks, we generally prefer they do so
+ * with large I/O sizes.
+ *
+ * $Id: bitesize.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: bitesize.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD command and argument list
+ * value size in bytes
+ * count number of I/O operations
+ *
+ * NOTES:
+ *
+ * The application may be requesting smaller sized operations, which
+ * are being rounded up to the nearest sector size or UFS block size.
+ * To analyse what the application is requesting, DTraceToolkit programs
+ * such as Proc/fddist may help.
+ *
+ * SEE ALSO: seeksize.d, iosnoop
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 31-Mar-2004 Brendan Gregg Created this, build 51.
+ * 10-Oct-2004 " " Rewrote to use the io provider, build 63.
+ * 18-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/*
+ * Process io start
+ */
+io:::start
+{
+ /* fetch details */
+ this->size = args[0]->b_bcount;
+
+ /* store details */
+ @Size[pid, curpsinfo->pr_psargs] = quantize(this->size);
+}
+
+/*
+ * Print final report
+ */
+dtrace:::END
+{
+ printf("\n%8s %s\n", "PID", "CMD");
+ printa("%8d %S\n%@d\n", @Size);
+}
diff --git a/cddl/contrib/dtracetoolkit/Disk/diskhits b/cddl/contrib/dtracetoolkit/Disk/diskhits
new file mode 100755
index 0000000..3d72e4a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/diskhits
@@ -0,0 +1,113 @@
+#!/usr/bin/ksh
+#
+# diskhits - disk access by file offset.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: diskhits 3 2007-08-01 10:50:08Z brendan $
+#
+# This prints how a file was accessed, the locations on a distribution plot.
+# This is for the cache misses only - the file activity that resulted in
+# disk events.
+#
+# USAGE: diskhits pathname
+# eg,
+# diskhits /var/adm/messages
+#
+# FIELDS:
+# Location (KB) The file offset of the disk activity, Kbytes.
+# Size (KB) Size of the disk activity, Kbytes.
+# Total RW Total disk activity, reads + writes.
+#
+# BASED ON: /usr/demo/dtrace/applicat.d
+#
+# SEE ALSO: DTrace Guide "io Provider" chapter (docs.sun.com)
+# iosnoop (DTraceToolkit)
+#
+# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 08-Jun-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+### Usage
+function usage
+{
+ cat <<-END >&2
+ USAGE: diskhits pathname
+ eg,
+ diskhits /var/adm/wtmpx
+ END
+ exit 1
+}
+
+### Process arguments
+if (( $# != 1 )); then
+ usage
+fi
+if [[ $1 == "-h" ]]; then
+ usage
+fi
+pathname=$1
+if [[ ! -e $pathname ]]; then
+ print "ERROR2: file $pathname not found" >&2
+ exit 2
+fi
+
+### Calculate output scale
+report_lines=20
+set -- `ls -l $pathname`
+filesize=$5
+(( file_kb_max = filesize / 1024 ))
+(( scale_kb = filesize / (1024 * report_lines) ))
+if (( file_kb_max < 20 )); then file_kb_max=20; fi
+if (( scale_kb < 1 )); then scale_kb=1; fi
+
+#
+# Run DTrace
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ inline string PATHNAME = "'$pathname'";
+ inline int FILE_KB_MAX = '$file_kb_max';
+ inline int SCALE_KB = '$scale_kb';
+
+ dtrace:::BEGIN
+ {
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ }
+
+ io:::start
+ /args[2]->fi_pathname == PATHNAME/
+ {
+ this->kb = args[2]->fi_offset == -1 ? -1 : args[2]->fi_offset / 1024;
+ @Location = lquantize(this->kb, 0, FILE_KB_MAX, SCALE_KB);
+ @Size = quantize(args[0]->b_bcount/1024);
+ @Total = sum(args[0]->b_bcount/1024);
+ }
+
+ dtrace:::END
+ {
+ printf("Location (KB),");
+ printa(@Location);
+
+ printf("Size (KB),");
+ printa(@Size);
+
+ printa("Total RW: %@d KB\n", @Total);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Disk/hotspot.d b/cddl/contrib/dtracetoolkit/Disk/hotspot.d
new file mode 100755
index 0000000..6ab6ee4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/hotspot.d
@@ -0,0 +1,71 @@
+#!/usr/sbin/dtrace -s
+/*
+ * hotspot.d - plot disk event by location, look for hotspots.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * This simple DTrace script determines if disk activity is occuring in
+ * the one place - a "hotspot". This helps us understand the system's usage
+ * of a disk, it does not imply that the existance or not of a hotspot is
+ * good or bad (often may be good, less seeking).
+ *
+ * $Id: hotspot.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: hotspot.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * Disk disk instance name
+ * Major driver major number
+ * Minor driver minor number
+ * value location, by megabyte
+ * count number of I/O operations
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 07-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+inline int DISK_MB_MAX = 1000000; /* max size of a single disk */
+inline int REPORT_SCALE_MB = 1000; /* output step size for report */
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/*
+ * Process disk event
+ */
+io:::start
+{
+ this->mb = args[0]->b_blkno / 2048;
+ @Block[args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor] =
+ lquantize(this->mb, 0, DISK_MB_MAX, REPORT_SCALE_MB);
+}
+
+/*
+ * Print final report
+ */
+dtrace:::END
+{
+ printa("Disk: %s Major,Minor: %d,%d\n%@d\n", @Block);
+}
diff --git a/cddl/contrib/dtracetoolkit/Disk/iofile.d b/cddl/contrib/dtracetoolkit/Disk/iofile.d
new file mode 100755
index 0000000..255057a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/iofile.d
@@ -0,0 +1,79 @@
+#!/usr/sbin/dtrace -s
+/*
+ * iofile.d - I/O wait time by filename and process.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This prints the total I/O wait times for each filename by process.
+ * This can help determine why an application is performing poorly by
+ * identifying which file they are waiting on, and the total times.
+ * Both disk and NFS I/O are measured.
+ *
+ * $Id: iofile.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: iofile.d # wait, then hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * CMD Process name
+ * TIME Total wait time for disk events, us
+ * FILE File pathname
+ *
+ * BASED ON: /usr/demo/dtrace/iocpu.d
+ *
+ * SEE ALSO: iosnoop, iotop
+ *
+ * PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 24-Jul-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/* print header */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/* save time at start */
+io:::wait-start
+{
+ self->start = timestamp;
+}
+
+/* process event */
+io:::wait-done
+/self->start/
+{
+ /*
+ * wait-done is used as we are measing wait times. It also
+ * is triggered when the correct thread is on the CPU, obviating
+ * the need to link process details to the start event.
+ */
+ this->elapsed = timestamp - self->start;
+ @files[pid, execname, args[2]->fi_pathname] = sum(this->elapsed);
+ self->start = 0;
+}
+
+/* print report */
+dtrace:::END
+{
+ normalize(@files, 1000);
+ printf("%6s %-12s %8s %s\n", "PID", "CMD", "TIME", "FILE");
+ printa("%6d %-12.12s %@8d %s\n", @files);
+}
diff --git a/cddl/contrib/dtracetoolkit/Disk/iofileb.d b/cddl/contrib/dtracetoolkit/Disk/iofileb.d
new file mode 100755
index 0000000..e7572f3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/iofileb.d
@@ -0,0 +1,59 @@
+#!/usr/sbin/dtrace -s
+/*
+ * iofileb.d - I/O bytes by filename and process.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This prints a summary of requested disk activity by pathname,
+ * providing totals of the I/O events in bytes. It is a companion to the
+ * iofile.d script - which prints in terms of I/O wait time, not bytes.
+ * I/O wait time is a better metric for understanding performance issues.
+ * Both disk and NFS I/O are measured.
+ *
+ * $Id: iofileb.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: iofileb.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD command name
+ * KB Kilobytes of disk I/O
+ * FILE Full pathname of the file
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 20-Feb-2006 Brendan Gregg Created this.
+ * 20-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+io:::start
+{
+ @files[pid, execname, args[2]->fi_pathname] = sum(args[0]->b_bcount);
+}
+
+dtrace:::END
+{
+ normalize(@files, 1024);
+ printf("%6s %-12s %6s %s\n", "PID", "CMD", "KB", "FILE");
+ printa("%6d %-12.12s %@6d %s\n", @files);
+}
diff --git a/cddl/contrib/dtracetoolkit/Disk/iopending b/cddl/contrib/dtracetoolkit/Disk/iopending
new file mode 100755
index 0000000..ef9d4da
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/iopending
@@ -0,0 +1,261 @@
+#!/usr/bin/ksh
+#
+# iopending - Print a plot for the number of pending disk I/O events.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring disk events that have made it past system caches.
+# By plotting a distribution graph of the number of pending events, the
+# "serialness" or "parallelness" of disk behaviour can be distinguished.
+#
+# $Id: iopending 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: iopending [-c] [-d device] [-f filename]
+# [-m mount_point] [interval [count]]
+#
+# -c # clear the screen
+# -d device # instance name to snoop (eg, dad0)
+# -f filename # full pathname of file to snoop
+# -m mount_point # this FS only (will skip raw events)
+# eg,
+# iopending # default output, 5 second intervals
+# iopending 1 # 1 second samples
+# iopending -c # clear the screen
+# iopending 5 12 # print 12 x 5 second samples
+#
+# FIELDS:
+# value number of pending events, 0 == idle
+# count number of samples @ 1000 Hz
+# load 1 min load average
+# disk_r total disk read Kbytes for sample
+# disk_w total disk write Kbytes for sample
+#
+# SEE ALSO: iosnoop, iotop
+#
+# IDEA: Dr Rex di Bona (Sydney, Australia)
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 01-Nov-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_device=0; opt_file=0; opt_mount=0; opt_clear=0;
+opt_def=1; filter=0; device=.; filename=.; mount=.
+interval=5; count=-1
+
+### process options
+while getopts cd:f:hm: name
+do
+ case $name in
+ c) opt_clear=1 ;;
+ d) opt_device=1; device=$OPTARG ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ h|?) cat <<-END >&2
+ USAGE: iopending [-c] [-d device] [-f filename]
+ [-m mount_point] [interval [count]]
+
+ -c # clear the screen
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ eg,
+ iopending # default output, 5 second samples
+ iopending 1 # 1 second samples
+ iopending -m / # snoop events on filesystem / only
+ iopending 5 12 # print 12 x 5 second samples
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_device || opt_mount || opt_file )); then
+ filter=1
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_clear = '$opt_clear';
+ inline int OPT_device = '$opt_device';
+ inline int OPT_mount = '$opt_mount';
+ inline int OPT_file = '$opt_file';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int FILTER = '$filter';
+ inline string DEVICE = "'$device'";
+ inline string FILENAME = "'$filename'";
+ inline string MOUNT = "'$mount'";
+ inline string CLEAR = "'$clearstr'";
+
+ inline int MAX_PENDING = 32; /* max pending value */
+
+ #pragma D option quiet
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ disk_r = 0;
+ disk_w = 0;
+ pending = 0;
+
+ printf("Tracing... Please wait.\n");
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::start,
+ io:genunix::done
+ {
+ /* default is to trace unless filtering, */
+ this->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? this->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? this->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? this->ok = 1 : 1;
+ }
+
+ /*
+ * Store entry details
+ */
+ io:genunix::start
+ /this->ok/
+ {
+ /* track bytes */
+ disk_r += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
+ disk_w += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
+
+ /* increase event pending count */
+ pending++;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /this->ok/
+ {
+ /* decrease event pending count */
+ pending--;
+ }
+
+ /*
+ * Prevent pending from underflowing
+ * this can happen if this program is started during disk events.
+ */
+ io:genunix::done
+ /pending < 0/
+ {
+ pending = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ profile:::profile-1000hz
+ {
+ @out = lquantize(pending, 0, MAX_PENDING, 1);
+ }
+
+ /*
+ * Print Report
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert counters to Kbytes */
+ disk_r /= 1024;
+ disk_w /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, disk_r: %6d KB, disk_w: %6d KB",
+ walltimestamp, this->load1a, this->load1b, disk_r, disk_w);
+
+ /* print output */
+ printa(@out);
+
+ /* clear data */
+ trunc(@out);
+ disk_r = 0;
+ disk_w = 0;
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Cleanup for Ctrl-C
+ */
+ dtrace:::END
+ {
+ trunc(@out);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Disk/seeksize.d b/cddl/contrib/dtracetoolkit/Disk/seeksize.d
new file mode 100755
index 0000000..963d9ad
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Disk/seeksize.d
@@ -0,0 +1,85 @@
+#!/usr/sbin/dtrace -s
+/*
+ * seeksize.d - analyse disk head seek distance by process.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * Disk I/O events caused by processes will in turn cause the disk heads
+ * to seek. This program analyses those seeks, so that we can determine
+ * if processes are causing the disks to seek in a "random" or "sequential"
+ * manner.
+ *
+ * $Id: seeksize.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: seeksize.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD command and argument list
+ * value distance in disk blocks (sectors)
+ * count number of I/O operations
+ *
+ * SEE ALSO: bitesize.d, iosnoop
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 11-Sep-2004 Brendan Gregg Created this.
+ * 10-Oct-2004 " " Rewrote to use the io provider.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+self int last[dev_t];
+
+/*
+ * Process io start
+ */
+io:genunix::start
+/self->last[args[0]->b_edev] != 0/
+{
+ /* calculate seek distance */
+ this->last = self->last[args[0]->b_edev];
+ this->dist = (int)(args[0]->b_blkno - this->last) > 0 ?
+ args[0]->b_blkno - this->last : this->last - args[0]->b_blkno;
+
+ /* store details */
+ @Size[pid, curpsinfo->pr_psargs] = quantize(this->dist);
+}
+
+io:genunix::start
+{
+ /* save last position of disk head */
+ self->last[args[0]->b_edev] = args[0]->b_blkno +
+ args[0]->b_bcount / 512;
+}
+
+/*
+ * Print final report
+ */
+dtrace:::END
+{
+ printf("\n%8s %s\n", "PID", "CMD");
+ printa("%8d %S\n%@d\n", @Size);
+}
diff --git a/cddl/contrib/dtracetoolkit/Docs/Contents b/cddl/contrib/dtracetoolkit/Docs/Contents
new file mode 100644
index 0000000..525fd05
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Contents
@@ -0,0 +1,152 @@
+Contents - Command Summary
+
+ The following is a list of commands found in the DTraceToolkit, along
+ with their directory location.
+
+Generally commands that end in a ".d" are DTrace scripts, and commands
+that don't are DTrace scripts wrapped in another language (eg, shell
+or Perl). See the Docs/Readme for instructions for finding their docs.
+
+DTraceToolkit/
+ dexplorer run a series of scripts and archive output
+ dtruss process syscall info. DTrace truss
+ dvmstat vmstat by PID/name/command
+ errinfo report syscall failures with details
+ execsnoop snoop process execution as it occurs
+ iosnoop snoop I/O events as they occur
+ iopattern print disk I/O pattern
+ iotop display top disk I/O events by process
+ opensnoop snoop file opens as they occur
+ procsystime analyse process system call times
+ rwsnoop snoop read/write events
+ rwtop display top read/write bytes by process
+ statsnoop snoop file stats as they occur
+ Apps/
+ httpdstat.d realtime httpd statistics
+ nfswizard.d NFS client activity wizard
+ shellsnoop snoop live shell activity
+ weblatency.d website latency statistics
+ Cpu/
+ cputypes.d list CPU types
+ cpuwalk.d measure which CPUs a process runs on
+ dispqlen.d dispatcher queue length by CPU
+ intbycpu.d interrupts by CPU
+ intoncpu.d interrput on-cpu usage
+ inttimes.d interrput on-cpu time total
+ loads.d print load averages
+ runocc.d run queue occupancy by CPU
+ xcallsbypid.d CPU cross calls by PID
+ Disk/
+ bitesize.d print disk event size report
+ diskhits disk access by file offset
+ hotspot.d print disk event by location
+ iofile.d I/O wait time by filename and process
+ iofileb.d I/O bytes by filename and process
+ iopending plot number of pending disk events
+ pathopens.d pathnames successfully opened count
+ seeksize.d print disk seek size report
+ Docs/
+ oneliners.txt DTrace oneliners
+ FS/
+ fsrw.d file system read/write event tracing
+ fspaging.d file system read/write and paging tracing
+ rfsio.d read FS I/O stats, with cache miss rate
+ rfileio.d read file I/O stats, with cache miss rate
+ vopstat vnode interface statistics
+ Java/
+ j_*.d 18 scripts for tracing Java using the hotspot provider
+ JavaScript/
+ js_*.d 14 scripts for JavaScript with the Mozilla provider
+ Kernel/
+ cputimes print time by Kernel/Idle/Process
+ cpudists time distribution by Kernel/Idle/Process
+ cswstat.d context switch time statistics
+ dnlcps.d DNLC stats by process
+ dnlcsnoop.d snoop DNLC activity
+ dnlcstat DNLC statistics
+ kstat_types.d trace kstat reads with type info
+ modcalls.d kernel function calls by module name
+ priclass.d priority distribution by scheduling class
+ pridist.d process priority distribution
+ putnexts.d trace who is putting to which streams module
+ whatexec.d examine the type of files executed
+ Locks/
+ lockbyproc.d lock time by process name
+ lockbydist.d lock time distribution by process name
+ Mem/
+ anonpgpid.d anonymous memory paging info by PID on CPU
+ minfbypid.d minor faults by PID
+ minfbyproc.d minor faults by process name
+ pgpginbypid.d pages paged in by PID
+ pgpginbyproc.d pages paged in by process name
+ swapinfo.d print virtual memory info
+ vmbypid.d virtual memory stats by PID
+ vmstat.d vmstat demo using DTrace
+ vmstat-p.d vmstat -p demo using DTrace
+ xvmstat extended vmstat demo using DTrace
+ Misc/
+ guess.d guessing game
+ wpm.d words per minute tracing
+ woof.d audio alert for new processes
+ Net/
+ connections print inbound TCP connections by process
+ icmpstat.d print ICMP statistics
+ tcpsnoop snoop TCP network packets by process, Solaris 10 3/05
+ tcpsnoop_snv snoop TCP network packets by process, Solaris Nevada
+ tcpsnoop.d snoop TCP network packets by process, Solaris 10 3/05
+ tcpsnoop_snv.d snoop TCP network packets by process, Solaris Nevada
+ tcpstat.d print TCP statistics
+ tcptop display top TCP network packets by PID, Solaris 10 3/05
+ tcptop_snv display top TCP network packets by PID, Solaris Nevada
+ tcpwdist.d simple TCP write distribution by process
+ udpstat.d print UDP statistics
+ Perl/
+ pl_*.d 12 scripts for tracing Perl
+ Php/
+ php_*.d 12 scripts for tracing Php
+ Proc/
+ crash.d crashed application report
+ creatbyproc.d snoop file creat() by process name
+ dappprof profile user and lib function usage
+ dapptrace trace user and lib function usage
+ fddist file descriptor usage distribution
+ fileproc.d snoop files opened by process
+ kill.d snoop process signals
+ lastwords print syscalls before exit
+ mmapfiles.d mmap'd files by process
+ newproc.d snoop new processes
+ pfilestat show I/O latency break down by FD
+ pidpersec.d print new PIDs per sec
+ readbytes.d read bytes by process name
+ readdist.d read distribution by process name
+ rwbbypid.d read/write bytes by PID
+ rwbypid.d read/write calls by PID
+ rwbytype.d read/write bytes by vnode type
+ sampleproc sample processes on the CPUs
+ shortlived.d check short lived process time
+ sigdist.d signal distribution by process name
+ stacksize.d measure stack size for running threads
+ sysbypid.d system stats by PID
+ syscallbyproc.d system calls by process name
+ syscallbypid.d system calls by process ID
+ threaded.d sample multi-threaded CPU usage
+ topsysproc display top syscalls by process name
+ writebytes.d write bytes by process name
+ writedist.d write distribution by process name
+ Python/
+ py_*.d 14 scripts for tracing Python
+ Shell/
+ sh_*.d 15 scripts for tracing the Bourne shell
+ System/
+ sar-c.d sar -c demo using DTrace
+ syscallbysysc.d system calls by system call
+ topsyscall display top system call type
+ uname-a.d uname -a demo using DTrace
+ Tcl/
+ tcl_*.d 15 scripts for tracing Tcl
+ User/
+ setuids.d snoop setuid calls
+ Zones/
+ zvmstat vmstat info by zone
+
+Total: 230 scripts
diff --git a/cddl/contrib/dtracetoolkit/Docs/Examples b/cddl/contrib/dtracetoolkit/Docs/Examples
new file mode 120000
index 0000000..3098326
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Examples
@@ -0,0 +1 @@
+../Examples \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Docs/Faq b/cddl/contrib/dtracetoolkit/Docs/Faq
new file mode 100644
index 0000000..4919cac
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Faq
@@ -0,0 +1,126 @@
+Faq - Frequently Asked Questions
+
+ The following may serve as a guide to the DTraceToolkit.
+
+16-May-2005, ver 0.30 (first version of the FAQ)
+
+The DTraceToolkit is new, and as such there hasn't been many questions asked.
+This may be better called a "possibly asked questions" :)
+
+
+Questions
+
+1. Intro
+1.1. What is the DTraceToolkit?
+1.2. Who wrote the DTraceToolkit?
+1.3. Where do I get support?
+1.4. Am I now a performance tuning expert?
+1.5. Will this solve all my performance problems?
+1.6. So the DTraceToolkit *is* DTrace?
+
+2. Toolkit
+2.1. What is in it?
+2.2. What performance effect can the DTraceToolkit cause?
+
+3. Contributing
+3.1. Where do I send bugs?
+
+
+Answers
+
+1. Intro
+
+1.1. What is the DTraceToolkit?
+
+ The DTraceToolkit is a collection of tools written using DTrace for
+ the Solaris 10[tm] OS by Sun Microsystems[tm]. Many of these scripts
+ will also work on OpenSolaris.
+
+1.2. Who wrote the DTraceToolkit?
+
+ Volunteers of the DTrace and OpenSolaris community. Check the scripts
+ themselves, Docs/Contrib, Docs/Who and Docs/History.
+
+1.3. Where do I get support?
+
+ As the DTraceToolkit is a freeware product, there is no official company
+ offering support for this. Sun Microsystems does not support this. If you
+ post messages to the DTrace forums found in the Docs/Links file, a
+ volunteer may help you out.
+
+1.4. Am I now a performance tuning expert?
+
+ The DTraceToolkit does not turn people into performance tuning experts in
+ the same way that owning a set of golf clubs won't make you a professional
+ golfer. Experience and understanding are necessary. The toolkit certainly
+ helps by fetching the data in an easy way, and also by providing some
+ documentation. So it is valuable, but not magical.
+
+1.5. Will this solve all my performance problems?
+
+ This is similar to the previous point; the DTraceToolkit is valuable
+ for it's scripts and documentation, but it's no magical product.
+ Understanding and experience are necessary.
+
+1.6. So the DTraceToolkit *is* DTrace?
+
+ The DTraceToolkit is one use of DTrace, but there is far more to DTrace
+ than just the toolkit. DTrace allows people to write their own customised
+ scripts to solve a wide number of problems.
+
+ Think of the DTraceToolkit as a starting point. Maybe your problem has
+ a solution in the kit. Maybe changing one of the toolkit programs slightly
+ is what you want. Finally you may need to write your script from scratch.
+
+
+2. Toolkit
+
+2.1. What is in it?
+
+ Read the Guide file for a table of contents, and Docs/Contents for a
+ list of commands.
+
+2.2. What performance effect can the DTraceToolkit cause?
+
+ Enabling DTrace to monitor events has little effect on the system,
+ especially when compared to the disruptive behaviour of truss (See
+ http://www.brendangregg.com/DTrace/dtracevstruss.html for a comparison).
+
+ It really boils down to how often the events occur that you are monitoring.
+ The following numbers have been provided as an approximation:
+
+ 1. Fixed rate scripts. For example, dispqlen.d samples at 1000 hz.
+ The impact will be negligible, close to 0% CPU. (in testing, 0.1% CPU).
+
+ 2. Demand rated scripts. For example, iosnoop probes disk I/O events.
+ The impact depends on the rate of events, for many servers the disk
+ events would be slow enough for this to be less than 0.2% CPU.
+ Scripts such as execsnoop would expect even fewer events, their impact
+ would be close to 0.0% CPU. However scripts that monitor potentially
+ very rapid events will have a greater impact, for example running
+ dapptrace on Xorg (over 6000 lines of output per second) was consuming
+ around 10% of a CPU to do so.
+
+ 3. Heavy voodoo scripts. A few scripts in the toolkit must probe either
+ a ton of different events, or very rapid events, or both. They are
+ going to hurt and there is no way around it. Scripts such as cputimes
+ and cpudists trace very frequent events, and can chew around 5% of
+ the CPUs; scripts such as dapptrace and dappprof trace extreamly
+ frequent events, and can chew over 20%.
+
+ There is an emphasis in the DTraceToolkit to write demand rated scripts
+ that measure the fewest events, such that their impact is close to 0.0%
+ CPU usage. Some scripts are fixed rate, which are safer as their impact
+ has a known upper bound, and are most suitable to run in production.
+
+ There are additional notes in Notes/ALLoverhead_notes.txt about the
+ overheads for running DTrace.
+
+
+3. Contributing
+
+3.1. Where do I send bugs?
+
+ The DTraceToolkit maintainer. See the Docs/Maintainer file.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/History b/cddl/contrib/dtracetoolkit/Docs/History
new file mode 100644
index 0000000..d92bf11
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/History
@@ -0,0 +1,249 @@
+History - History of the DTraceToolkit
+
+------------------------------------------------------------------------------
+20-Apr-2005 Brendan Gregg Idea
+ For a while I had thought that a DTrace toolkit would be a nice
+ idea, but on this day it became clear. I was explaining DTrace to
+ an SSE from Sun (Canberra, Australia), who had a need for using
+ DTrace but didn't have the time to sit down and write all the
+ tools he was after. It simply made sense to have a DTrace toolkit
+ that people could download or carry around a copy to use. Some
+ people would write DTrace tools, others would use the toolkit.
+------------------------------------------------------------------------------
+15-May-2005 Brendan Gregg Version 0.30
+ I had discussed the idea of a DTrace toolkit with the Sun PAE guys in
+ Adelaide, Australia. It was making more sense now. It would be much
+ like the SE Toolkit, not just due to the large number of sample
+ scripts provided, but also due to the role it would play: few people
+ wrote SE Toolkit programs, more people used it as a toolkit. While
+ we would like a majority of Solaris users to write DTrace scripts,
+ the reality is that many would want to use a prewritten toolkit.
+ Today I created the toolkit as version 0.30, with 11 main directories,
+ a dozen scripts, man pages and a structure for documentation.
+------------------------------------------------------------------------------
+16-May-2005 Brendan Gregg OneLiners
+ I've been using the toolkit for a day now (wow!), and have noticed
+ a few problems I've been fixing. One of them was the dtrace oneliners.
+ I have them in two files, Docs/oneliners.txt and the examples in
+ Docs/Examples/oneliners_examples.txt. The problem is that when I'm
+ looking for a script, I'm looking in Docs/Commands - a list of the
+ seperate script files, or I'm doing an ls or find. Ok, so I've now
+ made each one liner a seperate script. This seems at first pretty
+ silly since they are oneliners and shouldn't deserve an entire script
+ each, but I've found having them as seperate scripts makes them far
+ easier to find and use. The scripts and man page for each script do
+ point out the fact that it's a one liner.
+------------------------------------------------------------------------------
+17-May-2005 Brendan Gregg Version 0.33
+ Version 0.33 with 33 scripts. Maybe I should make the version number
+ equal the script count. :) I just finished dtruss, dapptrace and
+ dappprof.
+------------------------------------------------------------------------------
+08-Jun-2005 Brendan Gregg Name changes.
+ I've renamed Docs/Commands to Docs/Contents. I found myself typing
+ "more Docs/Contents" by mistake a lot. ok, maybe it made more sense
+ to call it Contents after all. I've also made a symlink to it called
+ Index.
+------------------------------------------------------------------------------
+08-Jun-2005 Brendan Gregg Version 0.35
+ Version 0.35 with 35 scripts. Also touched up procsystime and some
+ man pages. Added the CDDL version 1.0.
+------------------------------------------------------------------------------
+09-Jun-2005 Brendan Gregg Version 0.42
+ Added 7 more scripts.
+------------------------------------------------------------------------------
+14-Jun-2005 Brendan Gregg Version 0.57
+ Added heaps of new scripts. Now at 57 scripts.
+------------------------------------------------------------------------------
+17-Jun-2005 Brendan Gregg Version 0.61
+ Restyled many commands.
+------------------------------------------------------------------------------
+28-Jun-2005 Brendan Gregg Version 0.70
+ Added several commands including dexplorer. Developed a few useful
+ variants of classic scripts while writing dexplorer, and have added
+ them to the toolkit (I kept wanting to run them individually but
+ not have to run an entire dexplorer).
+------------------------------------------------------------------------------
+25-Jul-2005 Brendan Gregg Version 0.77
+ Added tcpsnoop.d, tcpsnoop, tcptop. Because of their addition I have
+ dropped tcpwbytes.d and tcpwlist. These are complex scripts, but they
+ track TCP in an accurate manner. However! also because they are
+ complex scripts, I expect they will require maintainence for newer
+ versions of [Open]Solaris, as various probes may change. They will
+ become much more stable once a network provider has been added to
+ DTrace (which may be some time away).
+ Also added iotop, and updated a bunch of scripts. A lot of work went
+ into this version, although the version change doesn't reflect that
+ (I'm still keeping the version number == to number of scripts).
+ Also added rwsnoop, rwtop, and more.
+------------------------------------------------------------------------------
+26-Jul-2005 Brendan Gregg Version 0.82
+ Many new scripts added, many updates. This is a major release.
+------------------------------------------------------------------------------
+17-Sep-2005 Brendan Gregg Version 0.83
+ A few scripts have been updated so that they work better.
+ execsnoop, iosnoop, opensnoop and rwsnoop will be more responsive
+ (increased switchrate).
+------------------------------------------------------------------------------
+22-Sep-2005 Brendan Gregg Version 0.84
+ Some updates, fixed some bugs (cputimes, cpudists). Added cpuwalk.d.
+------------------------------------------------------------------------------
+15-Nov-2005 Brendan Gregg Sys Admin Magazine
+ Ryan Matteson wrote an article on the DTraceToolkit which has been
+ printed in Sys Admin Magazine, December 2005. It's quite good,
+ and made it as the feature article - which means it will be available
+ online for some time. Thanks Matty, and Sys Admin Magazine!
+ "Observing I/O Behavior with the DTraceToolkit"
+ http://www.samag.com/documents/sam0512a/
+------------------------------------------------------------------------------
+01-Dec-2005 Brendan Gregg Version 0.88
+ Many scripts were updated. Added the Apps category. I had planned
+ to add some key scripts, but they haven't made it out of testing yet.
+------------------------------------------------------------------------------
+03-Dec-2005 Brendan Gregg Version 0.89
+ Added nfswisard.d, fixed a minor bug with tcp* tools (see
+ dtrace-discuss mailing list).
+------------------------------------------------------------------------------
+12-Jan-2006 Brendan Gregg Version 0.92
+ Added a few scripts including rwbytype.d. Fixed several issues.
+------------------------------------------------------------------------------
+09-Apr-2006 Brendan Gregg Solaris Internals 2nd Edition
+ In the past few months I have been contributing to Solaris Internals
+ 2nd Edition. This book (now two volumes) is really amazing. The 2nd
+ volume does use the DTraceToolkit where appropriate, and covers loads
+ of useful topics. While writing and reviewing material for Solaris
+ Internals, I've had numerous new ideas for DTrace scripts. Not only
+ that, but a few people have managed to send me well styled, carefully
+ tested, well considered DTrace scripts for inclusion in the toolkit.
+------------------------------------------------------------------------------
+20-Apr-2006 Brendan Gregg TCP bug fixed
+ Stefan Parvu sent me a bug for the tcp* scripts: on build 31+ they
+ error'd on the symbol SS_TCP_FAST_ACCEPT. This symbol was
+ renamed to SS_DIRECT (I checked the code, they are used in the
+ same way). Ironically, when I first wrote the scripts I had hardcoded
+ the value 0x00200000, then rewrote it "properly" by importing
+ the header files and using the symbol name. Had I been lazy and left
+ it hardcoded, the bug would never have eventuated. Not to worry,
+ it has returned to being hardcoded, so that it works on all builds
+ (until something else changes).
+------------------------------------------------------------------------------
+21-Apr-2006 Brendan Gregg Restyled - again!
+ I've been writing the "DTraceToolkit Style Guide", to document
+ the style that these scripts obey. It is quite strict, and sets
+ the bar fairly high. I've been warned that it may cause very few
+ people to ever contribute scripts, which is fine. At some point
+ I'll carefully explain the mentality behind this, but in a nutshell:
+ Users on critical production servers expect the tools to be
+ accurate, carefully tested, and cause no undocumented harm.
+------------------------------------------------------------------------------
+22-Apr-2006 Brendan Gregg Docs changes
+ The "Contrib" file was merged into the "Who" file. In hindsight
+ it is better to keep this data together than to split it up.
+------------------------------------------------------------------------------
+24-Apr-2006 Brendan Gregg Version 0.96
+ The toolkit now contains 104 scripts, however I'll keep the version
+ number < 1.00 until the dust has settled on these new scripts.
+ There is some special significance with version 1.00, it would
+ imply that every script had been tested for some time - not that
+ I've just added a few.
+ There is a new main directory, FS for file system related scripts.
+ There are some interesting scripts in there, from or based on
+ Solaris Internals 2nd ed, vol 2.
+------------------------------------------------------------------------------
+30-Sep-2007 Brendan Gregg Version 0.99
+ It's been a year and a half since the last release, and a lot has
+ happneed. Firstly, the DTraceToolkit has featured in the Prentice Hall
+ book,
+ Solaris Performance and Tools
+ DTrace and mdb techniques for Solaris 10 and OpenSolaris
+
+ written by Richard McDougall, Jim Mauro and myself. It is a companion
+ book to "Solaris Internals 2nd edition" by Richard McDougall and
+ Jim Mauro. If you are serious about becomming a DTrace guru,
+ especially on Solaris, then please study both books. (Yes, I realize
+ that many people are using the DTraceToolkit because they don't have
+ the time or don't want to become DTrace gurus; well, so long as
+ you are using DTrace anyway :). The performance book was a great relief
+ to write - since we were able to put to print much performance wisdom
+ and knowledge that was begging to be documented.
+
+ Then, in late 2006 I joined an advanced products engineering team
+ at Sun in San Francisco, a team which includes the three members of
+ team DTrace. It's been a great opportunity to learn from such
+ engineers, and to contribute more directly to DTrace. So far my work
+ has included writing a JavaScript provider, integrated inet_ntoa()
+ style functions into DTrace, and prototying DTrace IP, TCP and UDP
+ providers.
+
+ Working on the network providers is good news for the DTraceToolkit,
+ as it will indirectly help the tcp* scripts become more stable. Yes,
+ those scripts have broken a few more times during the last 18 months,
+ sorry about that, and it will keep happening until we have stable
+ network providers. This is why I only ever wrote three tcp* scripts,
+ and not at least a dozen, which I'd really like to do.
+
+ I did leave my pile of old SPARC and x86 development servers behind
+ in Australia, and brought over a couple of laptops. That has made me
+ more dependant on Stefan for testing the toolkit - especially on SPARC.
+
+ So, it's been about 18 months since the last release, which is
+ mostly due to having less spare time due to moving countries and
+ learning a new job.
+
+ Michelle from Sun docs has been asking for a newer version of the
+ DTraceToolkit for the OpenSolaris starter kit, which is why I'm
+ releasing this version now and not waiting a few more weeks as
+ I complete bug fixes.
+
+ So the good and the bad news for this release, starting with the bad,
+
+ Bad: tcpsnoop/tcptop still don't work on some Solaris 10 releases.
+ I've added versions that should work on Solaris Nevada and OpenSolaris
+ for releases from around late 2007. They are likely to break again.
+ The real answer, as always, is for stable nework providers to be
+ integrated into Solaris.
+
+ Many of the exciting new language provider scripts in this release
+ currently require downloading, patching and compling of the language
+ interpreter to get working. See the Readme file in each directory
+ for pointers.
+
+ Good: many more scripts to cover the new DTrace language providers
+ that are available (the DTraceToolkit is now 227 scripts). Many
+ updates to the Notes directory. Bug fixes. Some new categories
+ other than for scripts: Code - for simple programs to DTrace (and
+ for the example files), and Snippits - for useful lumps of DTrace
+ code to copy-n-paste from. The man pages are also making room
+ for documenting both stability and supported operating systems for
+ each script - now that DTrace exists for MacOS X Leopard, the
+ DTraceToolkit will begin supporting multiple operating systems.
+
+ This can be thought of as a developer's release of the DTraceToolkit -
+ to help people start using DTrace with Perl, Python, Ruby, Php, Java,
+ JavaScript, Shell and Tcl. I've written about 15 scripts for each
+ language, to cover the basics and to show the way for deeper analysis.
+ The scripts are also similar from one language to another, having
+ devoleped a tried-and-tested group of scripts for analyzing real world
+ issues - it made sense to repeat these scripts for every language
+ possible. To see what I mean, try reading,
+
+ Examples/j_cputime_example.txt Examples/py_cputime_example.txt
+ Examples/js_cputime_example.txt Examples/rb_cputime_example.txt
+ Examples/php_cputime_example.txt Examples/sh_cputime_example.txt
+ Examples/pl_cputime_example.txt Examples/tcl_cputime_example.txt
+
+ You might notice that the example files are more clearly and carefully
+ explained. Claire (my wife), wrote close to one hundred of them for
+ this release while I focused on writing and testing the scripts.
+ Claire has worked as a SysAdmin and as an IT instructor, and is well
+ skilled at explaining relavent technical details. And she can spell
+ much better than I can. :)
+
+ The future: I still have many new scripts and some bug fixes in mind,
+ as well as generally improving the Notes and Examples provided.
+ Hopefully it won't be too many months before you see another
+ release. Check here for the lastest installment,
+
+ http://www.opensolaris.org/os/community/dtrace/dtracetoolkit
+------------------------------------------------------------------------------
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/Index b/cddl/contrib/dtracetoolkit/Docs/Index
new file mode 120000
index 0000000..9ae9ea0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Index
@@ -0,0 +1 @@
+Contents \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Docs/Links b/cddl/contrib/dtracetoolkit/Docs/Links
new file mode 100644
index 0000000..182bb54
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Links
@@ -0,0 +1,30 @@
+Links - DTrace links
+
+ http://www.opensolaris.org/os/community/dtrace/dtracetoolkit
+ DTraceToolkit Home
+
+ http://www.opensolaris.org/os/community/dtrace
+ OpenSolaris DTrace site
+
+ http://www.brendangregg.com/dtrace.html
+ DTraceToolkit
+ DTrace Tools
+
+ http://www.sun.com/bigadmin/content/dtrace
+ DTrace site on BigAdmin
+
+ http://docs.sun.com/db/doc/817-6223
+ DTrace Guide (answerbook)
+
+ http://blogs.sun.com/roller/page/bmc
+ Bryan Cantrill's Blog (DTrace Team)
+
+ http://blogs.sun.com/roller/page/ahl
+ Adam Leventhal's Blog (DTrace Team)
+
+ http://blogs.sun.com/mws
+ Mike Shapiro's Blog (DTrace Team)
+
+ http://www.solarisinternals.com/si/dtrace/index.php
+ DTrace scripts by Richard McDougall
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/Maintainer b/cddl/contrib/dtracetoolkit/Docs/Maintainer
new file mode 100644
index 0000000..3a8bb42
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Maintainer
@@ -0,0 +1,6 @@
+Maintainer - The DTraceToolkit Author and Maintainer,
+
+ Brendan Gregg
+ brendan@sun.com (or see website below for emailaddr)
+ http://www.brendangregg.com
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/Notes b/cddl/contrib/dtracetoolkit/Docs/Notes
new file mode 120000
index 0000000..e0856fe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Notes
@@ -0,0 +1 @@
+../Notes \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Docs/Readme b/cddl/contrib/dtracetoolkit/Docs/Readme
new file mode 100644
index 0000000..1f98f38
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Readme
@@ -0,0 +1,21 @@
+Docs - DTraceToolkit Documentation
+
+ Docs/Contents summary of toolkit commands
+ Examples examples of command usage
+ Notes notes on commands
+
+The following may be followed to learn about a DTraceToolkit command,
+
+ 1. read "Contents" for a command name and toolkit location.
+ 2. run the command with "-h" to check it's usage.
+ 3. read the manpage from Man/man1m.
+ 4. read the examples from Examples.
+ 5. read the notes from Notes.
+ 6. read the script itself
+
+Try the following to discover all docs related to a command, eg iosnoop,
+
+ find . | grep iosnoop
+
+best run from the DTraceToolkit root directory.
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/ToDo b/cddl/contrib/dtracetoolkit/Docs/ToDo
new file mode 100644
index 0000000..5561ea4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/ToDo
@@ -0,0 +1,7 @@
+ToDo - To Do List
+
+ The following is a list of todo reminders for the DTraceToolkit.
+
+* Run PHP examples on mediawiki.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/Who b/cddl/contrib/dtracetoolkit/Docs/Who
new file mode 100644
index 0000000..f1019a9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/Who
@@ -0,0 +1,74 @@
+Who - Who the Contributers are
+
+ This is a record of contributors to the DTraceToolkit whose name isn't
+ already mentioned (such as in the source of a script).
+
+
+In alphabetical first-name order,
+
+Adam Leventhal
+ Location: CA, USA
+ Blog: http://blogs.sun.com/ahl
+ wrote DTrace itself
+
+Ben Rockwood
+ Location: CA, USA
+ Website: http://www.cuddletech.com
+ first encouraged the idea of DTrace oneliners
+
+Brendan Gregg
+ Location: Sydney, Australia
+ Website: http://www.brendangregg.com
+ Email: brendan.gregg@tpg.com.au (maybe, check the website above)
+ Blog: http://bdgregg.blogspot.com
+ Notes: Also see http://www.brendangregg.com/dtrace.html
+ created toolkit, tools, manpages, example docs, notes docs, testing
+
+Bryan Cantrill
+ Location: CA, USA
+ Blog: http://blogs.sun.com/bmc
+ wrote DTrace itself
+
+David Rubio
+ technical advice
+
+James Dickens
+ Location: WI, USA
+ Blog: http://uadmin.blogspot.com
+ tool ideas and testing
+
+Jonathan Adams
+ Blog: http://blogs.sun.com/jwadams
+ wrote stacksize.d
+
+Mike Shapiro
+ Location: CA, USA
+ Blog: http://blogs.sun.com/mws
+ wrote DTrace itself
+
+Nathan Kroenert
+ Location: Sydney, Australia
+ thoughts on how to present tools
+
+Richard McDougall
+ Location: CA, USA
+ Website: http://www.solarisinternals.com
+ Blog: http://blogs.sun.com/rmc
+ wrote pfilestat, vopstat
+
+Ryan Matteson
+ Location: USA
+ Blog: http://blogomatty.blogspot.com
+ tool ideas and testing
+
+Stefan Parvu
+ Blog: http://stefanparvu.blogspot.com
+ suggestions, bug fixes, extensive testing
+
+unknown Sun people
+ wrote /usr/demo/dtrace tools, which some of the toolkit tools are
+ based on. See "BASED ON" in source or man page, or try the following,
+ cd Bin
+ grep 'BASED ON' *
+ for a list.
+
diff --git a/cddl/contrib/dtracetoolkit/Docs/cddl1.txt b/cddl/contrib/dtracetoolkit/Docs/cddl1.txt
new file mode 100644
index 0000000..b3487ad
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/cddl1.txt
@@ -0,0 +1,385 @@
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+
+ 1. Definitions.
+
+ 1.1. ÒContributorÓ means each individual or entity that
+ creates or contributes to the creation of Modifications.
+
+ 1.2. ÒContributor VersionÓ means the combination of the
+ Original Software, prior Modifications used by a
+ Contributor (if any), and the Modifications made by that
+ particular Contributor.
+
+ 1.3. ÒCovered SoftwareÓ means (a) the Original Software, or
+ (b) Modifications, or (c) the combination of files
+ containing Original Software with files containing
+ Modifications, in each case including portions thereof.
+
+ 1.4. ÒExecutableÓ means the Covered Software in any form
+ other than Source Code.
+
+ 1.5. ÒInitial DeveloperÓ means the individual or entity
+ that first makes Original Software available under this
+ License.
+
+ 1.6. ÒLarger WorkÓ means a work which combines Covered
+ Software or portions thereof with code not governed by the
+ terms of this License.
+
+ 1.7. ÒLicenseÓ means this document.
+
+ 1.8. ÒLicensableÓ means having the right to grant, to the
+ maximum extent possible, whether at the time of the initial
+ grant or subsequently acquired, any and all of the rights
+ conveyed herein.
+
+ 1.9. ÒModificationsÓ means the Source Code and Executable
+ form of any of the following:
+
+ A. Any file that results from an addition to,
+ deletion from or modification of the contents of a
+ file containing Original Software or previous
+ Modifications;
+
+ B. Any new file that contains any part of the
+ Original Software or previous Modification; or
+
+ C. Any new file that is contributed or otherwise made
+ available under the terms of this License.
+
+ 1.10. ÒOriginal SoftwareÓ means the Source Code and
+ Executable form of computer software code that is
+ originally released under this License.
+
+ 1.11. ÒPatent ClaimsÓ means any patent claim(s), now owned
+ or hereafter acquired, including without limitation,
+ method, process, and apparatus claims, in any patent
+ Licensable by grantor.
+
+ 1.12. ÒSource CodeÓ means (a) the common form of computer
+ software code in which modifications are made and (b)
+ associated documentation included in or with such code.
+
+ 1.13. ÒYouÓ (or ÒYourÓ) means an individual or a legal
+ entity exercising rights under, and complying with all of
+ the terms of, this License. For legal entities, ÒYouÓ
+ includes any entity which controls, is controlled by, or is
+ under common control with You. For purposes of this
+ definition, ÒcontrolÓ means (a) the power, direct or
+ indirect, to cause the direction or management of such
+ entity, whether by contract or otherwise, or (b) ownership
+ of more than fifty percent (50%) of the outstanding shares
+ or beneficial ownership of such entity.
+
+ 2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, the
+ Initial Developer hereby grants You a world-wide,
+ royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than
+ patent or trademark) Licensable by Initial Developer,
+ to use, reproduce, modify, display, perform,
+ sublicense and distribute the Original Software (or
+ portions thereof), with or without Modifications,
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making,
+ using or selling of Original Software, to make, have
+ made, use, practice, sell, and offer for sale, and/or
+ otherwise dispose of the Original Software (or
+ portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b)
+ are effective on the date Initial Developer first
+ distributes or otherwise makes the Original Software
+ available to a third party under the terms of this
+ License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent
+ license is granted: (1) for code that You delete from
+ the Original Software, or (2) for infringements
+ caused by: (i) the modification of the Original
+ Software, or (ii) the combination of the Original
+ Software with other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, each
+ Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than
+ patent or trademark) Licensable by Contributor to
+ use, reproduce, modify, display, perform, sublicense
+ and distribute the Modifications created by such
+ Contributor (or portions thereof), either on an
+ unmodified basis, with other Modifications, as
+ Covered Software and/or as part of a Larger Work; and
+
+
+ (b) under Patent Claims infringed by the making,
+ using, or selling of Modifications made by that
+ Contributor either alone and/or in combination with
+ its Contributor Version (or portions of such
+ combination), to make, use, sell, offer for sale,
+ have made, and/or otherwise dispose of: (1)
+ Modifications made by that Contributor (or portions
+ thereof); and (2) the combination of Modifications
+ made by that Contributor with its Contributor Version
+ (or portions of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and
+ 2.2(b) are effective on the date Contributor first
+ distributes or otherwise makes the Modifications
+ available to a third party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent
+ license is granted: (1) for any code that Contributor
+ has deleted from the Contributor Version; (2) for
+ infringements caused by: (i) third party
+ modifications of Contributor Version, or (ii) the
+ combination of Modifications made by that Contributor
+ with other software (except as part of the
+ Contributor Version) or other devices; or (3) under
+ Patent Claims infringed by Covered Software in the
+ absence of Modifications made by that Contributor.
+
+ 3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make
+ available in Executable form must also be made available in
+ Source Code form and that Source Code form must be
+ distributed only under the terms of this License. You must
+ include a copy of this License with every copy of the
+ Source Code form of the Covered Software You distribute or
+ otherwise make available. You must inform recipients of any
+ such Covered Software in Executable form as to how they can
+ obtain such Covered Software in Source Code form in a
+ reasonable manner on or through a medium customarily used
+ for software exchange.
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You
+ contribute are governed by the terms of this License. You
+ represent that You believe Your Modifications are Your
+ original creation(s) and/or You have sufficient rights to
+ grant the rights conveyed by this License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications
+ that identifies You as the Contributor of the Modification.
+ You may not remove or alter any copyright, patent or
+ trademark notices contained within the Covered Software, or
+ any notices of licensing or any descriptive text giving
+ attribution to any Contributor or the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered
+ Software in Source Code form that alters or restricts the
+ applicable version of this License or the recipientsÕ
+ rights hereunder. You may choose to offer, and to charge a
+ fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Software.
+ However, you may do so only on Your own behalf, and not on
+ behalf of the Initial Developer or any Contributor. You
+ must make it absolutely clear that any such warranty,
+ support, indemnity or liability obligation is offered by
+ You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred
+ by the Initial Developer or such Contributor as a result of
+ warranty, support, indemnity or liability terms You offer.
+
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered
+ Software under the terms of this License or under the terms
+ of a license of Your choice, which may contain terms
+ different from this License, provided that You are in
+ compliance with the terms of this License and that the
+ license for the Executable form does not attempt to limit
+ or alter the recipientÕs rights in the Source Code form
+ from the rights set forth in this License. If You
+ distribute the Covered Software in Executable form under a
+ different license, You must make it absolutely clear that
+ any terms which differ from this License are offered by You
+ alone, not by the Initial Developer or Contributor. You
+ hereby agree to indemnify the Initial Developer and every
+ Contributor for any liability incurred by the Initial
+ Developer or such Contributor as a result of any such terms
+ You offer.
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software
+ with other code not governed by the terms of this License
+ and distribute the Larger Work as a single product. In such
+ a case, You must make sure the requirements of this License
+ are fulfilled for the Covered Software.
+
+ 4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Sun Microsystems, Inc. is the initial license steward and
+ may publish revised and/or new versions of this License
+ from time to time. Each version will be given a
+ distinguishing version number. Except as provided in
+ Section 4.3, no one other than the license steward has the
+ right to modify this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise
+ make the Covered Software available under the terms of the
+ version of the License under which You originally received
+ the Covered Software. If the Initial Developer includes a
+ notice in the Original Software prohibiting it from being
+ distributed or otherwise made available under any
+ subsequent version of the License, You must distribute and
+ make the Covered Software available under the terms of the
+ version of the License under which You originally received
+ the Covered Software. Otherwise, You may also choose to
+ use, distribute or otherwise make the Covered Software
+ available under the terms of any subsequent version of the
+ License published by the license steward.
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a
+ new license for Your Original Software, You may create and
+ use a modified version of this License if You: (a) rename
+ the license and remove any references to the name of the
+ license steward (except to note that the license differs
+ from this License); and (b) otherwise make it clear that
+ the license contains terms which differ from this License.
+
+
+ 5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN ÒAS ISÓ
+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+ SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+ PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+ COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF
+ ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+ WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+ DISCLAIMER.
+
+ 6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will
+ terminate automatically if You fail to comply with terms
+ herein and fail to cure such breach within 30 days of
+ becoming aware of the breach. Provisions which, by their
+ nature, must remain in effect beyond the termination of
+ this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding
+ declaratory judgment actions) against Initial Developer or
+ a Contributor (the Initial Developer or Contributor against
+ whom You assert such claim is referred to as ÒParticipantÓ)
+ alleging that the Participant Software (meaning the
+ Contributor Version where the Participant is a Contributor
+ or the Original Software where the Participant is the
+ Initial Developer) directly or indirectly infringes any
+ patent, then any and all rights granted directly or
+ indirectly to You by such Participant, the Initial
+ Developer (if the Initial Developer is not the Participant)
+ and all Contributors under Sections 2.1 and/or 2.2 of this
+ License shall, upon 60 days notice from Participant
+ terminate prospectively and automatically at the expiration
+ of such 60 day notice period, unless if within such 60 day
+ period You withdraw Your claim with respect to the
+ Participant Software against such Participant either
+ unilaterally or pursuant to a written agreement with
+ Participant.
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2
+ above, all end user licenses that have been validly granted
+ by You or any distributor hereunder prior to termination
+ (excluding licenses granted to You by any distributor)
+ shall survive termination.
+
+ 7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+ LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+ INJURY RESULTING FROM SUCH PARTYÕS NEGLIGENCE TO THE EXTENT
+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+ NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+ APPLY TO YOU.
+
+ 8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a Òcommercial item,Ó as that term is
+ defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of Òcommercial
+ computer softwareÓ (as that term is defined at 48 C.F.R. ¤
+ 252.227-7014(a)(1)) and Òcommercial computer software
+ documentationÓ as such terms are used in 48 C.F.R. 12.212 (Sept.
+ 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1
+ through 227.7202-4 (June 1995), all U.S. Government End Users
+ acquire Covered Software with only those rights set forth herein.
+ This U.S. Government Rights clause is in lieu of, and supersedes,
+ any other FAR, DFAR, or other clause or provision that addresses
+ Government rights in computer software under this License.
+
+ 9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the
+ extent necessary to make it enforceable. This License shall be
+ governed by the law of the jurisdiction specified in a notice
+ contained within the Original Software (except to the extent
+ applicable law, if any, provides otherwise), excluding such
+ jurisdictionÕs conflict-of-law provisions. Any litigation
+ relating to this License shall be subject to the jurisdiction of
+ the courts located in the jurisdiction and venue specified in a
+ notice contained within the Original Software, with the losing
+ party responsible for costs, including, without limitation, court
+ costs and reasonable attorneysÕ fees and expenses. The
+ application of the United Nations Convention on Contracts for the
+ International Sale of Goods is expressly excluded. Any law or
+ regulation which provides that the language of a contract shall
+ be construed against the drafter shall not apply to this License.
+ You agree that You alone are responsible for compliance with the
+ United States export administration regulations (and the export
+ control laws and regulation of any other countries) when You use,
+ distribute or otherwise make available any Covered Software.
+
+ 10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or
+ indirectly, out of its utilization of rights under this License
+ and You agree to work with Initial Developer and Contributors to
+ distribute such responsibility on an equitable basis. Nothing
+ herein is intended or shall be deemed to constitute any admission
+ of liability.
diff --git a/cddl/contrib/dtracetoolkit/Docs/oneliners.txt b/cddl/contrib/dtracetoolkit/Docs/oneliners.txt
new file mode 100644
index 0000000..fca2aa3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Docs/oneliners.txt
@@ -0,0 +1,81 @@
+#
+# DTrace OneLiners
+#
+
+DTrace One Liners,
+
+# New processes with arguments,
+dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }'
+
+# Files opened by process name,
+dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
+
+# Files created using creat() by process name,
+dtrace -n 'syscall::creat*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
+
+# Syscall count by process name,
+dtrace -n 'syscall:::entry { @num[execname] = count(); }'
+
+# Syscall count by syscall,
+dtrace -n 'syscall:::entry { @num[probefunc] = count(); }'
+
+# Syscall count by process ID,
+dtrace -n 'syscall:::entry { @num[pid,execname] = count(); }'
+
+# Read bytes by process name,
+dtrace -n 'sysinfo:::readch { @bytes[execname] = sum(arg0); }'
+
+# Write bytes by process name,
+dtrace -n 'sysinfo:::writech { @bytes[execname] = sum(arg0); }'
+
+# Read size distribution by process name,
+dtrace -n 'sysinfo:::readch { @dist[execname] = quantize(arg0); }'
+
+# Write size distribution by process name,
+dtrace -n 'sysinfo:::writech { @dist[execname] = quantize(arg0); }'
+
+# Disk size by process ID,
+dtrace -n 'io:::start { printf("%d %s %d",pid,execname,args[0]->b_bcount); }'
+
+# Disk size aggregation
+dtrace -n 'io:::start { @size[execname] = quantize(args[0]->b_bcount); }'
+
+# Pages paged in by process name,
+dtrace -n 'vminfo:::pgpgin { @pg[execname] = sum(arg0); }'
+
+# Minor faults by process name,
+dtrace -n 'vminfo:::as_fault { @mem[execname] = sum(arg0); }'
+
+# Interrupts by CPU,
+dtrace -n 'sdt:::interrupt-start { @num[cpu] = count(); }'
+
+# CPU cross calls by process name,
+dtrace -n 'sysinfo:::xcalls { @num[execname] = count(); }'
+
+# Lock time by process name,
+dtrace -n 'lockstat:::adaptive-block { @time[execname] = sum(arg1); }'
+
+# Lock distribution by process name,
+dtrace -n 'lockstat:::adaptive-block { @time[execname] = quantize(arg1); }'
+
+# Kernel funtion calls by module
+dtrace -n 'fbt:::entry { @calls[probemod] = count(); }'
+
+# Stack size for processes
+dtrace -n 'sched:::on-cpu { @[execname] = max(curthread->t_procp->p_stksize);}'
+
+# Kill all top processes when they are invoked,
+dtrace -wn 'syscall::exece:return /execname == "top"/ { raise(9); }'
+
+
+
+DTrace Longer One Liners,
+
+# New processes with arguments and time,
+dtrace -qn 'syscall::exec*:return { printf("%Y %s\n",walltimestamp,curpsinfo->pr_psargs); }'
+
+# Successful signal details,
+dtrace -n 'proc:::signal-send /pid/ { printf("%s -%d %d",execname,args[2],args[1]->pr_pid); }'
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/Copyright b/cddl/contrib/dtracetoolkit/Examples/Copyright
new file mode 100644
index 0000000..d802fe9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/Copyright
@@ -0,0 +1 @@
+The examples in this directory are copyright to their author.
diff --git a/cddl/contrib/dtracetoolkit/Examples/Readme b/cddl/contrib/dtracetoolkit/Examples/Readme
new file mode 100644
index 0000000..762a331
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/Readme
@@ -0,0 +1,21 @@
+Examples - Script demos, screenshots, and how to read the output
+
+ This directory contains an example file per script in the DTraceToolkit.
+
+ When I hear of a new performance tool or what not, the first thing I want
+ to see are screenshots. They illustrate,
+
+ - generally what the tool is for
+ - many details and features, since the output is (supposed to be)
+ as intuitive as possible
+ - how to use the tool (command line usage)
+
+ It is a rapid way to get a handle on what a tool generally is, and how
+ to start using it. The files in this directory serve that purpose.
+
+ These are especially important now that the DTraceToolkit has over 200
+ scripts. Flicking through these files and seeing the screenshots may
+ be the quickest way to find what you are after.
+
+ Of course, don't forget to read the man pages and notes files too :)
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/anonpgpid_example.txt b/cddl/contrib/dtracetoolkit/Examples/anonpgpid_example.txt
new file mode 100644
index 0000000..b505f3d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/anonpgpid_example.txt
@@ -0,0 +1,73 @@
+The following is a demonstration of the anonpgpid.d script,
+
+
+Here we run it on a system that is implementing memory caps using the
+resource capping daemon, "rcapd",
+
+ # anonpgpid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD D BYTES
+ 6215 bash R 8192
+ 6215 bash W 126976
+ 5809 rcapd R 245760
+ 6222 memleak.pl R 974848
+ 6222 memleak.pl W 3055616
+
+The "memleak.pl" process consumes memory, and we can see above that it has
+encountered both reads and writes to the physical swap device - it is being
+paged out. A bash shell was also effected (which was in the same project that
+rcapd was monitoring).
+
+
+
+The following is an ordinary system that is very low on memory,
+
+ # anonpgpid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD D BYTES
+ 18885 sendmail R 4096
+ 18600 automountd R 4096
+ 1 init R 4096
+ 2456 inetd R 8192
+ 18546 nscd R 8192
+ 2400 bash R 12288
+ 217 utmpd R 28672
+ 221 ttymon R 32768
+ 210 sac R 36864
+ 18777 snmpd R 49152
+ 18440 init R 49152
+ 89 nscd R 61440
+ 318 syslogd R 73728
+ 487 snmpd R 81920
+ 2453 inetd R 102400
+ 165 in.routed R 131072
+ 294 automountd R 135168
+ 215 inetd R 135168
+ 187 rpcbind R 204800
+ 86 kcfd R 290816
+ 7 svc.startd R 1015808
+ 9 svc.configd R 1478656
+ 2 pageout W 23453696
+
+The "pageout" process is responsible for writing all the anonymous memory
+pages to the physical swap device, and we can see from the above that it
+has written 23 Mb. When processes access anonymous memory that has been
+swapped out, a major fault occurs and the memory is paged back in; in this
+case we can trace the process that was effected, and from the above we can
+see that several processes have been effected by the memory pressure.
+The most is "svc.configd", which needed to page back in 1.4 Mb of anonymous
+memory.
+
+
+
+Sometimes anonpgpid.d doesn't help too much. Here we only have pageouts
+to the physical swap device and no pageins,
+
+ # anonpgpid.d
+ ^C
+ PID CMD D BYTES
+ 2 pageout W 61083648
+
+Only pageout is identified.
diff --git a/cddl/contrib/dtracetoolkit/Examples/bitesize_example.txt b/cddl/contrib/dtracetoolkit/Examples/bitesize_example.txt
new file mode 100644
index 0000000..dcc697d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/bitesize_example.txt
@@ -0,0 +1,74 @@
+In this example, bitesize.d was run for several seconds then Ctrl-C was hit.
+As bitesize.d runs it records how processes on the system are accessing the
+disks - in particular the size of the I/O operation. It is usually desirable
+for processes to be requesting large I/O operations rather than taking many
+small "bites".
+
+The final report highlights how processes performed. The find command mostly
+read 1K blocks while the tar command was reading large blocks - both as
+expected.
+
+ # bitesize.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ PID CMD
+ 7110 -bash\0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ 7110 sync\0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@ 1
+ 2048 |@@@@@@@@@@ 2
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 16384 | 0
+
+ 0 sched\0
+
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@ 1
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 16384 | 0
+
+ 7109 find /\0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1452
+ 2048 |@@ 91
+ 4096 | 33
+ 8192 |@@ 97
+ 16384 | 0
+
+ 3 fsflush\0
+
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 449
+ 16384 | 0
+
+ 7108 tar cf /dev/null /\0
+
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 | 70
+ 1024 |@@@@@@@@@@ 1306
+ 2048 |@@@@ 569
+ 4096 |@@@@@@@@@ 1286
+ 8192 |@@@@@@@@@@ 1403
+ 16384 |@ 190
+ 32768 |@@@ 396
+ 65536 | 0
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/connections_example.txt b/cddl/contrib/dtracetoolkit/Examples/connections_example.txt
new file mode 100644
index 0000000..e39d063
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/connections_example.txt
@@ -0,0 +1,23 @@
+The following is an example of connections. As inbound TCP connections are
+established their details are printed out. This includes the UID, PID and
+CMD of the server process that is listening on that port,
+
+ # connections
+ UID PID CMD TYPE PORT IP_SOURCE
+ 0 242 inetd tcp 79 192.168.1.1
+ 0 359 sshd tcp 22 192.168.1.1
+ 100 1532 Xorg tcp 6000 192.168.1.1
+ ^C
+
+
+In another window snoop was running for comparison,
+
+ # snoop 'tcp[13:1] = 0x02'
+ Using device /dev/rtls0 (promiscuous mode)
+ mars -> jupiter FINGER C port=56760
+ mars -> jupiter TCP D=22 S=56761 Syn Seq=3264782212 Len=0 ...
+ mars -> jupiter XWIN C port=56763
+
+snoop can already tell me that these connections are happening - but does not
+print out details of the server that accepted the connection.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/cpudists_example.txt b/cddl/contrib/dtracetoolkit/Examples/cpudists_example.txt
new file mode 100644
index 0000000..aa8256b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/cpudists_example.txt
@@ -0,0 +1,276 @@
+The following demonstrates the cpudists program. It prints distributions
+of CPU time consumed by the Kernel, Idle thread, or Processes.
+
+Here we run cpudists for 5 seconds once,
+
+# ./cpudists 5 1
+2005 Apr 28 00:08:42,
+ KERNEL
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1134
+ 16384 |@@@@@@@@@ 344
+ 32768 |@@@ 104
+ 65536 | 3
+ 131072 | 0
+ 262144 | 1
+ 524288 | 0
+ 1048576 | 11
+ 2097152 | 0
+
+ PROCESS
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@ 170
+ 32768 |@@@@@@@@@@@@@@@@@@ 331
+ 65536 |@@@@@@@@ 152
+ 131072 |@ 17
+ 262144 |@ 25
+ 524288 |@ 13
+ 1048576 | 4
+ 2097152 | 9
+ 4194304 | 0
+
+ IDLE
+ value ------------- Distribution ------------- count
+ 2097152 | 0
+ 4194304 |@ 9
+ 8388608 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 418
+ 16777216 |@@@ 31
+ 33554432 | 0
+
+The value indicates the time in nanoseconds, the count the number of
+runs for this length.
+
+From the above, we can see the kernel has run many times - but for short
+intervals each time. Processes have taken fom 10 to 60 microseconds;
+and when the idle thread runs it runs for some time - around 8 milliseconds
+for each.
+
+
+
+
+cpudists has a "-a" option for all processes,
+
+# ./cpudists -a 5 1
+2005 Apr 28 00:17:34,
+ mapping-daemon
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 |@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ sendmail
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+ nautilus
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+ fmd
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+ in.routed
+ value ------------- Distribution ------------- count
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 262144 | 0
+
+ miniserv.pl
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@ 1
+ 262144 | 0
+
+ xscreensaver
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@ 2
+ 131072 | 0
+
+gnome-vfs-daemon
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@ 2
+ 131072 | 0
+
+ gnome-panel
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@ 1
+ 32768 |@@@@@@@@@@@@@@@@ 2
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@ 2
+ 262144 | 0
+
+ svc.startd
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 32768 |@@@@@@@@@@@ 4
+ 65536 |@@@ 1
+ 131072 | 0
+
+ nscd
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 25
+ 32768 |@ 1
+ 65536 | 0
+ 131072 |@ 1
+ 262144 | 0
+
+gnome-netstatus-
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 | 0
+ 65536 | 0
+ 131072 | 0
+ 262144 | 0
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ mixer_applet2
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@ 10
+ 32768 |@@@@@@@@@@@@@@@@@ 19
+ 65536 |@@@@@@@@@@@@@@ 16
+ 131072 | 0
+
+ soffice.bin
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@ 7
+ 32768 |@@@@@@@@@@@@@@@@@@@ 14
+ 65536 |@@@@@@@@ 6
+ 131072 | 0
+ 262144 |@@@ 2
+ 524288 | 0
+ 1048576 | 0
+ 2097152 |@ 1
+ 4194304 | 0
+
+ dtrace
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32768 | 0
+ 65536 | 0
+ 131072 | 0
+ 262144 |@@@ 1
+ 524288 |@@@@@@@@@ 3
+ 1048576 | 0
+ 2097152 |@@@ 1
+ 4194304 | 0
+
+ Xorg
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@ 15
+ 131072 |@@@@@@@@ 6
+ 262144 |@@@@@@@@@@@@ 9
+ 524288 | 0
+
+ java_vm
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@ 101
+ 32768 |@@@@@@@@@@@@@@@@ 84
+ 65536 |@@@@ 20
+ 131072 | 0
+
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@ 12
+ 65536 |@@@@@@@@@@@ 8
+ 131072 |@ 1
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@ 9
+ 1048576 | 0
+
+ acroread
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 | 1
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 188
+ 65536 |@@@@@@@@ 47
+ 131072 |@@ 10
+ 262144 | 0
+
+ mozilla-bin
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@ 21
+ 32768 |@@@@@ 13
+ 65536 |@@@@@@@@@@@@@ 36
+ 131072 |@@@@@@@ 19
+ 262144 |@@@ 9
+ 524288 |@@ 5
+ 1048576 |@ 2
+ 2097152 |@@ 5
+ 4194304 | 0
+
+ KERNEL
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 1085
+ 16384 |@@@@@@@@@@@ 443
+ 32768 |@@ 98
+ 65536 | 5
+ 131072 | 1
+ 262144 | 1
+ 524288 | 0
+ 1048576 | 11
+ 2097152 | 0
+
+ fsflush
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@ 1
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 2097152 | 0
+ 4194304 | 0
+ 8388608 | 0
+ 16777216 | 0
+ 33554432 |@@@@@@@ 1
+ 67108864 | 0
+
+ IDLE
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 | 1
+ 2097152 | 0
+ 4194304 |@ 13
+ 8388608 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 411
+ 16777216 |@@@ 31
+ 33554432 | 0
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/cputimes_example.txt b/cddl/contrib/dtracetoolkit/Examples/cputimes_example.txt
new file mode 100644
index 0000000..253a7a3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/cputimes_example.txt
@@ -0,0 +1,210 @@
+The following demonstrates running the cputimes program on an idle system.
+We use an interval of 1 second and a count of 3,
+
+ # ./cputimes 1 3
+ 2005 Apr 27 23:37:58,
+ THREADS TIME (ns)
+ KERNEL 10795499
+ PROCESS 20941091
+ IDLE 970707443
+ 2005 Apr 27 23:37:59,
+ THREADS TIME (ns)
+ KERNEL 8919418
+ PROCESS 77446789
+ IDLE 910555040
+ 2005 Apr 27 23:38:00,
+ THREADS TIME (ns)
+ KERNEL 8615123
+ PROCESS 78314246
+ IDLE 810100417
+
+In the above output, we can see a breakdown of CPU time into the catagories
+KERNEL, PROCESS and IDLE. The time is measured in nanoseconds. Most of the
+time is in the IDLE category, as the system is idle. Very little time
+was spent serving the kernel.
+
+
+
+
+In the following example, several programs are run to hog the CPUs,
+
+ # ./cputimes 1 3
+ 2005 Apr 27 23:40:58,
+ THREADS TIME (ns)
+ KERNEL 11398807
+ PROCESS 992254664
+ 2005 Apr 27 23:40:59,
+ THREADS TIME (ns)
+ KERNEL 9205260
+ PROCESS 987561182
+ 2005 Apr 27 23:41:00,
+ THREADS TIME (ns)
+ KERNEL 9196669
+ PROCESS 877850474
+
+Now there is no IDLE category, as the system is 100% utilised.
+The programs were the following,
+
+ while :; do :; done &
+
+which keeps the CPU busy.
+
+
+
+
+In the following example a different style of program is run to hog the CPUs,
+
+ while :; do date; done
+
+This causes many processes to be created and destroyed in a hurry, and can
+be difficult to troubleshoot (tools like prstat cannot sample quick enough
+to easily identify what is going on). The following is the cputimes output,
+
+ # ./cputimes 1 3
+ 2005 Apr 27 23:45:30,
+ THREADS TIME (ns)
+ KERNEL 192647392
+ PROCESS 835397568
+ 2005 Apr 27 23:45:31,
+ THREADS TIME (ns)
+ KERNEL 168773713
+ PROCESS 810825730
+ 2005 Apr 27 23:45:32,
+ THREADS TIME (ns)
+ KERNEL 151676122
+ PROCESS 728477272
+
+Now the kernel is doing a substantial amount of work to create and destroy
+these processes.
+
+
+
+
+In the following example, a large amount of network activity occurs while
+cputimes is running,
+
+ # ./cputimes 1 6
+ 2005 Apr 27 23:49:29,
+ THREADS TIME (ns)
+ KERNEL 10596399
+ PROCESS 21793920
+ IDLE 974395713
+ 2005 Apr 27 23:49:30,
+ THREADS TIME (ns)
+ KERNEL 251465759
+ IDLE 357436576
+ PROCESS 508986422
+ 2005 Apr 27 23:49:31,
+ THREADS TIME (ns)
+ IDLE 9758227
+ KERNEL 367645318
+ PROCESS 385427847
+ 2005 Apr 27 23:49:32,
+ THREADS TIME (ns)
+ IDLE 28351679
+ KERNEL 436022725
+ PROCESS 451304688
+ 2005 Apr 27 23:49:33,
+ THREADS TIME (ns)
+ KERNEL 262586158
+ PROCESS 325238896
+ IDLE 358243503
+ 2005 Apr 27 23:49:34,
+ THREADS TIME (ns)
+ KERNEL 10075578
+ PROCESS 238170506
+ IDLE 647956998
+
+Initially the system is idle. A command is run to cause heavy network
+activity, which peaks during the fourth sample - during which the kernel
+is using around 40% of the CPU. The Solaris 10 command "intrstat" can
+help to analyse this activity further.
+
+
+
+
+Longer samples are possible. The following is a 60 second sample,
+
+ # ./cputimes 60 1
+ 2005 Apr 27 23:53:02,
+ THREADS TIME (ns)
+ KERNEL 689808449
+ PROCESS 8529562214
+ IDLE 50406951876
+ #
+
+
+
+
+cputimes has a "-a" option to print all processes. The following is a
+single 1 second sample with -a,
+
+ # ./cputimes -a 1 1
+ 2005 Apr 28 00:00:32,
+ THREADS TIME (ns)
+ svc.startd 51042
+ nautilus 130645
+ in.routed 131823
+ fmd 152822
+ nscd 307042
+ dsdm 415799
+ mixer_applet2 551066
+ gnome-smproxy 587234
+ xscreensaver 672270
+ fsflush 1060196
+ java_vm 1552988
+ wnck-applet 2060870
+ dtrace 2398658
+ acroread 2614687
+ soffice.bin 2825117
+ mozilla-bin 5497488
+ KERNEL 13541120
+ metacity 28924204
+ gnome-terminal 74304348
+ Xorg 289631407
+ IDLE 465054209
+
+The times are in nanoseconds, and multiple processes with the same name
+have their times aggregated. The above output is at an amazing resolution -
+svc.startd ran for 51 microseconds, and soffice.bin ran for 28 milliseconds.
+
+
+
+
+The following is a 10 second sample on an idle desktop,
+
+ # ./cputimes -a 10 1
+ 2005 Apr 28 00:03:57,
+ THREADS TIME (ns)
+ snmpd 127859
+ fmd 171897
+ inetd 177134
+ svc.configd 185006
+ mapping-daemon 197674
+ miniserv.pl 305603
+ gconfd-2 330511
+ xscreensaver 443207
+ sendmail 473434
+ nautilus 506799
+ gnome-vfs-daemon 549037
+ gnome-panel 770631
+ nscd 885353
+ svc.startd 1181286
+ gnome-netstatus- 4329671
+ mixer_applet2 4833519
+ dtrace 6244366
+ in.routed 6556075
+ fsflush 9553155
+ soffice.bin 13954327
+ java_vm 16285243
+ acroread 32126193
+ gnome-terminal 34891991
+ Xorg 35553412
+ mozilla-bin 67855629
+ KERNEL 94834997
+ IDLE 9540941846
+
+Wow, maybe not as idle as I thought!
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/cputypes_example.txt b/cddl/contrib/dtracetoolkit/Examples/cputypes_example.txt
new file mode 100644
index 0000000..158a43f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/cputypes_example.txt
@@ -0,0 +1,40 @@
+The following are demonstrations of the cputypes.d script,
+
+
+This is running cputypes.d on a desktop,
+
+ # cputypes.d
+ CPU CHIP PSET LGRP CLOCK TYPE FPU
+ 0 0 0 0 867 i386 i387 compatible
+
+fairly boring.
+
+
+
+The following is a multi CPU x86 server,
+
+ # cputypes.d
+ CPU CHIP PSET LGRP CLOCK TYPE FPU
+ 0 0 0 0 2791 i386 i387 compatible
+ 1 3 1 0 2791 i386 i387 compatible
+ 2 0 0 0 2791 i386 i387 compatible
+ 3 3 0 0 2791 i386 i387 compatible
+
+Much more interesting! We can see from the CHIP field that there is actually
+two CPUs, each with two cores. There is also two processor sets (0, 1).
+
+The CPUs were printed in CPU id order by mere chance.
+
+
+
+Here is a multi CPU SPARC server,
+
+ # cputypes.d
+ CPU CHIP PSET LGRP CLOCK TYPE FPU
+ 0 0 0 0 400 sparcv9 sparcv9
+ 1 1 0 0 400 sparcv9 sparcv9
+ 4 4 0 0 400 sparcv9 sparcv9
+ 5 5 0 0 400 sparcv9 sparcv9
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/cpuwalk_example.txt b/cddl/contrib/dtracetoolkit/Examples/cpuwalk_example.txt
new file mode 100644
index 0000000..34afa95
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/cpuwalk_example.txt
@@ -0,0 +1,85 @@
+The following is a demonstration of the cpuwalk.d script,
+
+
+cpuwalk.d is not that useful on a single CPU server,
+
+ # cpuwalk.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+
+ PID: 18843 CMD: bash
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 30
+ 1 | 0
+
+ PID: 8079 CMD: mozilla-bin
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 1 | 0
+
+The output above shows that PID 18843, "bash", was sampled on CPU 0 a total
+of 30 times (we sample at 1000 hz).
+
+
+
+The following is a demonstration of running cpuwalk.d with a 5 second
+duration. This is on a 4 CPU server running a multithreaded CPU bound
+application called "cputhread",
+
+ # cpuwalk.d 5
+ Sampling...
+
+ PID: 3 CMD: fsflush
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 30
+ 3 | 0
+
+ PID: 12186 CMD: cputhread
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@ 4900
+ 1 |@@@@@@@@@@ 4900
+ 2 |@@@@@@@@@@ 4860
+ 3 |@@@@@@@@@@ 4890
+ 4 | 0
+
+As we are sampling at 1000 hz, the application cputhread is indeed running
+concurrently across all available CPUs. We measured the applicaiton on
+CPU 0 a total of 4900 times, on CPU 1 a total of 4900 times, etc. As there
+are around 5000 samples per CPU available in this 5 second 1000 hz sample,
+the application is using almost all the CPU capacity in this server well.
+
+
+
+The following is a similar demonstration, this time running a multithreaded
+CPU bound application called "cpuserial" that has a poor use of locking
+such that the threads "serialise",
+
+
+ # cpuwalk.d 5
+ Sampling...
+
+ PID: 12194 CMD: cpuserial
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@ 470
+ 1 |@@@@@@ 920
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@ 3840
+ 3 |@@@@@@ 850
+ 4 | 0
+
+In the above, we can see that this CPU bound application is not making
+efficient use of the CPU resources available, only reaching 3840 samples
+on CPU 2 out of a potential 5000. This problem was caused by a poor use
+of locks.
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/crash_example.txt b/cddl/contrib/dtracetoolkit/Examples/crash_example.txt
new file mode 100644
index 0000000..f0034d3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/crash_example.txt
@@ -0,0 +1,68 @@
+The following is an example of the crashed application script, crash.d
+This demonstration is for version 0.80 of crash.d, newer versions may
+produce enhanced output.
+
+Here is the report generated as crash.d catches a crashing procmail process,
+
+# ./crash.d
+Waiting for crashing applications...
+
+-----------------------------------------------------
+CRASH DETECTED at 2005 May 30 19:41:34
+-----------------------------------------------------
+Type: SIGSEGV
+Program: procmail
+Args: procmail -m\0
+PID: 2877
+TID: 1
+LWPs: 1
+PPID: 1778
+UID: 100
+GID: 1
+TaskID: 76
+ProjID: 3
+PoolID: 0
+ZoneID: 0
+zone: global
+CWD: /usr/include/sys
+errno: 0
+
+User Stack Backtrace,
+ procmail`sendcomsat+0x24
+ procmail`Terminate+0x76
+ procmail`0x805a2b0
+ procmail`0x805a40f
+ libc.so.1`__sighndlr+0xf
+ libc.so.1`call_user_handler+0x22b
+ libc.so.1`sigacthandler+0xbb
+ 0xffffffff
+ procmail`rread+0x1d
+ procmail`0x805bcb4
+ procmail`read2blk+0x6b
+ procmail`readdyn+0x1f
+ procmail`readmail+0x181
+ procmail`main+0x532
+ procmail`_start+0x5d
+
+Kernel Stack Backtrace,
+ genunix`sigaddqa+0x3f
+ genunix`trapsig+0xdb
+ unix`trap+0xc2b
+ unix`_cmntrap+0x83
+
+Ansestors,
+ 2877 procmail -m\0
+ 1778 bash\0
+ 1777 xterm -bg black -fg grey70 -sl 500 -vb\0
+ 1 /sbin/init\0
+ 0 sched\0
+
+Times,
+ User: 0 ticks
+ Sys: 1 ticks
+ Elapsed: 3307 ms
+
+Sizes,
+ Heap: 16388 bytes
+ Stack: 8192 bytes
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/creatbyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/creatbyproc_example.txt
new file mode 100644
index 0000000..295e07f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/creatbyproc_example.txt
@@ -0,0 +1,23 @@
+The following is an example of the creatbyproc.d script,
+
+
+Here we run creatbyproc.d for several seconds,
+
+ # ./creatbyproc.d
+ dtrace: script './creatbyproc.d' matched 2 probes
+ CPU ID FUNCTION:NAME
+ 0 5438 creat64:entry touch /tmp/newfile
+ 0 5438 creat64:entry sh /tmp/mpLaaOik
+ 0 5438 creat64:entry sh /dev/null
+ ^C
+
+In another window, the following commands were run,
+
+ touch /tmp/newfile
+ man ls
+
+The file creation activity caused by these commands can be seen in the
+output by creatbyproc.d
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/cswstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/cswstat_example.txt
new file mode 100644
index 0000000..d45347c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/cswstat_example.txt
@@ -0,0 +1,25 @@
+The following is an example of the cswstat.d script,
+
+ # cswstat.d
+ TIME NUM CSWTIME AVGTIME
+ 2005 May 17 01:57:21 276 2407 8
+ 2005 May 17 01:57:22 283 2251 7
+ 2005 May 17 01:57:23 259 2098 8
+ 2005 May 17 01:57:24 268 2169 8
+ 2005 May 17 01:57:25 1248 10864 8
+ 2005 May 17 01:57:26 2421 21263 8
+ 2005 May 17 01:57:27 2183 19804 9
+ 2005 May 17 01:57:28 1980 18640 9
+ 2005 May 17 01:57:29 794 7422 9
+ 2005 May 17 01:57:30 275 2233 8
+ 2005 May 17 01:57:31 288 2338 8
+ 2005 May 17 01:57:32 545 4154 7
+ 2005 May 17 01:57:33 264 2149 8
+ ^C
+
+In the above output, the average context switch time is 8 microseconds.
+During the sample there was a burst of activity, increasing the number
+of context switches per second from around 270 to over 2000. The time
+consumed by all of these context switches in total is printed, peaking
+at 21 ms.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dappprof_example.txt b/cddl/contrib/dtracetoolkit/Examples/dappprof_example.txt
new file mode 100644
index 0000000..a2c3935
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dappprof_example.txt
@@ -0,0 +1,71 @@
+The following is a demonstration of the dappprof command,
+
+This is the usage for version 0.60,
+
+ # dappprof -h
+ USAGE: dappprof [-cehoTU] [-u lib] { -p PID | command }
+
+ -p PID # examine this PID
+ -a # print all details
+ -c # print syscall counts
+ -e # print elapsed times (us)
+ -o # print on cpu times
+ -T # print totals
+ -u lib # trace this library instead
+ -U # trace all libraries + user funcs
+ -b bufsize # dynamic variable buf size
+ eg,
+ dappprof df -h # run and examine "df -h"
+ dappprof -p 1871 # examine PID 1871
+ dappprof -ap 1871 # print all data
+
+
+
+The following shows running dappprof with the "banner hello" command.
+Elapsed and on-cpu times are printed (-eo), as well as counts (-c) and
+totals (-T),
+
+ # dappprof -eocT banner hello
+
+ # # ###### # # ####
+ # # # # # # #
+ ###### ##### # # # #
+ # # # # # # #
+ # # # # # # #
+ # # ###### ###### ###### ####
+
+
+ CALL COUNT
+ __fsr 1
+ main 1
+ banprt 1
+ banner 1
+ banset 1
+ convert 5
+ banfil 5
+ TOTAL: 15
+
+ CALL ELAPSED
+ banset 37363
+ banfil 147407
+ convert 149606
+ banprt 423507
+ banner 891088
+ __fsr 1694349
+ TOTAL: 3343320
+
+ CALL CPU
+ banset 7532
+ convert 8805
+ banfil 11092
+ __fsr 15708
+ banner 48696
+ banprt 388853
+ TOTAL: 480686
+
+The above output has analysed user functions (the default). It makes it
+easy to identify which function is being called the most (COUNT), which
+is taking the most time (ELAPSED), and which is consuming the most CPU (CPU).
+These times are totals for all the functions called.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dapptrace_example.txt b/cddl/contrib/dtracetoolkit/Examples/dapptrace_example.txt
new file mode 100644
index 0000000..f19606c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dapptrace_example.txt
@@ -0,0 +1,215 @@
+The following is a demonstration of the dapptrace command,
+
+This is the usage for version 0.60,
+
+ # dapptrace -h
+ USAGE: dapptrace [-acdeholFLU] [-u lib] { -p PID | command }
+
+ -p PID # examine this PID
+ -a # print all details
+ -c # print syscall counts
+ -d # print relative times (us)
+ -e # print elapsed times (us)
+ -F # print flow indentation
+ -l # print pid/lwpid
+ -o # print CPU on cpu times
+ -u lib # trace this library instead
+ -U # trace all libraries + user funcs
+ -b bufsize # dynamic variable buf size
+ eg,
+ dapptrace df -h # run and examine "df -h"
+ dapptrace -p 1871 # examine PID 1871
+ dapptrace -Fp 1871 # print using flow indents
+ dapptrace -eop 1871 # print elapsed and CPU times
+
+
+
+The following is an example of the default output. We run dapptrace with
+the "banner hello" command,
+
+ # dapptrace banner hi
+
+ # # #
+ # # #
+ ###### #
+ # # #
+ # # #
+ # # #
+
+ CALL(args) = return
+ -> __fsr(0x2, 0x8047D7C, 0x8047D88)
+ <- __fsr = 122
+ -> main(0x2, 0x8047D7C, 0x8047D88)
+ -> banner(0x8047E3B, 0x80614C2, 0x8047D38)
+ -> banset(0x20, 0x80614C2, 0x8047DCC)
+ <- banset = 36
+ -> convert(0x68, 0x8047DCC, 0x2)
+ <- convert = 319
+ -> banfil(0x8061412, 0x80614C2, 0x8047DCC)
+ <- banfil = 57
+ -> convert(0x69, 0x8047DCC, 0x2)
+ <- convert = 319
+ -> banfil(0x8061419, 0x80614CA, 0x8047DCC)
+ <- banfil = 57
+ <- banner = 118
+ -> banprt(0x80614C2, 0x8047D38, 0xD27FB824)
+ <- banprt = 74
+
+The default output shows user function calls. An entry is prefixed
+with a "->", and the return has a "<-".
+
+
+
+Here we run dapptrace with the -F for flow indent option,
+
+ # dapptrace -F banner hi
+
+ # # #
+ # # #
+ ###### #
+ # # #
+ # # #
+ # # #
+
+ CALL(args) = return
+ -> __fsr(0x2, 0x8047D7C, 0x8047D88)
+ <- __fsr = 122
+ -> main(0x2, 0x8047D7C, 0x8047D88)
+ -> banner(0x8047E3B, 0x80614C2, 0x8047D38)
+ -> banset(0x20, 0x80614C2, 0x8047DCC)
+ <- banset = 36
+ -> convert(0x68, 0x8047DCC, 0x2)
+ <- convert = 319
+ -> banfil(0x8061412, 0x80614C2, 0x8047DCC)
+ <- banfil = 57
+ -> convert(0x69, 0x8047DCC, 0x2)
+ <- convert = 319
+ -> banfil(0x8061419, 0x80614CA, 0x8047DCC)
+ <- banfil = 57
+ <- banner = 118
+ -> banprt(0x80614C2, 0x8047D38, 0xD27FB824)
+ <- banprt = 74
+
+The above output illustrates the flow of the program, which functions
+call which other functions.
+
+
+
+Now the same command is run with -d to display relative timestamps,
+
+ # dapptrace -dF banner hi
+
+ # # #
+ # # #
+ ###### #
+ # # #
+ # # #
+ # # #
+
+ RELATIVE CALL(args) = return
+ 2512 -> __fsr(0x2, 0x8047D7C, 0x8047D88)
+ 2516 <- __fsr = 122
+ 2518 -> main(0x2, 0x8047D7C, 0x8047D88)
+ 2863 -> banner(0x8047E3B, 0x80614C2, 0x8047D38)
+ 2865 -> banset(0x20, 0x80614C2, 0x8047DCC)
+ 2872 <- banset = 36
+ 2874 -> convert(0x68, 0x8047DCC, 0x2)
+ 2877 <- convert = 319
+ 2879 -> banfil(0x8061412, 0x80614C2, 0x8047DCC)
+ 2882 <- banfil = 57
+ 2883 -> convert(0x69, 0x8047DCC, 0x2)
+ 2885 <- convert = 319
+ 2886 -> banfil(0x8061419, 0x80614CA, 0x8047DCC)
+ 2888 <- banfil = 57
+ 2890 <- banner = 118
+ 2892 -> banprt(0x80614C2, 0x8047D38, 0xD27FB824)
+ 3214 <- banprt = 74
+
+The relative times are in microseconds since the program's invocation. Great!
+
+
+
+Even better is if we use the -eo options, to print elapsed times and on-cpu
+times,
+
+ # dapptrace -eoF banner hi
+
+ # # #
+ # # #
+ ###### #
+ # # #
+ # # #
+ # # #
+
+ ELAPSD CPU CALL(args) = return
+ . . -> __fsr(0x2, 0x8047D7C, 0x8047D88)
+ 41 4 <- __fsr = 122
+ . . -> main(0x2, 0x8047D7C, 0x8047D88)
+ . . -> banner(0x8047E3B, 0x80614C2, 0x8047D38)
+ . . -> banset(0x20, 0x80614C2, 0x8047DCC)
+ 29 6 <- banset = 36
+ . . -> convert(0x68, 0x8047DCC, 0x2)
+ 26 3 <- convert = 319
+ . . -> banfil(0x8061412, 0x80614C2, 0x8047DCC)
+ 25 2 <- banfil = 57
+ . . -> convert(0x69, 0x8047DCC, 0x2)
+ 23 1 <- convert = 319
+ . . -> banfil(0x8061419, 0x80614CA, 0x8047DCC)
+ 23 1 <- banfil = 57
+ 309 28 <- banner = 118
+ . . -> banprt(0x80614C2, 0x8047D38, 0xD27FB824)
+ 349 322 <- banprt = 74
+
+Now it is easy to see which functions take the longest (elapsed), and
+which consume the most CPU cycles.
+
+
+
+The following demonstrates the -U option, to trace all libraries,
+
+ # dapptrace -U banner hi
+
+ # # #
+ # # #
+ ###### #
+ # # #
+ # # #
+ # # #
+
+ CALL(args) = return
+ -> ld.so.1:_rt_boot(0x8047E34, 0x8047E3B, 0x0)
+ -> ld.so.1:_setup(0x8047D38, 0x20AE4, 0x3)
+ -> ld.so.1:setup(0x8047D88, 0x8047DCC, 0x0)
+ -> ld.so.1:fmap_setup(0x0, 0xD27FB2E4, 0xD27FB824)
+ <- ld.so.1:fmap_setup = 125
+ -> ld.so.1:addfree(0xD27FD3C0, 0xC40, 0x0)
+ <- ld.so.1:addfree = 65
+ -> ld.so.1:security(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
+ <- ld.so.1:security = 142
+ -> ld.so.1:readenv_user(0x8047D88, 0xD27FB204, 0xD27FB220)
+ -> ld.so.1:ld_str_env(0x8047E3E, 0xD27FB204, 0xD27FB220)
+ <- ld.so.1:ld_str_env = 389
+ -> ld.so.1:ld_str_env(0x8047E45, 0xD27FB204, 0xD27FB220)
+ <- ld.so.1:ld_str_env = 389
+ -> ld.so.1:ld_str_env(0x8047E49, 0xD27FB204, 0xD27FB220)
+ <- ld.so.1:ld_str_env = 389
+ -> ld.so.1:ld_str_env(0x8047E50, 0xD27FB204, 0xD27FB220)
+ -> ld.so.1:strncmp(0x8047E53, 0xD27F7BEB, 0x4)
+ <- ld.so.1:strncmp = 113
+ -> ld.so.1:rd_event(0xD27FB1F8, 0x3, 0x0)
+ [...4486 lines deleted...]
+ -> ld.so.1:_lwp_mutex_unlock(0xD27FD380, 0xD27FB824, 0x8047C04)
+ <- ld.so.1:_lwp_mutex_unlock = 47
+ <- ld.so.1:rt_mutex_unlock = 34
+ -> ld.so.1:rt_bind_clear(0x1, 0xD279ECC0, 0xD27FDB2C)
+ <- ld.so.1:rt_bind_clear = 34
+ <- ld.so.1:leave = 210
+ <- ld.so.1:elf_bndr = 803
+ <- ld.so.1:elf_rtbndr = 35
+
+The output was huge, around 4500 lines long. Function names are prefixed
+with their library name, eg "ld.so.1".
+
+This full output should be used with caution, as it enables so many probes
+it could well be a burden on the system.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dexplorer_example.txt b/cddl/contrib/dtracetoolkit/Examples/dexplorer_example.txt
new file mode 100644
index 0000000..cba6171
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dexplorer_example.txt
@@ -0,0 +1,95 @@
+The following is a demonstration of the dexplorer program.
+
+
+Here we run dexplorer with no arguments. By default it will sample various
+system activities using DTrace at 5 seconds per sample. It creates an
+output tar.gz file containing all the DTrace output,
+
+ # dexplorer
+ Output dir will be the current dir (/export/home/root/DTrace/Dexplorer).
+ Hit enter for yes, or type path:
+ Starting dexplorer ver 0.70.
+ Sample interval is 5 seconds. Total run is > 100 seconds.
+ 0% Interrupts by CPU...
+ 5% Interrupt counts...
+ 10% Dispatcher queue length by CPU...
+ 15% Sdt counts...
+ 20% Pages paged in by process name...
+ 25% Files opened count...
+ 30% Disk I/O size distribution by process name...
+ 35% Minor faults by process name...
+ 40% Vminfo data by process name...
+ 45% Mib data by mib statistic...
+ 50% TCP write bytes by process...
+ 55% Sample process @ 1000 Hz...
+ 60% Syscall count by process name...
+ 65% Syscall count by syscall...
+ 70% Read bytes by process name...
+ 75% Write bytes by process name...
+ 80% Sysinfo counts by process name...
+ 85% New process counts with arguments...
+ 90% Signal counts...
+ 95% Syscall error counts...
+ 100% Done.
+ File is de_jupiter_200506271803.tar.gz
+
+As each sample is taken, a line of output is printed above. The above example
+is for version 0.70, newer versions of dexplorer are likely to print more
+lines as they take more samples.
+
+The final line states which file all the output is now in.
+
+
+
+
+The following displays the contents of a dexplorer file,
+
+ # gunzip de_jupiter_200506271803.tar.gz
+ # tar xf de_jupiter_200506271803.tar
+ de_jupiter_200506271803
+ de_jupiter_200506271803/Cpu
+ de_jupiter_200506271803/Cpu/interrupt_by_cpu
+ de_jupiter_200506271803/Cpu/interrupt_time
+ de_jupiter_200506271803/Cpu/dispqlen_by_cpu
+ de_jupiter_200506271803/Cpu/sdt_count
+ de_jupiter_200506271803/Disk
+ de_jupiter_200506271803/Disk/pgpgin_by_processname
+ de_jupiter_200506271803/Disk/fileopen_count
+ de_jupiter_200506271803/Disk/sizedist_by_processname
+ de_jupiter_200506271803/Mem
+ de_jupiter_200506271803/Mem/minf_by_processname
+ de_jupiter_200506271803/Mem/vminfo_by_processname
+ de_jupiter_200506271803/Net
+ de_jupiter_200506271803/Net/mib_data
+ de_jupiter_200506271803/Net/tcpw_by_process
+ de_jupiter_200506271803/Proc
+ de_jupiter_200506271803/Proc/sample_process
+ de_jupiter_200506271803/Proc/syscall_by_processname
+ de_jupiter_200506271803/Proc/syscall_count
+ de_jupiter_200506271803/Proc/readb_by_processname
+ de_jupiter_200506271803/Proc/writeb_by_processname
+ de_jupiter_200506271803/Proc/sysinfo_by_processname
+ de_jupiter_200506271803/Proc/newprocess_count
+ de_jupiter_200506271803/Proc/signal_count
+ de_jupiter_200506271803/Proc/syscall_errors
+ de_jupiter_200506271803/Info
+ de_jupiter_200506271803/Info/uname-a
+ de_jupiter_200506271803/Info/psrinfo-v
+ de_jupiter_200506271803/Info/prtconf
+ de_jupiter_200506271803/Info/df-k
+ de_jupiter_200506271803/Info/ifconfig-a
+ de_jupiter_200506271803/Info/ps-o
+ de_jupiter_200506271803/Info/uptime
+ de_jupiter_200506271803/log
+
+
+
+The following demonstrates running dexplorer in full quiet mode,
+
+ # dexplorer -qy -d /var/tmp
+ #
+
+No text is written to the screen (-qy). The output file will have been
+put in /var/tmp (-d).
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/diskhits_example.txt b/cddl/contrib/dtracetoolkit/Examples/diskhits_example.txt
new file mode 100644
index 0000000..6fe3a85
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/diskhits_example.txt
@@ -0,0 +1,107 @@
+The following is a demonstration of the diskhits command.
+
+
+Here we run diskhits on a large file, /extra1/contents with is 46 Mb, and
+currently hasn't been accessed (so isn't in any cache).
+
+While diskhits is running, the file is grep'd in another window. This causes
+the entire file to be read,
+
+ # ./diskhits /extra1/contents
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ Location (KB),
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@ 47
+ 2303 |@@ 41
+ 4606 |@@ 41
+ 6909 |@@ 42
+ 9212 |@@ 41
+ 11515 |@@ 41
+ 13818 |@@ 42
+ 16121 |@@ 43
+ 18424 |@@ 42
+ 20727 |@@ 41
+ 23030 |@@ 41
+ 25333 |@@ 41
+ 27636 |@@ 41
+ 29939 |@@ 42
+ 32242 |@@ 44
+ 34545 |@@ 41
+ 36848 |@@ 41
+ 39151 |@@ 41
+ 41454 |@@ 41
+ 43757 |@@ 40
+ >= 46060 | 0
+
+ Size (KB),
+
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 | 6
+ 16 | 10
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 818
+ 64 | 0
+
+ Total RW: 46064 KB
+
+Ok, so the file was read evently with each access around 32 to 63 Kb in size,
+and a total of 46 Mb read. This all makes sense, as it is reading the file
+for the first time.
+
+
+
+Now the same file is grep'd with diskhits running, this time we can see what
+effect caching the file has made,
+
+ # ./diskhits /extra1/contents
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ Location (KB),
+
+ value ------------- Distribution ------------- count
+ 2303 | 0
+ 4606 | 5
+ 6909 |@ 67
+ 9212 |@@@@ 170
+ 11515 |@@@@@ 216
+ 13818 |@@@@@ 224
+ 16121 |@@@@@@ 287
+ 18424 |@@@@@ 227
+ 20727 |@@@ 144
+ 23030 |@@ 75
+ 25333 |@ 59
+ 27636 |@ 42
+ 29939 |@ 41
+ 32242 |@ 44
+ 34545 |@ 41
+ 36848 |@ 41
+ 39151 |@ 41
+ 41454 |@ 41
+ 43757 |@ 39
+ >= 46060 | 0
+
+ Size (KB),
+
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@ 1137
+ 8 |@@@@@ 211
+ 16 |@@ 111
+ 32 |@@@@@@@@ 345
+ 64 | 0
+
+ Total RW: 29392 KB
+
+The difference is dramatic. This time only 29 Mb is read, leaving around
+17 Mb that was read from the cache. The way the file is read differs -
+in the later half of the file it looks the same, but in the first half there
+are many more events; oddly enough, this is because the early part of the
+file is cached more, the extra events are likely to be much smaller in size -
+as indicated in the difference in the size distribution.
+
+It appears that everything less that 4606 Kb has remained in the cache, with
+zero hits for that range.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dispqlen_example.txt b/cddl/contrib/dtracetoolkit/Examples/dispqlen_example.txt
new file mode 100644
index 0000000..f3542c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dispqlen_example.txt
@@ -0,0 +1,62 @@
+This is a demonstration of the dispqlen.d script,
+
+
+Here we run it on a single CPU desktop,
+
+ # dispqlen.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CPU 0
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1790
+ 1 |@@@ 160
+ 2 | 10
+ 3 | 0
+
+The output shows the length of the dispatcher queue is mostly 0. This is
+evidence that the CPU is not very saturated. It does not indicate that the
+CPU is idle - as we are measuring the length of the queue, not what is
+on the CPU.
+
+
+
+Here it is run on a multi CPU server,
+
+ # dispqlen.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CPU 1
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1573
+ 1 |@@@@@@@@@ 436
+ 2 | 4
+ 3 | 0
+
+ CPU 4
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@ 1100
+ 1 |@@@@@@@@@@@@@@@@@@ 912
+ 2 | 1
+ 3 | 0
+
+ CPU 0
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@ 846
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@ 1167
+ 2 | 0
+
+ CPU 5
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@ 397
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1537
+ 2 |@@ 79
+ 3 | 0
+
+The above output shows that threads are queueing up on CPU 5 much more than
+CPU 0.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dnlcps_example.txt b/cddl/contrib/dtracetoolkit/Examples/dnlcps_example.txt
new file mode 100644
index 0000000..eed35b4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dnlcps_example.txt
@@ -0,0 +1,47 @@
+The following is a demonstration of the dnlcps.d script.
+
+
+Here we run dnlcps.d for o few seconds, then hit Ctrl-C,
+
+ # dnlcps.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ CMD: bash PID: 12508
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@ 2
+ >= 1 |@@@@@@@@@@@@@@@@@@@@@@@@ 3
+
+ CMD: nscd PID: 109
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ >= 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+
+ CMD: in.routed PID: 143
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ >= 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+
+ CMD: ls PID: 12508
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@ 2
+ >= 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+
+ CMD: find PID: 12507
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@ 5768
+ >= 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 11263
+
+A "find" command was running at the time, which had 11,263 hits on the DNLC
+and 5768 misses. An "ls" command scored 22 hits.
+
+The above distribution output can help us identify if procesess
+are both using the DNLC a lot, and what hit rate they are scoring.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dnlcsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/dnlcsnoop_example.txt
new file mode 100644
index 0000000..45915f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dnlcsnoop_example.txt
@@ -0,0 +1,88 @@
+The following is a demonstration of the dnlcsnoop.d script.
+
+
+Here we run dnlcsnoop.d, while in another window a "find /etc/default"
+command is executed,
+
+ # dnlcsnoop.d
+ PID CMD TIME HIT PATH
+ 9185 bash 9 Y /etc
+ 9185 bash 3 Y /etc
+ 12293 bash 9 Y /usr
+ 12293 bash 3 Y /usr/bin
+ 12293 bash 4 Y /usr/bin/find
+ 12293 bash 7 Y /lib
+ 12293 bash 3 Y /lib/ld.so.1
+ 12293 find 6 Y /usr
+ 12293 find 3 Y /usr/bin
+ 12293 find 3 Y /usr/bin/find
+ 12293 find 3 Y /usr
+ 12293 find 3 Y /usr/lib
+ 12293 find 3 Y /usr/lib/ld.so.1
+ 12293 find 3 Y /usr/lib/..
+ 12293 find 3 Y /usr/..
+ 12293 find 3 Y /lib
+ 12293 find 3 Y /lib/ld.so.1
+ 12293 find 3 Y /usr
+ 12293 find 3 Y /usr/bin
+ 12293 find 2 Y /usr/bin/find
+ 12293 find 4 Y /var
+ 12293 find 3 Y /var/ld
+ 12293 find 3 Y /var/ld/ld.config
+ 12293 find 3 Y /lib
+ 12293 find 3 Y /lib/libc.so.1
+ 12293 find 3 Y /lib
+ 12293 find 3 Y /lib/libc.so.1
+ 12293 find 3 Y /lib
+ 12293 find 3 Y /lib/libc.so.1
+ 12293 find 8 Y /export
+ 12293 find 4 Y /export/home
+ 12293 find 3 Y /export/home/root
+ 12293 find 4 Y /export/home/root/CacheKit-0.93
+ 12293 find 3 Y /export
+ 12293 find 3 Y /export/home
+ 12293 find 3 Y /export/home/root
+ 12293 find 3 Y /export/home/root/CacheKit-0.93
+ 12293 find 3 Y /etc
+ 12293 find 3 Y /etc/default
+ 12293 find 3 Y /etc
+ 12293 find 3 Y /etc/default
+ 12293 find 5 N /etc/default/cron
+ 12293 find 3 N /etc/default/devfsadm
+ 12293 find 4 N /etc/default/fs
+ 12293 find 4 N /etc/default/kbd
+ 12293 find 3 N /etc/default/keyserv
+ 12293 find 4 N /etc/default/nss
+ 12293 find 3 N /etc/default/syslogd
+ 12293 find 3 N /etc/default/tar
+ 12293 find 4 N /etc/default/utmpd
+ 12293 find 5 N /etc/default/init
+ 12293 find 4 Y /etc/default/login
+ 12293 find 4 Y /etc/default/su
+ 12293 find 3 N /etc/default/passwd
+ 12293 find 3 N /etc/default/dhcpagent
+ 12293 find 4 N /etc/default/inetinit
+ 12293 find 3 N /etc/default/ipsec
+ 12293 find 3 N /etc/default/mpathd
+ 12293 find 3 N /etc/default/telnetd
+ 12293 find 3 Y /etc/default/nfs
+ 12293 find 3 N /etc/default/autofs
+ 12293 find 9 Y /etc/default/ftp
+ 12293 find 5 N /etc/default/rpc.nisd
+ 12293 find 5 N /etc/default/nfslogd
+ 12293 find 4 N /etc/default/lu
+ 12293 find 6 N /etc/default/power
+ 12293 find 5 N /etc/default/sys-suspend
+ 12293 find 6 N /etc/default/metassist.xml
+ 12293 find 5 N /etc/default/yppasswdd
+ 12293 find 4 N /etc/default/webconsole
+ 12293 find 5 Y /export
+ 12293 find 4 Y /export/home
+ 12293 find 4 Y /export/home/root
+ 12293 find 4 Y /export/home/root/CacheKit-0.93
+
+The DNLC is the Directory Name Lookup Cache. Here we can see name lookups,
+and whether the cache returned a hit. "/export/home/root/CacheKit-0.93" was
+looked up a few times - this was the current directory that the find
+command was executed from.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dnlcstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/dnlcstat_example.txt
new file mode 100644
index 0000000..a6ce1d6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dnlcstat_example.txt
@@ -0,0 +1,40 @@
+The following is a demonstration of the dnlcstat command.
+
+
+Here we run dnlcstat with no options. It prints a line every second,
+
+ # dnlcstat
+ dnlc %hit hit miss
+ 0 0 0
+ 0 0 0
+ 93 95 7
+ 89 1920 231
+ 89 2130 243
+ 91 2358 232
+ 92 1476 124
+ 92 1953 159
+ 94 2416 134
+ 94 1962 114
+ 95 2113 101
+ 97 1969 54
+ 98 1489 26
+ 41 564 786
+ 40 622 913
+ 35 520 952
+ 27 937 2503
+ 22 1696 5806
+ 22 955 3281
+ 21 1377 5059
+ 31 2043 4516
+ 22 1423 4968
+ 13 550 3438
+ 2 95 3810
+ 0 58 6410
+ 4 223 4433
+ 4 198 4491
+ 7 339 4383
+
+In another window, a "find /" was run. We can see the DNLC activity above,
+initially there are high hit rates in the DNLC - over 90%. Eventually
+the find command exhausts the DNLC, and the hit rate drops to below 10%.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dtruss_example.txt b/cddl/contrib/dtracetoolkit/Examples/dtruss_example.txt
new file mode 100644
index 0000000..107fc19
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dtruss_example.txt
@@ -0,0 +1,120 @@
+The following demonstrates the dtruss command - a DTrace version of truss.
+This version is designed to be less intrusive and safer than running truss.
+
+dtruss has many options. Here is the help for version 0.70,
+
+ USAGE: dtruss [-acdefholL] [-t syscall] { -p PID | -n name | command }
+
+ -p PID # examine this PID
+ -n name # examine this process name
+ -t syscall # examine this syscall only
+ -a # print all details
+ -c # print syscall counts
+ -d # print relative times (us)
+ -e # print elapsed times (us)
+ -f # follow children
+ -l # force printing pid/lwpid
+ -o # print on cpu times
+ -L # don't print pid/lwpid
+ -b bufsize # dynamic variable buf size
+ eg,
+ dtruss df -h # run and examine "df -h"
+ dtruss -p 1871 # examine PID 1871
+ dtruss -n tar # examine all processes called "tar"
+ dtruss -f test.sh # run test.sh and follow children
+
+
+
+For example, here we dtruss any process with the name "ksh" - the Korn shell,
+
+ # dtruss -n ksh
+ PID/LWP SYSCALL(args) = return
+ 27547/1: llseek(0x3F, 0xE4E, 0x0) = 3662 0
+ 27547/1: read(0x3F, "\0", 0x400) = 0 0
+ 27547/1: llseek(0x3F, 0x0, 0x0) = 3662 0
+ 27547/1: write(0x3F, "ls -l\n\0", 0x8) = 8 0
+ 27547/1: fdsync(0x3F, 0x10, 0xFEC1D444) = 0 0
+ 27547/1: lwp_sigmask(0x3, 0x20000, 0x0) = 0xFFBFFEFF 0
+ 27547/1: stat64("/usr/bin/ls\0", 0x8047A00, 0xFEC1D444) = 0 0
+ 27547/1: lwp_sigmask(0x3, 0x0, 0x0) = 0xFFBFFEFF 0
+ [...]
+
+The output for each system call does not yet evaluate as much as truss does.
+
+
+
+In the following example, syscall elapsed and overhead times are measured.
+Elapsed times represent the time from syscall start to finish; overhead
+times measure the time spent on the CPU,
+
+ # dtruss -eon bash
+ PID/LWP ELAPSD CPU SYSCALL(args) = return
+ 3911/1: 41 26 write(0x2, "l\0", 0x1) = 1 0
+ 3911/1: 1001579 43 read(0x0, "s\0", 0x1) = 1 0
+ 3911/1: 38 26 write(0x2, "s\0", 0x1) = 1 0
+ 3911/1: 1019129 43 read(0x0, " \001\0", 0x1) = 1 0
+ 3911/1: 38 26 write(0x2, " \0", 0x1) = 1 0
+ 3911/1: 998533 43 read(0x0, "-\0", 0x1) = 1 0
+ 3911/1: 38 26 write(0x2, "-\001\0", 0x1) = 1 0
+ 3911/1: 1094323 42 read(0x0, "l\0", 0x1) = 1 0
+ 3911/1: 39 27 write(0x2, "l\001\0", 0x1) = 1 0
+ 3911/1: 1210496 44 read(0x0, "\r\0", 0x1) = 1 0
+ 3911/1: 40 28 write(0x2, "\n\001\0", 0x1) = 1 0
+ 3911/1: 9 1 lwp_sigmask(0x3, 0x2, 0x0) = 0xFFBFFEFF 0
+ 3911/1: 70 63 ioctl(0x0, 0x540F, 0x80F6D00) = 0 0
+
+A bash command was in another window, where the "ls -l" command was being
+typed. The keystrokes can be seen above, along with the long elapsed times
+(keystroke delays), and short overhead times (as the bash process blocks
+on the read and leaves the CPU).
+
+
+
+Now dtruss is put to the test. Here we truss a test program that runs several
+hundred smaller programs, which in turn generate thousands of system calls.
+
+First, as a "control" we run the program without a truss or dtruss running,
+
+ # time ./test
+ real 0m38.508s
+ user 0m5.299s
+ sys 0m25.668s
+
+Now we try truss,
+
+ # time truss ./test 2> /dev/null
+ real 0m41.281s
+ user 0m0.558s
+ sys 0m1.351s
+
+Now we try dtruss,
+
+ # time dtruss ./test 2> /dev/null
+ real 0m46.226s
+ user 0m6.771s
+ sys 0m31.703s
+
+In the above test, truss slowed the program from 38 seconds to 41. dtruss
+slowed the program from 38 seconds to 46, slightly slower that truss...
+
+Now we try follow mode "-f". The test program does run several hundred
+smaller programs, so now there are plenty more system calls to track,
+
+ # time truss -f ./test 2> /dev/null
+ real 2m28.317s
+ user 0m0.893s
+ sys 0m3.527s
+
+Now we try dtruss,
+
+ # time dtruss -f ./test 2> /dev/null
+ real 0m56.179s
+ user 0m10.040s
+ sys 0m38.185s
+
+Wow, the difference is huge! truss slows the program from 38 to 148 seconds;
+but dtruss has only slowed the program from 38 to 56 seconds.
+
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/dvmstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/dvmstat_example.txt
new file mode 100644
index 0000000..1fb7fbb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/dvmstat_example.txt
@@ -0,0 +1,91 @@
+The following is a demonstration of the dvmstat program,
+
+
+Here we run dvmstat to monitor all processes called "find". In another
+window, a "find /" command is run,
+
+ # dvmstat -n find
+ re maj mf fr epi epo api apo fpi fpo sy
+ 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0
+ 6336 0 372 0 0 0 0 0 0 0 22255
+ 1624 0 0 0 0 0 0 0 0 0 5497
+ 2292 0 0 0 0 0 0 0 0 0 7715
+ 13064 0 0 0 0 0 0 0 0 0 43998
+ 7972 168 0 0 0 0 0 0 168 0 38361
+ 468 636 0 0 0 0 0 0 636 0 13774
+ 376 588 0 0 0 0 0 0 588 0 10723
+ 80 636 0 0 0 0 0 0 656 0 11078
+ 48 772 0 0 0 0 0 0 812 0 9841
+ 16 1028 0 0 0 0 0 0 1056 0 10752
+ 0 1712 0 0 0 0 0 0 1740 0 12176
+ 4 1224 0 0 0 0 0 0 1236 0 9024
+
+The output above is spectacular! When the find command is first run,
+it begins be reading data from the file cache, as indicated by the "re"
+reclaims, and a lack of "fpi" filesystem page ins.
+
+Eventually the find command travels to places which are not cached, we can
+see the "re" value drops, and both the "maj" major faults and "fpi" values
+increase. This transition from cache hits to file system activity is
+very clear from the above output.
+
+
+
+Here we run a dvmstat to examine the PID 3778,
+
+ # dvmstat -p 3778
+ re maj mf fr epi epo api apo fpi fpo sy
+ 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0
+ 24 28 0 0 0 0 0 0 28 0 109
+ 4 148 16 0 0 0 0 0 148 0 1883
+ 16 412 384 0 0 0 0 0 412 0 21019
+ 0 0 0 0 0 0 0 0 0 0 3
+ 0 0 0 0 0 0 0 0 0 0 221
+ 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 84
+ 0 0 0 0 0 0 0 0 0 0 0
+
+Here we can see the statistics for that process only.
+
+
+
+The following runs the date command through dvmstat,
+
+ # dvmstat date
+ Sun Jun 12 17:44:24 EST 2005
+ re maj mf fr epi epo api apo fpi fpo sy
+ 16 0 208 0 0 0 0 0 0 0 38
+
+The values above are for the date command only.
+
+
+
+Now we run dvmstat on a tar command. Here we tar around 50Mb of files,
+so the command takes around 20 seconds to complete,
+
+ # dvmstat tar cf backup.tar DTrace
+ re maj mf fr epi epo api apo fpi fpo sy
+ 20 256 304 0 8 0 0 0 352 0 621
+ 4540 56 896 0 0 0 0 0 4636 0 1005
+ 4432 12 644 0 0 0 0 0 4384 0 906
+ 680 180 136 0 8 0 0 0 1056 0 502
+ 2328 60 468 0 0 0 0 0 2296 0 592
+ 1300 380 272 0 0 0 0 0 1704 0 1095
+ 2816 72 560 0 0 0 0 0 2940 0 709
+ 4084 40 416 0 0 0 0 0 4220 0 894
+ 2764 4 276 0 0 0 0 0 2700 0 566
+ 1824 96 328 0 0 0 0 0 2072 0 556
+ 3408 80 392 0 20 0 0 0 3496 0 857
+ 2804 92 552 0 4 0 0 0 2924 0 741
+ 1344 16 272 0 0 0 0 0 1376 0 289
+ 3284 52 520 0 12 0 0 0 3260 0 743
+ 4832 200 812 0 0 0 0 0 5292 0 1276
+ 11052 56 2200 0 0 0 0 0 8676 0 2326
+ 5256 328 1020 0 8 0 0 0 4404 0 1725
+ re maj mf fr epi epo api apo fpi fpo sy
+ 404 340 72 0 64 0 0 0 536 0 1135
+
+Great! Activity from the tar command such as "fpi"s can be clearly seen.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/errinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/errinfo_example.txt
new file mode 100644
index 0000000..1dcb28d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/errinfo_example.txt
@@ -0,0 +1,90 @@
+This is an example of the errinfo program, which prints details on syscall
+failures.
+
+By default it "snoops" syscall failures and prints their details,
+
+ # ./errinfo
+ EXEC SYSCALL ERR DESC
+ wnck-applet read 11 Resource temporarily unavailable
+ Xorg read 11 Resource temporarily unavailable
+ nautilus read 11 Resource temporarily unavailable
+ Xorg read 11 Resource temporarily unavailable
+ dsdm read 11 Resource temporarily unavailable
+ Xorg read 11 Resource temporarily unavailable
+ Xorg pollsys 4 interrupted system call
+ mozilla-bin lwp_park 62 timer expired
+ gnome-netstatus- ioctl 12 Not enough core
+ mozilla-bin lwp_park 62 timer expired
+ Xorg read 11 Resource temporarily unavailable
+ mozilla-bin lwp_park 62 timer expired
+ [...]
+
+which is useful to see these events live, but can scroll off the screen
+somewhat rapidly.. so,
+
+
+
+The "-c" option will count the number of errors. Hit Ctrl-C to stop the
+sample. For example,
+
+# ./errinfo -c
+Tracing... Hit Ctrl-C to end.
+^C
+ EXEC SYSCALL ERR COUNT DESC
+ nscd fcntl 22 1 Invalid argument
+ xscreensaver read 11 1 Resource temporarily unavailable
+ inetd lwp_park 62 1 timer expired
+ svc.startd lwp_park 62 1 timer expired
+ svc.configd lwp_park 62 1 timer expired
+ ttymon ioctl 25 1 Inappropriate ioctl for device
+gnome-netstatus- ioctl 12 2 Not enough core
+ mozilla-bin lwp_kill 3 2 No such process
+ mozilla-bin connect 150 5 operation now in progress
+ svc.startd portfs 62 8 timer expired
+ java_vm lwp_cond_wait 62 8 timer expired
+ soffice.bin read 11 9 Resource temporarily unavailable
+ gnome-terminal read 11 23 Resource temporarily unavailable
+ mozilla-bin recv 11 26 Resource temporarily unavailable
+ nautilus read 11 26 Resource temporarily unavailable
+gnome-settings-d read 11 26 Resource temporarily unavailable
+ gnome-smproxy read 11 34 Resource temporarily unavailable
+ gnome-panel read 11 42 Resource temporarily unavailable
+ dsdm read 11 112 Resource temporarily unavailable
+ metacity read 11 128 Resource temporarily unavailable
+ mozilla-bin lwp_park 62 133 timer expired
+ Xorg pollsys 4 147 interrupted system call
+ wnck-applet read 11 179 Resource temporarily unavailable
+ mozilla-bin read 11 258 Resource temporarily unavailable
+ Xorg read 11 1707 Resource temporarily unavailable
+
+Ok, so Xorg has received 1707 of the same type of error for the syscall read().
+
+
+
+The "-n" option lets us match on one type of process only. In the following
+we match processes that have the name "mozilla-bin",
+
+# ./errinfo -c -n mozilla-bin
+Tracing... Hit Ctrl-C to end.
+^C
+ EXEC SYSCALL ERR COUNT DESC
+ mozilla-bin getpeername 134 1 Socket is not connected
+ mozilla-bin recv 11 2 Resource temporarily unavailable
+ mozilla-bin lwp_kill 3 2 No such process
+ mozilla-bin connect 150 5 operation now in progress
+ mozilla-bin lwp_park 62 207 timer expired
+ mozilla-bin read 11 396 Resource temporarily unavailable
+
+
+
+The "-p" option lets us examine one PID only. The following example examines
+PID 1119,
+
+# ./errinfo -c -p 1119
+Tracing... Hit Ctrl-C to end.
+^C
+ EXEC SYSCALL ERR COUNT DESC
+ Xorg pollsys 4 47 interrupted system call
+ Xorg read 11 669 Resource temporarily unavailable
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/execsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/execsnoop_example.txt
new file mode 100644
index 0000000..e55682a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/execsnoop_example.txt
@@ -0,0 +1,78 @@
+The following is an example of execsnoop. As processes are executed their
+details are printed out. Another user was logged in running a few commands
+which can be viewed below,
+
+ # ./execsnoop
+ UID PID PPID ARGS
+ 100 3008 2656 ls
+ 100 3009 2656 ls -l
+ 100 3010 2656 cat /etc/passwd
+ 100 3011 2656 vi /etc/hosts
+ 100 3012 2656 date
+ 100 3013 2656 ls -l
+ 100 3014 2656 ls
+ 100 3015 2656 finger
+ [...]
+
+
+
+In this example the command "man gzip" was executed. The output lets us
+see what the man command is actually doing,
+
+ # ./execsnoop
+ UID PID PPID ARGS
+ 100 3064 2656 man gzip
+ 100 3065 3064 sh -c cd /usr/share/man; tbl /usr/share/man/man1/gzip.1 |nroff -u0 -Tlp -man -
+ 100 3067 3066 tbl /usr/share/man/man1/gzip.1
+ 100 3068 3066 nroff -u0 -Tlp -man -
+ 100 3066 3065 col -x
+ 100 3069 3064 sh -c trap '' 1 15; /usr/bin/mv -f /tmp/mpoMaa_f /usr/share/man/cat1/gzip.1 2>
+ 100 3070 3069 /usr/bin/mv -f /tmp/mpoMaa_f /usr/share/man/cat1/gzip.1
+ 100 3071 3064 sh -c more -s /tmp/mpoMaa_f
+ 100 3072 3071 more -s /tmp/mpoMaa_f
+ ^C
+
+
+
+Execsnoop has other options,
+
+ # ./execsnoop -h
+ USAGE: execsnoop [-a|-A|-sv] [-c command]
+ execsnoop # default output
+ -a # print all data
+ -A # dump all data, space delimited
+ -s # include start time, us
+ -v # include start time, string
+ -c command # command name to snoop
+
+
+
+In particular the verbose option for human readable timestamps is
+very useful,
+
+ # ./execsnoop -v
+ STRTIME UID PID PPID ARGS
+ 2005 Jan 22 00:07:22 0 23053 20933 date
+ 2005 Jan 22 00:07:24 0 23054 20933 uname -a
+ 2005 Jan 22 00:07:25 0 23055 20933 ls -latr
+ 2005 Jan 22 00:07:27 0 23056 20933 df -k
+ 2005 Jan 22 00:07:29 0 23057 20933 ps -ef
+ 2005 Jan 22 00:07:29 0 23057 20933 ps -ef
+ 2005 Jan 22 00:07:34 0 23058 20933 uptime
+ 2005 Jan 22 00:07:34 0 23058 20933 uptime
+ [...]
+
+
+
+It is also possible to match particular commands. Here we watch
+anyone using the vi command only,
+
+ # ./execsnoop -vc vi
+ STRTIME UID PID PPID ARGS
+ 2005 Jan 22 00:10:33 0 23063 20933 vi /etc/passwd
+ 2005 Jan 22 00:10:40 0 23064 20933 vi /etc/shadow
+ 2005 Jan 22 00:10:51 0 23065 20933 vi /etc/group
+ 2005 Jan 22 00:10:57 0 23066 20933 vi /.rhosts
+ [...]
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/fddist_example.txt b/cddl/contrib/dtracetoolkit/Examples/fddist_example.txt
new file mode 100644
index 0000000..3d943b9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/fddist_example.txt
@@ -0,0 +1,38 @@
+The following is a demonstration of the fddist command,
+
+
+Here fddist is run for a few seconds on an idle workstation,
+
+ Tracing reads and writes... Hit Ctrl-C to end.
+ ^C
+ EXEC: dtrace PID: 3288
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 2 | 0
+
+ EXEC: mozilla-bin PID: 1659
+
+ value ------------- Distribution ------------- count
+ 3 | 0
+ 4 |@@@@@@@@@@ 28
+ 5 | 0
+ 6 |@@@@@@@@@@@@@@@ 40
+ 7 |@@@@@@@@@@@@@@@ 40
+ 8 | 0
+
+ EXEC: Xorg PID: 1532
+
+ value ------------- Distribution ------------- count
+ 22 | 0
+ 23 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 57
+ 24 | 0
+
+The above displays the usage pattern for process file descriptors.
+We can see the Xorg process (PID 1532) has made 57 reads or writes to
+it's file descriptor 23.
+
+The pfiles(1) command can be used to help determine what file
+descriptor 23 actually is.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/filebyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/filebyproc_example.txt
new file mode 100644
index 0000000..8267da2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/filebyproc_example.txt
@@ -0,0 +1,27 @@
+The following is an example of the filebyproc.d script,
+
+ # filebyproc.d
+ dtrace: description 'syscall::open*:entry ' matched 2 probes
+ CPU ID FUNCTION:NAME
+ 0 14 open:entry gnome-netstatus- /dev/kstat
+ 0 14 open:entry man /var/ld/ld.config
+ 0 14 open:entry man /lib/libc.so.1
+ 0 14 open:entry man /usr/share/man/man.cf
+ 0 14 open:entry man /usr/share/man/windex
+ 0 14 open:entry man /usr/share/man/man1/ls.1
+ 0 14 open:entry man /usr/share/man/man1/ls.1
+ 0 14 open:entry man /tmp/mpqea4RF
+ 0 14 open:entry sh /var/ld/ld.config
+ 0 14 open:entry sh /lib/libc.so.1
+ 0 14 open:entry neqn /var/ld/ld.config
+ 0 14 open:entry neqn /lib/libc.so.1
+ 0 14 open:entry neqn /usr/share/lib/pub/eqnchar
+ 0 14 open:entry tbl /var/ld/ld.config
+ 0 14 open:entry tbl /lib/libc.so.1
+ 0 14 open:entry tbl /usr/share/man/man1/ls.1
+ 0 14 open:entry nroff /var/ld/ld.config
+ [...]
+
+In the above example, the command "man ls" was run. Each file that was
+attempted to be opened can be seen, along with the program name responsible.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/fspaging_example.txt b/cddl/contrib/dtracetoolkit/Examples/fspaging_example.txt
new file mode 100644
index 0000000..c29cb08
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/fspaging_example.txt
@@ -0,0 +1,32 @@
+The following is a short sample of output from the fspaging.d script.
+
+
+fspaging.d traces syscall read and writes, vnode interface reads, writes,
+getpage and putpage, and disk io.
+
+ # ./fspaging.d
+ Event Device RW Size Offset Path
+ disk_io dad1 R 1024 0 /extra1
+ disk_io dad1 R 8192 0 <none>
+ disk_io dad1 R 2048 0 <none>
+ sc-write . W 51200 0 /extra1/outfile
+ fop_write . W 51200 0 /extra1/outfile
+ fop_getpage . R 8192 0 /extra1/50k
+ disk_io dad1 R 8192 0 /extra1/50k
+ disk_ra dad1 R 8192 8 /extra1/50k
+ fop_getpage . R 8192 8 /extra1/50k
+ disk_ra dad1 R 34816 16 /extra1/50k
+ fop_getpage . R 8192 16 /extra1/50k
+ fop_getpage . R 8192 24 /extra1/50k
+ fop_getpage . R 8192 32 /extra1/50k
+ fop_getpage . R 8192 40 /extra1/50k
+ fop_getpage . R 8192 48 /extra1/50k
+ fop_putpage . W 8192 0 /extra1/outfile
+ fop_putpage . W 8192 8 /extra1/outfile
+ fop_putpage . W 8192 16 /extra1/outfile
+ fop_putpage . W 8192 24 /extra1/outfile
+ fop_putpage . W 8192 32 /extra1/outfile
+ fop_putpage . W 8192 40 /extra1/outfile
+ disk_io dad1 W 51200 0 /extra1/outfile
+
+For a full discussion of this example, see fsrw_example.txt.
diff --git a/cddl/contrib/dtracetoolkit/Examples/fsrw_example.txt b/cddl/contrib/dtracetoolkit/Examples/fsrw_example.txt
new file mode 100644
index 0000000..b153303
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/fsrw_example.txt
@@ -0,0 +1,129 @@
+The following are demonstrations of the fsrw.d script.
+
+
+Here the fsrw.d script was running while a 50 Kbyte file was read,
+
+ # ./fsrw.d
+ Event Device RW Size Offset Path
+ sc-read . R 8192 0 /extra1/50k
+ fop_read . R 8192 0 /extra1/50k
+ disk_io cmdk0 R 8192 0 /extra1/50k
+ disk_ra cmdk0 R 8192 8 /extra1/50k
+ sc-read . R 8192 8 /extra1/50k
+ fop_read . R 8192 8 /extra1/50k
+ disk_ra cmdk0 R 34816 16 /extra1/50k
+ sc-read . R 8192 16 /extra1/50k
+ fop_read . R 8192 16 /extra1/50k
+ sc-read . R 8192 24 /extra1/50k
+ fop_read . R 8192 24 /extra1/50k
+ sc-read . R 8192 32 /extra1/50k
+ fop_read . R 8192 32 /extra1/50k
+ sc-read . R 8192 40 /extra1/50k
+ fop_read . R 8192 40 /extra1/50k
+ sc-read . R 8192 48 /extra1/50k
+ fop_read . R 8192 48 /extra1/50k
+ sc-read . R 8192 50 /extra1/50k
+ fop_read . R 8192 50 /extra1/50k
+ ^C
+
+By looking closely at the Offset (Kbytes) and Size of each transaction, we
+can see how the read() system calls (sc-read) were satisfied by the file
+system. There were 8 read() system calls, and 3 disk events - 2 of which were
+UFS read-ahead (disk_ra). The final read-ahead was for 34 Kbytes and began
+with an offset of 16 Kbytes, which read the remaining file data (34 + 16 = 50
+Kbytes). The subsequent read() system calls and corresponding fop_read() calls
+returned from the page cache.
+
+
+
+The following demonstrates how a logical I/O is broken up into multiple
+physical I/O events. Here a dd command was used to read 1 Mbytes from the
+/var/sadm/install/contents file while fsrw.d was tracing.
+
+ # ./fsrw.d
+ Event Device RW Size Offset Path
+ sc-read . R 1048576 0 /var/sadm/install/contents
+ fop_read . R 1048576 0 /var/sadm/install/contents
+ disk_ra cmdk0 R 4096 72 /var/sadm/install/contents
+ disk_ra cmdk0 R 8192 96 <none>
+ disk_ra cmdk0 R 57344 96 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 152 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 208 /var/sadm/install/contents
+ disk_ra cmdk0 R 49152 264 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 312 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 368 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 424 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 480 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 536 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 592 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 648 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 704 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 760 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 816 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 872 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 928 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 984 /var/sadm/install/contents
+ disk_ra cmdk0 R 57344 1040 /var/sadm/install/contents
+ ^C
+
+Both the read() syscall (sc-read) and the fop_read() call asked the file system
+for 1048576 bytes, which was then broken into numerous disk I/O events of up to
+56 Kbytes in size. The 8192 byte read with a path of "<none>" is likely to be
+the file system reading the indirect block pointers for the
+/var/sadm/install/contents file (something DTrace could confirm in detail).
+
+
+
+
+The following traces activity as a cp command copies a 50 Kbyte file.
+
+ # ./fsrw.d
+ Event Device RW Size Offset Path
+ disk_io dad1 R 1024 0 /extra1
+ disk_io dad1 R 8192 0 <none>
+ disk_io dad1 R 8192 0 <none>
+ disk_io dad1 R 2048 0 <none>
+ disk_io dad1 R 2048 0 <none>
+ sc-write . W 51200 0 /extra1/outfile
+ fop_write . W 51200 0 /extra1/outfile
+ disk_io dad1 R 8192 0 /extra1/50k
+ disk_ra dad1 R 8192 8 /extra1/50k
+ disk_ra dad1 R 34816 16 /extra1/50k
+ disk_io dad1 R 2048 0 <none>
+ disk_io dad1 W 49152 0 /extra1/outfile
+ ^C
+
+Reads including UFS read-ahead can be seen as the file is read.
+The output finishes with disk writes as the new file is flushed to disk.
+The syscall write() and fop_write() can be seen to the /extra1/outfile,
+however there is no syscall read() or fop_read() to /extra1/50k - which
+we may have expected to occur before the writes. This is due to the way
+the cp command now works, it uses mmap() to map files in for reading.
+This activity can be seen if we also trace fop_getpage() and fop_putpage(),
+as the fspaging.d dtrace script does.
+
+ # ./fspaging.d
+ Event Device RW Size Offset Path
+ disk_io dad1 R 1024 0 /extra1
+ disk_io dad1 R 8192 0 <none>
+ disk_io dad1 R 2048 0 <none>
+ sc-write . W 51200 0 /extra1/outfile
+ fop_write . W 51200 0 /extra1/outfile
+ fop_getpage . R 8192 0 /extra1/50k
+ disk_io dad1 R 8192 0 /extra1/50k
+ disk_ra dad1 R 8192 8 /extra1/50k
+ fop_getpage . R 8192 8 /extra1/50k
+ disk_ra dad1 R 34816 16 /extra1/50k
+ fop_getpage . R 8192 16 /extra1/50k
+ fop_getpage . R 8192 24 /extra1/50k
+ fop_getpage . R 8192 32 /extra1/50k
+ fop_getpage . R 8192 40 /extra1/50k
+ fop_getpage . R 8192 48 /extra1/50k
+ fop_putpage . W 8192 0 /extra1/outfile
+ fop_putpage . W 8192 8 /extra1/outfile
+ fop_putpage . W 8192 16 /extra1/outfile
+ fop_putpage . W 8192 24 /extra1/outfile
+ fop_putpage . W 8192 32 /extra1/outfile
+ fop_putpage . W 8192 40 /extra1/outfile
+ disk_io dad1 W 51200 0 /extra1/outfile
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/guess_example.txt b/cddl/contrib/dtracetoolkit/Examples/guess_example.txt
new file mode 100644
index 0000000..74be8b3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/guess_example.txt
@@ -0,0 +1,39 @@
+The following is a demonstration of the guess.d script,
+
+
+guess.d is a guessing game written in DTrace. It goes like this,
+
+ # ./guess.d
+ guess.d - Guess a number between 1 and 100
+
+ Enter guess 1: 50
+ Lower...
+ Enter guess 2: 25
+ Higher...
+ Enter guess 3: 37
+ Higher...
+ Enter guess 4: 44
+ Higher...
+ Enter guess 5: 48
+ Lower...
+ Enter guess 6: 46
+ Lower...
+ Enter guess 7: 45
+ Correct! That took 7 guesses.
+
+ Please enter your name: Brendan Gregg
+
+ Previous high scores,
+ Fred Nurk 7
+ Brendan Gregg 7
+
+It was written as a demonstration of the same code written in dozens of
+languages. It makes a good demonstration, as it covers integer and string
+variables, conditional statements, loops, keyboard input, screen output,
+and file input and output.
+
+Written in DTrace however, is not such a good demonstration! DTrace doesn't
+have loops (it doesn't really need them either) which made the code a
+little odd. DTrace also doesn't have keyboard input... So this script is
+somewhat amusing as an example, but not terribly useful.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/hotkernel_example.txt b/cddl/contrib/dtracetoolkit/Examples/hotkernel_example.txt
new file mode 100644
index 0000000..d8a5aec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/hotkernel_example.txt
@@ -0,0 +1,153 @@
+The following are demonstrations of the hotkernel DTrace program.
+
+
+Here hotkernel is run for a couple of seconds then Ctrl-C is hit,
+
+ # ./hotkernel
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ FUNCTION COUNT PCNT
+ unix`swtch 1 0.1%
+ pcplusmp`apic_redistribute_compute 1 0.1%
+ genunix`strrput 1 0.1%
+ unix`sys_call 1 0.1%
+ genunix`fsflush_do_pages 1 0.1%
+ TS`ts_wakeup 1 0.1%
+ genunix`callout_schedule_1 1 0.1%
+ unix`page_create_putback 1 0.1%
+ unix`mutex_enter 4 0.3%
+ unix`cpu_halt 1575 99.2%
+
+The output summarises which kernel-level function was sampled on the
+CPU the most. This report shows that unix`cpu_halt was sampled 1575
+times, which was 99.2% of the kernel-level samples.
+
+As it turns out, unix`cpu_halt is called on this x86 server as part of the
+kernel idle thread - explaining why it is so often found on the CPU,
+
+ # dtrace -n 'fbt::cpu_halt:entry { @[stack()] = count(); }'
+ dtrace: description 'fbt::cpu_halt:entry ' matched 1 probe
+ ^C
+
+ unix`idle+0x3b
+ unix`thread_start+0x3
+ 956
+
+This kernel stack trace indicates that cpu_halt() is called by idle().
+
+The following is a SPARC example,
+
+ # ./hotkernel
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ FUNCTION COUNT PCNT
+ genunix`fop_ioctl 1 0.1%
+ genunix`allocb_cred 1 0.1%
+ genunix`poll_common 1 0.1%
+ genunix`cv_block 1 0.1%
+ genunix`strioctl 1 0.1%
+ genunix`disp_lock_exit 1 0.1%
+ genunix`crfree 1 0.1%
+ ufs`ufs_getpage 1 0.1%
+ SUNW,UltraSPARC-IIi`copyin 1 0.1%
+ genunix`strmakedata 1 0.1%
+ genunix`cv_waituntil_sig 1 0.1%
+ SUNW,UltraSPARC-IIi`prefetch_page_r 1 0.1%
+ unix`set_freemem 1 0.1%
+ unix`page_trylock 1 0.1%
+ genunix`anon_get_ptr 1 0.1%
+ unix`page_hashin 1 0.1%
+ genunix`bt_getlowbit 1 0.1%
+ unix`pp_load_tlb 1 0.1%
+ unix`_resume_from_idle 1 0.1%
+ unix`hat_pageunload 1 0.1%
+ genunix`strrput 1 0.1%
+ genunix`strpoll 1 0.1%
+ unix`page_do_hashin 1 0.1%
+ unix`cpu_vm_stats_ks_update 1 0.1%
+ genunix`sleepq_wakeone_chan 1 0.1%
+ unix`lock_set_spl 1 0.1%
+ tl`tl_wput 1 0.1%
+ genunix`kstrgetmsg 1 0.1%
+ genunix`qbackenable 1 0.1%
+ genunix`releasef 1 0.1%
+ genunix`callout_execute 1 0.1%
+ uata`ata_hba_start 1 0.1%
+ genunix`pcacheset_cmp 1 0.1%
+ genunix`sleepq_insert 1 0.1%
+ genunix`syscall_mstate 1 0.1%
+ sockfs`sotpi_recvmsg 1 0.1%
+ genunix`strput 1 0.1%
+ genunix`timespectohz 1 0.1%
+ unix`lock_clear_splx 1 0.1%
+ genunix`read 1 0.1%
+ genunix`as_segcompar 1 0.1%
+ unix`atomic_cas_64 1 0.1%
+ unix`mutex_exit 1 0.1%
+ genunix`cv_unsleep 1 0.1%
+ unix`putnext 1 0.1%
+ unix`intr_thread 1 0.1%
+ genunix`hrt2tv 1 0.1%
+ sockfs`socktpi_poll 1 0.1%
+ unix`sfmmu_mlspl_enter 1 0.1%
+ SUNW,UltraSPARC-IIi`get_ecache_tag 1 0.1%
+ SUNW,UltraSPARC-IIi`gethrestime 1 0.1%
+ genunix`cv_timedwait_sig 1 0.1%
+ genunix`getq_noenab 1 0.1%
+ SUNW,UltraSPARC-IIi`flushecacheline 1 0.1%
+ unix`utl0 1 0.1%
+ genunix`anon_alloc 1 0.1%
+ unix`page_downgrade 1 0.1%
+ unix`setfrontdq 1 0.1%
+ genunix`timeout_common 1 0.1%
+ unix`bzero 1 0.1%
+ unix`ktl0 2 0.1%
+ genunix`canputnext 2 0.1%
+ genunix`clear_active_fd 2 0.1%
+ unix`sfmmu_tlb_demap 2 0.1%
+ unix`page_vpadd 2 0.1%
+ SUNW,UltraSPARC-IIi`check_ecache_line 2 0.1%
+ genunix`cyclic_softint 2 0.1%
+ genunix`restore_mstate 2 0.1%
+ genunix`anon_map_getpages 2 0.1%
+ genunix`putq 2 0.1%
+ unix`page_lookup_create 2 0.1%
+ dtrace`dtrace_dynvar_clean 2 0.1%
+ unix`sfmmu_pageunload 2 0.1%
+ genunix`cpu_decay 2 0.1%
+ genunix`kmem_cache_alloc 3 0.2%
+ unix`rw_exit 3 0.2%
+ tl`tl_wput_data_ser 3 0.2%
+ unix`page_get_replacement_page 3 0.2%
+ unix`page_sub 3 0.2%
+ genunix`clock 3 0.2%
+ SUNW,UltraSPARC-IIi`copyout 3 0.2%
+ unix`mutex_enter 4 0.2%
+ genunix`pcache_poll 5 0.3%
+ SUNW,UltraSPARC-IIi`scrub_ecache_line 5 0.3%
+ SUNW,UltraSPARC-IIi`hwblkpagecopy 22 1.2%
+ SUNW,UltraSPARC-IIi`hwblkclr 39 2.1%
+ unix`generic_idle_cpu 506 26.8%
+ unix`idle 1199 63.5%
+
+Which shows the most common function is unix`idle.
+
+
+
+
+Now the hotkernel tool is demonstrated with the -m option, to only print
+out samples by module,
+
+ # ./hotkernel -m
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ MODULE COUNT PCNT
+ usbms 1 0.0%
+ specfs 1 0.0%
+ uhci 1 0.0%
+ sockfs 2 0.0%
+ genunix 28 0.6%
+ unix 4539 99.3%
+
+Here, genunix and unix (the two core parts of the kernel) were the most
+common module to be executing on-CPU.
diff --git a/cddl/contrib/dtracetoolkit/Examples/hotspot_example.txt b/cddl/contrib/dtracetoolkit/Examples/hotspot_example.txt
new file mode 100644
index 0000000..179ba8d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/hotspot_example.txt
@@ -0,0 +1,34 @@
+The following is a demonstration of the hotspot.d script.
+
+Here the script is run while a large file is copied from one filesystem
+(cmdk0 102,0) to another (cmdk0 102,3). We can see the file mostly resided
+around the 9000 to 10999 Mb range on the source disk (102,0), and was
+copied to the 0 to 999 Mb range on the target disk (102,3).
+
+ # ./hotspot.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ Disk: cmdk0 Major,Minor: 102,3
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 418
+ 1000 | 0
+
+ Disk: cmdk0 Major,Minor: 102,0
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 | 1
+ 1000 | 5
+ 2000 | 0
+ 3000 | 0
+ 4000 | 0
+ 5000 | 0
+ 6000 | 0
+ 7000 | 0
+ 8000 | 0
+ 9000 |@@@@@ 171
+ 10000 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1157
+ 11000 | 0
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/hotuser_example.txt b/cddl/contrib/dtracetoolkit/Examples/hotuser_example.txt
new file mode 100644
index 0000000..c038acd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/hotuser_example.txt
@@ -0,0 +1,107 @@
+The following are demonstrations of the hotuser DTrace program.
+
+
+Here, hotuser is run on a test program called "dofuncs", which is hard coded
+to spend half its time in delta(), a third in beta() and a sixth in alpha().
+
+ # ./hotuser -c ./dofuncs
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ FUNCTION COUNT PCNT
+ dofuncs`alpha 511 16.5%
+ dofuncs`beta 1029 33.3%
+ dofuncs`delta 1552 50.2%
+
+hotuser has accurately sampled which user-level functions are on the CPU,
+producing a report of the expected breakdown. The hottest user-level function
+is delta(), which was sampled 1552 times - 50.2% of the total samples.
+
+
+
+Now hotuser is run on gunzip, to find which functions are most often
+on the CPU,
+
+ # ./hotuser -c 'gunzip contents.gz'
+ Sampling... Hit Ctrl-C to end.
+
+ FUNCTION COUNT PCNT
+ libc.so.1`_free_unlocked 1 0.1%
+ gunzip`unzip 1 0.1%
+ ld.so.1`strcmp 1 0.1%
+ gunzip`inflate_dynamic 1 0.1%
+ libc.so.1`_write 1 0.1%
+ gunzip`write_buf 1 0.1%
+ gunzip`0x2d990 2 0.3%
+ libc.so.1`write 2 0.3%
+ gunzip`0x2d994 2 0.3%
+ ld.so.1`rtld_db_preinit 3 0.4%
+ gunzip`0x2d98c 7 0.9%
+ gunzip`huft_build 9 1.2%
+ libc_psr.so.1`memcpy 138 18.5%
+ gunzip`inflate_codes 233 31.2%
+ gunzip`updcrc 344 46.1%
+
+This shows that updcrc() was sampled 344 times, and 46.1% of the total
+samples.
+
+
+
+A -l option will provide a breakdown on libraries only. hotuser
+is run on gzip to show library usage only,
+
+ # ./hotuser -lc 'gzip contents'
+ Sampling... Hit Ctrl-C to end.
+
+ LIBRARY COUNT PCNT
+ libc.so.1 2 0.0%
+ libc_psr.so.1 37 0.9%
+ gzip 4113 99.1%
+
+This shows that code in the gzip binary itself was on the CPU 99.1% of
+the sample times, with libc_psr.so.1 code on the CPU 0.9% of the time.
+
+
+
+The following shows library usage of mozilla. The pgrep command is used to
+match the most recent PID of mozilla-bin.
+
+ # ./hotuser -lp `pgrep -n mozilla-bin`
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ LIBRARY COUNT PCNT
+ libplds4.so 1 0.1%
+ libappcomps.so 1 0.1%
+ libi18n.so 1 0.1%
+ libuconv.so 1 0.1%
+ libpref.so 1 0.1%
+ libblueprint.so 1 0.1%
+ libz.so.1 2 0.2%
+ libcaps.so 2 0.2%
+ libXrender.so.1 2 0.2%
+ libimglib2.so 2 0.2%
+ libXft.so.2 3 0.3%
+ libCrun.so.1 3 0.3%
+ libdocshell.so 3 0.3%
+ libplc4.so 4 0.4%
+ libgtk-x11-2.0.so.0.400.9 5 0.5%
+ libjsd.so 5 0.5%
+ libX11.so.4 5 0.5%
+ libnecko.so 8 0.9%
+ libwidget_gtk2.so 9 1.0%
+ libgkgfx.so 13 1.4%
+ libglib-2.0.so.0.400.1 14 1.5%
+ libgfx_gtk.so 18 2.0%
+ libnspr4.so 20 2.2%
+ libxpconnect.so 22 2.4%
+ libgdk-x11-2.0.so.0.400.9 23 2.5%
+ libgobject-2.0.so.0.400.1 25 2.7%
+ libhtmlpars.so 27 3.0%
+ libfontconfig.so.1 41 4.5%
+ libxpcom.so 49 5.4%
+ mozilla-bin 55 6.0%
+ libmozjs.so 80 8.8%
+ libc.so.1 115 12.6%
+ libgklayout.so 352 38.6%
+
+This shows that 352 samples found code from libgklayout.so running, which
+was 38.6% of the samples.
diff --git a/cddl/contrib/dtracetoolkit/Examples/httpdstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/httpdstat_example.txt
new file mode 100644
index 0000000..b9f59e8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/httpdstat_example.txt
@@ -0,0 +1,36 @@
+The following is an example of using the httpdstat.d script.
+
+
+This Solaris 10 server is running Apache as a webserver. The script matches
+on the process name "httpd". Here it shows many GET connections,
+
+ # httpdstat.d
+ TIME NUM GET POST HEAD TRACE
+ 2005 Nov 29 18:46:46 38 38 0 0 0
+ 2005 Nov 29 18:46:47 109 109 0 0 0
+ 2005 Nov 29 18:46:48 112 112 0 0 0
+ 2005 Nov 29 18:46:49 113 113 0 0 0
+ 2005 Nov 29 18:46:50 107 107 0 0 0
+ 2005 Nov 29 18:46:51 56 56 0 0 0
+ 2005 Nov 29 18:46:52 0 0 0 0 0
+ 2005 Nov 29 18:46:53 0 0 0 0 0
+ 2005 Nov 29 18:46:54 20 20 0 0 0
+ 2005 Nov 29 18:46:55 48 48 0 0 0
+ ^C
+
+For a few seconds we had around 100 GETs per second.
+
+
+
+httpdstat.d accepts an argument as the sample interval, here we print a
+line every 30 seconds,
+
+ # httpdstat.d 30
+ TIME NUM GET POST HEAD TRACE
+ 2005 Nov 29 18:50:49 462 458 3 1 0
+ 2005 Nov 29 18:51:19 421 413 5 2 1
+ 2005 Nov 29 18:51:49 1361 1358 3 0 0
+ ^C
+
+The values are for the entire interval.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/icmpstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/icmpstat_example.txt
new file mode 100644
index 0000000..e8b8cfe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/icmpstat_example.txt
@@ -0,0 +1,29 @@
+The following is a demonstration of the icmpstat.d script,
+
+
+Here we run it and catch an inbound ping,
+
+ # icmpstat.d
+ 2005 Jul 25 23:05:39,
+
+ STATISTIC VALUE
+
+ 2005 Jul 25 23:05:40,
+
+ STATISTIC VALUE
+ icmpOutMsgs 1
+ icmpOutEchoReps 1
+ icmpInEchos 1
+ icmpInMsgs 1
+
+ 2005 Jul 25 23:05:41,
+
+ STATISTIC VALUE
+
+ ^C
+
+Files such as /usr/include/inet/mib2.h may explain each of the statistics.
+
+The icmpstat.d is a simple demonstration of tracing ICMP activity. It may
+serve as the starting point for other scripts.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/intbycpu_example.txt b/cddl/contrib/dtracetoolkit/Examples/intbycpu_example.txt
new file mode 100644
index 0000000..5ed213c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/intbycpu_example.txt
@@ -0,0 +1,11 @@
+The following is a demonstration of the intbycpu.d script,
+
+ # intbycpu.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ CPU INTERRUPTS
+ 0 374
+ 1 412
+
+In the above output, CPU 1 had 412 interrupts, and CPU 0 had 374.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/intoncpu_example.txt b/cddl/contrib/dtracetoolkit/Examples/intoncpu_example.txt
new file mode 100644
index 0000000..ed408eb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/intoncpu_example.txt
@@ -0,0 +1,93 @@
+The following is an example of the intoncpu.d script.
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # ./intoncpu.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ uhci1
+
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8192 | 0
+ uhci0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 2048 |@@@@ 2
+ 4096 |@@ 1
+ 8192 |@@ 1
+ 16384 | 0
+ rtls0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@ 8
+ 2048 |@@@@@@@@@@ 5
+ 4096 |@@@@@@ 3
+ 8192 | 0
+ 16384 |@@ 1
+ 32768 |@@ 1
+ 65536 |@@@@ 2
+ 131072 | 0
+
+The rtls0 driver (the network interface) has encourtered the most interrupts,
+with the time taken to process each interrupt visible as a distribution.
+These times ranged from around 1000 ns (1 us), to at least 65536 ns (65 us).
+
+To determine which devices the instance names represent (eg, "uhci1"), the
+/etc/path_to_inst file could be examied.
+
+
+
+The following is a longer example of running intoncpu.d,
+
+ # ./intoncpu.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ uhci1
+
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 8192 | 0
+ ata1
+
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@ 2
+ 32768 |@@@@@@@@@@@@@@@@@@@@ 2
+ 65536 | 0
+ ata0
+
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@ 55
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 113
+ 16384 |@ 5
+ 32768 | 0
+ uhci0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1288
+ 2048 |@@ 53
+ 4096 | 6
+ 8192 | 0
+ rtls0
+
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 665
+ 2048 |@@@@@@@@@ 307
+ 4096 |@ 35
+ 8192 | 0
+ 16384 |@@@@@@@ 229
+ 32768 |@@@ 91
+ 65536 |@ 19
+ 131072 | 1
+ 262144 | 0
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/inttimes_example.txt b/cddl/contrib/dtracetoolkit/Examples/inttimes_example.txt
new file mode 100644
index 0000000..384d700
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/inttimes_example.txt
@@ -0,0 +1,18 @@
+The following is a demonstration of the inttimes.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # inttimes.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ DEVICE TIME (ns)
+ ata0 22324
+ uhci1 45893
+ ata1 138559
+ uhci0 229226
+ i80420 1305617
+ rtls0 2540175
+
+In the above output, we can see that the rtls0 driver spent 2540 us on the
+CPU servicing interrupts, while ata0 spent only 22 us.
diff --git a/cddl/contrib/dtracetoolkit/Examples/iofile_example.txt b/cddl/contrib/dtracetoolkit/Examples/iofile_example.txt
new file mode 100644
index 0000000..f4fc476
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iofile_example.txt
@@ -0,0 +1,35 @@
+The following is a demonstration of the iofile.d script,
+
+
+Here we run it while a tar command is backing up /var/adm,
+
+ # iofile.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD TIME FILE
+ 5206 tar 109 /var/adm/acct/nite
+ 5206 tar 110 /var/adm/acct/sum
+ 5206 tar 114 /var/adm/acct/fiscal
+ 5206 tar 117 /var/adm/messages.3
+ 5206 tar 172 /var/adm/sa
+ 5206 tar 3605 /var/adm/messages.2
+ 5206 tar 4548 /var/adm/spellhist
+ 5206 tar 5769 /var/adm/exacct/brendan1task
+ 5206 tar 6416 /var/adm/acct
+ 5206 tar 7587 /var/adm/messages.1
+ 5206 tar 8246 /var/adm/exacct/task
+ 5206 tar 8320 /var/adm/pool
+ 5206 tar 8973 /var/adm/pool/history
+ 5206 tar 9183 /var/adm/exacct
+ 3 fsflush 10882 <none>
+ 5206 tar 11861 /var/adm/exacct/flow
+ 5206 tar 12042 /var/adm/messages.0
+ 5206 tar 12408 /var/adm/sm.bin
+ 5206 tar 13021 /var/adm/sulog
+ 5206 tar 19007 /var/adm/streams
+ 5206 tar 21811 <none>
+ 5206 tar 24918 /var/adm/exacct/proc
+
+In the above output, we can see that the tar command spent 24918 us (25 ms)
+waiting for disk I/O on the /var/adm/exacct/proc file.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/iofileb_example.txt b/cddl/contrib/dtracetoolkit/Examples/iofileb_example.txt
new file mode 100644
index 0000000..21597f7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iofileb_example.txt
@@ -0,0 +1,23 @@
+The following is a demonstration of the iofileb.d script,
+
+
+Here we run it while a tar command is backing up /var/adm,
+
+ # ./iofileb.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD KB FILE
+ 29529 tar 56 /var/adm/sa/sa31
+ 29529 tar 56 /var/adm/sa/sa03
+ 29529 tar 56 /var/adm/sa/sa02
+ 29529 tar 56 /var/adm/sa/sa01
+ 29529 tar 56 /var/adm/sa/sa04
+ 29529 tar 56 /var/adm/sa/sa27
+ 29529 tar 56 /var/adm/sa/sa28
+ 29529 tar 324 /var/adm/exacct/task
+ 29529 tar 736 /var/adm/wtmpx
+
+In the above output, we can see that the tar command has caused 736 Kbytes
+of the /var/adm/wtmpx file to be read from disk. All af the Kbyte values
+measured are for disk activity.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/iopattern_example.txt b/cddl/contrib/dtracetoolkit/Examples/iopattern_example.txt
new file mode 100644
index 0000000..818a4a2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iopattern_example.txt
@@ -0,0 +1,57 @@
+The following is a demonstration of the iopattern program,
+
+
+Here we run iopattern for a few seconds then hit Ctrl-C. There is a "dd"
+command running on this system to intentionally create heavy sequential
+disk activity,
+
+ # iopattern
+ %RAN %SEQ COUNT MIN MAX AVG KR KW
+ 1 99 465 4096 57344 52992 23916 148
+ 0 100 556 57344 57344 57344 31136 0
+ 0 100 634 57344 57344 57344 35504 0
+ 6 94 554 512 57344 54034 29184 49
+ 0 100 489 57344 57344 57344 27384 0
+ 21 79 568 4096 57344 46188 25576 44
+ 4 96 431 4096 57344 56118 23620 0
+ ^C
+
+In the above output we can see that the disk activity is mostly sequential.
+The disks are also pulling around 30 Mb during each sample, with a large
+average event size.
+
+
+
+The following demonstrates iopattern while running a "find" command to
+cause random disk activity,
+
+ # iopattern
+ %RAN %SEQ COUNT MIN MAX AVG KR KW
+ 86 14 400 1024 8192 1543 603 0
+ 81 19 455 1024 8192 1606 714 0
+ 89 11 469 512 8192 1854 550 299
+ 83 17 463 1024 8192 1782 806 0
+ 87 13 394 1024 8192 1551 597 0
+ 85 15 348 512 57344 2835 808 155
+ 91 9 513 512 47616 2812 570 839
+ 76 24 317 512 35840 3755 562 600
+ ^C
+
+In the above output, we can see from the percentages that the disk events
+were mostly random. We can also see that the average event size is small -
+which makes sense if we are reading through many directory files.
+
+
+
+iopattern has options. Here we print timestamps "-v" and measure every 10
+seconds,
+
+ # iopattern -v 10
+ TIME %RAN %SEQ COUNT MIN MAX AVG KR KW
+ 2005 Jul 25 20:40:55 97 3 33 512 8192 1163 8 29
+ 2005 Jul 25 20:41:05 0 0 0 0 0 0 0 0
+ 2005 Jul 25 20:41:15 84 16 6 512 11776 5973 22 13
+ 2005 Jul 25 20:41:25 100 0 26 512 8192 1496 8 30
+ 2005 Jul 25 20:41:35 0 0 0 0 0 0 0 0
+ ^C
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/iopending_example.txt b/cddl/contrib/dtracetoolkit/Examples/iopending_example.txt
new file mode 100644
index 0000000..f4bc822
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iopending_example.txt
@@ -0,0 +1,126 @@
+The following is a demonstration of the iopending tool,
+
+Here we run it with a sample interval of 1 second,
+
+ # iopending 1
+ Tracing... Please wait.
+ 2006 Jan 6 20:21:59, load: 0.02, disk_r: 0 KB, disk_w: 0 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1010
+ 1 | 0
+
+ 2006 Jan 6 20:22:00, load: 0.03, disk_r: 0 KB, disk_w: 0 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1000
+ 1 | 0
+
+ 2006 Jan 6 20:22:01, load: 0.03, disk_r: 0 KB, disk_w: 0 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1000
+ 1 | 0
+
+ ^C
+
+The iopending tool samples at 1000 Hz, and prints a distribution of how many
+disk events were "pending" completion. In the above example the disks are
+quiet - for all the samples there are zero disk events pending.
+
+
+
+Now iopending is run with no arguments. It will default to an interval of 5
+seconds,
+
+ # iopending
+ Tracing... Please wait.
+ 2006 Jan 6 19:15:41, load: 0.03, disk_r: 3599 KB, disk_w: 0 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4450
+ 1 |@@@ 390
+ 2 |@ 80
+ 3 | 40
+ 4 | 20
+ 5 | 30
+ 6 | 0
+
+ ^C
+
+In the above output there was a little disk activity. For 390 samples there
+was 1 I/O event pending; for 80 samples there was 2, and so on.
+
+
+
+
+In the following example iopending is run during heavy disk activity. We
+print output every 10 seconds,
+
+ # iopending 10
+ Tracing... Please wait.
+ 2006 Jan 6 20:58:07, load: 0.03, disk_r: 25172 KB, disk_w: 33321 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@ 2160
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6720
+ 2 |@@@@ 1000
+ 3 | 50
+ 4 | 30
+ 5 | 20
+ 6 | 10
+ 7 | 10
+ 8 | 10
+ 9 | 0
+
+ 2006 Jan 6 20:58:17, load: 0.05, disk_r: 8409 KB, disk_w: 12449 KB
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7260
+ 1 |@@@@@@@ 1700
+ 2 |@ 300
+ 3 | 0
+ 4 | 10
+ 5 | 10
+ 6 | 10
+ 7 | 20
+ 8 | 0
+ 9 | 0
+ 10 | 0
+ 11 | 0
+ 12 | 0
+ 13 | 0
+ 14 | 0
+ 15 | 0
+ 16 | 0
+ 17 | 10
+ 18 | 20
+ 19 | 0
+ 20 | 0
+ 21 | 0
+ 22 | 0
+ 23 | 0
+ 24 | 0
+ 25 | 0
+ 26 | 0
+ 27 | 0
+ 28 | 0
+ 29 | 0
+ 30 | 0
+ 31 | 10
+ >= 32 |@@@ 650
+
+ ^C
+
+In the first output, most of the time (67%) there was 1 event pending,
+and for a short time there were 8 events pending. In the second output we
+see many samples were off the scale - 650 samples at 32 or more pending
+events. For this sample I had typed "sync" in another window, which
+queued many disk events immediately which were eventually completed.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/iosnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/iosnoop_example.txt
new file mode 100644
index 0000000..addb7dc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iosnoop_example.txt
@@ -0,0 +1,39 @@
+The following demonstrates iosnoop. It was run on a system that was
+fairly quiet until a tar command was run,
+
+# ./iosnoop
+ UID PID D BLOCK SIZE COMM PATHNAME
+ 0 0 W 1067 512 sched <none>
+ 0 0 W 6496304 1024 sched <none>
+ 0 3 W 6498797 512 fsflush <none>
+ 0 0 W 1067 512 sched <none>
+ 0 0 W 6496304 1024 sched <none>
+ 100 443 R 892288 4096 Xsun /usr/openwin/bin/Xsun
+ 100 443 R 891456 4096 Xsun /usr/openwin/bin/Xsun
+ 100 15795 R 3808 8192 tar /usr/bin/eject
+ 100 15795 R 35904 6144 tar /usr/bin/eject
+ 100 15795 R 39828 6144 tar /usr/bin/env
+ 100 15795 R 3872 8192 tar /usr/bin/expr
+ 100 15795 R 21120 7168 tar /usr/bin/expr
+ 100 15795 R 43680 6144 tar /usr/bin/false
+ 100 15795 R 44176 6144 tar /usr/bin/fdetach
+ 100 15795 R 3920 8192 tar /usr/bin/fdformat
+ 100 15795 R 3936 8192 tar /usr/bin/fdformat
+ 100 15795 R 4080 8192 tar /usr/bin/fdformat
+ 100 15795 R 9680 3072 tar /usr/bin/fdformat
+ 100 15795 R 4096 8192 tar /usr/bin/fgrep
+ 100 15795 R 46896 6144 tar /usr/bin/fgrep
+ 100 15795 R 4112 8192 tar /usr/bin/file
+ 100 15795 R 4128 8192 tar /usr/bin/file
+ 100 15795 R 4144 8192 tar /usr/bin/file
+ 100 15795 R 21552 7168 tar /usr/bin/file
+ 100 15795 R 4192 8192 tar /usr/bin/fmli
+ 100 15795 R 4208 8192 tar /usr/bin/fmli
+ 100 15795 R 4224 57344 tar /usr/bin/fmli
+ 100 15795 R 4336 24576 tar /usr/bin/fmli
+ 100 15795 R 695792 8192 tar <none>
+ 100 15795 R 696432 57344 tar /usr/bin/fmli
+[...]
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/iotop_example.txt b/cddl/contrib/dtracetoolkit/Examples/iotop_example.txt
new file mode 100644
index 0000000..8cf55c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/iotop_example.txt
@@ -0,0 +1,142 @@
+The following are demonstrations of the iotop program,
+
+
+Here we run iotop with the -C option to not clear the screen, but instead
+provide a scrolling output,
+
+ # iotop -C
+ Tracing... Please wait.
+ 2005 Jul 16 00:34:40, load: 1.21, disk_r: 12891 KB, disk_w: 1087 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D BYTES
+ 0 3 0 fsflush cmdk0 102 4 W 512
+ 0 3 0 fsflush cmdk0 102 0 W 11776
+ 0 27751 20320 tar cmdk0 102 16 W 23040
+ 0 3 0 fsflush cmdk0 102 0 R 73728
+ 0 0 0 sched cmdk0 102 0 R 548864
+ 0 0 0 sched cmdk0 102 0 W 1078272
+ 0 27751 20320 tar cmdk0 102 16 R 1514496
+ 0 27751 20320 tar cmdk0 102 3 R 11767808
+
+ 2005 Jul 16 00:34:45, load: 1.23, disk_r: 83849 KB, disk_w: 488 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D BYTES
+ 0 0 0 sched cmdk0 102 4 W 1536
+ 0 0 0 sched cmdk0 102 0 R 131072
+ 0 27752 20320 find cmdk0 102 0 R 262144
+ 0 0 0 sched cmdk0 102 0 W 498176
+ 0 27751 20320 tar cmdk0 102 3 R 11780096
+ 0 27751 20320 tar cmdk0 102 5 R 29745152
+ 0 27751 20320 tar cmdk0 102 4 R 47203328
+
+ 2005 Jul 16 00:34:50, load: 1.25, disk_r: 22394 KB, disk_w: 2 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D BYTES
+ 0 27752 20320 find cmdk0 102 0 W 2048
+ 0 0 0 sched cmdk0 102 0 R 16384
+ 0 321 1 automountd cmdk0 102 0 R 22528
+ 0 27752 20320 find cmdk0 102 0 R 1462272
+ 0 27751 20320 tar cmdk0 102 5 R 17465344
+
+In the above output, we can see a tar command is reading from the cmdk0
+disk, from several different slices (different minor numbers), on the last
+report focusing on 102,5 (an "ls -lL" in /dev/dsk can explain the number to
+slice mappings).
+
+The disk_r and disk_w values give a summary of the overall activity in
+bytes.
+
+
+
+Bytes can be used as a yardstick to determine which process is keeping the
+disks busy, however either of the delta times available from iotop would
+be more accurate (as they take into account whether the activity is random
+or sequential).
+
+ # iotop -Co
+ Tracing... Please wait.
+ 2005 Jul 16 00:39:03, load: 1.10, disk_r: 5302 KB, disk_w: 20 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D DISKTIME
+ 0 0 0 sched cmdk0 102 0 W 532
+ 0 0 0 sched cmdk0 102 0 R 245398
+ 0 27758 20320 find cmdk0 102 0 R 3094794
+
+ 2005 Jul 16 00:39:08, load: 1.14, disk_r: 5268 KB, disk_w: 273 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D DISKTIME
+ 0 3 0 fsflush cmdk0 102 0 W 2834
+ 0 0 0 sched cmdk0 102 0 W 263527
+ 0 0 0 sched cmdk0 102 0 R 285015
+ 0 3 0 fsflush cmdk0 102 0 R 519187
+ 0 27758 20320 find cmdk0 102 0 R 2429232
+
+ 2005 Jul 16 00:39:13, load: 1.16, disk_r: 602 KB, disk_w: 1238 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D DISKTIME
+ 0 3 0 fsflush cmdk0 102 4 W 200
+ 0 3 0 fsflush cmdk0 102 6 W 260
+ 0 3 0 fsflush cmdk0 102 0 W 883
+ 0 27758 20320 find cmdk0 102 0 R 55686
+ 0 3 0 fsflush cmdk0 102 0 R 317508
+ 0 0 0 sched cmdk0 102 0 R 320195
+ 0 0 0 sched cmdk0 102 0 W 571084
+ [...]
+
+The disk time is in microseconds. In the first sample, we can see the find
+command caused a total of 3.094 seconds of disk time - the duration of the
+samples here is 5 seconds (the default), so it would be fair to say that
+the find command is keeping the disk 60% busy.
+
+
+
+A new option for iotop is to print percents "-P" which are based on disk
+I/O times, and hense are a fair measurementt of what is keeping the disks
+busy.
+
+ # iotop -PC 1
+ Tracing... Please wait.
+ 2005 Nov 18 15:26:14, load: 0.24, disk_r: 13176 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2215 1663 bart cmdk0 102 0 R 85
+
+ 2005 Nov 18 15:26:15, load: 0.25, disk_r: 5263 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2214 1663 find cmdk0 102 0 R 15
+ 0 2215 1663 bart cmdk0 102 0 R 67
+
+ 2005 Nov 18 15:26:16, load: 0.25, disk_r: 8724 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2214 1663 find cmdk0 102 0 R 10
+ 0 2215 1663 bart cmdk0 102 0 R 71
+
+ 2005 Nov 18 15:26:17, load: 0.25, disk_r: 7528 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2214 1663 find cmdk0 102 0 R 0
+ 0 2215 1663 bart cmdk0 102 0 R 85
+
+ 2005 Nov 18 15:26:18, load: 0.26, disk_r: 11389 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2214 1663 find cmdk0 102 0 R 2
+ 0 2215 1663 bart cmdk0 102 0 R 80
+
+ 2005 Nov 18 15:26:19, load: 0.26, disk_r: 22109 KB, disk_w: 0 KB
+
+ UID PID PPID CMD DEVICE MAJ MIN D %I/O
+ 0 2215 1663 bart cmdk0 102 0 R 76
+
+ ^C
+
+In the above output, bart and find jostle for disk access as they create
+a database of file checksums. The command was,
+
+ find / | bart create -I > /dev/null
+
+Note that the %I/O is in terms of 1 disk. A %I/O of say 200 is allowed - it
+would mean that effectively 2 disks were at 100%, or 4 disks at 50%, etc.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_calldist_example.txt
new file mode 100644
index 0000000..b659c0a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_calldist_example.txt
@@ -0,0 +1,247 @@
+This is an example of j_calldist.d showing the elapsed times for different
+types of Java operations.
+
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0), and produces the output in graphical format, showing
+a histogram of the amount of time taken by each call. Method calls are only
+visible when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+Because of the extensive results returned otherwise, this script will show you
+a configurable number of results in each section. The default (as in this
+example) is ten.
+
+Here we see it tracing the activity of Code/Java/Func_abc.
+
+# j_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 elapsed times (us),
+
+Top 10 exclusive method elapsed times (us),
+ PID=311342, method, sun/net/www/ParseUtil.decode
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@ 3
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2048 |@@@@ 1
+ 4096 | 0
+
+ PID=311342, method, java/net/URLClassLoader.<clinit>
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, java/util/jar/JarFile.hasClassPathAttribute
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, java/util/zip/ZipFile.read
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, sun/nio/cs/US_ASCII.newEncoder
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, java/util/zip/ZipFile.getInputStream
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, sun/nio/cs/US_ASCII.newDecoder
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@@@@@@@@@ 1
+ 16384 | 0
+
+ PID=311342, method, java/util/HashMap.<init>
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@ 8
+ 16 |@@@@@@@@@@@@@@@@ 9
+ 32 |@@@@@@@@@ 5
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@ 1
+ 16384 | 0
+
+ PID=311342, method, java/io/UnixFileSystem.normalize
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@ 1
+ 16 | 0
+ 32 | 0
+ 64 |@@@@@@@@@ 8
+ 128 |@@@@@@@@@@@@@ 11
+ 256 |@@@@@@ 5
+ 512 |@@@@@@@@@ 8
+ 1024 | 0
+ 2048 | 0
+ 4096 |@ 1
+ 8192 | 0
+
+ PID=311342, method, java/lang/Thread.sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+
+Top 10 inclusive method elapsed times (us),
+ PID=311342, method, java/net/URLClassLoader$1.run
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+ PID=311342, method, java/net/URLClassLoader.findClass
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+ PID=311342, method, sun/misc/URLClassPath.getLoader
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@ 1
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@ 2
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 8192 | 0
+ 16384 |@@@ 1
+ 32768 | 0
+ 65536 |@@@ 1
+ 131072 | 0
+
+ PID=311342, method, java/lang/ClassLoader.loadClass
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@ 6
+ 256 |@@@@@@@@@@@@@@@@@@@@@@ 15
+ 512 |@@@@ 3
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 | 0
+ 65536 |@@@@ 3
+ 131072 | 0
+
+ PID=311342, method, java/security/AccessController.doPrivileged
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@ 2
+ 32 |@ 1
+ 64 |@@@@ 4
+ 128 |@@@@@@@@@@@@@@@@ 17
+ 256 |@ 1
+ 512 |@@@@ 4
+ 1024 |@@ 2
+ 2048 |@ 1
+ 4096 |@@@@@@ 6
+ 8192 |@ 1
+ 16384 |@@ 2
+ 32768 | 0
+ 65536 |@@ 2
+ 131072 | 0
+
+ PID=311342, method, Func_abc.func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ PID=311342, method, Func_abc.func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=311342, method, java/lang/Thread.sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+ PID=311342, method, Func_abc.func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ PID=311342, method, Func_abc.main
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+The elapsed times section is empty. It would show us anything that is not a
+Java method - garbage collection for example. However there was nothing of
+the kind in this example.
+
+The exclusive method elapsed times show us the time spent in the top ten most
+time consuming methods, not including time spent in subroutines called by
+those methods.
+
+The inclusive method elapsed times show us the time spent in the top ten most
+time consuming methods including time spent in subroutines called by those
+methods.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly.
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_calls_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_calls_example.txt
new file mode 100644
index 0000000..3aacb2c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_calls_example.txt
@@ -0,0 +1,137 @@
+The following are examples of running the j_calls.d script.
+
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls and object allocation are only visible
+when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+Here we see it running on Code/Java/Func_abc
+
+# j_calls.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ PID TYPE NAME COUNT
+ 311334 cload Func_abc 1
+ 311334 cload java/io/BufferedInputStream 1
+ 311334 cload java/io/BufferedOutputStream 1
+ 311334 cload java/io/BufferedReader 1
+ 311334 cload java/io/BufferedWriter 1
+ 311334 cload java/io/Closeable 1
+ 311334 cload java/io/Console 1
+ 311334 cload java/io/Console$1 1
+ 311334 cload java/io/Console$1$1 1
+ 311334 cload java/io/DataInput 1
+ 311334 cload java/io/DataInputStream 1
+ 311334 cload java/io/DeleteOnExitHook 1
+ 311334 cload java/io/ExpiringCache 1
+ 311334 cload java/io/ExpiringCache$1 1
+ 311334 cload java/io/ExpiringCache$Entry 1
+ 311334 cload java/io/File 1
+ 311334 cload java/io/File$1 1
+ 311334 cload java/io/FileDescriptor 1
+ 311334 cload java/io/FileInputStream 1
+ 311334 cload java/io/FileOutputStream 1
+ 311334 cload java/io/FilePermission 1
+ 311334 cload java/io/FilePermission$1 1
+ 311334 cload java/io/FilePermissionCollection 1
+ 311334 cload java/io/FileReader 1
+ 311334 cload java/io/FileSystem 1
+ 311334 cload java/io/FilterInputStream 1
+ 311334 cload java/io/FilterOutputStream 1
+ 311334 cload java/io/Flushable 1
+ 311334 cload java/io/InputStream 1
+ 311334 cload java/io/InputStreamReader 1
+ 311334 cload java/io/ObjectStreamClass 1
+ 311334 cload java/io/ObjectStreamField 1
+ 311334 cload java/io/OutputStream 1
+ 311334 cload java/io/OutputStreamWriter 1
+ 311334 cload java/io/PrintStream 1
+ 311334 cload java/io/Reader 1
+ 311334 cload java/io/Serializable 1
+ 311334 cload java/io/UnixFileSystem 1
+ 311334 cload java/io/Writer 1
+ 311334 cload java/lang/AbstractStringBuilder 1
+ 311334 cload java/lang/Appendable 1
+ 311334 cload java/lang/ApplicationShutdownHooks 1
+ 311334 cload java/lang/ArithmeticException 1
+ 311334 cload java/lang/ArrayStoreException 1
+ 311334 cload java/lang/Boolean 1
+ 311334 cload java/lang/Byte 1
+ 311334 cload java/lang/CharSequence 1
+ 311334 cload java/lang/Character 1
+ 311334 cload java/lang/CharacterDataLatin1 1
+ 311334 cload java/lang/Class 1
+[... 1400 lines truncated ...]
+ 311334 method java/lang/Class.getClassLoader0 34
+ 311334 method java/lang/String.toLowerCase 34
+ 311334 method sun/security/action/GetPropertyAction.run 34
+ 311334 method java/nio/CharBuffer.arrayOffset 36
+ 311334 method java/util/HashMap.getEntry 36
+ 311334 method java/io/File.<init> 37
+ 311334 method java/io/UnixFileSystem.prefixLength 37
+ 311334 oalloc java/io/File 37
+ 311334 oalloc java/lang/reflect/Field 37
+ 311334 method java/io/BufferedReader.readLine 38
+ 311334 method java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread 38
+ 311334 method java/lang/CharacterDataLatin1.toLowerCase 41
+ 311334 method java/lang/CharacterDataLatin1.getProperties 43
+ 311334 method java/security/AccessController.doPrivileged 43
+ 311334 method java/util/Vector.size 43
+ 311334 method java/nio/Buffer.position 44
+ 311334 method java/nio/ByteBuffer.arrayOffset 44
+ 311334 method java/lang/System.getProperty 48
+ 311334 method java/util/Properties.getProperty 50
+ 311334 method java/util/BitSet.expandTo 51
+ 311334 method java/util/BitSet.set 51
+ 311334 method java/lang/System.checkKey 56
+ 311334 method java/lang/Thread.currentThread 57
+ 311334 method java/util/Hashtable$Entry.<init> 57
+ 311334 oalloc [Ljava/lang/String; 57
+ 311334 oalloc java/util/Hashtable$Entry 57
+ 311334 method java/util/Hashtable.get 59
+ 311334 method java/util/Hashtable.put 63
+ 311334 method java/util/BitSet.checkInvariants 71
+ 311334 method java/util/BitSet.wordIndex 72
+ 311334 method java/lang/StringBuilder.<init> 73
+ 311334 method java/lang/StringBuilder.toString 73
+ 311334 oalloc java/lang/StringBuilder 73
+ 311334 method java/lang/AbstractStringBuilder.expandCapacity 81
+ 311334 method java/util/HashMap.hash 81
+ 311334 method java/util/HashMap.indexFor 81
+ 311334 method java/lang/AbstractStringBuilder.<init> 82
+ 311334 method java/lang/Character.toLowerCase 82
+ 311334 method java/lang/String.startsWith 83
+ 311334 method java/util/Arrays.copyOf 87
+ 311334 method java/lang/String.lastIndexOf 90
+ 311334 method java/lang/String.substring 94
+ 311334 method java/util/Arrays.copyOfRange 107
+ 311334 method java/lang/String.getChars 156
+ 311334 method java/lang/System.getSecurityManager 174
+ 311334 method java/lang/String.<init> 175
+ 311334 method java/lang/String.equals 202
+ 311334 method java/lang/Math.min 208
+ 311334 method java/lang/String.hashCode 213
+ 311334 method java/lang/String.indexOf 302
+ 311334 oalloc [Ljava/lang/Object; 326
+ 311334 method java/lang/System.arraycopy 360
+ 311334 oalloc [I 374
+ 311334 oalloc java/lang/Class 395
+ 311334 oalloc [B 406
+ 311334 oalloc [S 486
+ 311334 method java/lang/StringBuilder.append 533
+ 311334 oalloc [[I 541
+ 311334 method java/lang/AbstractStringBuilder.append 549
+ 311334 method java/lang/Object.<init> 823
+ 311334 oalloc java/lang/String 931
+ 311334 oalloc [C 1076
+ 311334 method java/lang/String.charAt 1960
+
+This shows us each of the events associated with the PID 311334, and the
+number of times each event happened. These events can be of type cload (class
+load), method (method call), mcompile (method compile), mload (compiled method
+load), oalloc (object alloc) or thread (thread start).
+
+In this case you can see 1960 calls to java/lang/String.charAt, and 1076
+object allocations of type [C.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_calltime_example.txt
new file mode 100644
index 0000000..937e06f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_calltime_example.txt
@@ -0,0 +1,67 @@
+The following are examples of j_calltime.d.
+
+This script traces the elapsed time of Java methods and prints a report of the
+top ten in each category. This number is configurable with simple edit of
+the DTrace script
+
+Here it traces the example program, Code/Java/Func_abc
+
+# j_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 counts,
+ PID TYPE NAME COUNT
+ 311358 method java/lang/String.equals 202
+ 311358 method java/lang/Math.min 208
+ 311358 method java/lang/String.hashCode 213
+ 311358 method java/lang/String.indexOf 302
+ 311358 method java/lang/System.arraycopy 360
+ 311358 method java/lang/StringBuilder.append 533
+ 311358 method java/lang/AbstractStringBuilder.append 549
+ 311358 method java/lang/Object.<init> 823
+ 311358 method java/lang/String.charAt 1960
+ 0 total - 12020
+
+Top 10 elapsed times (us),
+ PID TYPE NAME TOTAL
+
+Top 10 exclusive method elapsed times (us),
+ PID TYPE NAME TOTAL
+ 311358 method java/nio/ByteBuffer.<init> 5430
+ 311358 method java/lang/String.charAt 6079
+ 311358 method java/lang/String.<init> 7306
+ 311358 method java/lang/StringBuilder.append 10240
+ 311358 method java/util/StringTokenizer.scanToken 11075
+ 311358 method java/net/URL.<clinit> 12519
+ 311358 method java/io/UnixFileSystem.normalize 13218
+ 311358 method sun/net/www/ParseUtil.decode 14208
+ 311358 method java/lang/Thread.sleep 3016374
+ 0 total - 3344993
+
+Top 10 inclusive method elapsed times (us),
+ PID TYPE NAME TOTAL
+ 311358 method sun/misc/Launcher.<clinit> 129120
+ 311358 method java/lang/ClassLoader.initSystemClassLoader 129851
+ 311358 method java/lang/ClassLoader.getSystemClassLoader 129897
+ 311358 method java/lang/ClassLoader.loadClass 267404
+ 311358 method java/security/AccessController.doPrivileged 278364
+ 311358 method Func_abc.func_c 1009971
+ 311358 method Func_abc.func_b 2019995
+ 311358 method java/lang/Thread.sleep 3016374
+ 311358 method Func_abc.func_a 3027043
+ 311358 method Func_abc.main 3027068
+
+Counts shows us how many times each different method was called, and how
+many methods were called in total.
+
+The exclusive method elapsed times show the time that each method spent
+processing code - while not in other method.
+
+The inclusive method elapsed times show the time that each method spent
+processing code, including the time spent in other calls.
+
+These elapsed times are the absolute time from when the method began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_classflow_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_classflow_example.txt
new file mode 100644
index 0000000..b8a9b75
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_classflow_example.txt
@@ -0,0 +1,89 @@
+Following are examples of j_classflow.d.
+
+This watches Java method entries and returns from all Java processes on the
+system with hotspot provider support (1.6.0) and the flag
+"+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+Here we can see it run on Code/Java/Func_abc.
+
+# j_classflow.d Func_abc
+ C PID TIME(us) -- CLASS.METHOD
+ 0 311425 4789778117827 -> Func_abc.main
+ 0 311425 4789778117844 -> Func_abc.func_a
+ 0 311425 4789779120071 -> Func_abc.func_b
+ 0 311425 4789780130070 -> Func_abc.func_c
+ 0 311425 4789781140067 <- Func_abc.func_c
+ 0 311425 4789781140079 <- Func_abc.func_b
+ 0 311425 4789781140087 <- Func_abc.func_a
+ 0 311425 4789781140095 <- Func_abc.main
+^C
+
+The first column, C gives us the CPU ID.
+
+The second column, TIME(us), gives us the time since boot in microseconds.
+
+The third column, PID gives us the Process ID.
+
+The fourth column, CLASS.METHOD gives us the Java class and method name.
+
+We can see that Func_abc.main called Func.abc.func_a, which in turn
+called Func_abc.funcb etc.
+
+Here we can see an example of running it on java/io/BufferedOutputStream
+
+# j_classflow.d java/io/BufferedOutputStream
+ C PID TIME(us) -- CLASS.METHOD
+ 0 311461 4790094765413 -> java/io/BufferedOutputStream.<init>
+ 0 311461 4790094765459 <- java/io/BufferedOutputStream.<init>
+ 0 311461 4790094779559 -> java/io/BufferedOutputStream.<init>
+ 0 311461 4790094779595 <- java/io/BufferedOutputStream.<init>
+ 0 311461 4790094965883 -> java/io/BufferedOutputStream.write
+ 0 311461 4790094965913 <- java/io/BufferedOutputStream.write
+ 0 311461 4790094965926 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790094965936 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966279 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966293 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790094966588 -> java/io/BufferedOutputStream.write
+ 0 311461 4790094966602 <- java/io/BufferedOutputStream.write
+ 0 311461 4790094966610 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790094966618 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966778 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966787 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790094966811 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790094966819 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966828 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790094966836 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790095970345 -> java/io/BufferedOutputStream.write
+ 0 311461 4790095970372 <- java/io/BufferedOutputStream.write
+ 0 311461 4790095970382 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790095970390 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970453 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970462 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790095970737 -> java/io/BufferedOutputStream.write
+ 0 311461 4790095970751 <- java/io/BufferedOutputStream.write
+ 0 311461 4790095970759 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790095970766 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970795 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970804 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790095970828 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790095970836 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970844 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790095970853 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790096980348 -> java/io/BufferedOutputStream.write
+ 0 311461 4790096980373 <- java/io/BufferedOutputStream.write
+ 0 311461 4790096980383 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790096980391 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980452 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980460 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790096980735 -> java/io/BufferedOutputStream.write
+ 0 311461 4790096980749 <- java/io/BufferedOutputStream.write
+ 0 311461 4790096980757 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790096980765 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980794 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980803 <- java/io/BufferedOutputStream.flush
+ 0 311461 4790096980826 -> java/io/BufferedOutputStream.flush
+ 0 311461 4790096980834 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980843 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311461 4790096980851 <- java/io/BufferedOutputStream.flush
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_cpudist_example.txt
new file mode 100644
index 0000000..15abac6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_cpudist_example.txt
@@ -0,0 +1,252 @@
+This is an example of j_cpudist.d showing the elapsed times for different
+types of Java operations.
+
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0), and produces the output in graphical format, showing
+a histogram of the amount of time taken by each call. Method calls are only
+visible when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+Because of the extensive results returned otherwise, this script will show you
+a configurable number of results in each section. The default (as in this
+example) is ten.
+
+Here we see it tracing the activity of Code/Java/Func_abc.
+
+# j_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 on-CPU times (us),
+
+Top 10 exclusive method on-CPU times (us),
+ PID=311364, method, java/lang/AbstractStringBuilder.append
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 382
+ 2 |@@@@@@@@@@@ 151
+ 4 |@ 13
+ 8 | 1
+ 16 | 1
+ 32 | 1
+ 64 | 0
+
+ PID=311364, method, java/util/Arrays.copyOf
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 68
+ 4 |@@@@@@@ 15
+ 8 | 0
+ 16 | 0
+ 32 | 1
+ 64 | 1
+ 128 | 0
+ 256 |@ 2
+ 512 | 0
+
+ PID=311364, method, java/io/UnixFileSystem.normalize
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@ 9
+ 16 |@@@@@@@@@@@@@@ 12
+ 32 |@@@@@@ 5
+ 64 |@@@@@@@ 6
+ 128 |@ 1
+ 256 | 0
+
+ PID=311364, method, java/io/File.<clinit>
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=311364, method, sun/misc/URLClassPath$JarLoader.getJarFile
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=311364, method, java/io/FilePermission$1.run
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@ 1
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 |@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=311364, method, java/lang/StringBuilder.append
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 526
+ 4 | 2
+ 8 | 0
+ 16 | 4
+ 32 | 1
+ 64 | 0
+
+ PID=311364, method, java/lang/String.<init>
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 162
+ 4 |@@ 10
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 1
+ 128 | 0
+ 256 | 1
+ 512 | 0
+ 1024 | 1
+ 2048 | 0
+
+ PID=311364, method, java/lang/String.charAt
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1953
+ 2 | 3
+ 4 | 1
+ 8 | 1
+ 16 | 2
+ 32 | 0
+
+ PID=311364, method, java/lang/System.initializeSystemClass
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+
+Top 10 inclusive method on-CPU times (us),
+ PID=311364, method, sun/misc/Launcher$ExtClassLoader.<init>
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/Launcher$ExtClassLoader.getExtClassLoader
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/Launcher$ExtClassLoader.getExtURLs
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/Launcher.<clinit>
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/Launcher.<init>
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, java/lang/ClassLoader.loadClassInternal
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 128 |@@@@@@@@@ 2
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 |@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/Launcher$AppClassLoader.loadClass
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 128 |@@@@@@@@@ 2
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 |@@@@ 1
+ 32768 | 0
+
+ PID=311364, method, sun/misc/URLClassPath.getLoader
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@ 1
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@ 1
+ 512 |@@@@@@@@@@@@@@@@@@@@@@ 7
+ 1024 |@@@@@@ 2
+ 2048 | 0
+ 4096 |@@@ 1
+ 8192 |@@@ 1
+ 16384 | 0
+
+ PID=311364, method, java/lang/ClassLoader.loadClass
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@ 6
+ 64 |@@@@@@@@@@@@@@@@@@@@@ 14
+ 128 |@@@@@@ 4
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@ 1
+ 16384 |@@@ 2
+ 32768 | 0
+
+ PID=311364, method, java/security/AccessController.doPrivileged
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@ 1
+ 8 |@@@@ 4
+ 16 |@@@@@@@@@@ 11
+ 32 |@@@@@@@@@@ 11
+ 64 | 0
+ 128 |@@@ 3
+ 256 |@ 1
+ 512 |@@@@@ 5
+ 1024 |@@ 2
+ 2048 |@ 1
+ 4096 |@ 1
+ 8192 |@@ 2
+ 16384 |@ 1
+ 32768 | 0
+
+The elapsed times section is empty. It would show us anything that is not a
+Java method - garbage collection for example. However there was nothing of
+the kind in this example.
+
+The exclusive method elapsed times show us the time spent on-CPU by the most
+time consuming methods, not including time spent in subroutines called by
+those methods.
+
+The inclusive method elapsed times show us the time spent on-CPU by the top
+ten most time consuming methods including time spent in subroutines called by
+those methods.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_cputime_example.txt
new file mode 100644
index 0000000..0947cc0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_cputime_example.txt
@@ -0,0 +1,75 @@
+The following are examples of j_cputime.d.
+
+This script traces the on-CPU time of Java methods and prints a report. Here
+it traces the example program, Code/Java/Func_abc
+
+# j_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 counts,
+ PID TYPE NAME COUNT
+ 311374 method java/lang/String.equals 202
+ 311374 method java/lang/Math.min 208
+ 311374 method java/lang/String.hashCode 213
+ 311374 method java/lang/String.indexOf 302
+ 311374 method java/lang/System.arraycopy 360
+ 311374 method java/lang/StringBuilder.append 533
+ 311374 method java/lang/AbstractStringBuilder.append 549
+ 311374 method java/lang/Object.<init> 823
+ 311374 method java/lang/String.charAt 1960
+ 0 total - 12020
+
+Top 10 on-CPU times (us),
+ PID TYPE NAME TOTAL
+
+Top 10 exclusive method on-CPU times (us),
+ PID TYPE NAME TOTAL
+ 311374 method java/io/FilePermission$1.run 1055
+ 311374 method java/util/Arrays.copyOf 1110
+ 311374 method sun/net/www/ParseUtil.decode 1161
+ 311374 method java/io/File.<clinit> 1212
+ 311374 method java/lang/StringBuilder.append 1228
+ 311374 method java/io/UnixFileSystem.normalize 1402
+ 311374 method java/lang/String.<init> 2251
+ 311374 method java/lang/String.charAt 2262
+ 311374 method java/lang/System.initializeSystemClass 2751
+ 0 total - 99868
+
+Top 10 inclusive method on-CPU times (us),
+ PID TYPE NAME TOTAL
+ 311374 method java/lang/ClassLoader.loadClassInternal 25826
+ 311374 method sun/misc/Launcher$ExtClassLoader.getExtClassLoader 25914
+ 311374 method java/net/URL.<init> 27677
+ 311374 method sun/misc/Launcher.<init> 28566
+ 311374 method sun/misc/Launcher.<clinit> 28744
+ 311374 method java/lang/ClassLoader.initSystemClassLoader 29241
+ 311374 method java/lang/ClassLoader.getSystemClassLoader 29249
+ 311374 method java/lang/System.initializeSystemClass 33814
+ 311374 method java/lang/ClassLoader.loadClass 66564
+ 311374 method java/security/AccessController.doPrivileged 67499
+
+You can see that it prints the top ten results in each of four categories.
+
+The first section reports how many times each subroutine was called, and it's
+type.
+
+The second section reports on the on-CPU time of anything that was not of type
+"method", in this case - none.
+
+The exclusive method on-CPU times shows, amongst other results, that
+java/lang/String.charAt spent around 2,200 microseconds on-CPU. This times
+excludes time spent in other subroutines.
+
+The inclusive method on-CPU times show the times that various methods
+spent on-CPU. This includes the time spent in other subroutines called.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_events_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_events_example.txt
new file mode 100644
index 0000000..2c48700
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_events_example.txt
@@ -0,0 +1,134 @@
+The following are examples of j_events.d.
+
+This counts events from all Java processes on the system with hotspot
+provider support (1.6.0). Some events such as method calls are only visible
+when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+Here you can see it running while the program Code/Java/Func_abc
+
+# j_events.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ PID EVENT COUNT
+ 311379 AttachCurrentThread-entry 1
+ 311379 AttachCurrentThread-return 1
+ 311379 CallIntMethod-entry 1
+ 311379 CallIntMethod-return 1
+ 311379 CallStaticBooleanMethod-entry 1
+ 311379 CallStaticBooleanMethod-return 1
+ 311379 CallStaticObjectMethod-entry 1
+ 311379 CallStaticObjectMethod-return 1
+ 311379 CallStaticObjectMethodV-entry 1
+ 311379 CallStaticObjectMethodV-return 1
+ 311379 CallStaticVoidMethod-entry 1
+ 311379 CallStaticVoidMethod-return 1
+ 311379 CreateJavaVM-entry 1
+ 311379 CreateJavaVM-return 1
+ 311379 DestroyJavaVM-entry 1
+ 311379 DestroyJavaVM-return 1
+ 311379 DetachCurrentThread-entry 1
+ 311379 DetachCurrentThread-return 1
+ 311379 ExceptionCheck-entry 1
+ 311379 ExceptionCheck-return 1
+ 311379 ExceptionClear-entry 1
+ 311379 ExceptionClear-return 1
+ 311379 GetDefaultJavaVMInitArgs-entry 1
+ 311379 GetDefaultJavaVMInitArgs-return 1
+ 311379 GetJavaVM-entry 1
+ 311379 GetJavaVM-return 1
+ 311379 GetStringRegion-entry 1
+ 311379 GetStringRegion-return 1
+ 311379 NewByteArray-entry 1
+ 311379 NewByteArray-return 1
+ 311379 NewObject-entry 1
+ 311379 NewObject-return 1
+ 311379 NewObjectV-entry 1
+ 311379 NewObjectV-return 1
+ 311379 SetBooleanField-entry 1
+ 311379 SetBooleanField-return 1
+ 311379 ToReflectedMethod-entry 1
+ 311379 ToReflectedMethod-return 1
+ 311379 vm-init-begin 1
+ 311379 vm-init-end 1
+ 311379 vm-shutdown 1
+ 311379 NewGlobalRef-entry 2
+ 311379 NewGlobalRef-return 2
+ 311379 monitor-wait 2
+ 311379 GetStaticFieldID-entry 3
+ 311379 GetStaticFieldID-return 3
+ 311379 NewObjectArray-entry 3
+ 311379 NewObjectArray-return 3
+ 311379 SetStaticObjectField-entry 3
+ 311379 SetStaticObjectField-return 3
+ 311379 GetStaticMethodID-entry 4
+ 311379 GetStaticMethodID-return 4
+ 311379 EnsureLocalCapacity-entry 5
+ 311379 EnsureLocalCapacity-return 5
+ 311379 SetByteArrayRegion-entry 5
+ 311379 SetByteArrayRegion-return 5
+ 311379 SetLongField-entry 5
+ 311379 SetLongField-return 5
+ 311379 GetMethodID-entry 6
+ 311379 GetMethodID-return 6
+ 311379 GetObjectArrayElement-entry 6
+ 311379 GetObjectArrayElement-return 6
+ 311379 GetSuperclass-entry 6
+ 311379 GetSuperclass-return 6
+ 311379 thread-start 6
+ 311379 SetIntField-entry 8
+ 311379 SetIntField-return 8
+ 311379 GetArrayLength-entry 9
+ 311379 GetArrayLength-return 9
+ 311379 GetByteArrayRegion-entry 9
+ 311379 GetByteArrayRegion-return 9
+ 311379 RegisterNatives-entry 9
+ 311379 RegisterNatives-return 9
+ 311379 GetObjectClass-entry 10
+ 311379 GetObjectClass-return 10
+ 311379 FindClass-entry 11
+ 311379 FindClass-return 11
+ 311379 SetObjectArrayElement-entry 12
+ 311379 SetObjectArrayElement-return 12
+ 311379 GetStringUTFLength-entry 18
+ 311379 GetStringUTFLength-return 18
+ 311379 GetStringUTFRegion-entry 18
+ 311379 GetStringUTFRegion-return 18
+ 311379 GetFieldID-entry 21
+ 311379 GetFieldID-return 21
+ 309790 CallStaticVoidMethod-entry 24
+ 309790 CallStaticVoidMethod-return 24
+ 194441 CallStaticVoidMethod-entry 26
+ 194441 CallStaticVoidMethod-return 26
+ 311379 GetStringUTFChars-entry 29
+ 311379 GetStringUTFChars-return 29
+ 311379 ReleaseStringUTFChars-entry 29
+ 311379 ReleaseStringUTFChars-return 29
+ 311379 CallObjectMethod-entry 30
+ 311379 CallObjectMethod-return 30
+ 311379 GetStringCritical-entry 35
+ 311379 GetStringCritical-return 35
+ 311379 ReleaseStringCritical-entry 35
+ 311379 ReleaseStringCritical-return 35
+ 311379 ExceptionOccurred-entry 46
+ 311379 ExceptionOccurred-return 46
+ 311379 GetStringLength-entry 54
+ 311379 GetStringLength-return 54
+ 311379 NewStringUTF-entry 54
+ 311379 NewStringUTF-return 54
+ 311379 NewString-entry 55
+ 311379 NewString-return 55
+ 311379 GetObjectField-entry 60
+ 311379 GetObjectField-return 60
+ 311379 DeleteLocalRef-entry 108
+ 311379 DeleteLocalRef-return 108
+ 311379 class-loaded 327
+ 311379 object-alloc 5389
+ 311379 method-return 12024
+ 311379 method-entry 12031
+
+You can see that nearly all of the events recorded are from PID 311379, which
+we can assume in this case is the program in question. Not all of the lines
+correspond to this, however, which is something to be aware of while analysing
+the results.
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_flow_example.txt
new file mode 100644
index 0000000..433bef3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_flow_example.txt
@@ -0,0 +1,1292 @@
+The following are examples of j_flow.d.
+
+This is a simple script to trace the not-so-simple flow of Java methods and
+classes. Here it traces the example program, Code/Java/func_abc
+
+# j_flow.d
+ C PID TIME(us) -- CLASS.METHOD
+ 0 311403 4789112583163 -> java/lang/Object.<clinit>
+ 0 311403 4789112583207 -> java/lang/Object.registerNatives
+ 0 311403 4789112583323 <- java/lang/Object.registerNatives
+ 0 311403 4789112583333 <- java/lang/Object.<clinit>
+ 0 311403 4789112583343 -> java/lang/String.<clinit>
+ 0 311403 4789112583732 -> java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311403 4789112583743 -> java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311403 4789112583752 -> java/lang/Object.<init>
+ 0 311403 4789112583760 <- java/lang/Object.<init>
+ 0 311403 4789112583767 <- java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311403 4789112583774 <- java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311403 4789112583783 <- java/lang/String.<clinit>
+ 0 311403 4789112583849 -> java/lang/System.<clinit>
+ 0 311403 4789112583859 -> java/lang/System.registerNatives
+ 0 311403 4789112583878 <- java/lang/System.registerNatives
+ 0 311403 4789112583887 -> java/lang/System.nullInputStream
+ 0 311403 4789112583895 -> java/lang/System.currentTimeMillis
+ 0 311403 4789112583905 <- java/lang/System.currentTimeMillis
+ 0 311403 4789112583913 <- java/lang/System.nullInputStream
+ 0 311403 4789112583923 -> java/lang/System.nullPrintStream
+ 0 311403 4789112583929 -> java/lang/System.currentTimeMillis
+ 0 311403 4789112583937 <- java/lang/System.currentTimeMillis
+ 0 311403 4789112583944 <- java/lang/System.nullPrintStream
+ 0 311403 4789112583951 -> java/lang/System.nullPrintStream
+ 0 311403 4789112583958 -> java/lang/System.currentTimeMillis
+ 0 311403 4789112583965 <- java/lang/System.currentTimeMillis
+ 0 311403 4789112583972 <- java/lang/System.nullPrintStream
+ 0 311403 4789112583982 <- java/lang/System.<clinit>
+ 0 311403 4789112584058 -> java/lang/ThreadGroup.<init>
+ 0 311403 4789112584068 -> java/lang/Object.<init>
+ 0 311403 4789112584075 <- java/lang/Object.<init>
+ 0 311403 4789112584100 <- java/lang/ThreadGroup.<init>
+ 0 311403 4789112584109 -> java/lang/ThreadGroup.<init>
+ 0 311403 4789112584116 -> java/lang/Object.<init>
+ 0 311403 4789112584123 <- java/lang/Object.<init>
+ 0 311403 4789112584139 -> java/lang/ThreadGroup.checkAccess
+ 0 311403 4789112584148 -> java/lang/System.getSecurityManager
+ 0 311403 4789112584157 <- java/lang/System.getSecurityManager
+ 0 311403 4789112584164 <- java/lang/ThreadGroup.checkAccess
+ 0 311403 4789112584175 -> java/lang/ThreadGroup.add
+ 0 311403 4789112584196 <- java/lang/ThreadGroup.add
+ 0 311403 4789112584202 <- java/lang/ThreadGroup.<init>
+ 0 311403 4789112584385 -> java/lang/Thread.<clinit>
+ 0 311403 4789112584396 -> java/lang/Thread.registerNatives
+ 0 311403 4789112584421 <- java/lang/Thread.registerNatives
+ 0 311403 4789112584779 -> java/lang/RuntimePermission.<init>
+ 0 311403 4789112584789 -> java/security/BasicPermission.<init>
+ 0 311403 4789112584798 -> java/security/Permission.<init>
+ 0 311403 4789112584806 -> java/lang/Object.<init>
+ 0 311403 4789112584814 <- java/lang/Object.<init>
+ 0 311403 4789112584823 <- java/security/Permission.<init>
+ 0 311403 4789112584831 -> java/security/BasicPermission.init
+ 0 311403 4789112584842 -> java/lang/String.length
+ 0 311403 4789112584850 <- java/lang/String.length
+ 0 311403 4789112584860 -> java/lang/String.charAt
+ 0 311403 4789112584869 <- java/lang/String.charAt
+ 0 311403 4789112584880 -> java/lang/String.equals
+ 0 311403 4789112584888 <- java/lang/String.equals
+ 0 311403 4789112584896 <- java/security/BasicPermission.init
+ 0 311403 4789112584903 <- java/security/BasicPermission.<init>
+ 0 311403 4789112584910 <- java/lang/RuntimePermission.<init>
+ 0 311403 4789112585319 -> sun/misc/SoftCache.<init>
+ 0 311403 4789112585329 -> java/util/AbstractMap.<init>
+ 0 311403 4789112585337 -> java/lang/Object.<init>
+ 0 311403 4789112585345 <- java/lang/Object.<init>
+ 0 311403 4789112585355 <- java/util/AbstractMap.<init>
+ 0 311403 4789112585485 -> java/lang/ref/ReferenceQueue.<clinit>
+ 0 311403 4789112585554 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585564 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585572 -> java/lang/ref/ReferenceQueue.<init>
+ 0 311403 4789112585581 -> java/lang/Object.<init>
+ 0 311403 4789112585589 <- java/lang/Object.<init>
+ 0 311403 4789112585646 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585656 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585664 -> java/lang/Object.<init>
+ 0 311403 4789112585671 <- java/lang/Object.<init>
+ 0 311403 4789112585678 <- java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585685 <- java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585696 <- java/lang/ref/ReferenceQueue.<init>
+ 0 311403 4789112585702 <- java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585709 <- java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585717 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585723 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311403 4789112585729 -> java/lang/ref/ReferenceQueue.<init>
+ 0 311403 4789112585736 -> java/lang/Object.<init>
+ 0 311403 4789112585743 <- java/lang/Object.<init>
+ 0 311403 4789112585748 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585755 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585761 -> java/lang/Object.<init>
+ 0 311403 4789112585768 <- java/lang/Object.<init>
+ 0 311403 4789112585796 <- java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311403 4789112585803 <- java/lang/ref/ReferenceQueue$Lock.<init>
+[... 22800 lines truncated ...]
+ 0 311403 4789112982170 <- java/lang/reflect/Method.getModifiers
+ 0 311403 4789112982182 -> Func_abc.main
+ 0 311403 4789112982193 -> Func_abc.func_a
+ 0 311403 4789112982201 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112982208 -> java/lang/System.getSecurityManager
+ 0 311403 4789112982215 <- java/lang/System.getSecurityManager
+ 0 311403 4789112982221 -> java/util/HashSet.add
+ 0 311403 4789112982228 -> java/util/HashMap.put
+ 0 311403 4789112982234 -> java/lang/Object.hashCode
+ 0 311403 4789112982241 <- java/lang/Object.hashCode
+ 0 311403 4789112982247 -> java/util/HashMap.hash
+ 0 311403 4789112982254 <- java/util/HashMap.hash
+ 0 311403 4789112982260 -> java/util/HashMap.indexFor
+ 0 311403 4789112982267 <- java/util/HashMap.indexFor
+ 0 311403 4789112982274 <- java/util/HashMap.put
+ 0 311403 4789112982280 <- java/util/HashSet.add
+ 0 311403 4789112982287 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112982349 -> java/lang/ClassLoader.loadClassInternal
+ 0 311403 4789112982356 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112982363 -> sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311403 4789112982369 -> java/lang/String.lastIndexOf
+ 0 311403 4789112982376 -> java/lang/String.lastIndexOf
+ 0 311403 4789112982384 <- java/lang/String.lastIndexOf
+ 0 311403 4789112982391 <- java/lang/String.lastIndexOf
+ 0 311403 4789112982396 -> java/lang/System.getSecurityManager
+ 0 311403 4789112982404 <- java/lang/System.getSecurityManager
+ 0 311403 4789112982410 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112982416 -> java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112982422 -> java/lang/ClassLoader.check
+ 0 311403 4789112982429 <- java/lang/ClassLoader.check
+ 0 311403 4789112982435 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112982442 -> java/lang/String.indexOf
+ 0 311403 4789112982448 -> java/lang/String.indexOf
+ 0 311403 4789112982456 <- java/lang/String.indexOf
+ 0 311403 4789112982462 <- java/lang/String.indexOf
+ 0 311403 4789112982468 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982475 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982481 -> java/lang/String.charAt
+ 0 311403 4789112982488 <- java/lang/String.charAt
+ 0 311403 4789112982495 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112982501 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112982510 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112982517 <- java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112982524 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112982530 -> java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112982536 -> java/lang/ClassLoader.check
+ 0 311403 4789112982543 <- java/lang/ClassLoader.check
+ 0 311403 4789112982549 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112982555 -> java/lang/String.indexOf
+ 0 311403 4789112982561 -> java/lang/String.indexOf
+ 0 311403 4789112982569 <- java/lang/String.indexOf
+ 0 311403 4789112982576 <- java/lang/String.indexOf
+ 0 311403 4789112982582 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982589 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982594 -> java/lang/String.charAt
+ 0 311403 4789112982602 <- java/lang/String.charAt
+ 0 311403 4789112982608 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112982614 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112982623 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112982630 <- java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112982636 -> java/lang/ClassLoader.findBootstrapClass0
+ 0 311403 4789112982642 -> java/lang/ClassLoader.check
+ 0 311403 4789112982650 <- java/lang/ClassLoader.check
+ 0 311403 4789112982655 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112982662 -> java/lang/String.indexOf
+ 0 311403 4789112982668 -> java/lang/String.indexOf
+ 0 311403 4789112982676 <- java/lang/String.indexOf
+ 0 311403 4789112982682 <- java/lang/String.indexOf
+ 0 311403 4789112982688 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982695 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112982701 -> java/lang/String.charAt
+ 0 311403 4789112982708 <- java/lang/String.charAt
+ 0 311403 4789112982715 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112982720 -> java/lang/ClassLoader.findBootstrapClass
+ 0 311403 4789112982730 <- java/lang/ClassLoader.findBootstrapClass
+ 0 311403 4789112982737 <- java/lang/ClassLoader.findBootstrapClass0
+ 0 311403 4789112982744 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112982751 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112982757 <- sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311403 4789112982764 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112982771 <- java/lang/ClassLoader.loadClassInternal
+ 0 311403 4789112982780 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112982787 -> java/lang/System.getSecurityManager
+ 0 311403 4789112982794 <- java/lang/System.getSecurityManager
+ 0 311403 4789112982800 -> java/util/HashSet.add
+ 0 311403 4789112982806 -> java/util/HashMap.put
+ 0 311403 4789112982813 -> java/lang/Object.hashCode
+ 0 311403 4789112982820 <- java/lang/Object.hashCode
+ 0 311403 4789112982826 -> java/util/HashMap.hash
+ 0 311403 4789112982833 <- java/util/HashMap.hash
+ 0 311403 4789112982839 -> java/util/HashMap.indexFor
+ 0 311403 4789112982846 <- java/util/HashMap.indexFor
+ 0 311403 4789112982853 <- java/util/HashMap.put
+ 0 311403 4789112982859 <- java/util/HashSet.add
+ 0 311403 4789112982866 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112982879 -> java/io/PrintStream.println
+ 0 311403 4789112982889 -> java/io/PrintStream.print
+ 0 311403 4789112982897 -> java/io/PrintStream.write
+ 0 311403 4789112982906 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789112982916 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789112982927 -> java/io/Writer.write
+ 0 311403 4789112982939 -> java/io/BufferedWriter.write
+ 0 311403 4789112982948 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112982956 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112982964 -> java/io/BufferedWriter.min
+ 0 311403 4789112982971 <- java/io/BufferedWriter.min
+ 0 311403 4789112982980 -> java/lang/String.getChars
+ 0 311403 4789112982987 -> java/lang/System.arraycopy
+ 0 311403 4789112982995 <- java/lang/System.arraycopy
+ 0 311403 4789112983002 <- java/lang/String.getChars
+ 0 311403 4789112983009 <- java/io/BufferedWriter.write
+ 0 311403 4789112983016 <- java/io/Writer.write
+ 0 311403 4789112983024 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789112983031 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112983038 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112983046 -> java/io/OutputStreamWriter.write
+ 0 311403 4789112983056 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789112983066 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789112983073 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789112983082 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789112983093 -> java/nio/CharBuffer.wrap
+ 0 311403 4789112983099 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789112983106 -> java/nio/CharBuffer.<init>
+ 0 311403 4789112983113 -> java/nio/Buffer.<init>
+ 0 311403 4789112983119 -> java/lang/Object.<init>
+ 0 311403 4789112983126 <- java/lang/Object.<init>
+ 0 311403 4789112983133 -> java/nio/Buffer.limit
+ 0 311403 4789112983140 <- java/nio/Buffer.limit
+ 0 311403 4789112983146 -> java/nio/Buffer.position
+ 0 311403 4789112983153 <- java/nio/Buffer.position
+ 0 311403 4789112983160 <- java/nio/Buffer.<init>
+ 0 311403 4789112983166 <- java/nio/CharBuffer.<init>
+ 0 311403 4789112983173 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789112983180 <- java/nio/CharBuffer.wrap
+ 0 311403 4789112983188 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789112983196 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789112983206 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789112983216 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789112983226 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789112983233 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789112983243 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789112983250 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789112983259 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789112983267 -> java/nio/CharBuffer.array
+ 0 311403 4789112983274 <- java/nio/CharBuffer.array
+ 0 311403 4789112983282 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983289 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983297 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983305 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983316 -> java/nio/ByteBuffer.array
+ 0 311403 4789112983323 <- java/nio/ByteBuffer.array
+ 0 311403 4789112983331 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983338 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983346 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983354 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983366 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983374 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112983382 -> java/nio/Buffer.position
+ 0 311403 4789112983389 <- java/nio/Buffer.position
+ 0 311403 4789112983395 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983402 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983410 -> java/nio/Buffer.position
+ 0 311403 4789112983417 <- java/nio/Buffer.position
+ 0 311403 4789112983424 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789112983431 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789112983439 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789112983447 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789112983454 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112983462 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112983469 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789112983477 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112983485 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112983494 -> java/nio/Buffer.remaining
+ 0 311403 4789112983501 <- java/nio/Buffer.remaining
+ 0 311403 4789112983508 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789112983515 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789112983522 <- java/io/OutputStreamWriter.write
+ 0 311403 4789112983528 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789112983537 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789112983546 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789112983555 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789112983565 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789112983574 -> java/nio/Buffer.flip
+ 0 311403 4789112983581 <- java/nio/Buffer.flip
+ 0 311403 4789112983591 -> java/nio/ByteBuffer.array
+ 0 311403 4789112983598 <- java/nio/ByteBuffer.array
+ 0 311403 4789112983606 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983613 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112983623 -> java/io/PrintStream.write
+ 0 311403 4789112983629 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789112983636 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789112983645 -> java/io/BufferedOutputStream.write
+ 0 311403 4789112983657 -> java/lang/System.arraycopy
+ 0 311403 4789112983664 <- java/lang/System.arraycopy
+ 0 311403 4789112983671 <- java/io/BufferedOutputStream.write
+ 0 311403 4789112983679 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789112983688 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112983698 -> java/io/FileOutputStream.write
+ 0 311403 4789112983707 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789112983860 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789112983868 <- java/io/FileOutputStream.write
+ 0 311403 4789112983874 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112983885 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789112983892 <- java/io/PrintStream.write
+ 0 311403 4789112983901 -> java/nio/Buffer.clear
+ 0 311403 4789112983909 <- java/nio/Buffer.clear
+ 0 311403 4789112983915 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789112983922 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789112983929 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789112983936 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789112983946 -> java/lang/String.indexOf
+ 0 311403 4789112983952 -> java/lang/String.indexOf
+ 0 311403 4789112983961 <- java/lang/String.indexOf
+ 0 311403 4789112983967 <- java/lang/String.indexOf
+ 0 311403 4789112983974 <- java/io/PrintStream.write
+ 0 311403 4789112983981 <- java/io/PrintStream.print
+ 0 311403 4789112983989 -> java/io/PrintStream.newLine
+ 0 311403 4789112983995 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789112984002 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789112984010 -> java/io/BufferedWriter.newLine
+ 0 311403 4789112984019 -> java/io/Writer.write
+ 0 311403 4789112984025 -> java/io/BufferedWriter.write
+ 0 311403 4789112984031 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112984039 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112984045 -> java/io/BufferedWriter.min
+ 0 311403 4789112984052 <- java/io/BufferedWriter.min
+ 0 311403 4789112984058 -> java/lang/String.getChars
+ 0 311403 4789112984064 -> java/lang/System.arraycopy
+ 0 311403 4789112984072 <- java/lang/System.arraycopy
+ 0 311403 4789112984078 <- java/lang/String.getChars
+ 0 311403 4789112984085 <- java/io/BufferedWriter.write
+ 0 311403 4789112984092 <- java/io/Writer.write
+ 0 311403 4789112984099 <- java/io/BufferedWriter.newLine
+ 0 311403 4789112984104 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789112984111 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112984118 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789112984124 -> java/io/OutputStreamWriter.write
+ 0 311403 4789112984130 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789112984137 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789112984144 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789112984150 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789112984156 -> java/nio/CharBuffer.wrap
+ 0 311403 4789112984163 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789112984169 -> java/nio/CharBuffer.<init>
+ 0 311403 4789112984175 -> java/nio/Buffer.<init>
+ 0 311403 4789112984181 -> java/lang/Object.<init>
+ 0 311403 4789112984189 <- java/lang/Object.<init>
+ 0 311403 4789112984194 -> java/nio/Buffer.limit
+ 0 311403 4789112984202 <- java/nio/Buffer.limit
+ 0 311403 4789112984207 -> java/nio/Buffer.position
+ 0 311403 4789112984214 <- java/nio/Buffer.position
+ 0 311403 4789112984221 <- java/nio/Buffer.<init>
+ 0 311403 4789112984228 <- java/nio/CharBuffer.<init>
+ 0 311403 4789112984234 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789112984241 <- java/nio/CharBuffer.wrap
+ 0 311403 4789112984247 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789112984254 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789112984260 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789112984266 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789112984273 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789112984280 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789112984286 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789112984293 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789112984299 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789112984305 -> java/nio/CharBuffer.array
+ 0 311403 4789112984312 <- java/nio/CharBuffer.array
+ 0 311403 4789112984318 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984325 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984331 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984338 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984344 -> java/nio/ByteBuffer.array
+ 0 311403 4789112984352 <- java/nio/ByteBuffer.array
+ 0 311403 4789112984358 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984365 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984371 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984378 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984384 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984391 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789112984397 -> java/nio/Buffer.position
+ 0 311403 4789112984404 <- java/nio/Buffer.position
+ 0 311403 4789112984410 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984417 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984423 -> java/nio/Buffer.position
+ 0 311403 4789112984430 <- java/nio/Buffer.position
+ 0 311403 4789112984437 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789112984444 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789112984450 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789112984457 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789112984463 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112984470 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112984477 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789112984483 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112984491 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789112984497 -> java/nio/Buffer.remaining
+ 0 311403 4789112984504 <- java/nio/Buffer.remaining
+ 0 311403 4789112984510 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789112984517 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789112984524 <- java/io/OutputStreamWriter.write
+ 0 311403 4789112984531 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789112984536 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789112984543 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789112984549 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789112984556 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789112984562 -> java/nio/Buffer.flip
+ 0 311403 4789112984569 <- java/nio/Buffer.flip
+ 0 311403 4789112984575 -> java/nio/ByteBuffer.array
+ 0 311403 4789112984582 <- java/nio/ByteBuffer.array
+ 0 311403 4789112984588 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984595 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789112984601 -> java/io/PrintStream.write
+ 0 311403 4789112984607 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789112984615 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789112984621 -> java/io/BufferedOutputStream.write
+ 0 311403 4789112984627 -> java/lang/System.arraycopy
+ 0 311403 4789112984635 <- java/lang/System.arraycopy
+ 0 311403 4789112984641 <- java/io/BufferedOutputStream.write
+ 0 311403 4789112984647 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789112984654 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112984660 -> java/io/FileOutputStream.write
+ 0 311403 4789112984666 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789112984712 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789112984719 <- java/io/FileOutputStream.write
+ 0 311403 4789112984726 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112984733 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789112984740 <- java/io/PrintStream.write
+ 0 311403 4789112984746 -> java/nio/Buffer.clear
+ 0 311403 4789112984753 <- java/nio/Buffer.clear
+ 0 311403 4789112984760 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789112984766 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789112984773 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789112984780 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789112984786 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789112984792 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112984800 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789112984807 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789112984813 <- java/io/PrintStream.newLine
+ 0 311403 4789112984820 <- java/io/PrintStream.println
+ 0 311403 4789112984835 -> java/lang/ClassLoader.loadClassInternal
+ 0 311403 4789112984842 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112984849 -> sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311403 4789112984855 -> java/lang/String.lastIndexOf
+ 0 311403 4789112984862 -> java/lang/String.lastIndexOf
+ 0 311403 4789112984870 <- java/lang/String.lastIndexOf
+ 0 311403 4789112984877 <- java/lang/String.lastIndexOf
+ 0 311403 4789112984882 -> java/lang/System.getSecurityManager
+ 0 311403 4789112984890 <- java/lang/System.getSecurityManager
+ 0 311403 4789112984896 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112984902 -> java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112984908 -> java/lang/ClassLoader.check
+ 0 311403 4789112984915 <- java/lang/ClassLoader.check
+ 0 311403 4789112984921 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112984927 -> java/lang/String.indexOf
+ 0 311403 4789112984934 -> java/lang/String.indexOf
+ 0 311403 4789112984942 <- java/lang/String.indexOf
+ 0 311403 4789112984948 <- java/lang/String.indexOf
+ 0 311403 4789112984954 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112984961 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112984967 -> java/lang/String.charAt
+ 0 311403 4789112984974 <- java/lang/String.charAt
+ 0 311403 4789112984981 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112984987 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112984998 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112985005 <- java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112985011 -> java/lang/ClassLoader.loadClass
+ 0 311403 4789112985018 -> java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112985024 -> java/lang/ClassLoader.check
+ 0 311403 4789112985031 <- java/lang/ClassLoader.check
+ 0 311403 4789112985037 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112985043 -> java/lang/String.indexOf
+ 0 311403 4789112985049 -> java/lang/String.indexOf
+ 0 311403 4789112985057 <- java/lang/String.indexOf
+ 0 311403 4789112985064 <- java/lang/String.indexOf
+ 0 311403 4789112985070 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112985077 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112985083 -> java/lang/String.charAt
+ 0 311403 4789112985090 <- java/lang/String.charAt
+ 0 311403 4789112985096 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112985102 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112985111 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311403 4789112985118 <- java/lang/ClassLoader.findLoadedClass
+ 0 311403 4789112985124 -> java/lang/ClassLoader.findBootstrapClass0
+ 0 311403 4789112985130 -> java/lang/ClassLoader.check
+ 0 311403 4789112985138 <- java/lang/ClassLoader.check
+ 0 311403 4789112985143 -> java/lang/ClassLoader.checkName
+ 0 311403 4789112985150 -> java/lang/String.indexOf
+ 0 311403 4789112985156 -> java/lang/String.indexOf
+ 0 311403 4789112985164 <- java/lang/String.indexOf
+ 0 311403 4789112985170 <- java/lang/String.indexOf
+ 0 311403 4789112985176 -> sun/misc/VM.allowArraySyntax
+ 0 311403 4789112985183 <- sun/misc/VM.allowArraySyntax
+ 0 311403 4789112985189 -> java/lang/String.charAt
+ 0 311403 4789112985196 <- java/lang/String.charAt
+ 0 311403 4789112985203 <- java/lang/ClassLoader.checkName
+ 0 311403 4789112985208 -> java/lang/ClassLoader.findBootstrapClass
+ 0 311403 4789112985219 <- java/lang/ClassLoader.findBootstrapClass
+ 0 311403 4789112985226 <- java/lang/ClassLoader.findBootstrapClass0
+ 0 311403 4789112985233 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112985240 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112985247 <- sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311403 4789112985253 <- java/lang/ClassLoader.loadClass
+ 0 311403 4789112985260 <- java/lang/ClassLoader.loadClassInternal
+ 0 311403 4789112985270 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112985277 -> java/lang/System.getSecurityManager
+ 0 311403 4789112985285 <- java/lang/System.getSecurityManager
+ 0 311403 4789112985291 -> java/util/HashSet.add
+ 0 311403 4789112985297 -> java/util/HashMap.put
+ 0 311403 4789112985304 -> java/lang/Object.hashCode
+ 0 311403 4789112985311 <- java/lang/Object.hashCode
+ 0 311403 4789112985317 -> java/util/HashMap.hash
+ 0 311403 4789112985324 <- java/util/HashMap.hash
+ 0 311403 4789112985330 -> java/util/HashMap.indexFor
+ 0 311403 4789112985337 <- java/util/HashMap.indexFor
+ 0 311403 4789112985344 <- java/util/HashMap.put
+ 0 311403 4789112985351 <- java/util/HashSet.add
+ 0 311403 4789112985358 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311403 4789112985371 -> java/lang/Thread.currentThread
+ 0 311403 4789112985379 <- java/lang/Thread.currentThread
+ 0 311403 4789112985387 -> java/lang/Thread.sleep
+ 0 311403 4789113990048 <- java/lang/Thread.sleep
+ 0 311403 4789113990080 -> Func_abc.func_b
+ 0 311403 4789113990104 -> java/io/PrintStream.println
+ 0 311403 4789113990112 -> java/io/PrintStream.print
+ 0 311403 4789113990118 -> java/io/PrintStream.write
+ 0 311403 4789113990125 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789113990133 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789113990139 -> java/io/Writer.write
+ 0 311403 4789113990147 -> java/io/BufferedWriter.write
+ 0 311403 4789113990154 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113990161 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113990168 -> java/io/BufferedWriter.min
+ 0 311403 4789113990176 <- java/io/BufferedWriter.min
+ 0 311403 4789113990182 -> java/lang/String.getChars
+ 0 311403 4789113990189 -> java/lang/System.arraycopy
+ 0 311403 4789113990198 <- java/lang/System.arraycopy
+ 0 311403 4789113990205 <- java/lang/String.getChars
+ 0 311403 4789113990212 <- java/io/BufferedWriter.write
+ 0 311403 4789113990219 <- java/io/Writer.write
+ 0 311403 4789113990225 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789113990231 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113990238 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113990245 -> java/io/OutputStreamWriter.write
+ 0 311403 4789113990252 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789113990258 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789113990265 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789113990272 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789113990279 -> java/nio/CharBuffer.wrap
+ 0 311403 4789113990286 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789113990293 -> java/nio/CharBuffer.<init>
+ 0 311403 4789113990299 -> java/nio/Buffer.<init>
+ 0 311403 4789113990306 -> java/lang/Object.<init>
+ 0 311403 4789113990313 <- java/lang/Object.<init>
+ 0 311403 4789113990320 -> java/nio/Buffer.limit
+ 0 311403 4789113990327 <- java/nio/Buffer.limit
+ 0 311403 4789113990333 -> java/nio/Buffer.position
+ 0 311403 4789113990340 <- java/nio/Buffer.position
+ 0 311403 4789113990347 <- java/nio/Buffer.<init>
+ 0 311403 4789113990354 <- java/nio/CharBuffer.<init>
+ 0 311403 4789113990360 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789113990367 <- java/nio/CharBuffer.wrap
+ 0 311403 4789113990373 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789113990381 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789113990387 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789113990394 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789113990401 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789113990409 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789113990415 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789113990422 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789113990428 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789113990435 -> java/nio/CharBuffer.array
+ 0 311403 4789113990442 <- java/nio/CharBuffer.array
+ 0 311403 4789113990448 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990455 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990461 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990468 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990475 -> java/nio/ByteBuffer.array
+ 0 311403 4789113990482 <- java/nio/ByteBuffer.array
+ 0 311403 4789113990488 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990495 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990501 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990508 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990517 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990524 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113990529 -> java/nio/Buffer.position
+ 0 311403 4789113990537 <- java/nio/Buffer.position
+ 0 311403 4789113990542 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990550 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990555 -> java/nio/Buffer.position
+ 0 311403 4789113990563 <- java/nio/Buffer.position
+ 0 311403 4789113990569 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789113990576 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789113990583 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789113990590 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789113990596 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113990603 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113990610 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789113990616 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113990624 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113990630 -> java/nio/Buffer.remaining
+ 0 311403 4789113990637 <- java/nio/Buffer.remaining
+ 0 311403 4789113990643 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789113990650 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789113990657 <- java/io/OutputStreamWriter.write
+ 0 311403 4789113990664 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789113990670 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789113990677 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789113990683 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789113990690 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789113990697 -> java/nio/Buffer.flip
+ 0 311403 4789113990704 <- java/nio/Buffer.flip
+ 0 311403 4789113990710 -> java/nio/ByteBuffer.array
+ 0 311403 4789113990717 <- java/nio/ByteBuffer.array
+ 0 311403 4789113990723 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990730 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113990736 -> java/io/PrintStream.write
+ 0 311403 4789113990742 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789113990749 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789113990756 -> java/io/BufferedOutputStream.write
+ 0 311403 4789113990763 -> java/lang/System.arraycopy
+ 0 311403 4789113990770 <- java/lang/System.arraycopy
+ 0 311403 4789113990777 <- java/io/BufferedOutputStream.write
+ 0 311403 4789113990783 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789113990790 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113990797 -> java/io/FileOutputStream.write
+ 0 311403 4789113990803 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789113990841 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789113990848 <- java/io/FileOutputStream.write
+ 0 311403 4789113990855 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113990862 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789113990869 <- java/io/PrintStream.write
+ 0 311403 4789113990875 -> java/nio/Buffer.clear
+ 0 311403 4789113990882 <- java/nio/Buffer.clear
+ 0 311403 4789113990888 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789113990895 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789113990902 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789113990909 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789113990915 -> java/lang/String.indexOf
+ 0 311403 4789113990922 -> java/lang/String.indexOf
+ 0 311403 4789113990930 <- java/lang/String.indexOf
+ 0 311403 4789113990936 <- java/lang/String.indexOf
+ 0 311403 4789113990943 <- java/io/PrintStream.write
+ 0 311403 4789113990950 <- java/io/PrintStream.print
+ 0 311403 4789113990956 -> java/io/PrintStream.newLine
+ 0 311403 4789113990962 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789113990969 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789113990975 -> java/io/BufferedWriter.newLine
+ 0 311403 4789113990981 -> java/io/Writer.write
+ 0 311403 4789113990988 -> java/io/BufferedWriter.write
+ 0 311403 4789113990994 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113991001 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113991007 -> java/io/BufferedWriter.min
+ 0 311403 4789113991014 <- java/io/BufferedWriter.min
+ 0 311403 4789113991020 -> java/lang/String.getChars
+ 0 311403 4789113991026 -> java/lang/System.arraycopy
+ 0 311403 4789113991034 <- java/lang/System.arraycopy
+ 0 311403 4789113991040 <- java/lang/String.getChars
+ 0 311403 4789113991047 <- java/io/BufferedWriter.write
+ 0 311403 4789113991054 <- java/io/Writer.write
+ 0 311403 4789113991060 <- java/io/BufferedWriter.newLine
+ 0 311403 4789113991066 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789113991072 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113991080 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789113991086 -> java/io/OutputStreamWriter.write
+ 0 311403 4789113991092 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789113991098 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789113991106 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789113991112 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789113991118 -> java/nio/CharBuffer.wrap
+ 0 311403 4789113991124 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789113991131 -> java/nio/CharBuffer.<init>
+ 0 311403 4789113991137 -> java/nio/Buffer.<init>
+ 0 311403 4789113991143 -> java/lang/Object.<init>
+ 0 311403 4789113991150 <- java/lang/Object.<init>
+ 0 311403 4789113991156 -> java/nio/Buffer.limit
+ 0 311403 4789113991163 <- java/nio/Buffer.limit
+ 0 311403 4789113991169 -> java/nio/Buffer.position
+ 0 311403 4789113991176 <- java/nio/Buffer.position
+ 0 311403 4789113991182 <- java/nio/Buffer.<init>
+ 0 311403 4789113991189 <- java/nio/CharBuffer.<init>
+ 0 311403 4789113991196 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789113991202 <- java/nio/CharBuffer.wrap
+ 0 311403 4789113991208 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789113991215 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789113991221 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789113991281 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789113991287 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789113991295 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789113991301 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789113991308 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789113991314 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789113991320 -> java/nio/CharBuffer.array
+ 0 311403 4789113991328 <- java/nio/CharBuffer.array
+ 0 311403 4789113991333 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991341 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991347 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991354 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991360 -> java/nio/ByteBuffer.array
+ 0 311403 4789113991367 <- java/nio/ByteBuffer.array
+ 0 311403 4789113991373 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991380 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991386 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991393 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991400 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991407 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789113991413 -> java/nio/Buffer.position
+ 0 311403 4789113991420 <- java/nio/Buffer.position
+ 0 311403 4789113991426 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991433 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991439 -> java/nio/Buffer.position
+ 0 311403 4789113991446 <- java/nio/Buffer.position
+ 0 311403 4789113991453 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789113991459 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789113991465 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789113991473 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789113991479 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113991486 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113991493 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789113991499 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113991506 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789113991512 -> java/nio/Buffer.remaining
+ 0 311403 4789113991519 <- java/nio/Buffer.remaining
+ 0 311403 4789113991526 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789113991533 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789113991539 <- java/io/OutputStreamWriter.write
+ 0 311403 4789113991546 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789113991552 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789113991559 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789113991565 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789113991572 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789113991578 -> java/nio/Buffer.flip
+ 0 311403 4789113991585 <- java/nio/Buffer.flip
+ 0 311403 4789113991591 -> java/nio/ByteBuffer.array
+ 0 311403 4789113991598 <- java/nio/ByteBuffer.array
+ 0 311403 4789113991604 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991611 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789113991617 -> java/io/PrintStream.write
+ 0 311403 4789113991623 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789113991630 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789113991636 -> java/io/BufferedOutputStream.write
+ 0 311403 4789113991643 -> java/lang/System.arraycopy
+ 0 311403 4789113991651 <- java/lang/System.arraycopy
+ 0 311403 4789113991657 <- java/io/BufferedOutputStream.write
+ 0 311403 4789113991663 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789113991670 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113991676 -> java/io/FileOutputStream.write
+ 0 311403 4789113991682 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789113991701 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789113991708 <- java/io/FileOutputStream.write
+ 0 311403 4789113991720 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113991728 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789113991734 <- java/io/PrintStream.write
+ 0 311403 4789113991740 -> java/nio/Buffer.clear
+ 0 311403 4789113991747 <- java/nio/Buffer.clear
+ 0 311403 4789113991754 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789113991761 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789113991768 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789113991774 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789113991780 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789113991787 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113991794 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789113991801 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789113991808 <- java/io/PrintStream.newLine
+ 0 311403 4789113991815 <- java/io/PrintStream.println
+ 0 311403 4789113991821 -> java/lang/Thread.currentThread
+ 0 311403 4789113991828 <- java/lang/Thread.currentThread
+ 0 311403 4789113991834 -> java/lang/Thread.sleep
+ 0 311403 4789115000050 <- java/lang/Thread.sleep
+ 0 311403 4789115000081 -> Func_abc.func_c
+ 0 311403 4789115000105 -> java/io/PrintStream.println
+ 0 311403 4789115000113 -> java/io/PrintStream.print
+ 0 311403 4789115000120 -> java/io/PrintStream.write
+ 0 311403 4789115000126 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789115000134 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789115000141 -> java/io/Writer.write
+ 0 311403 4789115000148 -> java/io/BufferedWriter.write
+ 0 311403 4789115000155 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115000162 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115000170 -> java/io/BufferedWriter.min
+ 0 311403 4789115000177 <- java/io/BufferedWriter.min
+ 0 311403 4789115000183 -> java/lang/String.getChars
+ 0 311403 4789115000191 -> java/lang/System.arraycopy
+ 0 311403 4789115000199 <- java/lang/System.arraycopy
+ 0 311403 4789115000206 <- java/lang/String.getChars
+ 0 311403 4789115000213 <- java/io/BufferedWriter.write
+ 0 311403 4789115000220 <- java/io/Writer.write
+ 0 311403 4789115000226 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789115000233 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115000240 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115000246 -> java/io/OutputStreamWriter.write
+ 0 311403 4789115000253 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789115000260 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789115000267 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789115000274 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789115000281 -> java/nio/CharBuffer.wrap
+ 0 311403 4789115000288 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789115000294 -> java/nio/CharBuffer.<init>
+ 0 311403 4789115000301 -> java/nio/Buffer.<init>
+ 0 311403 4789115000307 -> java/lang/Object.<init>
+ 0 311403 4789115000315 <- java/lang/Object.<init>
+ 0 311403 4789115000321 -> java/nio/Buffer.limit
+ 0 311403 4789115000328 <- java/nio/Buffer.limit
+ 0 311403 4789115000334 -> java/nio/Buffer.position
+ 0 311403 4789115000342 <- java/nio/Buffer.position
+ 0 311403 4789115000348 <- java/nio/Buffer.<init>
+ 0 311403 4789115000355 <- java/nio/CharBuffer.<init>
+ 0 311403 4789115000362 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789115000368 <- java/nio/CharBuffer.wrap
+ 0 311403 4789115000374 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789115000382 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789115000388 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789115000396 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789115000402 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789115000410 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789115000416 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789115000424 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789115000430 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789115000436 -> java/nio/CharBuffer.array
+ 0 311403 4789115000444 <- java/nio/CharBuffer.array
+ 0 311403 4789115000450 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000457 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000463 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000470 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000476 -> java/nio/ByteBuffer.array
+ 0 311403 4789115000483 <- java/nio/ByteBuffer.array
+ 0 311403 4789115000489 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000496 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000502 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000509 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000518 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000525 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115000531 -> java/nio/Buffer.position
+ 0 311403 4789115000538 <- java/nio/Buffer.position
+ 0 311403 4789115000544 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000551 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000557 -> java/nio/Buffer.position
+ 0 311403 4789115000564 <- java/nio/Buffer.position
+ 0 311403 4789115000570 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789115000577 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789115000584 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789115000591 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789115000597 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115000605 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115000611 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789115000617 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115000625 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115000631 -> java/nio/Buffer.remaining
+ 0 311403 4789115000638 <- java/nio/Buffer.remaining
+ 0 311403 4789115000645 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789115000652 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789115000658 <- java/io/OutputStreamWriter.write
+ 0 311403 4789115000665 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789115000671 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789115000678 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789115000685 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789115000692 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789115000698 -> java/nio/Buffer.flip
+ 0 311403 4789115000705 <- java/nio/Buffer.flip
+ 0 311403 4789115000711 -> java/nio/ByteBuffer.array
+ 0 311403 4789115000718 <- java/nio/ByteBuffer.array
+ 0 311403 4789115000724 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000731 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115000738 -> java/io/PrintStream.write
+ 0 311403 4789115000744 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789115000751 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789115000758 -> java/io/BufferedOutputStream.write
+ 0 311403 4789115000764 -> java/lang/System.arraycopy
+ 0 311403 4789115000772 <- java/lang/System.arraycopy
+ 0 311403 4789115000778 <- java/io/BufferedOutputStream.write
+ 0 311403 4789115000785 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789115000791 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115000798 -> java/io/FileOutputStream.write
+ 0 311403 4789115000805 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789115000843 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789115000850 <- java/io/FileOutputStream.write
+ 0 311403 4789115000857 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115000864 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789115000871 <- java/io/PrintStream.write
+ 0 311403 4789115000877 -> java/nio/Buffer.clear
+ 0 311403 4789115000884 <- java/nio/Buffer.clear
+ 0 311403 4789115000891 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789115000897 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789115000904 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789115000911 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789115000917 -> java/lang/String.indexOf
+ 0 311403 4789115000924 -> java/lang/String.indexOf
+ 0 311403 4789115000932 <- java/lang/String.indexOf
+ 0 311403 4789115000939 <- java/lang/String.indexOf
+ 0 311403 4789115000945 <- java/io/PrintStream.write
+ 0 311403 4789115000952 <- java/io/PrintStream.print
+ 0 311403 4789115000958 -> java/io/PrintStream.newLine
+ 0 311403 4789115000964 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789115000971 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789115000977 -> java/io/BufferedWriter.newLine
+ 0 311403 4789115000983 -> java/io/Writer.write
+ 0 311403 4789115000990 -> java/io/BufferedWriter.write
+ 0 311403 4789115000996 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115001003 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115001009 -> java/io/BufferedWriter.min
+ 0 311403 4789115001016 <- java/io/BufferedWriter.min
+ 0 311403 4789115001022 -> java/lang/String.getChars
+ 0 311403 4789115001029 -> java/lang/System.arraycopy
+ 0 311403 4789115001036 <- java/lang/System.arraycopy
+ 0 311403 4789115001042 <- java/lang/String.getChars
+ 0 311403 4789115001049 <- java/io/BufferedWriter.write
+ 0 311403 4789115001056 <- java/io/Writer.write
+ 0 311403 4789115001062 <- java/io/BufferedWriter.newLine
+ 0 311403 4789115001068 -> java/io/BufferedWriter.flushBuffer
+ 0 311403 4789115001075 -> java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115001082 <- java/io/BufferedWriter.ensureOpen
+ 0 311403 4789115001088 -> java/io/OutputStreamWriter.write
+ 0 311403 4789115001094 -> sun/nio/cs/StreamEncoder.write
+ 0 311403 4789115001101 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789115001108 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311403 4789115001114 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789115001120 -> java/nio/CharBuffer.wrap
+ 0 311403 4789115001127 -> java/nio/HeapCharBuffer.<init>
+ 0 311403 4789115001133 -> java/nio/CharBuffer.<init>
+ 0 311403 4789115001139 -> java/nio/Buffer.<init>
+ 0 311403 4789115001145 -> java/lang/Object.<init>
+ 0 311403 4789115001152 <- java/lang/Object.<init>
+ 0 311403 4789115001158 -> java/nio/Buffer.limit
+ 0 311403 4789115001165 <- java/nio/Buffer.limit
+ 0 311403 4789115001171 -> java/nio/Buffer.position
+ 0 311403 4789115001178 <- java/nio/Buffer.position
+ 0 311403 4789115001185 <- java/nio/Buffer.<init>
+ 0 311403 4789115001191 <- java/nio/CharBuffer.<init>
+ 0 311403 4789115001198 <- java/nio/HeapCharBuffer.<init>
+ 0 311403 4789115001204 <- java/nio/CharBuffer.wrap
+ 0 311403 4789115001210 -> java/nio/Buffer.hasRemaining
+ 0 311403 4789115001217 <- java/nio/Buffer.hasRemaining
+ 0 311403 4789115001223 -> java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789115001230 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789115001236 -> java/nio/CharBuffer.hasArray
+ 0 311403 4789115001243 <- java/nio/CharBuffer.hasArray
+ 0 311403 4789115001249 -> java/nio/ByteBuffer.hasArray
+ 0 311403 4789115001256 <- java/nio/ByteBuffer.hasArray
+ 0 311403 4789115001262 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789115001269 -> java/nio/CharBuffer.array
+ 0 311403 4789115001276 <- java/nio/CharBuffer.array
+ 0 311403 4789115001281 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001288 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001294 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001302 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001308 -> java/nio/ByteBuffer.array
+ 0 311403 4789115001315 <- java/nio/ByteBuffer.array
+ 0 311403 4789115001320 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001328 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001334 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001341 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001347 -> java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001354 <- java/nio/CharBuffer.arrayOffset
+ 0 311403 4789115001360 -> java/nio/Buffer.position
+ 0 311403 4789115001367 <- java/nio/Buffer.position
+ 0 311403 4789115001373 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001380 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001386 -> java/nio/Buffer.position
+ 0 311403 4789115001393 <- java/nio/Buffer.position
+ 0 311403 4789115001400 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311403 4789115001407 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311403 4789115001413 -> java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789115001420 <- java/nio/charset/CoderResult.isOverflow
+ 0 311403 4789115001426 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115001433 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115001440 <- java/nio/charset/CharsetEncoder.encode
+ 0 311403 4789115001446 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115001453 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311403 4789115001459 -> java/nio/Buffer.remaining
+ 0 311403 4789115001466 <- java/nio/Buffer.remaining
+ 0 311403 4789115001473 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311403 4789115001480 <- sun/nio/cs/StreamEncoder.write
+ 0 311403 4789115001487 <- java/io/OutputStreamWriter.write
+ 0 311403 4789115001493 <- java/io/BufferedWriter.flushBuffer
+ 0 311403 4789115001499 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789115001506 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789115001512 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789115001519 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789115001525 -> java/nio/Buffer.flip
+ 0 311403 4789115001532 <- java/nio/Buffer.flip
+ 0 311403 4789115001538 -> java/nio/ByteBuffer.array
+ 0 311403 4789115001545 <- java/nio/ByteBuffer.array
+ 0 311403 4789115001551 -> java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001558 <- java/nio/ByteBuffer.arrayOffset
+ 0 311403 4789115001564 -> java/io/PrintStream.write
+ 0 311403 4789115001570 -> java/io/PrintStream.ensureOpen
+ 0 311403 4789115001577 <- java/io/PrintStream.ensureOpen
+ 0 311403 4789115001583 -> java/io/BufferedOutputStream.write
+ 0 311403 4789115001590 -> java/lang/System.arraycopy
+ 0 311403 4789115001597 <- java/lang/System.arraycopy
+ 0 311403 4789115001604 <- java/io/BufferedOutputStream.write
+ 0 311403 4789115001610 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789115001621 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115001628 -> java/io/FileOutputStream.write
+ 0 311403 4789115001634 -> java/io/FileOutputStream.writeBytes
+ 0 311403 4789115001652 <- java/io/FileOutputStream.writeBytes
+ 0 311403 4789115001706 <- java/io/FileOutputStream.write
+ 0 311403 4789115001713 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115001720 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789115001727 <- java/io/PrintStream.write
+ 0 311403 4789115001733 -> java/nio/Buffer.clear
+ 0 311403 4789115001740 <- java/nio/Buffer.clear
+ 0 311403 4789115001747 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311403 4789115001753 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311403 4789115001760 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311403 4789115001767 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311403 4789115001773 -> java/io/BufferedOutputStream.flush
+ 0 311403 4789115001779 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115001787 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311403 4789115001794 <- java/io/BufferedOutputStream.flush
+ 0 311403 4789115001801 <- java/io/PrintStream.newLine
+ 0 311403 4789115001807 <- java/io/PrintStream.println
+ 0 311403 4789115001813 -> java/lang/Thread.currentThread
+ 0 311403 4789115001821 <- java/lang/Thread.currentThread
+ 0 311403 4789115001827 -> java/lang/Thread.sleep
+ 0 311403 4789116010060 <- java/lang/Thread.sleep
+ 0 311403 4789116010073 <- Func_abc.func_c
+ 0 311403 4789116010080 <- Func_abc.func_b
+ 0 311403 4789116010086 <- Func_abc.func_a
+ 0 311403 4789116010093 <- Func_abc.main
+ 0 311403 4789116010118 -> java/lang/Thread.exit
+ 0 311403 4789116010145 -> java/lang/ThreadGroup.remove
+ 0 311403 4789116010160 -> java/lang/System.arraycopy
+ 0 311403 4789116010169 <- java/lang/System.arraycopy
+ 0 311403 4789116010178 -> java/lang/Object.notifyAll
+ 0 311403 4789116010192 <- java/lang/Object.notifyAll
+ 0 311403 4789116010199 <- java/lang/ThreadGroup.remove
+ 0 311403 4789116010212 <- java/lang/Thread.exit
+ 0 311403 4789116010380 -> java/lang/Thread.<init>
+ 0 311403 4789116010388 -> java/lang/Object.<init>
+ 0 311403 4789116010395 <- java/lang/Object.<init>
+ 0 311403 4789116010402 -> java/lang/Object.<init>
+ 0 311403 4789116010409 <- java/lang/Object.<init>
+ 0 311403 4789116010415 -> java/lang/Thread.init
+ 0 311403 4789116010422 -> java/lang/Thread.currentThread
+ 0 311403 4789116010430 <- java/lang/Thread.currentThread
+ 0 311403 4789116010436 -> java/lang/System.getSecurityManager
+ 0 311403 4789116010444 <- java/lang/System.getSecurityManager
+ 0 311403 4789116010450 -> java/lang/ThreadGroup.checkAccess
+ 0 311403 4789116010457 -> java/lang/System.getSecurityManager
+ 0 311403 4789116010464 <- java/lang/System.getSecurityManager
+ 0 311403 4789116010471 <- java/lang/ThreadGroup.checkAccess
+ 0 311403 4789116010477 -> java/lang/ThreadGroup.addUnstarted
+ 0 311403 4789116010484 <- java/lang/ThreadGroup.addUnstarted
+ 0 311403 4789116010491 -> java/lang/String.toCharArray
+ 0 311403 4789116010499 -> java/lang/String.getChars
+ 0 311403 4789116010506 -> java/lang/System.arraycopy
+ 0 311403 4789116010514 <- java/lang/System.arraycopy
+ 0 311403 4789116010521 <- java/lang/String.getChars
+ 0 311403 4789116010527 <- java/lang/String.toCharArray
+ 0 311403 4789116010534 -> java/lang/Thread.getContextClassLoader
+ 0 311403 4789116010541 <- java/lang/Thread.getContextClassLoader
+ 0 311403 4789116010548 -> java/security/AccessController.getContext
+ 0 311403 4789116010554 -> java/security/AccessController.getStackAccessControlContext
+ 0 311403 4789116010569 <- java/security/AccessController.getStackAccessControlContext
+ 0 311403 4789116010576 -> java/security/AccessControlContext.optimize
+ 0 311403 4789116010583 -> java/security/AccessController.getInheritedAccessControlContext
+ 0 311403 4789116010591 <- java/security/AccessController.getInheritedAccessControlContext
+ 0 311403 4789116010599 <- java/security/AccessControlContext.optimize
+ 0 311403 4789116010606 <- java/security/AccessController.getContext
+ 0 311403 4789116010612 -> java/lang/Thread.setPriority
+ 0 311403 4789116010618 -> java/lang/Thread.checkAccess
+ 0 311403 4789116010625 -> java/lang/System.getSecurityManager
+ 0 311403 4789116010632 <- java/lang/System.getSecurityManager
+ 0 311403 4789116010639 <- java/lang/Thread.checkAccess
+ 0 311403 4789116010645 -> java/lang/Thread.setPriority0
+ 0 311403 4789116010664 <- java/lang/Thread.setPriority0
+ 0 311403 4789116010671 <- java/lang/Thread.setPriority
+ 0 311403 4789116010678 -> java/lang/Thread.nextThreadID
+ 0 311403 4789116010686 <- java/lang/Thread.nextThreadID
+ 0 311403 4789116010693 <- java/lang/Thread.init
+ 0 311403 4789116010700 <- java/lang/Thread.<init>
+ 0 311403 4789116010707 -> java/lang/ThreadGroup.add
+ 0 311403 4789116010716 <- java/lang/ThreadGroup.add
+ 0 311403 4789116010729 -> java/lang/Shutdown.shutdown
+ 0 311403 4789116010740 -> java/lang/Shutdown.sequence
+ 0 311403 4789116010748 -> java/lang/Shutdown.runHooks
+ 0 311403 4789116010758 -> java/util/AbstractList.iterator
+ 0 311403 4789116011022 -> java/util/AbstractList$Itr.<init>
+ 0 311403 4789116011032 -> java/util/AbstractList$Itr.<init>
+ 0 311403 4789116011042 -> java/lang/Object.<init>
+ 0 311403 4789116011050 <- java/lang/Object.<init>
+ 0 311403 4789116011062 <- java/util/AbstractList$Itr.<init>
+ 0 311403 4789116011069 <- java/util/AbstractList$Itr.<init>
+ 0 311403 4789116011076 <- java/util/AbstractList.iterator
+ 0 311403 4789116011087 -> java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011099 <- java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011107 -> java/util/AbstractList$Itr.next
+ 0 311403 4789116011115 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116011123 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116011131 -> java/util/ArrayList.get
+ 0 311403 4789116011138 -> java/util/ArrayList.RangeCheck
+ 0 311403 4789116011145 <- java/util/ArrayList.RangeCheck
+ 0 311403 4789116011152 <- java/util/ArrayList.get
+ 0 311403 4789116011159 <- java/util/AbstractList$Itr.next
+ 0 311403 4789116011170 -> java/io/Console$1$1.run
+ 0 311403 4789116011180 -> java/io/Console.access$600
+ 0 311403 4789116011189 <- java/io/Console.access$600
+ 0 311403 4789116011196 <- java/io/Console$1$1.run
+ 0 311403 4789116011202 -> java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011209 <- java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011215 -> java/util/AbstractList$Itr.next
+ 0 311403 4789116011221 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116011229 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116011235 -> java/util/ArrayList.get
+ 0 311403 4789116011241 -> java/util/ArrayList.RangeCheck
+ 0 311403 4789116011248 <- java/util/ArrayList.RangeCheck
+ 0 311403 4789116011255 <- java/util/ArrayList.get
+ 0 311403 4789116011262 <- java/util/AbstractList$Itr.next
+ 0 311403 4789116011268 -> java/lang/ApplicationShutdownHooks.run
+ 0 311403 4789116011280 -> java/util/IdentityHashMap.keySet
+ 0 311403 4789116011442 -> java/util/IdentityHashMap$KeySet.<init>
+ 0 311403 4789116011452 -> java/util/IdentityHashMap$KeySet.<init>
+ 0 311403 4789116011462 -> java/util/AbstractSet.<init>
+ 0 311403 4789116011469 -> java/util/AbstractCollection.<init>
+ 0 311403 4789116011475 -> java/lang/Object.<init>
+ 0 311403 4789116011483 <- java/lang/Object.<init>
+ 0 311403 4789116011490 <- java/util/AbstractCollection.<init>
+ 0 311403 4789116011497 <- java/util/AbstractSet.<init>
+ 0 311403 4789116011503 <- java/util/IdentityHashMap$KeySet.<init>
+ 0 311403 4789116011510 <- java/util/IdentityHashMap$KeySet.<init>
+ 0 311403 4789116011528 <- java/util/IdentityHashMap.keySet
+ 0 311403 4789116011538 -> java/util/IdentityHashMap$KeySet.iterator
+ 0 311403 4789116011727 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011737 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011748 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011757 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011766 -> java/lang/Object.<init>
+ 0 311403 4789116011774 <- java/lang/Object.<init>
+ 0 311403 4789116011784 -> java/util/IdentityHashMap.access$000
+ 0 311403 4789116011793 <- java/util/IdentityHashMap.access$000
+ 0 311403 4789116011803 -> java/util/IdentityHashMap.access$200
+ 0 311403 4789116011811 <- java/util/IdentityHashMap.access$200
+ 0 311403 4789116011821 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011828 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011835 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011842 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011849 <- java/util/IdentityHashMap$KeySet.iterator
+ 0 311403 4789116011858 -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311403 4789116011866 <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311403 4789116011873 -> java/util/IdentityHashMap$KeySet.iterator
+ 0 311403 4789116011879 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011886 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011892 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011899 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011905 -> java/lang/Object.<init>
+ 0 311403 4789116011912 <- java/lang/Object.<init>
+ 0 311403 4789116011919 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011926 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311403 4789116011934 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011940 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311403 4789116011947 <- java/util/IdentityHashMap$KeySet.iterator
+ 0 311403 4789116011953 -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311403 4789116011961 <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311403 4789116011968 <- java/lang/ApplicationShutdownHooks.run
+ 0 311403 4789116011974 -> java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011982 <- java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116011988 -> java/util/AbstractList$Itr.next
+ 0 311403 4789116011994 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116012002 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311403 4789116012008 -> java/util/ArrayList.get
+ 0 311403 4789116012014 -> java/util/ArrayList.RangeCheck
+ 0 311403 4789116012021 <- java/util/ArrayList.RangeCheck
+ 0 311403 4789116012028 <- java/util/ArrayList.get
+ 0 311403 4789116012035 <- java/util/AbstractList$Itr.next
+ 0 311403 4789116012041 -> java/io/File$1.run
+ 0 311403 4789116012187 -> java/io/DeleteOnExitHook.<clinit>
+ 0 311403 4789116012333 -> java/util/LinkedHashSet.<init>
+ 0 311403 4789116012343 -> java/util/HashSet.<init>
+ 0 311403 4789116012350 -> java/util/AbstractSet.<init>
+ 0 311403 4789116012356 -> java/util/AbstractCollection.<init>
+ 0 311403 4789116012362 -> java/lang/Object.<init>
+ 0 311403 4789116012370 <- java/lang/Object.<init>
+ 0 311403 4789116012377 <- java/util/AbstractCollection.<init>
+ 0 311403 4789116012384 <- java/util/AbstractSet.<init>
+ 0 311403 4789116012394 -> java/util/LinkedHashMap.<init>
+ 0 311403 4789116012404 -> java/util/HashMap.<init>
+ 0 311403 4789116012410 -> java/util/AbstractMap.<init>
+ 0 311403 4789116012417 -> java/lang/Object.<init>
+ 0 311403 4789116012424 <- java/lang/Object.<init>
+ 0 311403 4789116012431 <- java/util/AbstractMap.<init>
+ 0 311403 4789116012438 -> java/lang/Float.isNaN
+ 0 311403 4789116012445 <- java/lang/Float.isNaN
+ 0 311403 4789116012456 -> java/util/LinkedHashMap.init
+ 0 311403 4789116012463 -> java/util/LinkedHashMap$Entry.<init>
+ 0 311403 4789116012469 -> java/util/HashMap$Entry.<init>
+ 0 311403 4789116012476 -> java/lang/Object.<init>
+ 0 311403 4789116012482 <- java/lang/Object.<init>
+ 0 311403 4789116012489 <- java/util/HashMap$Entry.<init>
+ 0 311403 4789116012496 <- java/util/LinkedHashMap$Entry.<init>
+ 0 311403 4789116012503 <- java/util/LinkedHashMap.init
+ 0 311403 4789116012510 <- java/util/HashMap.<init>
+ 0 311403 4789116012516 <- java/util/LinkedHashMap.<init>
+ 0 311403 4789116012523 <- java/util/HashSet.<init>
+ 0 311403 4789116012529 <- java/util/LinkedHashSet.<init>
+ 0 311403 4789116012538 <- java/io/DeleteOnExitHook.<clinit>
+ 0 311403 4789116012547 -> java/io/DeleteOnExitHook.hook
+ 0 311403 4789116012556 -> java/io/DeleteOnExitHook.<init>
+ 0 311403 4789116012565 -> java/lang/Object.<init>
+ 0 311403 4789116012572 <- java/lang/Object.<init>
+ 0 311403 4789116012579 <- java/io/DeleteOnExitHook.<init>
+ 0 311403 4789116012586 <- java/io/DeleteOnExitHook.hook
+ 0 311403 4789116012594 -> java/io/DeleteOnExitHook.run
+ 0 311403 4789116012605 -> java/util/ArrayList.<init>
+ 0 311403 4789116012612 -> java/util/AbstractList.<init>
+ 0 311403 4789116012618 -> java/util/AbstractCollection.<init>
+ 0 311403 4789116012624 -> java/lang/Object.<init>
+ 0 311403 4789116012631 <- java/lang/Object.<init>
+ 0 311403 4789116012638 <- java/util/AbstractCollection.<init>
+ 0 311403 4789116012645 <- java/util/AbstractList.<init>
+ 0 311403 4789116012654 -> java/util/AbstractCollection.toArray
+ 0 311403 4789116012664 -> java/util/HashSet.size
+ 0 311403 4789116012674 <- java/util/HashSet.size
+ 0 311403 4789116012682 -> java/util/HashSet.iterator
+ 0 311403 4789116012691 -> java/util/HashMap.keySet
+ 0 311403 4789116012782 -> java/util/HashMap$KeySet.<init>
+ 0 311403 4789116012791 -> java/util/HashMap$KeySet.<init>
+ 0 311403 4789116012801 -> java/util/AbstractSet.<init>
+ 0 311403 4789116012807 -> java/util/AbstractCollection.<init>
+ 0 311403 4789116012814 -> java/lang/Object.<init>
+ 0 311403 4789116012821 <- java/lang/Object.<init>
+ 0 311403 4789116012828 <- java/util/AbstractCollection.<init>
+ 0 311403 4789116012835 <- java/util/AbstractSet.<init>
+ 0 311403 4789116012841 <- java/util/HashMap$KeySet.<init>
+ 0 311403 4789116012848 <- java/util/HashMap$KeySet.<init>
+ 0 311403 4789116012855 <- java/util/HashMap.keySet
+ 0 311403 4789116012864 -> java/util/HashMap$KeySet.iterator
+ 0 311403 4789116012874 -> java/util/LinkedHashMap.newKeyIterator
+ 0 311403 4789116013056 -> java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311403 4789116013066 -> java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311403 4789116013076 -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311403 4789116013085 -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311403 4789116013095 -> java/lang/Object.<init>
+ 0 311403 4789116013102 <- java/lang/Object.<init>
+ 0 311403 4789116013117 <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311403 4789116013125 <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311403 4789116013132 <- java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311403 4789116013138 <- java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311403 4789116013145 <- java/util/LinkedHashMap.newKeyIterator
+ 0 311403 4789116013152 <- java/util/HashMap$KeySet.iterator
+ 0 311403 4789116013159 <- java/util/HashSet.iterator
+ 0 311403 4789116013168 -> java/util/LinkedHashMap$LinkedHashIterator.hasNext
+ 0 311403 4789116013176 <- java/util/LinkedHashMap$LinkedHashIterator.hasNext
+ 0 311403 4789116013183 <- java/util/AbstractCollection.toArray
+ 0 311403 4789116013190 -> java/lang/Object.getClass
+ 0 311403 4789116013198 <- java/lang/Object.getClass
+ 0 311403 4789116013206 <- java/util/ArrayList.<init>
+ 0 311403 4789116013216 -> java/util/Collections.reverse
+ 0 311403 4789116013228 <- java/util/Collections.reverse
+ 0 311403 4789116013236 -> java/util/AbstractList.iterator
+ 0 311403 4789116013243 -> java/util/AbstractList$Itr.<init>
+ 0 311403 4789116013250 -> java/util/AbstractList$Itr.<init>
+ 0 311403 4789116013256 -> java/lang/Object.<init>
+ 0 311403 4789116013263 <- java/lang/Object.<init>
+ 0 311403 4789116013270 <- java/util/AbstractList$Itr.<init>
+ 0 311403 4789116013276 <- java/util/AbstractList$Itr.<init>
+ 0 311403 4789116013283 <- java/util/AbstractList.iterator
+ 0 311403 4789116013292 -> java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116013299 <- java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116013306 <- java/io/DeleteOnExitHook.run
+ 0 311403 4789116013313 <- java/io/File$1.run
+ 0 311403 4789116013319 -> java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116013326 <- java/util/AbstractList$Itr.hasNext
+ 0 311403 4789116013333 <- java/lang/Shutdown.runHooks
+ 0 311403 4789116013342 <- java/lang/Shutdown.sequence
+ 0 311403 4789116013349 <- java/lang/Shutdown.shutdown
+
+The fourth column is indented by 2 spaces to show when a new method begins.
+This shows what is calling what.
+
+The TIME(us) column shows time from boot in microseconds.
+
+If the output looks strange, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+I truncated the above output by 22800 lines so that it would fit. To make
+sense of the output, try searching for "Func_abc" or using grep. The
+lines were,
+
+ 0 311403 4789112982182 -> Func_abc.main
+ 0 311403 4789112982193 -> Func_abc.func_a
+ 0 311403 4789113990080 -> Func_abc.func_b
+ 0 311403 4789115000081 -> Func_abc.func_c
+ 0 311403 4789116010073 <- Func_abc.func_c
+ 0 311403 4789116010080 <- Func_abc.func_b
+ 0 311403 4789116010086 <- Func_abc.func_a
+ 0 311403 4789116010093 <- Func_abc.main
+
+You can also use the j_classflow.d script to only trace one class.
+
+If you see "drops" warnings, see the Notes/ALLjava_notes.txt file for details.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_flowtime_example.txt
new file mode 100644
index 0000000..22c6a61
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_flowtime_example.txt
@@ -0,0 +1,1287 @@
+The following are examples of j_flowtime.d.
+
+This is a simple script to trace the timing and the not-so-simple flow of
+Java methods and classes. Here it traces the example program,
+Code/Java/func_abc
+
+# j_flowtime.d
+ C PID/TID TIME(us) DELTA(us) -- CLASS.METHOD
+ 0 311481/2 4790256870903 2 -> java/lang/Object.<clinit>
+ 0 311481/2 4790256870950 46 -> java/lang/Object.registerNatives
+ 0 311481/2 4790256871090 140 <- java/lang/Object.registerNatives
+ 0 311481/2 4790256871109 18 <- java/lang/Object.<clinit>
+ 0 311481/2 4790256871121 12 -> java/lang/String.<clinit>
+ 0 311481/2 4790256871518 397 -> java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311481/2 4790256871531 12 -> java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311481/2 4790256871541 10 -> java/lang/Object.<init>
+ 0 311481/2 4790256871549 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256871558 8 <- java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311481/2 4790256871566 7 <- java/lang/String$CaseInsensitiveComparator.<init>
+ 0 311481/2 4790256871575 9 <- java/lang/String.<clinit>
+ 0 311481/2 4790256871644 68 -> java/lang/System.<clinit>
+ 0 311481/2 4790256871656 11 -> java/lang/System.registerNatives
+ 0 311481/2 4790256871675 18 <- java/lang/System.registerNatives
+ 0 311481/2 4790256871686 10 -> java/lang/System.nullInputStream
+ 0 311481/2 4790256871695 9 -> java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871705 10 <- java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871714 8 <- java/lang/System.nullInputStream
+ 0 311481/2 4790256871726 11 -> java/lang/System.nullPrintStream
+ 0 311481/2 4790256871734 7 -> java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871741 7 <- java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871749 7 <- java/lang/System.nullPrintStream
+ 0 311481/2 4790256871758 9 -> java/lang/System.nullPrintStream
+ 0 311481/2 4790256871766 7 -> java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871773 7 <- java/lang/System.currentTimeMillis
+ 0 311481/2 4790256871781 7 <- java/lang/System.nullPrintStream
+ 0 311481/2 4790256871792 10 <- java/lang/System.<clinit>
+ 0 311481/2 4790256871870 78 -> java/lang/ThreadGroup.<init>
+ 0 311481/2 4790256871881 10 -> java/lang/Object.<init>
+ 0 311481/2 4790256871889 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256871906 17 <- java/lang/ThreadGroup.<init>
+ 0 311481/2 4790256871918 11 -> java/lang/ThreadGroup.<init>
+ 0 311481/2 4790256871926 7 -> java/lang/Object.<init>
+ 0 311481/2 4790256871933 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256871945 12 -> java/lang/ThreadGroup.checkAccess
+ 0 311481/2 4790256871955 10 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790256871964 8 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790256871972 8 <- java/lang/ThreadGroup.checkAccess
+ 0 311481/2 4790256871984 12 -> java/lang/ThreadGroup.add
+ 0 311481/2 4790256872006 21 <- java/lang/ThreadGroup.add
+ 0 311481/2 4790256872014 8 <- java/lang/ThreadGroup.<init>
+ 0 311481/2 4790256872201 187 -> java/lang/Thread.<clinit>
+ 0 311481/2 4790256872213 12 -> java/lang/Thread.registerNatives
+ 0 311481/2 4790256872239 25 <- java/lang/Thread.registerNatives
+ 0 311481/2 4790256872606 367 -> java/lang/RuntimePermission.<init>
+ 0 311481/2 4790256872618 11 -> java/security/BasicPermission.<init>
+ 0 311481/2 4790256872628 9 -> java/security/Permission.<init>
+ 0 311481/2 4790256872637 9 -> java/lang/Object.<init>
+ 0 311481/2 4790256872645 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256872656 10 <- java/security/Permission.<init>
+ 0 311481/2 4790256872666 10 -> java/security/BasicPermission.init
+ 0 311481/2 4790256872677 11 -> java/lang/String.length
+ 0 311481/2 4790256872686 8 <- java/lang/String.length
+ 0 311481/2 4790256872697 11 -> java/lang/String.charAt
+ 0 311481/2 4790256872707 10 <- java/lang/String.charAt
+ 0 311481/2 4790256872720 12 -> java/lang/String.equals
+ 0 311481/2 4790256872728 8 <- java/lang/String.equals
+ 0 311481/2 4790256872737 9 <- java/security/BasicPermission.init
+ 0 311481/2 4790256872745 7 <- java/security/BasicPermission.<init>
+ 0 311481/2 4790256872753 7 <- java/lang/RuntimePermission.<init>
+ 0 311481/2 4790256873195 442 -> sun/misc/SoftCache.<init>
+ 0 311481/2 4790256873208 12 -> java/util/AbstractMap.<init>
+ 0 311481/2 4790256873218 9 -> java/lang/Object.<init>
+ 0 311481/2 4790256873226 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256873238 11 <- java/util/AbstractMap.<init>
+ 0 311481/2 4790256873371 133 -> java/lang/ref/ReferenceQueue.<clinit>
+ 0 311481/2 4790256873443 72 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873454 10 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873464 9 -> java/lang/ref/ReferenceQueue.<init>
+ 0 311481/2 4790256873474 9 -> java/lang/Object.<init>
+ 0 311481/2 4790256873481 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256873542 60 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311481/2 4790256873553 10 -> java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311481/2 4790256873562 9 -> java/lang/Object.<init>
+ 0 311481/2 4790256873570 7 <- java/lang/Object.<init>
+ 0 311481/2 4790256873578 7 <- java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311481/2 4790256873585 7 <- java/lang/ref/ReferenceQueue$Lock.<init>
+ 0 311481/2 4790256873597 11 <- java/lang/ref/ReferenceQueue.<init>
+ 0 311481/2 4790256873604 7 <- java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873612 7 <- java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873622 9 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873629 7 -> java/lang/ref/ReferenceQueue$Null.<init>
+ 0 311481/2 4790256873636 7 -> java/lang/ref/ReferenceQueue.<init>
+ 0 311481/2 4790256873644 7 -> java/lang/Object.<init>
+ 0 311481/2 4790256873651 6 <- java/lang/Object.<init>
+ 0 311481/2 4790256873659 7 -> java/lang/ref/ReferenceQueue$Lock.<init>
+[... 22800 lines truncated ...]
+ 0 311481/2 4790257387424 7 <- java/util/HashMap.indexFor
+ 0 311481/2 4790257387432 8 <- java/util/HashMap.put
+ 0 311481/2 4790257387440 7 <- java/util/HashSet.add
+ 0 311481/2 4790257387447 7 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257387473 26 -> java/lang/reflect/Method.getModifiers
+ 0 311481/2 4790257387486 12 <- java/lang/reflect/Method.getModifiers
+ 0 311481/2 4790257387500 14 -> Func_abc.main
+ 0 311481/2 4790257387512 11 -> Func_abc.func_a
+ 0 311481/2 4790257387522 9 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257387530 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790257387537 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790257387545 8 -> java/util/HashSet.add
+ 0 311481/2 4790257387552 7 -> java/util/HashMap.put
+ 0 311481/2 4790257387559 7 -> java/lang/Object.hashCode
+ 0 311481/2 4790257387567 7 <- java/lang/Object.hashCode
+ 0 311481/2 4790257387574 7 -> java/util/HashMap.hash
+ 0 311481/2 4790257387581 7 <- java/util/HashMap.hash
+ 0 311481/2 4790257387589 7 -> java/util/HashMap.indexFor
+ 0 311481/2 4790257387596 7 <- java/util/HashMap.indexFor
+ 0 311481/2 4790257387604 8 <- java/util/HashMap.put
+ 0 311481/2 4790257387611 7 <- java/util/HashSet.add
+ 0 311481/2 4790257387619 7 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257387683 64 -> java/lang/ClassLoader.loadClassInternal
+ 0 311481/2 4790257387691 8 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257387699 7 -> sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311481/2 4790257387706 7 -> java/lang/String.lastIndexOf
+ 0 311481/2 4790257387713 7 -> java/lang/String.lastIndexOf
+ 0 311481/2 4790257387722 8 <- java/lang/String.lastIndexOf
+ 0 311481/2 4790257387729 7 <- java/lang/String.lastIndexOf
+ 0 311481/2 4790257387737 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790257387760 22 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790257387768 7 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257387775 7 -> java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257387782 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257387789 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257387797 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257387805 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257387812 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257387820 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257387828 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257387835 7 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257387843 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257387850 7 -> java/lang/String.charAt
+ 0 311481/2 4790257387857 7 <- java/lang/String.charAt
+ 0 311481/2 4790257387865 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257387873 7 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257387883 9 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257387890 7 <- java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257387899 8 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257387906 7 -> java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257387913 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257387920 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257387928 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257387935 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257387942 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257387951 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257387958 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257387966 7 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257387973 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257387981 7 -> java/lang/String.charAt
+ 0 311481/2 4790257387988 7 <- java/lang/String.charAt
+ 0 311481/2 4790257387995 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257388003 7 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257388012 8 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257388020 7 <- java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257388028 7 -> java/lang/ClassLoader.findBootstrapClass0
+ 0 311481/2 4790257388035 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257388042 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257388050 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257388057 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257388064 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257388072 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257388080 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257388087 7 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257388094 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257388102 7 -> java/lang/String.charAt
+ 0 311481/2 4790257388109 7 <- java/lang/String.charAt
+ 0 311481/2 4790257388117 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257388124 7 -> java/lang/ClassLoader.findBootstrapClass
+ 0 311481/2 4790257388134 9 <- java/lang/ClassLoader.findBootstrapClass
+ 0 311481/2 4790257388142 8 <- java/lang/ClassLoader.findBootstrapClass0
+ 0 311481/2 4790257388150 8 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257388158 7 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257388166 7 <- sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311481/2 4790257388173 7 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257388181 7 <- java/lang/ClassLoader.loadClassInternal
+ 0 311481/2 4790257388193 11 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257388200 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790257388207 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790257388215 7 -> java/util/HashSet.add
+ 0 311481/2 4790257388223 7 -> java/util/HashMap.put
+ 0 311481/2 4790257388230 7 -> java/lang/Object.hashCode
+ 0 311481/2 4790257388237 7 <- java/lang/Object.hashCode
+ 0 311481/2 4790257388245 7 -> java/util/HashMap.hash
+ 0 311481/2 4790257388252 7 <- java/util/HashMap.hash
+ 0 311481/2 4790257388260 7 -> java/util/HashMap.indexFor
+ 0 311481/2 4790257388267 7 <- java/util/HashMap.indexFor
+ 0 311481/2 4790257388275 7 <- java/util/HashMap.put
+ 0 311481/2 4790257388282 7 <- java/util/HashSet.add
+ 0 311481/2 4790257388290 7 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257388305 15 -> java/io/PrintStream.println
+ 0 311481/2 4790257388316 11 -> java/io/PrintStream.print
+ 0 311481/2 4790257388326 9 -> java/io/PrintStream.write
+ 0 311481/2 4790257388335 9 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257388345 10 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257388358 12 -> java/io/Writer.write
+ 0 311481/2 4790257388371 13 -> java/io/BufferedWriter.write
+ 0 311481/2 4790257388382 10 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257388389 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257388399 10 -> java/io/BufferedWriter.min
+ 0 311481/2 4790257388407 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790257388417 10 -> java/lang/String.getChars
+ 0 311481/2 4790257388425 8 -> java/lang/System.arraycopy
+ 0 311481/2 4790257388434 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790257388442 7 <- java/lang/String.getChars
+ 0 311481/2 4790257388450 8 <- java/io/BufferedWriter.write
+ 0 311481/2 4790257388457 7 <- java/io/Writer.write
+ 0 311481/2 4790257388467 10 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790257388475 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257388482 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257388493 10 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790257388504 11 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790257388515 10 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790257388522 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790257388533 10 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790257388544 11 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790257388552 8 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790257388560 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790257388567 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790257388574 7 -> java/lang/Object.<init>
+ 0 311481/2 4790257388582 7 <- java/lang/Object.<init>
+ 0 311481/2 4790257388590 8 -> java/nio/Buffer.limit
+ 0 311481/2 4790257388598 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790257388605 7 -> java/nio/Buffer.position
+ 0 311481/2 4790257388612 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257388620 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790257388628 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790257388635 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790257388643 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790257388654 10 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790257388661 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790257388673 11 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790257388684 10 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790257388695 10 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790257388702 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790257388714 11 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790257388722 7 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790257388732 10 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790257388742 9 -> java/nio/CharBuffer.array
+ 0 311481/2 4790257388749 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790257388759 9 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388766 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388776 9 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388784 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388797 13 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790257388804 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790257388814 9 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388821 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388831 9 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388838 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388853 14 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388861 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257388871 9 -> java/nio/Buffer.position
+ 0 311481/2 4790257388878 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257388886 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388893 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257388903 9 -> java/nio/Buffer.position
+ 0 311481/2 4790257388910 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257388918 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790257388925 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790257388936 10 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790257388943 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790257388953 9 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257388961 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257388969 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790257388979 10 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257388987 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257388998 11 -> java/nio/Buffer.remaining
+ 0 311481/2 4790257389005 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790257389013 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790257389020 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790257389028 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790257389113 85 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790257389125 11 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790257389135 9 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790257389146 11 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790257389158 11 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790257389167 9 -> java/nio/Buffer.flip
+ 0 311481/2 4790257389174 7 <- java/nio/Buffer.flip
+ 0 311481/2 4790257389186 11 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790257389193 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790257389203 9 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257389210 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257389222 11 -> java/io/PrintStream.write
+ 0 311481/2 4790257389230 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257389237 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257389248 11 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790257389261 12 -> java/lang/System.arraycopy
+ 0 311481/2 4790257389268 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790257389276 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790257389286 9 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257389295 9 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257389307 11 -> java/io/FileOutputStream.write
+ 0 311481/2 4790257389317 10 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790257389479 162 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790257389489 9 <- java/io/FileOutputStream.write
+ 0 311481/2 4790257389497 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257389509 12 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257389517 8 <- java/io/PrintStream.write
+ 0 311481/2 4790257389527 10 -> java/nio/Buffer.clear
+ 0 311481/2 4790257389536 8 <- java/nio/Buffer.clear
+ 0 311481/2 4790257389543 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790257389551 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790257389559 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790257389566 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790257389579 12 -> java/lang/String.indexOf
+ 0 311481/2 4790257389586 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257389595 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257389602 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257389610 7 <- java/io/PrintStream.write
+ 0 311481/2 4790257389617 7 <- java/io/PrintStream.print
+ 0 311481/2 4790257389627 9 -> java/io/PrintStream.newLine
+ 0 311481/2 4790257389635 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257389642 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257389651 9 -> java/io/BufferedWriter.newLine
+ 0 311481/2 4790257389661 9 -> java/io/Writer.write
+ 0 311481/2 4790257389668 7 -> java/io/BufferedWriter.write
+ 0 311481/2 4790257389713 44 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257389721 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257389729 8 -> java/io/BufferedWriter.min
+ 0 311481/2 4790257389737 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790257389744 7 -> java/lang/String.getChars
+ 0 311481/2 4790257389752 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790257389760 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790257389767 7 <- java/lang/String.getChars
+ 0 311481/2 4790257389775 7 <- java/io/BufferedWriter.write
+ 0 311481/2 4790257389783 7 <- java/io/Writer.write
+ 0 311481/2 4790257389790 7 <- java/io/BufferedWriter.newLine
+ 0 311481/2 4790257389798 7 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790257389805 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257389812 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790257389820 7 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790257389828 7 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790257389835 7 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790257389842 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790257389850 7 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790257389857 7 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790257389865 7 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790257389872 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790257389879 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790257389886 6 -> java/lang/Object.<init>
+ 0 311481/2 4790257389893 7 <- java/lang/Object.<init>
+ 0 311481/2 4790257389901 7 -> java/nio/Buffer.limit
+ 0 311481/2 4790257389908 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790257389916 7 -> java/nio/Buffer.position
+ 0 311481/2 4790257389923 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257389930 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790257389938 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790257389946 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790257389953 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790257389961 7 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790257389968 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790257389976 7 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790257389984 7 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790257389991 7 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790257389998 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790257390760 761 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790257390772 11 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790257390782 10 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790257390790 7 -> java/nio/CharBuffer.array
+ 0 311481/2 4790257390797 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790257390805 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390812 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390820 8 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390828 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390836 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790257390844 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790257390851 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390859 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390866 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390874 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390883 8 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390890 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790257390898 8 -> java/nio/Buffer.position
+ 0 311481/2 4790257390906 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257390913 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390921 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257390928 7 -> java/nio/Buffer.position
+ 0 311481/2 4790257390936 7 <- java/nio/Buffer.position
+ 0 311481/2 4790257390943 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790257390951 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790257390959 8 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790257390967 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790257390974 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257390982 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257390990 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790257390998 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257391005 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790257391013 8 -> java/nio/Buffer.remaining
+ 0 311481/2 4790257391020 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790257391028 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790257391036 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790257391044 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790257391052 8 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790257391060 7 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790257391067 7 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790257391075 7 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790257391082 7 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790257391090 7 -> java/nio/Buffer.flip
+ 0 311481/2 4790257391097 7 <- java/nio/Buffer.flip
+ 0 311481/2 4790257391105 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790257391112 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790257391120 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257391127 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790257391135 8 -> java/io/PrintStream.write
+ 0 311481/2 4790257391142 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257391150 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790257391158 8 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790257391166 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790257391174 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790257391182 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790257391190 7 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257391197 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257391205 7 -> java/io/FileOutputStream.write
+ 0 311481/2 4790257391212 7 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790257391280 67 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790257391289 9 <- java/io/FileOutputStream.write
+ 0 311481/2 4790257391297 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257391305 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257391313 7 <- java/io/PrintStream.write
+ 0 311481/2 4790257391321 7 -> java/nio/Buffer.clear
+ 0 311481/2 4790257391329 7 <- java/nio/Buffer.clear
+ 0 311481/2 4790257391336 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790257391344 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790257391352 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790257391359 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790257391368 8 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257391375 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257391383 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790257391391 8 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790257391398 7 <- java/io/PrintStream.newLine
+ 0 311481/2 4790257391406 7 <- java/io/PrintStream.println
+ 0 311481/2 4790257391439 32 -> java/lang/ClassLoader.loadClassInternal
+ 0 311481/2 4790257391447 8 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391455 7 -> sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311481/2 4790257391463 7 -> java/lang/String.lastIndexOf
+ 0 311481/2 4790257391471 7 -> java/lang/String.lastIndexOf
+ 0 311481/2 4790257391479 8 <- java/lang/String.lastIndexOf
+ 0 311481/2 4790257391487 7 <- java/lang/String.lastIndexOf
+ 0 311481/2 4790257391495 8 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790257391503 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790257391511 8 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391518 7 -> java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257391526 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257391533 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257391541 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391549 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391556 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391564 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257391572 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257391580 8 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391587 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391595 7 -> java/lang/String.charAt
+ 0 311481/2 4790257391603 7 <- java/lang/String.charAt
+ 0 311481/2 4790257391610 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391618 7 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257391633 14 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257391641 8 <- java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257391651 9 -> java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391658 7 -> java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257391665 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257391672 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257391680 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391688 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391695 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391703 8 <- java/lang/String.indexOf
+ 0 311481/2 4790257391711 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257391718 7 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391725 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391733 7 -> java/lang/String.charAt
+ 0 311481/2 4790257391740 7 <- java/lang/String.charAt
+ 0 311481/2 4790257391748 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391755 7 -> java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257391765 9 <- java/lang/ClassLoader.findLoadedClass0
+ 0 311481/2 4790257391773 8 <- java/lang/ClassLoader.findLoadedClass
+ 0 311481/2 4790257391781 8 -> java/lang/ClassLoader.findBootstrapClass0
+ 0 311481/2 4790257391788 7 -> java/lang/ClassLoader.check
+ 0 311481/2 4790257391795 7 <- java/lang/ClassLoader.check
+ 0 311481/2 4790257391803 7 -> java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391810 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391817 7 -> java/lang/String.indexOf
+ 0 311481/2 4790257391825 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257391833 7 <- java/lang/String.indexOf
+ 0 311481/2 4790257391840 7 -> sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391848 7 <- sun/misc/VM.allowArraySyntax
+ 0 311481/2 4790257391855 7 -> java/lang/String.charAt
+ 0 311481/2 4790257391862 7 <- java/lang/String.charAt
+ 0 311481/2 4790257391870 7 <- java/lang/ClassLoader.checkName
+ 0 311481/2 4790257391877 7 -> java/lang/ClassLoader.findBootstrapClass
+ 0 311481/2 4790257391891 13 <- java/lang/ClassLoader.findBootstrapClass
+ 0 311481/2 4790257391899 7 <- java/lang/ClassLoader.findBootstrapClass0
+ 0 311481/2 4790257391907 8 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391915 7 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391922 7 <- sun/misc/Launcher$AppClassLoader.loadClass
+ 0 311481/2 4790257391930 7 <- java/lang/ClassLoader.loadClass
+ 0 311481/2 4790257391938 7 <- java/lang/ClassLoader.loadClassInternal
+ 0 311481/2 4790257391954 16 -> java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257391962 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790257391969 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790257391978 8 -> java/util/HashSet.add
+ 0 311481/2 4790257391986 8 -> java/util/HashMap.put
+ 0 311481/2 4790257391994 7 -> java/lang/Object.hashCode
+ 0 311481/2 4790257392001 7 <- java/lang/Object.hashCode
+ 0 311481/2 4790257392009 8 -> java/util/HashMap.hash
+ 0 311481/2 4790257392017 7 <- java/util/HashMap.hash
+ 0 311481/2 4790257392025 7 -> java/util/HashMap.indexFor
+ 0 311481/2 4790257392032 7 <- java/util/HashMap.indexFor
+ 0 311481/2 4790257392040 8 <- java/util/HashMap.put
+ 0 311481/2 4790257392048 7 <- java/util/HashSet.add
+ 0 311481/2 4790257392055 7 <- java/lang/ClassLoader.checkPackageAccess
+ 0 311481/2 4790257392076 20 -> java/lang/Thread.currentThread
+ 0 311481/2 4790257392084 8 <- java/lang/Thread.currentThread
+ 0 311481/2 4790257392094 10 -> java/lang/Thread.sleep
+ 0 311481/2 4790258400253 1008158 <- java/lang/Thread.sleep
+ 0 311481/2 4790258400299 45 -> Func_abc.func_b
+ 0 311481/2 4790258400329 30 -> java/io/PrintStream.println
+ 0 311481/2 4790258400338 8 -> java/io/PrintStream.print
+ 0 311481/2 4790258400345 7 -> java/io/PrintStream.write
+ 0 311481/2 4790258400353 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258400361 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258400369 8 -> java/io/Writer.write
+ 0 311481/2 4790258400378 8 -> java/io/BufferedWriter.write
+ 0 311481/2 4790258400386 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258400393 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258400402 9 -> java/io/BufferedWriter.min
+ 0 311481/2 4790258400410 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790258400418 8 -> java/lang/String.getChars
+ 0 311481/2 4790258400426 8 -> java/lang/System.arraycopy
+ 0 311481/2 4790258400435 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790258400442 7 <- java/lang/String.getChars
+ 0 311481/2 4790258400451 8 <- java/io/BufferedWriter.write
+ 0 311481/2 4790258400458 7 <- java/io/Writer.write
+ 0 311481/2 4790258400466 7 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790258400474 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258400481 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258400489 8 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790258400497 7 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790258400504 7 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790258400511 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790258400520 8 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790258400528 7 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790258400536 7 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790258400544 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790258400551 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790258400559 7 -> java/lang/Object.<init>
+ 0 311481/2 4790258400566 7 <- java/lang/Object.<init>
+ 0 311481/2 4790258400574 8 -> java/nio/Buffer.limit
+ 0 311481/2 4790258400582 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790258400590 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258400597 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258400604 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790258400612 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790258400620 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790258400627 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790258400635 8 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790258400643 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790258400651 8 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790258400659 8 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790258400667 7 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790258400675 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790258400683 8 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790258400690 7 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790258400698 7 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790258400706 7 -> java/nio/CharBuffer.array
+ 0 311481/2 4790258400713 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790258400721 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400728 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400736 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400743 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400752 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790258400759 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790258400766 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400774 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400781 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400789 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400799 9 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400806 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258400813 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258400821 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258400828 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400836 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258400843 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258400850 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258400858 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790258400866 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790258400874 8 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790258400881 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790258400889 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258400896 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258400904 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790258400912 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258400919 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258400927 8 -> java/nio/Buffer.remaining
+ 0 311481/2 4790258400934 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790258400942 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790258400950 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790258400957 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790258400965 7 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790258400973 8 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790258400981 7 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790258400988 7 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790258400996 7 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790258401004 7 -> java/nio/Buffer.flip
+ 0 311481/2 4790258401011 6 <- java/nio/Buffer.flip
+ 0 311481/2 4790258401019 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790258401026 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790258401033 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401041 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401049 7 -> java/io/PrintStream.write
+ 0 311481/2 4790258401056 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258401063 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258401071 8 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790258401079 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790258401087 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790258401094 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790258401103 8 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258401110 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258401118 7 -> java/io/FileOutputStream.write
+ 0 311481/2 4790258401125 7 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790258401164 39 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790258401173 8 <- java/io/FileOutputStream.write
+ 0 311481/2 4790258401181 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258401189 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258401196 7 <- java/io/PrintStream.write
+ 0 311481/2 4790258401204 7 -> java/nio/Buffer.clear
+ 0 311481/2 4790258401212 7 <- java/nio/Buffer.clear
+ 0 311481/2 4790258401219 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790258401227 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790258401235 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790258401242 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790258401251 8 -> java/lang/String.indexOf
+ 0 311481/2 4790258401258 7 -> java/lang/String.indexOf
+ 0 311481/2 4790258401266 8 <- java/lang/String.indexOf
+ 0 311481/2 4790258401274 7 <- java/lang/String.indexOf
+ 0 311481/2 4790258401281 7 <- java/io/PrintStream.write
+ 0 311481/2 4790258401289 7 <- java/io/PrintStream.print
+ 0 311481/2 4790258401297 7 -> java/io/PrintStream.newLine
+ 0 311481/2 4790258401304 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258401311 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258401319 7 -> java/io/BufferedWriter.newLine
+ 0 311481/2 4790258401326 7 -> java/io/Writer.write
+ 0 311481/2 4790258401334 7 -> java/io/BufferedWriter.write
+ 0 311481/2 4790258401341 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258401348 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258401356 7 -> java/io/BufferedWriter.min
+ 0 311481/2 4790258401363 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790258401371 7 -> java/lang/String.getChars
+ 0 311481/2 4790258401378 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790258401385 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790258401393 7 <- java/lang/String.getChars
+ 0 311481/2 4790258401401 7 <- java/io/BufferedWriter.write
+ 0 311481/2 4790258401408 7 <- java/io/Writer.write
+ 0 311481/2 4790258401416 7 <- java/io/BufferedWriter.newLine
+ 0 311481/2 4790258401423 7 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790258401430 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258401438 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790258401446 7 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790258401453 7 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790258401460 7 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790258401467 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790258401475 7 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790258401482 7 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790258401490 7 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790258401497 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790258401504 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790258401511 7 -> java/lang/Object.<init>
+ 0 311481/2 4790258401518 7 <- java/lang/Object.<init>
+ 0 311481/2 4790258401526 7 -> java/nio/Buffer.limit
+ 0 311481/2 4790258401533 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790258401541 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258401548 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258401556 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790258401563 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790258401570 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790258401578 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790258401586 7 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790258401593 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790258401601 7 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790258401608 7 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790258401615 7 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790258401623 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790258401630 7 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790258401638 7 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790258401645 7 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790258401653 7 -> java/nio/CharBuffer.array
+ 0 311481/2 4790258401660 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790258401667 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401675 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401682 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401690 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401697 7 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790258401705 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790258401712 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401719 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401727 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401734 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401743 8 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401750 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790258401757 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258401765 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258401772 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401780 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401787 7 -> java/nio/Buffer.position
+ 0 311481/2 4790258401794 7 <- java/nio/Buffer.position
+ 0 311481/2 4790258401802 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790258401809 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790258401817 7 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790258401825 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790258401832 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258401840 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258401848 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790258401855 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258401863 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790258401871 7 -> java/nio/Buffer.remaining
+ 0 311481/2 4790258401878 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790258401885 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790258401893 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790258401901 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790258401908 7 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790258401916 7 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790258401923 7 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790258401931 7 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790258401938 7 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790258401945 7 -> java/nio/Buffer.flip
+ 0 311481/2 4790258401952 7 <- java/nio/Buffer.flip
+ 0 311481/2 4790258401960 7 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790258401967 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790258401975 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401982 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790258401990 7 -> java/io/PrintStream.write
+ 0 311481/2 4790258401997 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258402004 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790258402012 7 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790258402020 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790258402027 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790258402035 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790258402042 7 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258402050 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258402057 7 -> java/io/FileOutputStream.write
+ 0 311481/2 4790258402064 7 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790258402082 17 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790258402090 8 <- java/io/FileOutputStream.write
+ 0 311481/2 4790258402098 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258402106 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258402113 7 <- java/io/PrintStream.write
+ 0 311481/2 4790258402121 7 -> java/nio/Buffer.clear
+ 0 311481/2 4790258402128 7 <- java/nio/Buffer.clear
+ 0 311481/2 4790258402136 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790258402143 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790258402151 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790258402159 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790258402166 7 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258402174 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258402181 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790258402189 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790258402196 7 <- java/io/PrintStream.newLine
+ 0 311481/2 4790258402204 7 <- java/io/PrintStream.println
+ 0 311481/2 4790258402212 7 -> java/lang/Thread.currentThread
+ 0 311481/2 4790258402220 7 <- java/lang/Thread.currentThread
+ 0 311481/2 4790258402228 7 -> java/lang/Thread.sleep
+ 0 311481/2 4790259410328 1008099 <- java/lang/Thread.sleep
+ 0 311481/2 4790259410374 46 -> Func_abc.func_c
+ 0 311481/2 4790259410404 29 -> java/io/PrintStream.println
+ 0 311481/2 4790259410412 8 -> java/io/PrintStream.print
+ 0 311481/2 4790259410420 7 -> java/io/PrintStream.write
+ 0 311481/2 4790259410428 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259410435 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259410444 8 -> java/io/Writer.write
+ 0 311481/2 4790259410453 8 -> java/io/BufferedWriter.write
+ 0 311481/2 4790259410460 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259410467 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259410477 9 -> java/io/BufferedWriter.min
+ 0 311481/2 4790259410484 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790259410492 8 -> java/lang/String.getChars
+ 0 311481/2 4790259410501 8 -> java/lang/System.arraycopy
+ 0 311481/2 4790259410509 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790259410517 7 <- java/lang/String.getChars
+ 0 311481/2 4790259410525 8 <- java/io/BufferedWriter.write
+ 0 311481/2 4790259410533 7 <- java/io/Writer.write
+ 0 311481/2 4790259410541 7 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790259410548 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259410555 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259410563 8 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790259410571 7 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790259410579 7 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790259410586 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790259410595 8 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790259410602 7 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790259410610 7 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790259410618 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790259410625 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790259410633 7 -> java/lang/Object.<init>
+ 0 311481/2 4790259410640 7 <- java/lang/Object.<init>
+ 0 311481/2 4790259410648 8 -> java/nio/Buffer.limit
+ 0 311481/2 4790259410656 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790259410664 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259410671 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259410678 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790259410686 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790259410694 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790259410701 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790259410710 8 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790259410717 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790259410725 8 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790259410733 8 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790259410741 7 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790259410749 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790259410757 8 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790259410764 7 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790259410772 7 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790259410780 7 -> java/nio/CharBuffer.array
+ 0 311481/2 4790259410787 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790259410795 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410802 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410810 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410817 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410826 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790259410833 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790259410841 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410848 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410855 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410863 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410873 9 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410880 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259410888 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259410895 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259410902 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410910 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259410917 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259410924 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259410932 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790259410940 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790259410948 8 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790259410955 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790259410963 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259410970 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259410978 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790259410986 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259410993 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259411001 8 -> java/nio/Buffer.remaining
+ 0 311481/2 4790259411008 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790259411016 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790259411024 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790259411031 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790259411039 7 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790259411047 8 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790259411055 7 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790259411062 7 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790259411070 7 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790259411077 7 -> java/nio/Buffer.flip
+ 0 311481/2 4790259411084 6 <- java/nio/Buffer.flip
+ 0 311481/2 4790259411092 8 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790259411100 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790259411107 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411114 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411122 7 -> java/io/PrintStream.write
+ 0 311481/2 4790259411130 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259411137 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259411145 8 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790259411153 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790259411160 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790259411168 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790259411176 8 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259411184 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259411192 7 -> java/io/FileOutputStream.write
+ 0 311481/2 4790259411199 7 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790259411241 41 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790259411249 8 <- java/io/FileOutputStream.write
+ 0 311481/2 4790259411257 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259411265 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259411272 7 <- java/io/PrintStream.write
+ 0 311481/2 4790259411280 7 -> java/nio/Buffer.clear
+ 0 311481/2 4790259411288 7 <- java/nio/Buffer.clear
+ 0 311481/2 4790259411295 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790259411303 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790259411310 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790259411318 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790259411326 8 -> java/lang/String.indexOf
+ 0 311481/2 4790259411334 7 -> java/lang/String.indexOf
+ 0 311481/2 4790259411342 8 <- java/lang/String.indexOf
+ 0 311481/2 4790259411349 7 <- java/lang/String.indexOf
+ 0 311481/2 4790259411357 7 <- java/io/PrintStream.write
+ 0 311481/2 4790259411365 7 <- java/io/PrintStream.print
+ 0 311481/2 4790259411372 7 -> java/io/PrintStream.newLine
+ 0 311481/2 4790259411380 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259411387 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259411395 7 -> java/io/BufferedWriter.newLine
+ 0 311481/2 4790259411402 7 -> java/io/Writer.write
+ 0 311481/2 4790259411409 7 -> java/io/BufferedWriter.write
+ 0 311481/2 4790259411416 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259411423 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259411431 7 -> java/io/BufferedWriter.min
+ 0 311481/2 4790259411439 7 <- java/io/BufferedWriter.min
+ 0 311481/2 4790259411446 7 -> java/lang/String.getChars
+ 0 311481/2 4790259411454 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790259411461 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790259411468 7 <- java/lang/String.getChars
+ 0 311481/2 4790259411476 7 <- java/io/BufferedWriter.write
+ 0 311481/2 4790259411484 7 <- java/io/Writer.write
+ 0 311481/2 4790259411491 7 <- java/io/BufferedWriter.newLine
+ 0 311481/2 4790259411499 7 -> java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790259411506 7 -> java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259411513 7 <- java/io/BufferedWriter.ensureOpen
+ 0 311481/2 4790259411521 7 -> java/io/OutputStreamWriter.write
+ 0 311481/2 4790259411528 7 -> sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790259411535 7 -> sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790259411543 7 <- sun/nio/cs/StreamEncoder.ensureOpen
+ 0 311481/2 4790259411550 7 -> sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790259411558 7 -> java/nio/CharBuffer.wrap
+ 0 311481/2 4790259411565 7 -> java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790259411572 7 -> java/nio/CharBuffer.<init>
+ 0 311481/2 4790259411579 7 -> java/nio/Buffer.<init>
+ 0 311481/2 4790259411586 6 -> java/lang/Object.<init>
+ 0 311481/2 4790259411594 7 <- java/lang/Object.<init>
+ 0 311481/2 4790259411601 7 -> java/nio/Buffer.limit
+ 0 311481/2 4790259411608 7 <- java/nio/Buffer.limit
+ 0 311481/2 4790259411616 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259411623 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259411631 7 <- java/nio/Buffer.<init>
+ 0 311481/2 4790259411638 7 <- java/nio/CharBuffer.<init>
+ 0 311481/2 4790259411646 7 <- java/nio/HeapCharBuffer.<init>
+ 0 311481/2 4790259411653 7 <- java/nio/CharBuffer.wrap
+ 0 311481/2 4790259411661 7 -> java/nio/Buffer.hasRemaining
+ 0 311481/2 4790259411668 7 <- java/nio/Buffer.hasRemaining
+ 0 311481/2 4790259411676 7 -> java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790259411684 7 -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790259411691 7 -> java/nio/CharBuffer.hasArray
+ 0 311481/2 4790259411698 7 <- java/nio/CharBuffer.hasArray
+ 0 311481/2 4790259411706 7 -> java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790259411713 7 <- java/nio/ByteBuffer.hasArray
+ 0 311481/2 4790259411721 7 -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790259411728 7 -> java/nio/CharBuffer.array
+ 0 311481/2 4790259411735 7 <- java/nio/CharBuffer.array
+ 0 311481/2 4790259411743 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411750 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411758 7 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411765 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411773 7 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790259411780 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790259411787 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411795 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411802 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411809 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411818 8 -> java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411825 7 <- java/nio/CharBuffer.arrayOffset
+ 0 311481/2 4790259411833 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259411840 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259411847 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411855 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259411862 7 -> java/nio/Buffer.position
+ 0 311481/2 4790259411869 7 <- java/nio/Buffer.position
+ 0 311481/2 4790259411877 7 <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 0 311481/2 4790259411885 7 <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 0 311481/2 4790259411893 8 -> java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790259411900 7 <- java/nio/charset/CoderResult.isOverflow
+ 0 311481/2 4790259411908 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259411915 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259411923 7 <- java/nio/charset/CharsetEncoder.encode
+ 0 311481/2 4790259411931 7 -> java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259411938 7 <- java/nio/charset/CoderResult.isUnderflow
+ 0 311481/2 4790259411946 7 -> java/nio/Buffer.remaining
+ 0 311481/2 4790259411953 7 <- java/nio/Buffer.remaining
+ 0 311481/2 4790259411960 7 <- sun/nio/cs/StreamEncoder.implWrite
+ 0 311481/2 4790259411968 7 <- sun/nio/cs/StreamEncoder.write
+ 0 311481/2 4790259411976 7 <- java/io/OutputStreamWriter.write
+ 0 311481/2 4790259411983 7 <- java/io/BufferedWriter.flushBuffer
+ 0 311481/2 4790259411991 7 -> java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790259411999 7 -> sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790259412006 7 -> sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790259412013 7 -> sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790259412021 7 -> java/nio/Buffer.flip
+ 0 311481/2 4790259412028 6 <- java/nio/Buffer.flip
+ 0 311481/2 4790259412035 7 -> java/nio/ByteBuffer.array
+ 0 311481/2 4790259412043 7 <- java/nio/ByteBuffer.array
+ 0 311481/2 4790259412050 7 -> java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259412057 7 <- java/nio/ByteBuffer.arrayOffset
+ 0 311481/2 4790259412065 7 -> java/io/PrintStream.write
+ 0 311481/2 4790259412072 7 -> java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259412080 7 <- java/io/PrintStream.ensureOpen
+ 0 311481/2 4790259412087 7 -> java/io/BufferedOutputStream.write
+ 0 311481/2 4790259412095 7 -> java/lang/System.arraycopy
+ 0 311481/2 4790259412102 7 <- java/lang/System.arraycopy
+ 0 311481/2 4790259412110 7 <- java/io/BufferedOutputStream.write
+ 0 311481/2 4790259412118 7 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259412125 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259412132 7 -> java/io/FileOutputStream.write
+ 0 311481/2 4790259412140 7 -> java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790259412157 17 <- java/io/FileOutputStream.writeBytes
+ 0 311481/2 4790259412165 8 <- java/io/FileOutputStream.write
+ 0 311481/2 4790259412172 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259412180 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259412188 7 <- java/io/PrintStream.write
+ 0 311481/2 4790259412195 7 -> java/nio/Buffer.clear
+ 0 311481/2 4790259412203 7 <- java/nio/Buffer.clear
+ 0 311481/2 4790259412210 7 <- sun/nio/cs/StreamEncoder.writeBytes
+ 0 311481/2 4790259412218 7 <- sun/nio/cs/StreamEncoder.implFlushBuffer
+ 0 311481/2 4790259412226 7 <- sun/nio/cs/StreamEncoder.flushBuffer
+ 0 311481/2 4790259412233 7 <- java/io/OutputStreamWriter.flushBuffer
+ 0 311481/2 4790259412241 7 -> java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259412248 7 -> java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259412256 7 <- java/io/BufferedOutputStream.flushBuffer
+ 0 311481/2 4790259412263 7 <- java/io/BufferedOutputStream.flush
+ 0 311481/2 4790259412271 7 <- java/io/PrintStream.newLine
+ 0 311481/2 4790259412279 7 <- java/io/PrintStream.println
+ 0 311481/2 4790259412287 8 -> java/lang/Thread.currentThread
+ 0 311481/2 4790259412294 7 <- java/lang/Thread.currentThread
+ 0 311481/2 4790259412302 7 -> java/lang/Thread.sleep
+ 0 311481/2 4790260420044 1007741 <- java/lang/Thread.sleep
+ 0 311481/2 4790260420073 29 <- Func_abc.func_c
+ 0 311481/2 4790260420081 7 <- Func_abc.func_b
+ 0 311481/2 4790260420088 7 <- Func_abc.func_a
+ 0 311481/2 4790260420096 7 <- Func_abc.main
+ 0 311481/2 4790260420121 24 -> java/lang/Thread.exit
+ 0 311481/2 4790260420153 32 -> java/lang/ThreadGroup.remove
+ 0 311481/2 4790260420169 15 -> java/lang/System.arraycopy
+ 0 311481/2 4790260420178 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790260420190 11 -> java/lang/Object.notifyAll
+ 0 311481/2 4790260420203 13 <- java/lang/Object.notifyAll
+ 0 311481/2 4790260420211 8 <- java/lang/ThreadGroup.remove
+ 0 311481/2 4790260420225 13 <- java/lang/Thread.exit
+ 0 311481/2 4790260420438 212 -> java/lang/Thread.<init>
+ 0 311481/2 4790260420447 8 -> java/lang/Object.<init>
+ 0 311481/2 4790260420454 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260420464 9 -> java/lang/Object.<init>
+ 0 311481/2 4790260420471 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260420479 8 -> java/lang/Thread.init
+ 0 311481/2 4790260420486 7 -> java/lang/Thread.currentThread
+ 0 311481/2 4790260420494 7 <- java/lang/Thread.currentThread
+ 0 311481/2 4790260420503 8 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790260420511 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790260420519 8 -> java/lang/ThreadGroup.checkAccess
+ 0 311481/2 4790260420526 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790260420534 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790260420542 8 <- java/lang/ThreadGroup.checkAccess
+ 0 311481/2 4790260420550 8 -> java/lang/ThreadGroup.addUnstarted
+ 0 311481/2 4790260420558 7 <- java/lang/ThreadGroup.addUnstarted
+ 0 311481/2 4790260420567 9 -> java/lang/String.toCharArray
+ 0 311481/2 4790260420575 8 -> java/lang/String.getChars
+ 0 311481/2 4790260420584 8 -> java/lang/System.arraycopy
+ 0 311481/2 4790260420592 8 <- java/lang/System.arraycopy
+ 0 311481/2 4790260420599 7 <- java/lang/String.getChars
+ 0 311481/2 4790260420607 7 <- java/lang/String.toCharArray
+ 0 311481/2 4790260420615 7 -> java/lang/Thread.getContextClassLoader
+ 0 311481/2 4790260420622 7 <- java/lang/Thread.getContextClassLoader
+ 0 311481/2 4790260420631 8 -> java/security/AccessController.getContext
+ 0 311481/2 4790260420638 7 -> java/security/AccessController.getStackAccessControlContext
+ 0 311481/2 4790260420653 14 <- java/security/AccessController.getStackAccessControlContext
+ 0 311481/2 4790260420662 8 -> java/security/AccessControlContext.optimize
+ 0 311481/2 4790260420670 8 -> java/security/AccessController.getInheritedAccessControlContext
+ 0 311481/2 4790260420678 8 <- java/security/AccessController.getInheritedAccessControlContext
+ 0 311481/2 4790260420687 8 <- java/security/AccessControlContext.optimize
+ 0 311481/2 4790260420695 7 <- java/security/AccessController.getContext
+ 0 311481/2 4790260420703 8 -> java/lang/Thread.setPriority
+ 0 311481/2 4790260420710 7 -> java/lang/Thread.checkAccess
+ 0 311481/2 4790260420718 7 -> java/lang/System.getSecurityManager
+ 0 311481/2 4790260420725 7 <- java/lang/System.getSecurityManager
+ 0 311481/2 4790260420732 7 <- java/lang/Thread.checkAccess
+ 0 311481/2 4790260420741 8 -> java/lang/Thread.setPriority0
+ 0 311481/2 4790260420760 19 <- java/lang/Thread.setPriority0
+ 0 311481/2 4790260420768 8 <- java/lang/Thread.setPriority
+ 0 311481/2 4790260420777 8 -> java/lang/Thread.nextThreadID
+ 0 311481/2 4790260420785 8 <- java/lang/Thread.nextThreadID
+ 0 311481/2 4790260420793 7 <- java/lang/Thread.init
+ 0 311481/2 4790260420801 7 <- java/lang/Thread.<init>
+ 0 311481/2 4790260420810 9 -> java/lang/ThreadGroup.add
+ 0 311481/2 4790260420819 8 <- java/lang/ThreadGroup.add
+ 0 311481/2 4790260420834 15 -> java/lang/Shutdown.shutdown
+ 0 311481/2 4790260420846 12 -> java/lang/Shutdown.sequence
+ 0 311481/2 4790260420855 9 -> java/lang/Shutdown.runHooks
+ 0 311481/2 4790260420867 11 -> java/util/AbstractList.iterator
+ 0 311481/2 4790260421144 277 -> java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260421156 12 -> java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260421168 11 -> java/lang/Object.<init>
+ 0 311481/2 4790260421175 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260421189 13 <- java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260421197 7 <- java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260421205 7 <- java/util/AbstractList.iterator
+ 0 311481/2 4790260421218 13 -> java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260421229 11 <- java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260421240 10 -> java/util/AbstractList$Itr.next
+ 0 311481/2 4790260421249 9 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260421256 7 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260421267 10 -> java/util/ArrayList.get
+ 0 311481/2 4790260421274 7 -> java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260421282 7 <- java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260421290 7 <- java/util/ArrayList.get
+ 0 311481/2 4790260421297 7 <- java/util/AbstractList$Itr.next
+ 0 311481/2 4790260421310 12 -> java/io/Console$1$1.run
+ 0 311481/2 4790260421321 10 -> java/io/Console.access$600
+ 0 311481/2 4790260421330 9 <- java/io/Console.access$600
+ 0 311481/2 4790260421338 7 <- java/io/Console$1$1.run
+ 0 311481/2 4790260421346 7 -> java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260421353 7 <- java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260421361 7 -> java/util/AbstractList$Itr.next
+ 0 311481/2 4790260421368 7 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260421376 7 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260421384 8 -> java/util/ArrayList.get
+ 0 311481/2 4790260421391 7 -> java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260421398 7 <- java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260421406 7 <- java/util/ArrayList.get
+ 0 311481/2 4790260421414 7 <- java/util/AbstractList$Itr.next
+ 0 311481/2 4790260421422 8 -> java/lang/ApplicationShutdownHooks.run
+ 0 311481/2 4790260421435 13 -> java/util/IdentityHashMap.keySet
+ 0 311481/2 4790260421598 163 -> java/util/IdentityHashMap$KeySet.<init>
+ 0 311481/2 4790260421610 11 -> java/util/IdentityHashMap$KeySet.<init>
+ 0 311481/2 4790260421622 11 -> java/util/AbstractSet.<init>
+ 0 311481/2 4790260421629 7 -> java/util/AbstractCollection.<init>
+ 0 311481/2 4790260421637 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260421644 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260421652 8 <- java/util/AbstractCollection.<init>
+ 0 311481/2 4790260421660 7 <- java/util/AbstractSet.<init>
+ 0 311481/2 4790260421668 7 <- java/util/IdentityHashMap$KeySet.<init>
+ 0 311481/2 4790260421675 7 <- java/util/IdentityHashMap$KeySet.<init>
+ 0 311481/2 4790260421683 7 <- java/util/IdentityHashMap.keySet
+ 0 311481/2 4790260421695 11 -> java/util/IdentityHashMap$KeySet.iterator
+ 0 311481/2 4790260421882 187 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260421894 11 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260421905 11 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260421915 10 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260421926 10 -> java/lang/Object.<init>
+ 0 311481/2 4790260421934 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260421945 11 -> java/util/IdentityHashMap.access$000
+ 0 311481/2 4790260421954 8 <- java/util/IdentityHashMap.access$000
+ 0 311481/2 4790260421967 12 -> java/util/IdentityHashMap.access$200
+ 0 311481/2 4790260421975 8 <- java/util/IdentityHashMap.access$200
+ 0 311481/2 4790260421986 10 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260421994 8 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260422002 7 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422010 7 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422018 7 <- java/util/IdentityHashMap$KeySet.iterator
+ 0 311481/2 4790260422029 11 -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311481/2 4790260422037 8 <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311481/2 4790260422045 8 -> java/util/IdentityHashMap$KeySet.iterator
+ 0 311481/2 4790260422053 7 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422060 7 -> java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422068 7 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260422075 7 -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260422083 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260422090 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260422098 8 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260422106 8 <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 0 311481/2 4790260422114 7 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422121 7 <- java/util/IdentityHashMap$KeyIterator.<init>
+ 0 311481/2 4790260422129 7 <- java/util/IdentityHashMap$KeySet.iterator
+ 0 311481/2 4790260422137 7 -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311481/2 4790260422145 7 <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 0 311481/2 4790260422153 8 <- java/lang/ApplicationShutdownHooks.run
+ 0 311481/2 4790260422161 7 -> java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260422168 7 <- java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260422176 7 -> java/util/AbstractList$Itr.next
+ 0 311481/2 4790260422183 7 -> java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260422191 7 <- java/util/AbstractList$Itr.checkForComodification
+ 0 311481/2 4790260422199 8 -> java/util/ArrayList.get
+ 0 311481/2 4790260422206 7 -> java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260422213 7 <- java/util/ArrayList.RangeCheck
+ 0 311481/2 4790260422221 7 <- java/util/ArrayList.get
+ 0 311481/2 4790260422229 7 <- java/util/AbstractList$Itr.next
+ 0 311481/2 4790260422237 8 -> java/io/File$1.run
+ 0 311481/2 4790260422318 81 -> java/io/DeleteOnExitHook.<clinit>
+ 0 311481/2 4790260422461 143 -> java/util/LinkedHashSet.<init>
+ 0 311481/2 4790260422473 12 -> java/util/HashSet.<init>
+ 0 311481/2 4790260422481 7 -> java/util/AbstractSet.<init>
+ 0 311481/2 4790260422488 7 -> java/util/AbstractCollection.<init>
+ 0 311481/2 4790260422495 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260422502 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260422511 8 <- java/util/AbstractCollection.<init>
+ 0 311481/2 4790260422519 7 <- java/util/AbstractSet.<init>
+ 0 311481/2 4790260422531 12 -> java/util/LinkedHashMap.<init>
+ 0 311481/2 4790260422541 10 -> java/util/HashMap.<init>
+ 0 311481/2 4790260422549 7 -> java/util/AbstractMap.<init>
+ 0 311481/2 4790260422556 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260422563 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260422571 7 <- java/util/AbstractMap.<init>
+ 0 311481/2 4790260422580 9 -> java/lang/Float.isNaN
+ 0 311481/2 4790260422588 7 <- java/lang/Float.isNaN
+ 0 311481/2 4790260422600 12 -> java/util/LinkedHashMap.init
+ 0 311481/2 4790260422608 8 -> java/util/LinkedHashMap$Entry.<init>
+ 0 311481/2 4790260422615 7 -> java/util/HashMap$Entry.<init>
+ 0 311481/2 4790260422623 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260422630 6 <- java/lang/Object.<init>
+ 0 311481/2 4790260422638 7 <- java/util/HashMap$Entry.<init>
+ 0 311481/2 4790260422645 7 <- java/util/LinkedHashMap$Entry.<init>
+ 0 311481/2 4790260422653 7 <- java/util/LinkedHashMap.init
+ 0 311481/2 4790260422660 7 <- java/util/HashMap.<init>
+ 0 311481/2 4790260422668 7 <- java/util/LinkedHashMap.<init>
+ 0 311481/2 4790260422676 7 <- java/util/HashSet.<init>
+ 0 311481/2 4790260422683 7 <- java/util/LinkedHashSet.<init>
+ 0 311481/2 4790260422692 9 <- java/io/DeleteOnExitHook.<clinit>
+ 0 311481/2 4790260422703 10 -> java/io/DeleteOnExitHook.hook
+ 0 311481/2 4790260422713 10 -> java/io/DeleteOnExitHook.<init>
+ 0 311481/2 4790260422723 9 -> java/lang/Object.<init>
+ 0 311481/2 4790260422730 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260422738 7 <- java/io/DeleteOnExitHook.<init>
+ 0 311481/2 4790260422746 7 <- java/io/DeleteOnExitHook.hook
+ 0 311481/2 4790260422756 10 -> java/io/DeleteOnExitHook.run
+ 0 311481/2 4790260422768 12 -> java/util/ArrayList.<init>
+ 0 311481/2 4790260422775 7 -> java/util/AbstractList.<init>
+ 0 311481/2 4790260422783 7 -> java/util/AbstractCollection.<init>
+ 0 311481/2 4790260422790 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260422797 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260422805 7 <- java/util/AbstractCollection.<init>
+ 0 311481/2 4790260422813 7 <- java/util/AbstractList.<init>
+ 0 311481/2 4790260422824 11 -> java/util/AbstractCollection.toArray
+ 0 311481/2 4790260422835 10 -> java/util/HashSet.size
+ 0 311481/2 4790260422844 9 <- java/util/HashSet.size
+ 0 311481/2 4790260422855 10 -> java/util/HashSet.iterator
+ 0 311481/2 4790260422865 9 -> java/util/HashMap.keySet
+ 0 311481/2 4790260422956 91 -> java/util/HashMap$KeySet.<init>
+ 0 311481/2 4790260422967 10 -> java/util/HashMap$KeySet.<init>
+ 0 311481/2 4790260422978 10 -> java/util/AbstractSet.<init>
+ 0 311481/2 4790260422985 7 -> java/util/AbstractCollection.<init>
+ 0 311481/2 4790260422993 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260423000 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260423008 7 <- java/util/AbstractCollection.<init>
+ 0 311481/2 4790260423015 7 <- java/util/AbstractSet.<init>
+ 0 311481/2 4790260423023 7 <- java/util/HashMap$KeySet.<init>
+ 0 311481/2 4790260423031 7 <- java/util/HashMap$KeySet.<init>
+ 0 311481/2 4790260423038 7 <- java/util/HashMap.keySet
+ 0 311481/2 4790260423049 10 -> java/util/HashMap$KeySet.iterator
+ 0 311481/2 4790260423060 11 -> java/util/LinkedHashMap.newKeyIterator
+ 0 311481/2 4790260423243 182 -> java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311481/2 4790260423254 11 -> java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311481/2 4790260423266 11 -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311481/2 4790260423276 9 -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311481/2 4790260423286 10 -> java/lang/Object.<init>
+ 0 311481/2 4790260423294 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260423311 16 <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311481/2 4790260423319 8 <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 0 311481/2 4790260423327 7 <- java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311481/2 4790260423334 7 <- java/util/LinkedHashMap$KeyIterator.<init>
+ 0 311481/2 4790260423342 7 <- java/util/LinkedHashMap.newKeyIterator
+ 0 311481/2 4790260423350 7 <- java/util/HashMap$KeySet.iterator
+ 0 311481/2 4790260423357 7 <- java/util/HashSet.iterator
+ 0 311481/2 4790260423369 11 -> java/util/LinkedHashMap$LinkedHashIterator.hasNext
+ 0 311481/2 4790260423377 8 <- java/util/LinkedHashMap$LinkedHashIterator.hasNext
+ 0 311481/2 4790260423385 8 <- java/util/AbstractCollection.toArray
+ 0 311481/2 4790260423393 8 -> java/lang/Object.getClass
+ 0 311481/2 4790260423402 8 <- java/lang/Object.getClass
+ 0 311481/2 4790260423410 8 <- java/util/ArrayList.<init>
+ 0 311481/2 4790260423422 11 -> java/util/Collections.reverse
+ 0 311481/2 4790260423435 13 <- java/util/Collections.reverse
+ 0 311481/2 4790260423445 10 -> java/util/AbstractList.iterator
+ 0 311481/2 4790260423453 8 -> java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260423460 7 -> java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260423468 7 -> java/lang/Object.<init>
+ 0 311481/2 4790260423475 7 <- java/lang/Object.<init>
+ 0 311481/2 4790260423483 7 <- java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260423490 7 <- java/util/AbstractList$Itr.<init>
+ 0 311481/2 4790260423498 7 <- java/util/AbstractList.iterator
+ 0 311481/2 4790260423508 10 -> java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260423516 7 <- java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260423524 8 <- java/io/DeleteOnExitHook.run
+ 0 311481/2 4790260423532 7 <- java/io/File$1.run
+ 0 311481/2 4790260423539 7 -> java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260423547 7 <- java/util/AbstractList$Itr.hasNext
+ 0 311481/2 4790260423554 7 <- java/lang/Shutdown.runHooks
+ 0 311481/2 4790260423564 9 <- java/lang/Shutdown.sequence
+ 0 311481/2 4790260423572 7 <- java/lang/Shutdown.shutdown
+
+I truncated 22800 lines from the above output to make it fit here.
+
+The fifth column is indented by 2 spaces to show when a new method begins.
+This shows which method is calling which.
+
+The TIME(us) column shows time since boot.
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read.
+
+The FILE column shows file that was being executed.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+Try skimming down the "DELTA(us)" column to find the largest delta time,
+and see what lines it corresponds with.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+If you see "drops" warnings, see the Notes/ALLjava_notes.txt file for details.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_methodcalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_methodcalls_example.txt
new file mode 100644
index 0000000..22a2b4d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_methodcalls_example.txt
@@ -0,0 +1,999 @@
+The following are examples of running the j_methodcalls.d script.
+
+This traces calls to methods from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls are only visible when using the flag
+"+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+Here we see it running on Code/Java/Func_abc
+
+# j_methodcalls_example.txt
+Tracing... Hit Ctrl-C to end.
+
+ PID COUNT CLASS.METHOD
+ 311492 1 Func_abc.func_a
+ 311492 1 Func_abc.func_b
+ 311492 1 Func_abc.func_c
+ 311492 1 Func_abc.main
+ 311492 1 java/io/BufferedInputStream.<clinit>
+ 311492 1 java/io/BufferedReader.<clinit>
+ 311492 1 java/io/BufferedReader.close
+ 311492 1 java/io/BufferedWriter.<clinit>
+ 311492 1 java/io/Console$1$1.<init>
+ 311492 1 java/io/Console$1$1.run
+ 311492 1 java/io/Console$1.<init>
+ 311492 1 java/io/Console$1.consoleRestoreHook
+ 311492 1 java/io/Console.<clinit>
+ 311492 1 java/io/Console.access$600
+ 311492 1 java/io/DataInputStream.<init>
+ 311492 1 java/io/DataInputStream.readFully
+ 311492 1 java/io/DeleteOnExitHook.<clinit>
+ 311492 1 java/io/DeleteOnExitHook.<init>
+ 311492 1 java/io/DeleteOnExitHook.hook
+ 311492 1 java/io/DeleteOnExitHook.run
+ 311492 1 java/io/File$1.<init>
+ 311492 1 java/io/File$1.run
+ 311492 1 java/io/File.<clinit>
+ 311492 1 java/io/File.lastModified
+ 311492 1 java/io/File.length
+ 311492 1 java/io/FileDescriptor.<clinit>
+ 311492 1 java/io/FileDescriptor.initIDs
+ 311492 1 java/io/FileInputStream.<clinit>
+ 311492 1 java/io/FileInputStream.available
+ 311492 1 java/io/FileInputStream.initIDs
+ 311492 1 java/io/FileOutputStream.<clinit>
+ 311492 1 java/io/FileOutputStream.initIDs
+ 311492 1 java/io/FilePermission.newPermissionCollection
+ 311492 1 java/io/FilePermissionCollection.<clinit>
+ 311492 1 java/io/FilePermissionCollection.<init>
+ 311492 1 java/io/FilePermissionCollection.add
+ 311492 1 java/io/FileReader.<init>
+ 311492 1 java/io/FileSystem.<clinit>
+ 311492 1 java/io/FileSystem.<init>
+ 311492 1 java/io/FileSystem.getFileSystem
+ 311492 1 java/io/FilterInputStream.close
+ 311492 1 java/io/InputStreamReader.<init>
+ 311492 1 java/io/InputStreamReader.close
+ 311492 1 java/io/ObjectStreamClass.<clinit>
+ 311492 1 java/io/ObjectStreamClass.initNative
+ 311492 1 java/io/UnixFileSystem.<clinit>
+ 311492 1 java/io/UnixFileSystem.<init>
+ 311492 1 java/io/UnixFileSystem.getLastModifiedTime
+ 311492 1 java/io/UnixFileSystem.getLength
+ 311492 1 java/io/UnixFileSystem.initIDs
+ 311492 1 java/lang/AbstractStringBuilder.<clinit>
+ 311492 1 java/lang/ApplicationShutdownHooks.<clinit>
+ 311492 1 java/lang/ApplicationShutdownHooks.<init>
+ 311492 1 java/lang/ApplicationShutdownHooks.hook
+ 311492 1 java/lang/ApplicationShutdownHooks.run
+ 311492 1 java/lang/Boolean.<clinit>
+ 311492 1 java/lang/Byte.<clinit>
+ 311492 1 java/lang/Character.<clinit>
+ 311492 1 java/lang/CharacterDataLatin1.<clinit>
+ 311492 1 java/lang/Class.<clinit>
+ 311492 1 java/lang/Class.access$302
+ 311492 1 java/lang/Class.registerNatives
+ 311492 1 java/lang/ClassLoader$3.<init>
+ 311492 1 java/lang/ClassLoader$3.run
+ 311492 1 java/lang/ClassLoader$NativeLibrary.<init>
+ 311492 1 java/lang/ClassLoader$NativeLibrary.getFromClass
+ 311492 1 java/lang/ClassLoader$NativeLibrary.load
+ 311492 1 java/lang/ClassLoader.<clinit>
+ 311492 1 java/lang/ClassLoader.access$100
+ 311492 1 java/lang/ClassLoader.addClass
+ 311492 1 java/lang/ClassLoader.checkCerts
+ 311492 1 java/lang/ClassLoader.defineClass
+ 311492 1 java/lang/ClassLoader.defineClass1
+ 311492 1 java/lang/ClassLoader.defineClassSourceLocation
+ 311492 1 java/lang/ClassLoader.getSystemClassLoader
+ 311492 1 java/lang/ClassLoader.initSystemClassLoader
+ 311492 1 java/lang/ClassLoader.loadLibrary
+ 311492 1 java/lang/ClassLoader.loadLibrary0
+ 311492 1 java/lang/ClassLoader.postDefineClass
+ 311492 1 java/lang/ClassLoader.preDefineClass
+ 311492 1 java/lang/ClassLoader.registerNatives
+ 311492 1 java/lang/Compiler$1.<init>
+ 311492 1 java/lang/Compiler$1.run
+ 311492 1 java/lang/Compiler.<clinit>
+ 311492 1 java/lang/Compiler.registerNatives
+ 311492 1 java/lang/Double.<clinit>
+ 311492 1 java/lang/Double.doubleToLongBits
+ 311492 1 java/lang/Double.doubleToRawLongBits
+ 311492 1 java/lang/Error.<init>
+ 311492 1 java/lang/Float.<clinit>
+ 311492 1 java/lang/Float.floatToIntBits
+ 311492 1 java/lang/Float.floatToRawIntBits
+ 311492 1 java/lang/IncompatibleClassChangeError.<init>
+ 311492 1 java/lang/Integer.<clinit>
+ 311492 1 java/lang/LinkageError.<init>
+ 311492 1 java/lang/Long.<clinit>
+ 311492 1 java/lang/Math.<clinit>
+ 311492 1 java/lang/NoSuchMethodError.<init>
+ 311492 1 java/lang/Object.<clinit>
+ 311492 1 java/lang/Object.notifyAll
+ 311492 1 java/lang/Object.registerNatives
+ 311492 1 java/lang/Runtime.<clinit>
+ 311492 1 java/lang/Runtime.<init>
+ 311492 1 java/lang/Runtime.loadLibrary0
+ 311492 1 java/lang/Runtime.maxMemory
+ 311492 1 java/lang/Short.<clinit>
+ 311492 1 java/lang/Shutdown.<clinit>
+ 311492 1 java/lang/Shutdown.runHooks
+ 311492 1 java/lang/Shutdown.sequence
+ 311492 1 java/lang/Shutdown.shutdown
+ 311492 1 java/lang/String.<clinit>
+ 311492 1 java/lang/String.checkBounds
+ 311492 1 java/lang/String.length
+ 311492 1 java/lang/String.trim
+ 311492 1 java/lang/StringBuffer.<clinit>
+ 311492 1 java/lang/StringCoding$StringDecoder.decode
+ 311492 1 java/lang/StringCoding.<clinit>
+ 311492 1 java/lang/StringCoding.access$000
+ 311492 1 java/lang/StringCoding.access$100
+ 311492 1 java/lang/StringCoding.decode
+ 311492 1 java/lang/StringCoding.deref
+ 311492 1 java/lang/StringCoding.lookupCharset
+ 311492 1 java/lang/StringCoding.safeTrim
+ 311492 1 java/lang/StringCoding.scale
+ 311492 1 java/lang/StringCoding.set
+ 311492 1 java/lang/System$2.<init>
+ 311492 1 java/lang/System.<clinit>
+ 311492 1 java/lang/System.getCallerClass
+ 311492 1 java/lang/System.initProperties
+ 311492 1 java/lang/System.initializeSystemClass
+ 311492 1 java/lang/System.loadLibrary
+ 311492 1 java/lang/System.mapLibraryName
+ 311492 1 java/lang/System.nullInputStream
+ 311492 1 java/lang/System.registerNatives
+ 311492 1 java/lang/System.setErr0
+ 311492 1 java/lang/System.setIn0
+ 311492 1 java/lang/System.setOut0
+ 311492 1 java/lang/SystemClassLoaderAction.<init>
+ 311492 1 java/lang/SystemClassLoaderAction.run
+ 311492 1 java/lang/Terminator$1.<init>
+ 311492 1 java/lang/Terminator.<clinit>
+ 311492 1 java/lang/Terminator.setup
+ 311492 1 java/lang/Thread.<clinit>
+ 311492 1 java/lang/Thread.exit
+ 311492 1 java/lang/Thread.getPriority
+ 311492 1 java/lang/Thread.interrupted
+ 311492 1 java/lang/Thread.isInterrupted
+ 311492 1 java/lang/Thread.registerNatives
+ 311492 1 java/lang/Thread.setContextClassLoader
+ 311492 1 java/lang/ThreadGroup.remove
+ 311492 1 java/lang/ThreadLocal$ThreadLocalMap$Entry.<init>
+ 311492 1 java/lang/ThreadLocal$ThreadLocalMap.<init>
+ 311492 1 java/lang/ThreadLocal$ThreadLocalMap.access$100
+ 311492 1 java/lang/ThreadLocal$ThreadLocalMap.set
+ 311492 1 java/lang/ThreadLocal$ThreadLocalMap.setThreshold
+ 311492 1 java/lang/ThreadLocal.<clinit>
+ 311492 1 java/lang/ThreadLocal.createMap
+ 311492 1 java/lang/ThreadLocal.get
+ 311492 1 java/lang/ThreadLocal.initialValue
+ 311492 1 java/lang/ThreadLocal.set
+ 311492 1 java/lang/ThreadLocal.setInitialValue
+ 311492 1 java/lang/ref/Finalizer$FinalizerThread.<init>
+ 311492 1 java/lang/ref/Finalizer$FinalizerThread.run
+ 311492 1 java/lang/ref/Finalizer.<clinit>
+ 311492 1 java/lang/ref/Finalizer.access$000
+ 311492 1 java/lang/ref/Reference$ReferenceHandler.<init>
+ 311492 1 java/lang/ref/Reference$ReferenceHandler.run
+ 311492 1 java/lang/ref/Reference.<clinit>
+ 311492 1 java/lang/ref/Reference.access$200
+ 311492 1 java/lang/ref/ReferenceQueue.<clinit>
+ 311492 1 java/lang/ref/ReferenceQueue.reallyPoll
+ 311492 1 java/lang/reflect/AccessibleObject.<clinit>
+ 311492 1 java/lang/reflect/Constructor.<clinit>
+ 311492 1 java/lang/reflect/Field.<clinit>
+ 311492 1 java/lang/reflect/Field.getName
+ 311492 1 java/lang/reflect/Method.<clinit>
+ 311492 1 java/lang/reflect/Method.getModifiers
+ 311492 1 java/lang/reflect/Modifier.<clinit>
+ 311492 1 java/lang/reflect/Modifier.isVolatile
+ 311492 1 java/lang/reflect/ReflectAccess.<init>
+ 311492 1 java/lang/reflect/ReflectPermission.<init>
+ 311492 1 java/net/ContentHandler.<init>
+ 311492 1 java/net/Parts.getQuery
+ 311492 1 java/net/URL.<clinit>
+ 311492 1 java/net/URL.openConnection
+ 311492 1 java/net/URLClassLoader$7.<init>
+ 311492 1 java/net/URLClassLoader.<clinit>
+ 311492 1 java/net/URLClassLoader.access$000
+ 311492 1 java/net/URLClassLoader.defineClass
+ 311492 1 java/net/URLClassLoader.getPermissions
+ 311492 1 java/net/URLConnection.<clinit>
+ 311492 1 java/net/URLConnection.<init>
+ 311492 1 java/net/UnknownContentHandler.<init>
+ 311492 1 java/nio/Bits.<clinit>
+ 311492 1 java/nio/ByteOrder.<clinit>
+ 311492 1 java/nio/charset/Charset.<clinit>
+ 311492 1 java/nio/charset/Charset.<init>
+ 311492 1 java/nio/charset/CharsetDecoder.<clinit>
+ 311492 1 java/nio/charset/CharsetDecoder.flush
+ 311492 1 java/nio/charset/CharsetDecoder.implFlush
+ 311492 1 java/nio/charset/CharsetEncoder.<clinit>
+ 311492 1 java/nio/charset/CoderResult$1.<init>
+ 311492 1 java/nio/charset/CoderResult$2.<init>
+ 311492 1 java/nio/charset/CoderResult.<clinit>
+ 311492 1 java/nio/charset/CodingErrorAction.<clinit>
+ 311492 1 java/nio/charset/spi/CharsetProvider.<init>
+ 311492 1 java/security/AccessControlContext.<clinit>
+ 311492 1 java/security/BasicPermission.newPermissionCollection
+ 311492 1 java/security/BasicPermissionCollection.<clinit>
+ 311492 1 java/security/BasicPermissionCollection.<init>
+ 311492 1 java/security/BasicPermissionCollection.add
+ 311492 1 java/security/CodeSource.<init>
+ 311492 1 java/security/Permissions.<clinit>
+ 311492 1 java/security/Policy$UnsupportedEmptyCollection.<init>
+ 311492 1 java/security/Policy.<clinit>
+ 311492 1 java/security/PrivilegedActionException.<init>
+ 311492 1 java/security/ProtectionDomain.<clinit>
+ 311492 1 java/security/ProtectionDomain.<init>
+ 311492 1 java/security/SecureClassLoader.<clinit>
+ 311492 1 java/security/SecureClassLoader.check
+ 311492 1 java/security/SecureClassLoader.defineClass
+ 311492 1 java/security/SecureClassLoader.getPermissions
+ 311492 1 java/security/SecureClassLoader.getProtectionDomain
+ 311492 1 java/util/AbstractCollection.toArray
+ 311492 1 java/util/BitSet.<clinit>
+ 311492 1 java/util/BitSet.<init>
+ 311492 1 java/util/BitSet.initWords
+ 311492 1 java/util/Collections$SynchronizedMap.<init>
+ 311492 1 java/util/Collections.<clinit>
+ 311492 1 java/util/Collections.reverse
+ 311492 1 java/util/Collections.synchronizedMap
+ 311492 1 java/util/HashMap$KeySet.iterator
+ 311492 1 java/util/HashMap.keySet
+ 311492 1 java/util/HashMap.size
+ 311492 1 java/util/HashSet.<clinit>
+ 311492 1 java/util/HashSet.iterator
+ 311492 1 java/util/HashSet.size
+ 311492 1 java/util/Hashtable$EmptyEnumerator.<init>
+ 311492 1 java/util/Hashtable$EmptyIterator.<init>
+ 311492 1 java/util/Hashtable.<clinit>
+ 311492 1 java/util/IdentityHashMap.<clinit>
+ 311492 1 java/util/IdentityHashMap.<init>
+ 311492 1 java/util/IdentityHashMap.access$000
+ 311492 1 java/util/IdentityHashMap.access$200
+ 311492 1 java/util/IdentityHashMap.init
+ 311492 1 java/util/IdentityHashMap.keySet
+ 311492 1 java/util/LinkedHashMap$LinkedHashIterator.hasNext
+ 311492 1 java/util/LinkedHashMap.newKeyIterator
+ 311492 1 java/util/LinkedHashSet.<init>
+ 311492 1 java/util/Locale.<clinit>
+ 311492 1 java/util/Locale.getInstance
+ 311492 1 java/util/Properties.<clinit>
+ 311492 1 java/util/StringTokenizer.countTokens
+ 311492 1 java/util/StringTokenizer.hasMoreTokens
+ 311492 1 java/util/Vector.contains
+ 311492 1 java/util/Vector.copyInto
+ 311492 1 java/util/Vector.indexOf
+ 311492 1 java/util/concurrent/ConcurrentHashMap$Segment.get
+ 311492 1 java/util/concurrent/ConcurrentHashMap$Segment.getFirst
+ 311492 1 java/util/concurrent/ConcurrentHashMap$Segment.newArray
+ 311492 1 java/util/concurrent/ConcurrentHashMap.get
+ 311492 1 java/util/concurrent/atomic/AtomicInteger.<clinit>
+ 311492 1 java/util/concurrent/atomic/AtomicInteger.<init>
+ 311492 1 java/util/concurrent/atomic/AtomicInteger.get
+ 311492 1 java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<clinit>
+ 311492 1 java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>
+ 311492 1 java/util/concurrent/atomic/AtomicReferenceFieldUpdater.<init>
+ 311492 1 java/util/concurrent/atomic/AtomicReferenceFieldUpdater.newUpdater
+ 311492 1 java/util/concurrent/locks/AbstractQueuedSynchronizer.<clinit>
+ 311492 1 java/util/concurrent/locks/AbstractQueuedSynchronizer.getState
+ 311492 1 java/util/jar/JarEntry.<init>
+ 311492 1 java/util/jar/JarFile$JarFileEntry.<init>
+ 311492 1 java/util/jar/JarFile.<clinit>
+ 311492 1 java/util/jar/JarFile.getManEntry
+ 311492 1 java/util/jar/JarFile.hasClassPathAttribute
+ 311492 1 java/util/jar/JarFile.isKnownToNotHaveClassPathAttribute
+ 311492 1 java/util/jar/JavaUtilJarAccessImpl.<init>
+ 311492 1 java/util/jar/JavaUtilJarAccessImpl.jarFileHasClassPathAttribute
+ 311492 1 java/util/zip/Inflater.<clinit>
+ 311492 1 java/util/zip/Inflater.<init>
+ 311492 1 java/util/zip/Inflater.finished
+ 311492 1 java/util/zip/Inflater.init
+ 311492 1 java/util/zip/Inflater.initIDs
+ 311492 1 java/util/zip/Inflater.needsDictionary
+ 311492 1 java/util/zip/Inflater.needsInput
+ 311492 1 java/util/zip/Inflater.setInput
+ 311492 1 java/util/zip/InflaterInputStream.<init>
+ 311492 1 java/util/zip/InflaterInputStream.ensureOpen
+ 311492 1 java/util/zip/InflaterInputStream.read
+ 311492 1 java/util/zip/ZipEntry.<clinit>
+ 311492 1 java/util/zip/ZipEntry.getSize
+ 311492 1 java/util/zip/ZipEntry.initFields
+ 311492 1 java/util/zip/ZipEntry.initIDs
+ 311492 1 java/util/zip/ZipFile$1.<init>
+ 311492 1 java/util/zip/ZipFile$1.close
+ 311492 1 java/util/zip/ZipFile$1.fill
+ 311492 1 java/util/zip/ZipFile$ZipFileInputStream.<init>
+ 311492 1 java/util/zip/ZipFile$ZipFileInputStream.read
+ 311492 1 java/util/zip/ZipFile.<clinit>
+ 311492 1 java/util/zip/ZipFile.<init>
+ 311492 1 java/util/zip/ZipFile.access$000
+ 311492 1 java/util/zip/ZipFile.access$1000
+ 311492 1 java/util/zip/ZipFile.access$1100
+ 311492 1 java/util/zip/ZipFile.access$1200
+ 311492 1 java/util/zip/ZipFile.access$800
+ 311492 1 java/util/zip/ZipFile.access$900
+ 311492 1 java/util/zip/ZipFile.ensureOpenOrZipException
+ 311492 1 java/util/zip/ZipFile.getCSize
+ 311492 1 java/util/zip/ZipFile.getInflater
+ 311492 1 java/util/zip/ZipFile.getMethod
+ 311492 1 java/util/zip/ZipFile.getTotal
+ 311492 1 java/util/zip/ZipFile.initIDs
+ 311492 1 java/util/zip/ZipFile.open
+ 311492 1 java/util/zip/ZipFile.read
+ 311492 1 java/util/zip/ZipFile.releaseInflater
+ 311492 1 sun/misc/ExtensionDependency.checkExtensionsDependencies
+ 311492 1 sun/misc/FileURLMapper.<init>
+ 311492 1 sun/misc/FileURLMapper.exists
+ 311492 1 sun/misc/JarIndex.getJarIndex
+ 311492 1 sun/misc/Launcher$AppClassLoader$1.<init>
+ 311492 1 sun/misc/Launcher$AppClassLoader$1.run
+ 311492 1 sun/misc/Launcher$AppClassLoader.<clinit>
+ 311492 1 sun/misc/Launcher$AppClassLoader.<init>
+ 311492 1 sun/misc/Launcher$AppClassLoader.getAppClassLoader
+ 311492 1 sun/misc/Launcher$AppClassLoader.getPermissions
+ 311492 1 sun/misc/Launcher$ExtClassLoader$1.<init>
+ 311492 1 sun/misc/Launcher$ExtClassLoader$1.run
+ 311492 1 sun/misc/Launcher$ExtClassLoader.<init>
+ 311492 1 sun/misc/Launcher$ExtClassLoader.getExtClassLoader
+ 311492 1 sun/misc/Launcher$ExtClassLoader.getExtDirs
+ 311492 1 sun/misc/Launcher$ExtClassLoader.getExtURLs
+ 311492 1 sun/misc/Launcher$Factory.<clinit>
+ 311492 1 sun/misc/Launcher.<clinit>
+ 311492 1 sun/misc/Launcher.<init>
+ 311492 1 sun/misc/Launcher.access$200
+ 311492 1 sun/misc/Launcher.access$300
+ 311492 1 sun/misc/Launcher.getClassPath
+ 311492 1 sun/misc/Launcher.getLauncher
+ 311492 1 sun/misc/Launcher.pathToURLs
+ 311492 1 sun/misc/MetaIndex.<clinit>
+ 311492 1 sun/misc/Resource.<init>
+ 311492 1 sun/misc/Resource.getByteBuffer
+ 311492 1 sun/misc/Resource.getBytes
+ 311492 1 sun/misc/Resource.getCodeSigners
+ 311492 1 sun/misc/SharedSecrets.<clinit>
+ 311492 1 sun/misc/SharedSecrets.getJavaIOAccess
+ 311492 1 sun/misc/SharedSecrets.getJavaIODeleteOnExitAccess
+ 311492 1 sun/misc/SharedSecrets.javaUtilJarAccess
+ 311492 1 sun/misc/SharedSecrets.setJavaIOAccess
+ 311492 1 sun/misc/SharedSecrets.setJavaIODeleteOnExitAccess
+ 311492 1 sun/misc/SharedSecrets.setJavaLangAccess
+ 311492 1 sun/misc/SharedSecrets.setJavaNetAccess
+ 311492 1 sun/misc/SharedSecrets.setJavaUtilJarAccess
+ 311492 1 sun/misc/Signal.<clinit>
+ 311492 1 sun/misc/SignalHandler.<clinit>
+ 311492 1 sun/misc/SoftCache.<init>
+ 311492 1 sun/misc/URLClassPath$FileLoader$1.<init>
+ 311492 1 sun/misc/URLClassPath$FileLoader$1.getCodeSourceURL
+ 311492 1 sun/misc/URLClassPath$FileLoader$1.getContentLength
+ 311492 1 sun/misc/URLClassPath$FileLoader$1.getInputStream
+ 311492 1 sun/misc/URLClassPath$FileLoader.<init>
+ 311492 1 sun/misc/URLClassPath$FileLoader.getResource
+ 311492 1 sun/misc/URLClassPath$JarLoader$1.<init>
+ 311492 1 sun/misc/URLClassPath$JarLoader$1.run
+ 311492 1 sun/misc/URLClassPath$JarLoader.access$502
+ 311492 1 sun/misc/URLClassPath$JarLoader.access$600
+ 311492 1 sun/misc/URLClassPath$JarLoader.access$702
+ 311492 1 sun/misc/URLClassPath$JarLoader.getJarFile
+ 311492 1 sun/misc/URLClassPath$JarLoader.parseExtensionsDependencies
+ 311492 1 sun/misc/URLClassPath$Loader.getClassPath
+ 311492 1 sun/misc/URLClassPath.<clinit>
+ 311492 1 sun/misc/URLClassPath.access$300
+ 311492 1 sun/misc/Unsafe.<clinit>
+ 311492 1 sun/misc/Unsafe.<init>
+ 311492 1 sun/misc/Unsafe.allocateMemory
+ 311492 1 sun/misc/Unsafe.ensureClassInitialized
+ 311492 1 sun/misc/Unsafe.freeMemory
+ 311492 1 sun/misc/Unsafe.getByte
+ 311492 1 sun/misc/Unsafe.putLong
+ 311492 1 sun/misc/Unsafe.registerNatives
+ 311492 1 sun/misc/VM.<clinit>
+ 311492 1 sun/misc/VM.booted
+ 311492 1 sun/misc/VM.initialize
+ 311492 1 sun/misc/VM.initializeOSEnvironment
+ 311492 1 sun/misc/Version.<clinit>
+ 311492 1 sun/net/www/MessageHeader.<init>
+ 311492 1 sun/net/www/MessageHeader.grow
+ 311492 1 sun/net/www/ParseUtil.<clinit>
+ 311492 1 sun/net/www/URLConnection.<init>
+ 311492 1 sun/net/www/protocol/file/FileURLConnection.<clinit>
+ 311492 1 sun/net/www/protocol/file/FileURLConnection.<init>
+ 311492 1 sun/net/www/protocol/file/FileURLConnection.getPermission
+ 311492 1 sun/net/www/protocol/file/Handler.<init>
+ 311492 1 sun/net/www/protocol/file/Handler.createFileURLConnection
+ 311492 1 sun/nio/cs/FastCharsetProvider.<init>
+ 311492 1 sun/nio/cs/StandardCharsets$Aliases.init
+ 311492 1 sun/nio/cs/StandardCharsets$Cache.init
+ 311492 1 sun/nio/cs/StandardCharsets$Classes.init
+ 311492 1 sun/nio/cs/StandardCharsets.<clinit>
+ 311492 1 sun/nio/cs/StandardCharsets.<init>
+ 311492 1 sun/nio/cs/StreamDecoder.<clinit>
+ 311492 1 sun/nio/cs/StreamDecoder.close
+ 311492 1 sun/nio/cs/StreamDecoder.forInputStreamReader
+ 311492 1 sun/nio/cs/StreamDecoder.implClose
+ 311492 1 sun/nio/cs/StreamDecoder.inReady
+ 311492 1 sun/nio/cs/StreamEncoder.<clinit>
+ 311492 1 sun/nio/cs/Surrogate$Parser.<clinit>
+ 311492 1 sun/nio/cs/US_ASCII$Decoder.<clinit>
+ 311492 1 sun/nio/cs/US_ASCII$Encoder.<clinit>
+ 311492 1 sun/nio/cs/US_ASCII.<init>
+ 311492 1 sun/reflect/Reflection.<clinit>
+ 311492 1 sun/reflect/ReflectionFactory$1.<init>
+ 311492 1 sun/reflect/ReflectionFactory$1.run
+ 311492 1 sun/reflect/ReflectionFactory.<clinit>
+ 311492 1 sun/reflect/ReflectionFactory.<init>
+ 311492 1 sun/reflect/ReflectionFactory.access$202
+ 311492 1 sun/reflect/ReflectionFactory.setLangReflectAccess
+ 311492 1 sun/reflect/misc/ReflectUtil.ensureMemberAccess
+ 311492 1 sun/security/provider/PolicyFile.<clinit>
+ 311492 1 sun/security/util/Debug.<clinit>
+ 311492 2 java/io/BufferedInputStream.<init>
+ 311492 2 java/io/BufferedOutputStream.<init>
+ 311492 2 java/io/BufferedReader.<init>
+ 311492 2 java/io/BufferedReader.fill
+ 311492 2 java/io/ExpiringCache$1.<init>
+ 311492 2 java/io/File.list
+ 311492 2 java/io/FileInputStream.close
+ 311492 2 java/io/FileInputStream.close0
+ 311492 2 java/io/FileInputStream.open
+ 311492 2 java/io/FileOutputStream.<init>
+ 311492 2 java/io/FilePermission$1.<init>
+ 311492 2 java/io/FilePermission.<init>
+ 311492 2 java/io/FilePermission.getMask
+ 311492 2 java/io/FilePermission.init
+ 311492 2 java/io/FileSystem.getBooleanProperty
+ 311492 2 java/io/InputStreamReader.read
+ 311492 2 java/io/OutputStreamWriter.<init>
+ 311492 2 java/io/PrintStream.init
+ 311492 2 java/io/UnixFileSystem.list
+ 311492 2 java/lang/Character.charCount
+ 311492 2 java/lang/CharacterDataLatin1.toUpperCase
+ 311492 2 java/lang/Class$1.<init>
+ 311492 2 java/lang/Class$1.run
+ 311492 2 java/lang/Class.arrayContentsEq
+ 311492 2 java/lang/Class.getConstructor0
+ 311492 2 java/lang/Class.getDeclaredConstructors0
+ 311492 2 java/lang/Class.isInterface
+ 311492 2 java/lang/Class.privateGetDeclaredConstructors
+ 311492 2 java/lang/ClassLoader.<init>
+ 311492 2 java/lang/ClassLoader.initializePath
+ 311492 2 java/lang/ClassNotFoundException.<init>
+ 311492 2 java/lang/Object.clone
+ 311492 2 java/lang/Runtime.getRuntime
+ 311492 2 java/lang/String$CaseInsensitiveComparator.<init>
+ 311492 2 java/lang/String.concat
+ 311492 2 java/lang/String.regionMatches
+ 311492 2 java/lang/StringCoding$StringDecoder.<init>
+ 311492 2 java/lang/System.getProperties
+ 311492 2 java/lang/System.nullPrintStream
+ 311492 2 java/lang/System.setProperties
+ 311492 2 java/lang/Thread.isAlive
+ 311492 2 java/lang/Thread.setDaemon
+ 311492 2 java/lang/Thread.start
+ 311492 2 java/lang/Thread.start0
+ 311492 2 java/lang/ThreadGroup.<init>
+ 311492 2 java/lang/ref/Reference$Lock.<init>
+ 311492 2 java/lang/ref/Reference.access$100
+ 311492 2 java/lang/ref/ReferenceQueue.remove
+ 311492 2 java/lang/ref/SoftReference.get
+ 311492 2 java/lang/reflect/AccessibleObject.setAccessible
+ 311492 2 java/lang/reflect/AccessibleObject.setAccessible0
+ 311492 2 java/lang/reflect/Constructor.<init>
+ 311492 2 java/lang/reflect/Constructor.acquireConstructorAccessor
+ 311492 2 java/lang/reflect/Constructor.copy
+ 311492 2 java/lang/reflect/Constructor.getParameterTypes
+ 311492 2 java/lang/reflect/Modifier.isAbstract
+ 311492 2 java/lang/reflect/Modifier.isProtected
+ 311492 2 java/lang/reflect/ReflectAccess.copyConstructor
+ 311492 2 java/net/URL.set
+ 311492 2 java/net/URLClassLoader$1.<init>
+ 311492 2 java/net/URLClassLoader$1.run
+ 311492 2 java/net/URLClassLoader.<init>
+ 311492 2 java/net/URLClassLoader.findClass
+ 311492 2 java/net/URLStreamHandler.parseURL
+ 311492 2 java/net/URLStreamHandler.setURL
+ 311492 2 java/nio/ByteOrder.<init>
+ 311492 2 java/nio/CharBuffer.allocate
+ 311492 2 java/nio/HeapByteBuffer.compact
+ 311492 2 java/nio/charset/Charset.cache
+ 311492 2 java/nio/charset/CharsetDecoder.reset
+ 311492 2 java/nio/charset/CharsetEncoder.isLegalReplacement
+ 311492 2 java/nio/charset/CharsetEncoder.onMalformedInput
+ 311492 2 java/nio/charset/CharsetEncoder.onUnmappableCharacter
+ 311492 2 java/nio/charset/CharsetEncoder.replaceWith
+ 311492 2 java/nio/charset/CoderResult.<init>
+ 311492 2 java/nio/charset/CoderResult.isError
+ 311492 2 java/security/AccessControlContext.<init>
+ 311492 2 java/security/BasicPermission.getCanonicalName
+ 311492 2 java/security/CodeSource.getCertificates
+ 311492 2 java/security/CodeSource.hashCode
+ 311492 2 java/security/PermissionCollection.setReadOnly
+ 311492 2 java/security/Permissions.<init>
+ 311492 2 java/security/Permissions.add
+ 311492 2 java/security/Permissions.getPermissionCollection
+ 311492 2 java/security/SecureClassLoader.<init>
+ 311492 2 java/util/AbstractList.iterator
+ 311492 2 java/util/BitSet.ensureCapacity
+ 311492 2 java/util/Collections$EmptyList.<init>
+ 311492 2 java/util/Collections$EmptyMap.<init>
+ 311492 2 java/util/Collections$EmptySet.<init>
+ 311492 2 java/util/Collections$ReverseComparator.<init>
+ 311492 2 java/util/HashMap$KeySet.<init>
+ 311492 2 java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+ 311492 2 java/util/IdentityHashMap$KeySet.<init>
+ 311492 2 java/util/IdentityHashMap$KeySet.iterator
+ 311492 2 java/util/LinkedHashMap$KeyIterator.<init>
+ 311492 2 java/util/LinkedHashMap$LinkedHashIterator.<init>
+ 311492 2 java/util/Properties.<init>
+ 311492 2 java/util/StringTokenizer.setMaxDelimCodePoint
+ 311492 2 java/util/concurrent/ConcurrentHashMap.<init>
+ 311492 2 java/util/jar/JarFile.<init>
+ 311492 2 java/util/zip/Inflater.inflate
+ 311492 2 java/util/zip/Inflater.inflateBytes
+ 311492 2 java/util/zip/ZipEntry.<init>
+ 311492 2 java/util/zip/ZipFile$ZipFileInputStream.close
+ 311492 2 java/util/zip/ZipFile.freeEntry
+ 311492 2 java/util/zip/ZipFile.getInputStream
+ 311492 2 java/util/zip/ZipFile.getSize
+ 311492 2 sun/misc/FileURLMapper.getPath
+ 311492 2 sun/misc/Launcher$Factory.<init>
+ 311492 2 sun/misc/Launcher$Factory.createURLStreamHandler
+ 311492 2 sun/misc/Launcher.access$100
+ 311492 2 sun/misc/MetaIndex.registerDirectory
+ 311492 2 sun/misc/NativeSignalHandler.<init>
+ 311492 2 sun/misc/Resource.cachedInputStream
+ 311492 2 sun/misc/URLClassPath.<init>
+ 311492 2 sun/misc/URLClassPath.getResource
+ 311492 2 sun/misc/URLClassPath.push
+ 311492 2 sun/misc/VM.maxDirectMemory
+ 311492 2 sun/misc/Version.init
+ 311492 2 sun/net/www/protocol/file/Handler.openConnection
+ 311492 2 sun/net/www/protocol/file/Handler.parseURL
+ 311492 2 sun/net/www/protocol/jar/Handler.<init>
+ 311492 2 sun/nio/cs/FastCharsetProvider.charsetForName
+ 311492 2 sun/nio/cs/FastCharsetProvider.lookup
+ 311492 2 sun/nio/cs/FastCharsetProvider.toLower
+ 311492 2 sun/nio/cs/StandardCharsets$Aliases.<init>
+ 311492 2 sun/nio/cs/StandardCharsets$Cache.<init>
+ 311492 2 sun/nio/cs/StandardCharsets$Classes.<init>
+ 311492 2 sun/nio/cs/StreamDecoder.<init>
+ 311492 2 sun/nio/cs/StreamDecoder.ensureOpen
+ 311492 2 sun/nio/cs/StreamDecoder.implRead
+ 311492 2 sun/nio/cs/StreamDecoder.read
+ 311492 2 sun/nio/cs/StreamDecoder.readBytes
+ 311492 2 sun/nio/cs/StreamEncoder.forOutputStreamWriter
+ 311492 2 sun/nio/cs/Surrogate$Parser.<init>
+ 311492 2 sun/nio/cs/US_ASCII.newEncoder
+ 311492 2 sun/reflect/DelegatingConstructorAccessorImpl.<init>
+ 311492 2 sun/reflect/DelegatingConstructorAccessorImpl.setDelegate
+ 311492 2 sun/reflect/NativeConstructorAccessorImpl.<init>
+ 311492 2 sun/reflect/NativeConstructorAccessorImpl.setParent
+ 311492 2 sun/reflect/Reflection.ensureMemberAccess
+ 311492 2 sun/reflect/Reflection.isSubclassOf
+ 311492 2 sun/reflect/Reflection.verifyMemberAccess
+ 311492 2 sun/reflect/ReflectionFactory.checkInitted
+ 311492 2 sun/reflect/ReflectionFactory.copyConstructor
+ 311492 2 sun/reflect/ReflectionFactory.newConstructorAccessor
+ 311492 2 sun/reflect/misc/ReflectUtil.checkPackageAccess
+ 311492 2 sun/security/provider/PolicyFile.canonPath
+ 311492 2 sun/util/PreHashedMap.put
+ 311492 3 java/io/BufferedWriter.newLine
+ 311492 3 java/io/FileInputStream.<init>
+ 311492 3 java/io/FileInputStream.read
+ 311492 3 java/io/FileInputStream.readBytes
+ 311492 3 java/io/FilterInputStream.<init>
+ 311492 3 java/io/PrintStream.newLine
+ 311492 3 java/io/PrintStream.print
+ 311492 3 java/io/PrintStream.println
+ 311492 3 java/io/Reader.<init>
+ 311492 3 java/lang/Boolean.<init>
+ 311492 3 java/lang/Class$3.<init>
+ 311492 3 java/lang/Class$3.run
+ 311492 3 java/lang/Class.forName
+ 311492 3 java/lang/Class.forName0
+ 311492 3 java/lang/Class.newInstance
+ 311492 3 java/lang/Class.newInstance0
+ 311492 3 java/lang/Exception.<init>
+ 311492 3 java/lang/Integer.<init>
+ 311492 3 java/lang/Object.wait
+ 311492 3 java/lang/RuntimePermission.<init>
+ 311492 3 java/lang/Shutdown.add
+ 311492 3 java/lang/Thread.sleep
+ 311492 3 java/lang/ThreadLocal.<init>
+ 311492 3 java/lang/ThreadLocal.getMap
+ 311492 3 java/lang/ThreadLocal.nextHashCode
+ 311492 3 java/lang/ref/WeakReference.<init>
+ 311492 3 java/lang/reflect/Constructor.newInstance
+ 311492 3 java/net/URLStreamHandler.<init>
+ 311492 3 java/nio/ByteBuffer.allocate
+ 311492 3 java/nio/charset/Charset.defaultCharset
+ 311492 3 java/nio/charset/Charset.lookup2
+ 311492 3 java/nio/charset/CharsetDecoder.maxCharsPerByte
+ 311492 3 java/nio/charset/CodingErrorAction.<init>
+ 311492 3 java/util/AbstractList$Itr.checkForComodification
+ 311492 3 java/util/AbstractList$Itr.next
+ 311492 3 java/util/ArrayList.clear
+ 311492 3 java/util/HashSet.<init>
+ 311492 3 java/util/Hashtable.rehash
+ 311492 3 java/util/LinkedHashMap.<init>
+ 311492 3 java/util/LinkedHashMap.init
+ 311492 3 java/util/Stack.<init>
+ 311492 3 java/util/StringTokenizer.nextToken
+ 311492 3 java/util/concurrent/atomic/AtomicInteger.compareAndSet
+ 311492 3 java/util/concurrent/atomic/AtomicInteger.getAndAdd
+ 311492 3 java/util/jar/JarFile.getEntry
+ 311492 3 java/util/jar/JarFile.getJarEntry
+ 311492 3 java/util/zip/ZipFile.access$300
+ 311492 3 sun/misc/Signal.<init>
+ 311492 3 sun/misc/Signal.findSignal
+ 311492 3 sun/misc/Signal.handle
+ 311492 3 sun/misc/Signal.handle0
+ 311492 3 sun/misc/URLClassPath$JarLoader.ensureOpen
+ 311492 3 sun/reflect/DelegatingConstructorAccessorImpl.newInstance
+ 311492 3 sun/reflect/NativeConstructorAccessorImpl.newInstance
+ 311492 3 sun/reflect/NativeConstructorAccessorImpl.newInstance0
+ 311492 3 sun/reflect/Reflection.getClassAccessFlags
+ 311492 3 sun/reflect/Reflection.quickCheckMemberAccess
+ 311492 3 sun/reflect/ReflectionFactory.inflationThreshold
+ 311492 3 sun/util/PreHashedMap.<init>
+ 311492 4 java/io/BufferedWriter.<init>
+ 311492 4 java/io/ExpiringCache$Entry.timestamp
+ 311492 4 java/io/ExpiringCache.<init>
+ 311492 4 java/io/File.compareTo
+ 311492 4 java/io/File.equals
+ 311492 4 java/io/FilePermission$1.run
+ 311492 4 java/io/FilterOutputStream.<init>
+ 311492 4 java/io/PrintStream.<init>
+ 311492 4 java/io/UnixFileSystem.compare
+ 311492 4 java/lang/Character.toUpperCase
+ 311492 4 java/lang/Class.getDeclaredFields0
+ 311492 4 java/lang/Number.<init>
+ 311492 4 java/lang/Shutdown$Lock.<init>
+ 311492 4 java/lang/String.compareTo
+ 311492 4 java/lang/ThreadGroup.getParent
+ 311492 4 java/lang/Throwable.<init>
+ 311492 4 java/lang/Throwable.fillInStackTrace
+ 311492 4 java/lang/ref/ReferenceQueue$Null.<init>
+ 311492 4 java/lang/ref/ReferenceQueue.<init>
+ 311492 4 java/lang/reflect/Array.newArray
+ 311492 4 java/lang/reflect/Array.newInstance
+ 311492 4 java/lang/reflect/Constructor.setConstructorAccessor
+ 311492 4 java/lang/reflect/Modifier.isPublic
+ 311492 4 java/nio/HeapByteBuffer.ix
+ 311492 4 java/nio/charset/Charset.forName
+ 311492 4 java/nio/charset/CharsetDecoder.onMalformedInput
+ 311492 4 java/nio/charset/CharsetDecoder.onUnmappableCharacter
+ 311492 4 java/nio/charset/CharsetDecoder.replaceWith
+ 311492 4 java/nio/charset/CharsetEncoder.<init>
+ 311492 4 java/nio/charset/CoderResult$Cache.<init>
+ 311492 4 java/security/BasicPermission.<init>
+ 311492 4 java/security/BasicPermission.init
+ 311492 4 java/util/AbstractList$Itr.<init>
+ 311492 4 java/util/ArrayList.toArray
+ 311492 4 java/util/Collections$SynchronizedMap.get
+ 311492 4 java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+ 311492 4 java/util/IdentityHashMap$KeyIterator.<init>
+ 311492 4 java/util/LinkedHashMap$Entry.recordAccess
+ 311492 4 java/util/StringTokenizer.<init>
+ 311492 4 java/util/zip/ZipFile.ensureOpen
+ 311492 4 sun/misc/MetaIndex.<init>
+ 311492 4 sun/misc/MetaIndex.mayContain
+ 311492 4 sun/nio/cs/FastCharsetProvider.canonicalize
+ 311492 4 sun/nio/cs/StreamEncoder.<init>
+ 311492 4 sun/nio/cs/US_ASCII$Encoder.<init>
+ 311492 4 sun/nio/cs/US_ASCII.newDecoder
+ 311492 4 sun/reflect/ConstructorAccessorImpl.<init>
+ 311492 4 sun/reflect/MagicAccessorImpl.<init>
+ 311492 4 sun/reflect/Reflection.filterFields
+ 311492 4 sun/reflect/ReflectionFactory$GetReflectionFactoryAction.<init>
+ 311492 4 sun/reflect/ReflectionFactory$GetReflectionFactoryAction.run
+ 311492 4 sun/reflect/ReflectionFactory.getReflectionFactory
+ 311492 4 sun/security/util/Debug.isOn
+ 311492 5 java/io/FileDescriptor.<init>
+ 311492 5 java/lang/Class.getModifiers
+ 311492 5 java/lang/Class.getName0
+ 311492 5 java/lang/String.valueOf
+ 311492 5 java/nio/ByteBuffer.wrap
+ 311492 5 java/nio/charset/Charset.isSupported
+ 311492 5 java/security/PermissionCollection.<init>
+ 311492 5 java/util/AbstractList$Itr.hasNext
+ 311492 5 java/util/Hashtable.remove
+ 311492 5 java/util/StringTokenizer.scanToken
+ 311492 5 java/util/StringTokenizer.skipDelimiters
+ 311492 5 sun/misc/MetaIndex.forJar
+ 311492 5 sun/misc/URLClassPath$JarLoader.<init>
+ 311492 5 sun/misc/URLClassPath$JarLoader.getClassPath
+ 311492 5 sun/misc/URLClassPath$JarLoader.getResource
+ 311492 5 sun/misc/Unsafe.getUnsafe
+ 311492 5 sun/util/PreHashedMap.toV
+ 311492 6 java/io/BufferedOutputStream.write
+ 311492 6 java/io/BufferedWriter.flushBuffer
+ 311492 6 java/io/BufferedWriter.min
+ 311492 6 java/io/BufferedWriter.write
+ 311492 6 java/io/File.getAbsolutePath
+ 311492 6 java/io/FileOutputStream.write
+ 311492 6 java/io/FileOutputStream.writeBytes
+ 311492 6 java/io/OutputStream.<init>
+ 311492 6 java/io/OutputStreamWriter.flushBuffer
+ 311492 6 java/io/OutputStreamWriter.write
+ 311492 6 java/io/UnixFileSystem.canonicalize0
+ 311492 6 java/io/Writer.<init>
+ 311492 6 java/io/Writer.write
+ 311492 6 java/lang/Class.checkMemberAccess
+ 311492 6 java/lang/Class.getComponentType
+ 311492 6 java/lang/Class.getDeclaredField
+ 311492 6 java/lang/Class.getName
+ 311492 6 java/lang/Class.getSuperclass
+ 311492 6 java/lang/Class.privateGetDeclaredFields
+ 311492 6 java/lang/Class.searchFields
+ 311492 6 java/lang/ThreadGroup.add
+ 311492 6 java/lang/reflect/Field.<init>
+ 311492 6 java/lang/reflect/Field.copy
+ 311492 6 java/lang/reflect/ReflectAccess.copyField
+ 311492 6 java/net/URL.getURLStreamHandler
+ 311492 6 java/net/URL.toExternalForm
+ 311492 6 java/net/URL.toString
+ 311492 6 java/net/URLStreamHandler.getDefaultPort
+ 311492 6 java/net/URLStreamHandler.getHostAddress
+ 311492 6 java/net/URLStreamHandler.hashCode
+ 311492 6 java/net/URLStreamHandler.toExternalForm
+ 311492 6 java/nio/Bits.byteOrder
+ 311492 6 java/nio/Buffer.clear
+ 311492 6 java/nio/ByteBuffer.<init>
+ 311492 6 java/nio/HeapByteBuffer.<init>
+ 311492 6 java/nio/charset/CharsetDecoder.decode
+ 311492 6 java/nio/charset/CharsetEncoder.encode
+ 311492 6 java/security/Permission.<init>
+ 311492 6 java/util/AbstractSet.<init>
+ 311492 6 java/util/HashMap.containsKey
+ 311492 6 java/util/Vector.add
+ 311492 6 java/util/concurrent/ConcurrentHashMap$Segment.rehash
+ 311492 6 sun/misc/Launcher.getFileURL
+ 311492 6 sun/misc/MetaIndex.getJarMap
+ 311492 6 sun/misc/URLClassPath$3.<init>
+ 311492 6 sun/misc/URLClassPath$3.run
+ 311492 6 sun/misc/URLClassPath$JarLoader.isOptimizable
+ 311492 6 sun/misc/URLClassPath$Loader.<init>
+ 311492 6 sun/misc/Unsafe.objectFieldOffset
+ 311492 6 sun/net/www/ParseUtil.fileToEncodedURL
+ 311492 6 sun/nio/cs/StreamEncoder.ensureOpen
+ 311492 6 sun/nio/cs/StreamEncoder.flushBuffer
+ 311492 6 sun/nio/cs/StreamEncoder.implFlushBuffer
+ 311492 6 sun/nio/cs/StreamEncoder.implWrite
+ 311492 6 sun/nio/cs/StreamEncoder.write
+ 311492 6 sun/nio/cs/StreamEncoder.writeBytes
+ 311492 6 sun/nio/cs/US_ASCII$Decoder.decodeArrayLoop
+ 311492 6 sun/nio/cs/US_ASCII$Decoder.decodeLoop
+ 311492 6 sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+ 311492 6 sun/nio/cs/US_ASCII$Encoder.encodeLoop
+ 311492 6 sun/reflect/ReflectionFactory.copyField
+ 311492 7 java/io/File.getCanonicalFile
+ 311492 7 java/io/InputStream.<init>
+ 311492 7 java/lang/ClassLoader.checkPackageAccess
+ 311492 7 java/lang/ref/SoftReference.<init>
+ 311492 7 java/util/Dictionary.<init>
+ 311492 7 java/util/HashSet.add
+ 311492 7 java/util/Stack.empty
+ 311492 7 java/util/Stack.pop
+ 311492 7 java/util/Stack.push
+ 311492 7 java/util/Vector.removeElementAt
+ 311492 7 java/util/zip/ZipFile.getEntry
+ 311492 7 sun/util/PreHashedMap.get
+ 311492 8 java/lang/Class.checkInitted
+ 311492 8 java/lang/Class.clearCachesOnClassRedefinition
+ 311492 8 java/lang/Class.getPrimitiveClass
+ 311492 8 java/lang/Class.getReflectionFactory
+ 311492 8 java/lang/Object.getClass
+ 311492 8 java/lang/System.setProperty
+ 311492 8 java/lang/Thread.<init>
+ 311492 8 java/lang/Thread.getContextClassLoader
+ 311492 8 java/lang/Thread.init
+ 311492 8 java/lang/Thread.nextThreadID
+ 311492 8 java/lang/ThreadGroup.addUnstarted
+ 311492 8 java/lang/ref/FinalReference.<init>
+ 311492 8 java/lang/ref/Finalizer.<init>
+ 311492 8 java/lang/ref/Finalizer.add
+ 311492 8 java/lang/ref/Finalizer.register
+ 311492 8 java/lang/ref/ReferenceQueue$Lock.<init>
+ 311492 8 java/lang/reflect/AccessibleObject.<init>
+ 311492 8 java/nio/charset/CharsetDecoder.<init>
+ 311492 8 java/security/AccessControlContext.optimize
+ 311492 8 java/security/AccessController.getInheritedAccessControlContext
+ 311492 8 java/util/Properties.setProperty
+ 311492 8 java/util/Stack.peek
+ 311492 8 sun/nio/cs/US_ASCII$Decoder.<init>
+ 311492 8 sun/reflect/ReflectionFactory.langReflectAccess
+ 311492 8 sun/security/util/Debug.getInstance
+ 311492 9 java/io/BufferedOutputStream.flush
+ 311492 9 java/io/BufferedOutputStream.flushBuffer
+ 311492 9 java/io/File.hashCode
+ 311492 9 java/io/File.isDirectory
+ 311492 9 java/io/PrintStream.write
+ 311492 9 java/io/UnixFileSystem.hashCode
+ 311492 9 java/lang/ClassLoader.findBootstrapClass
+ 311492 9 java/lang/ClassLoader.findBootstrapClass0
+ 311492 9 java/lang/ClassLoader.getCallerClassLoader
+ 311492 9 java/lang/ClassLoader.loadClassInternal
+ 311492 9 java/lang/StringBuffer.<init>
+ 311492 9 java/lang/StringBuffer.toString
+ 311492 9 java/nio/Buffer.flip
+ 311492 9 java/util/ArrayList.RangeCheck
+ 311492 9 java/util/ArrayList.get
+ 311492 9 sun/misc/Launcher$AppClassLoader.loadClass
+ 311492 9 sun/net/www/ParseUtil.decode
+ 311492 9 sun/net/www/ParseUtil.lowMask
+ 311492 10 java/io/File.getCanonicalPath
+ 311492 10 java/io/ObjectStreamClass.getClassSignature
+ 311492 10 java/io/UnixFileSystem.canonicalize
+ 311492 10 java/lang/Class.isPrimitive
+ 311492 10 java/lang/Thread.setPriority
+ 311492 10 java/lang/Thread.setPriority0
+ 311492 10 java/nio/CharBuffer.wrap
+ 311492 10 java/nio/charset/Charset.lookup
+ 311492 10 java/security/AccessController.getContext
+ 311492 10 java/security/AccessController.getStackAccessControlContext
+ 311492 10 java/util/Vector.addElement
+ 311492 11 java/lang/String.replace
+ 311492 11 java/lang/ThreadGroup.checkAccess
+ 311492 11 java/net/Parts.<init>
+ 311492 11 java/nio/CharBuffer.<init>
+ 311492 11 java/nio/HeapCharBuffer.<init>
+ 311492 12 java/io/BufferedWriter.ensureOpen
+ 311492 12 java/io/ExpiringCache$1.removeEldestEntry
+ 311492 12 java/io/ExpiringCache$Entry.<init>
+ 311492 12 java/io/ExpiringCache.put
+ 311492 12 java/io/File.exists
+ 311492 12 java/io/PrintStream.ensureOpen
+ 311492 12 java/lang/Class.isArray
+ 311492 12 java/lang/Thread.checkAccess
+ 311492 12 java/nio/ByteBuffer.hasArray
+ 311492 12 java/nio/CharBuffer.array
+ 311492 12 java/nio/CharBuffer.hasArray
+ 311492 12 java/nio/charset/CoderResult.isOverflow
+ 311492 12 java/util/HashMap.get
+ 311492 12 java/util/LinkedHashMap$Entry.access$600
+ 311492 12 java/util/LinkedHashMap$Entry.addBefore
+ 311492 12 java/util/LinkedHashMap.addEntry
+ 311492 12 java/util/LinkedHashMap.createEntry
+ 311492 12 sun/net/www/ParseUtil.highMask
+ 311492 13 java/io/UnixFileSystem.parentOrNull
+ 311492 13 java/nio/Buffer.hasRemaining
+ 311492 13 java/nio/Buffer.remaining
+ 311492 13 sun/misc/URLClassPath.getLoader
+ 311492 13 sun/net/www/ParseUtil.encodePath
+ 311492 14 java/lang/Float.isNaN
+ 311492 14 java/net/URL.hashCode
+ 311492 14 java/util/Hashtable.<init>
+ 311492 15 java/lang/Object.hashCode
+ 311492 15 java/nio/charset/Charset.checkName
+ 311492 15 java/util/ArrayList.<init>
+ 311492 15 java/util/HashMap.addEntry
+ 311492 15 java/util/LinkedHashMap$Entry.<init>
+ 311492 16 java/io/UnixFileSystem.isAbsolute
+ 311492 16 java/lang/ClassLoader$NativeLibrary.find
+ 311492 16 java/lang/String.intern
+ 311492 16 java/util/Vector.ensureCapacityHelper
+ 311492 16 java/util/concurrent/ConcurrentHashMap$Segment.<init>
+ 311492 16 java/util/concurrent/ConcurrentHashMap$Segment.setTable
+ 311492 16 java/util/concurrent/locks/AbstractOwnableSynchronizer.<init>
+ 311492 16 java/util/concurrent/locks/AbstractQueuedSynchronizer.<init>
+ 311492 16 java/util/concurrent/locks/ReentrantLock$NonfairSync.<init>
+ 311492 16 java/util/concurrent/locks/ReentrantLock$Sync.<init>
+ 311492 16 java/util/concurrent/locks/ReentrantLock.<init>
+ 311492 16 sun/reflect/Reflection.getCallerClass
+ 311492 17 java/lang/ClassLoader.findNative
+ 311492 17 java/lang/Math.max
+ 311492 17 java/lang/String.toCharArray
+ 311492 17 java/nio/Buffer.<init>
+ 311492 17 java/util/Locale.getDefault
+ 311492 17 sun/security/action/GetPropertyAction.<init>
+ 311492 18 java/io/ExpiringCache.get
+ 311492 18 java/lang/Class.desiredAssertionStatus
+ 311492 18 java/lang/Class.desiredAssertionStatus0
+ 311492 18 java/lang/ClassLoader.findLoadedClass
+ 311492 18 java/lang/ClassLoader.findLoadedClass0
+ 311492 19 java/io/BufferedReader.ensureOpen
+ 311492 19 java/lang/System.currentTimeMillis
+ 311492 19 java/nio/Buffer.limit
+ 311492 19 java/util/Locale.<init>
+ 311492 19 java/util/Locale.createSingleton
+ 311492 19 java/util/concurrent/ConcurrentHashMap$Segment.put
+ 311492 19 java/util/concurrent/ConcurrentHashMap.put
+ 311492 19 java/util/concurrent/locks/AbstractQueuedSynchronizer.compareAndSetState
+ 311492 19 java/util/concurrent/locks/AbstractQueuedSynchronizer.release
+ 311492 19 java/util/concurrent/locks/AbstractQueuedSynchronizer.setState
+ 311492 19 java/util/concurrent/locks/ReentrantLock$NonfairSync.lock
+ 311492 19 java/util/concurrent/locks/ReentrantLock$Sync.tryRelease
+ 311492 19 java/util/concurrent/locks/ReentrantLock.lock
+ 311492 19 java/util/concurrent/locks/ReentrantLock.unlock
+ 311492 20 java/io/ObjectStreamField.<init>
+ 311492 20 java/nio/ByteBuffer.array
+ 311492 20 java/util/AbstractList.<init>
+ 311492 20 java/util/BitSet.get
+ 311492 20 java/util/concurrent/ConcurrentHashMap.hash
+ 311492 20 java/util/concurrent/ConcurrentHashMap.segmentFor
+ 311492 20 sun/misc/VM.isBooted
+ 311492 21 java/io/File.getName
+ 311492 21 java/io/UnixFileSystem.getBooleanAttributes
+ 311492 21 java/io/UnixFileSystem.getBooleanAttributes0
+ 311492 21 java/lang/StringBuffer.append
+ 311492 21 java/nio/charset/Charset.atBugLevel
+ 311492 22 java/util/concurrent/ConcurrentHashMap$HashEntry.newArray
+ 311492 22 sun/misc/Unsafe.compareAndSwapInt
+ 311492 23 java/util/HashMap.<init>
+ 311492 23 java/util/concurrent/ConcurrentHashMap$HashEntry.<init>
+ 311492 24 java/nio/charset/CoderResult.isUnderflow
+ 311492 24 java/util/AbstractMap.<init>
+ 311492 24 java/util/Vector.elementAt
+ 311492 25 java/lang/Class.getClassLoader
+ 311492 26 java/util/AbstractCollection.<init>
+ 311492 26 java/util/ArrayList.add
+ 311492 26 java/util/ArrayList.ensureCapacity
+ 311492 27 java/lang/ClassLoader.loadClass
+ 311492 27 java/net/URL.<init>
+ 311492 28 java/lang/ClassLoader.check
+ 311492 28 java/lang/ClassLoader.checkName
+ 311492 28 java/lang/ref/Reference.<init>
+ 311492 29 java/lang/String.endsWith
+ 311492 29 sun/misc/VM.allowArraySyntax
+ 311492 30 java/io/ExpiringCache.entryFor
+ 311492 30 java/io/UnixFileSystem.resolve
+ 311492 30 java/util/HashMap$Entry.<init>
+ 311492 30 java/util/LinkedHashMap.get
+ 311492 33 java/util/HashMap.put
+ 311492 33 java/util/Vector.<init>
+ 311492 34 java/io/UnixFileSystem.normalize
+ 311492 34 java/lang/Class.getClassLoader0
+ 311492 34 java/lang/String.toLowerCase
+ 311492 34 sun/security/action/GetPropertyAction.run
+ 311492 36 java/nio/CharBuffer.arrayOffset
+ 311492 36 java/util/HashMap.getEntry
+ 311492 37 java/io/File.<init>
+ 311492 37 java/io/UnixFileSystem.prefixLength
+ 311492 38 java/io/BufferedReader.readLine
+ 311492 38 java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread
+ 311492 41 java/lang/CharacterDataLatin1.toLowerCase
+ 311492 43 java/lang/CharacterDataLatin1.getProperties
+ 311492 43 java/security/AccessController.doPrivileged
+ 311492 43 java/util/Vector.size
+ 311492 44 java/nio/Buffer.position
+ 311492 44 java/nio/ByteBuffer.arrayOffset
+ 311492 48 java/lang/System.getProperty
+ 311492 50 java/util/Properties.getProperty
+ 311492 51 java/util/BitSet.expandTo
+ 311492 51 java/util/BitSet.set
+ 311492 56 java/lang/System.checkKey
+ 311492 57 java/lang/Thread.currentThread
+ 311492 57 java/util/Hashtable$Entry.<init>
+ 311492 59 java/util/Hashtable.get
+ 311492 63 java/util/Hashtable.put
+ 311492 71 java/util/BitSet.checkInvariants
+ 311492 72 java/util/BitSet.wordIndex
+ 311492 73 java/lang/StringBuilder.<init>
+ 311492 73 java/lang/StringBuilder.toString
+ 311492 81 java/lang/AbstractStringBuilder.expandCapacity
+ 311492 81 java/util/HashMap.hash
+ 311492 81 java/util/HashMap.indexFor
+ 311492 82 java/lang/AbstractStringBuilder.<init>
+ 311492 82 java/lang/Character.toLowerCase
+ 311492 83 java/lang/String.startsWith
+ 311492 87 java/util/Arrays.copyOf
+ 311492 90 java/lang/String.lastIndexOf
+ 311492 94 java/lang/String.substring
+ 311492 107 java/util/Arrays.copyOfRange
+ 311492 156 java/lang/String.getChars
+ 311492 174 java/lang/System.getSecurityManager
+ 311492 175 java/lang/String.<init>
+ 311492 202 java/lang/String.equals
+ 311492 208 java/lang/Math.min
+ 311492 213 java/lang/String.hashCode
+ 311492 302 java/lang/String.indexOf
+ 311492 360 java/lang/System.arraycopy
+ 311492 533 java/lang/StringBuilder.append
+ 311492 549 java/lang/AbstractStringBuilder.append
+ 311492 823 java/lang/Object.<init>
+ 311492 1960 java/lang/String.charAt
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_objnew_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_objnew_example.txt
new file mode 100644
index 0000000..433c38f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_objnew_example.txt
@@ -0,0 +1,1460 @@
+The following are examples of j_objnew.d.
+
+This traces activity of object allocation by Java. It will print a histogram
+of the byte size of allocation of different type, followed by a count of each
+type of allocation.
+
+Here you can see it running on Code/Java/Func_abc
+
+# j_objnew.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Java object allocation byte distributions by pid and class,
+
+ 311496 java/io/Console$1
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/io/DeleteOnExitHook
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/io/File$1
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/ApplicationShutdownHooks
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/Compiler$1
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/Runtime
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/String$CaseInsensitiveComparator
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/System$2
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/Terminator$1
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/ref/Reference$Lock
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/lang/reflect/ReflectAccess
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/net/URLClassLoader$7
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/net/UnknownContentHandler
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/util/Collections$EmptySet
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/util/Collections$ReverseComparator
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/util/Hashtable$EmptyEnumerator
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/util/Hashtable$EmptyIterator
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 java/util/jar/JavaUtilJarAccessImpl
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 sun/misc/Launcher$Factory
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 sun/misc/Unsafe
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 sun/net/www/protocol/file/Handler
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 sun/reflect/ReflectionFactory
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 sun/reflect/ReflectionFactory$1
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ 311496 [Ljava/lang/StackTraceElement;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 [Ljava/security/Principal;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 [Ljava/security/cert/Certificate;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/io/Console$1$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/io/FilePermissionCollection
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/io/FileReader
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/io/UnixFileSystem
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/ArithmeticException
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/ClassLoader$3
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/NoSuchMethodError
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/NullPointerException
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/Shutdown$Lock
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+
+ 311496 java/lang/StringCoding$StringDecoder
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/SystemClassLoaderAction
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/ThreadLocal$ThreadLocalMap
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/VirtualMachineError
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/reflect/ReflectPermission
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/nio/charset/CoderResult$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/nio/charset/CoderResult$2
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/security/BasicPermissionCollection
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/security/Policy$UnsupportedEmptyCollection
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/BitSet
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/Collections$EmptyList
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/Collections$EmptyMap
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/HashMap$KeySet
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/IdentityHashMap$KeySet
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/LinkedHashSet
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/util/concurrent/atomic/AtomicInteger
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/FileURLMapper
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/Launcher
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/Launcher$AppClassLoader$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/Launcher$ExtClassLoader$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/URLClassPath$FileLoader
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/misc/URLClassPath$JarLoader$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/net/www/MessageHeader
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/net/www/protocol/jar/Handler
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+
+ 311496 sun/nio/cs/StandardCharsets
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 sun/nio/cs/US_ASCII
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ 311496 java/lang/Class$3
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 16 | 0
+
+ 311496 [J
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 [Ljava/io/File;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 [Ljava/lang/OutOfMemoryError;
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 [Ljava/lang/ThreadGroup;
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 [Ljava/lang/reflect/Constructor;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/io/BufferedInputStream
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/io/BufferedOutputStream
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/io/BufferedReader
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/io/DataInputStream
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/io/FileOutputStream
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/io/FilePermission$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/io/OutputStreamWriter
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/lang/Class$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/lang/ClassLoader$NativeLibrary
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/lang/ThreadLocal$ThreadLocalMap$Entry
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/lang/ref/ReferenceQueue
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/lang/ref/ReferenceQueue$Lock
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 | 0
+
+ 311496 java/lang/ref/ReferenceQueue$Null
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/lang/ref/WeakReference
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/net/URLClassLoader$1
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/nio/ByteOrder
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/nio/charset/CoderResult
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/security/CodeSource
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/security/Permissions
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/security/PrivilegedActionException
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/security/ProtectionDomain
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/AbstractList$Itr
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/util/Collections$SynchronizedMap
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/HashSet
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 java/util/IdentityHashMap
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/LinkedHashMap
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/LinkedHashMap$KeyIterator
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/Properties
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/concurrent/ConcurrentHashMap
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/jar/JarFile
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/zip/Inflater
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/zip/ZipFile$1
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/util/zip/ZipFile$ZipFileInputStream
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/misc/NativeSignalHandler
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 sun/misc/SoftCache
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/misc/URLClassPath$FileLoader$1
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/nio/cs/StandardCharsets$Aliases
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/nio/cs/StandardCharsets$Cache
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/nio/cs/StandardCharsets$Classes
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/nio/cs/StreamDecoder
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 sun/nio/cs/Surrogate$Parser
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 sun/reflect/DelegatingConstructorAccessorImpl
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 sun/reflect/NativeConstructorAccessorImpl
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ 311496 sun/reflect/ReflectionFactory$GetReflectionFactoryAction
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 | 0
+
+ 311496 [Ljava/net/URL;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ 311496 java/io/FileInputStream
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/lang/Boolean
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/lang/Integer
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/lang/RuntimePermission
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/lang/ThreadLocal
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/nio/charset/CodingErrorAction
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 java/util/Stack
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 sun/misc/Signal
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ 311496 [Ljava/lang/Thread;
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 [Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 [Ljava/lang/annotation/Annotation;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 32 | 0
+
+ 311496 [Ljava/util/concurrent/ConcurrentHashMap$Segment;
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 java/io/BufferedWriter
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/io/ExpiringCache
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/io/ExpiringCache$1
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/io/FilePermission
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/io/PrintStream
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/lang/ClassNotFoundException
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/lang/ThreadGroup
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/lang/ref/Finalizer$FinalizerThread
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 java/lang/ref/Reference$ReferenceHandler
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 java/lang/reflect/Method
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 java/util/IdentityHashMap$KeyIterator
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/util/StringTokenizer
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/util/jar/JarFile$JarFileEntry
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 java/util/zip/ZipEntry
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 sun/misc/Launcher$AppClassLoader
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 sun/misc/Launcher$ExtClassLoader
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 sun/misc/MetaIndex
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 32 | 0
+
+ 311496 sun/misc/URLClassPath
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 sun/net/www/protocol/file/FileURLConnection
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 311496 sun/nio/cs/StreamEncoder
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 sun/nio/cs/US_ASCII$Encoder
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ 311496 java/io/FileDescriptor
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 32 | 0
+
+ 311496 sun/misc/URLClassPath$3
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 32 | 0
+
+ 311496 [Ljava/io/ObjectStreamField;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32 | 0
+
+ 311496 [Ljava/lang/reflect/Field;
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 64 | 0
+
+ 311496 java/lang/Object
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 16 | 0
+
+ 311496 java/lang/OutOfMemoryError
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32 | 0
+
+ 311496 java/util/ArrayList
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32 | 0
+
+ 311496 java/util/Vector
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32 | 0
+
+ 311496 sun/nio/cs/US_ASCII$Decoder
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 64 | 0
+
+ 311496 java/lang/StringBuffer
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 32 | 0
+
+ 311496 java/security/AccessControlContext
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 32 | 0
+
+ 311496 sun/misc/URLClassPath$JarLoader
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 64 | 0
+
+ 311496 java/net/Parts
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 32 | 0
+
+ 311496 [Ljava/lang/Class;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 32 | 0
+
+ 311496 java/io/ExpiringCache$Entry
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 32 | 0
+
+ 311496 java/nio/HeapByteBuffer
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 64 | 0
+
+ 311496 java/util/Hashtable
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 64 | 0
+
+ 311496 java/lang/ref/SoftReference
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 64 | 0
+
+ 311496 java/util/HashMap$Entry
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 32 | 0
+
+ 311496 java/lang/ref/Finalizer
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 64 | 0
+
+ 311496 java/lang/reflect/Constructor
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 128 | 0
+
+ 311496 java/util/concurrent/locks/ReentrantLock$NonfairSync
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 32 | 0
+
+ 311496 sun/security/action/GetPropertyAction
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 17
+ 32 | 0
+
+ 311496 java/io/ObjectStreamField
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 64 | 0
+
+ 311496 java/nio/HeapCharBuffer
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 64 | 0
+
+ 311496 java/util/concurrent/ConcurrentHashMap$HashEntry
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 23
+ 32 | 0
+
+ 311496 java/lang/Thread
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 128 | 0
+
+ 311496 java/net/URL
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 13
+ 64 | 0
+
+ 311496 java/util/HashMap
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 64 | 0
+
+ 311496 java/util/LinkedHashMap$Entry
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 64 | 0
+
+ 311496 [Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 32 |@@@@@@@ 4
+ 64 |@@@@ 2
+ 128 | 0
+
+ 311496 java/util/concurrent/ConcurrentHashMap$Segment
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 64 | 0
+
+ 311496 java/io/File
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 37
+ 32 | 0
+
+ 311496 java/util/Locale
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 19
+ 64 | 0
+
+ 311496 [Ljava/util/Hashtable$Entry;
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 64 |@@@@ 1
+ 128 |@@@@ 1
+ 256 |@@@@ 1
+ 512 | 0
+
+ 311496 java/util/Hashtable$Entry
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 57
+ 32 | 0
+
+ 311496 [Ljava/util/HashMap$Entry;
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 17
+ 128 | 0
+
+ 311496 java/lang/StringBuilder
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 73
+ 32 | 0
+
+ 311496 [Ljava/lang/String;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@ 26
+ 32 |@@@@@@@@@@@@@@@ 22
+ 64 |@@@@@@ 9
+ 128 | 0
+
+ 311496 java/lang/reflect/Field
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 37
+ 128 | 0
+
+ 311496 [Ljava/lang/Object;
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 296
+ 32 |@@ 18
+ 64 | 0
+ 128 |@ 10
+ 256 | 1
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 1
+ 8192 | 0
+
+ 311496 java/lang/String
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 931
+ 32 | 0
+
+ 311496 [S
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 161
+ 32 |@@@@@@@@@@@@@@@@ 189
+ 64 |@@@@@@@ 82
+ 128 |@@@ 38
+ 256 |@ 12
+ 512 | 4
+ 1024 | 0
+
+ 311496 [[I
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 270
+ 32 |@@@@@@@@@@ 129
+ 64 |@@@@@@ 85
+ 128 |@@@ 34
+ 256 |@@ 22
+ 512 | 1
+ 1024 | 0
+
+ 311496 java/lang/Class
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 395
+ 128 | 0
+
+ 311496 [I
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 | 3
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 276
+ 64 |@@@@@@@@@ 87
+ 128 | 3
+ 256 | 1
+ 512 | 1
+ 1024 | 1
+ 2048 | 0
+ 4096 | 1
+ 8192 | 0
+ 16384 | 1
+ 32768 | 0
+
+ 311496 [B
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@ 87
+ 32 |@@@@@@@@@@ 100
+ 64 |@@@@@@@@ 83
+ 128 |@@@@@@@ 71
+ 256 |@@@@@ 47
+ 512 |@ 14
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 4
+ 16384 | 0
+
+ 311496 [C
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@ 271
+ 32 |@@@@@@@@@@@@@@@@@@@@@ 573
+ 64 |@@@@@@ 150
+ 128 |@@@ 68
+ 256 | 8
+ 512 | 1
+ 1024 | 2
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 3
+ 32768 | 0
+
+Java object allocation count by pid and class,
+
+ PID OBJS CLASS
+ 311496 1 [J
+ 311496 1 [Ljava/lang/OutOfMemoryError;
+ 311496 1 [Ljava/lang/StackTraceElement;
+ 311496 1 [Ljava/lang/ThreadGroup;
+ 311496 1 [Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+ 311496 1 [Ljava/security/Principal;
+ 311496 1 [Ljava/security/cert/Certificate;
+ 311496 1 [Ljava/util/concurrent/ConcurrentHashMap$Segment;
+ 311496 1 java/io/BufferedInputStream
+ 311496 1 java/io/BufferedReader
+ 311496 1 java/io/Console$1
+ 311496 1 java/io/Console$1$1
+ 311496 1 java/io/DataInputStream
+ 311496 1 java/io/DeleteOnExitHook
+ 311496 1 java/io/File$1
+ 311496 1 java/io/FilePermissionCollection
+ 311496 1 java/io/FileReader
+ 311496 1 java/io/UnixFileSystem
+ 311496 1 java/lang/ApplicationShutdownHooks
+ 311496 1 java/lang/ArithmeticException
+ 311496 1 java/lang/ClassLoader$3
+ 311496 1 java/lang/ClassLoader$NativeLibrary
+ 311496 1 java/lang/Compiler$1
+ 311496 1 java/lang/NoSuchMethodError
+ 311496 1 java/lang/NullPointerException
+ 311496 1 java/lang/Runtime
+ 311496 1 java/lang/String$CaseInsensitiveComparator
+ 311496 1 java/lang/StringCoding$StringDecoder
+ 311496 1 java/lang/System$2
+ 311496 1 java/lang/SystemClassLoaderAction
+ 311496 1 java/lang/Terminator$1
+ 311496 1 java/lang/ThreadLocal$ThreadLocalMap
+ 311496 1 java/lang/ThreadLocal$ThreadLocalMap$Entry
+ 311496 1 java/lang/VirtualMachineError
+ 311496 1 java/lang/ref/Finalizer$FinalizerThread
+ 311496 1 java/lang/ref/Reference$Lock
+ 311496 1 java/lang/ref/Reference$ReferenceHandler
+ 311496 1 java/lang/reflect/Method
+ 311496 1 java/lang/reflect/ReflectAccess
+ 311496 1 java/lang/reflect/ReflectPermission
+ 311496 1 java/net/URLClassLoader$7
+ 311496 1 java/net/UnknownContentHandler
+ 311496 1 java/nio/charset/CoderResult$1
+ 311496 1 java/nio/charset/CoderResult$2
+ 311496 1 java/security/BasicPermissionCollection
+ 311496 1 java/security/CodeSource
+ 311496 1 java/security/Policy$UnsupportedEmptyCollection
+ 311496 1 java/security/PrivilegedActionException
+ 311496 1 java/security/ProtectionDomain
+ 311496 1 java/util/BitSet
+ 311496 1 java/util/Collections$EmptyList
+ 311496 1 java/util/Collections$EmptyMap
+ 311496 1 java/util/Collections$EmptySet
+ 311496 1 java/util/Collections$ReverseComparator
+ 311496 1 java/util/Collections$SynchronizedMap
+ 311496 1 java/util/HashMap$KeySet
+ 311496 1 java/util/Hashtable$EmptyEnumerator
+ 311496 1 java/util/Hashtable$EmptyIterator
+ 311496 1 java/util/IdentityHashMap
+ 311496 1 java/util/IdentityHashMap$KeySet
+ 311496 1 java/util/LinkedHashMap
+ 311496 1 java/util/LinkedHashMap$KeyIterator
+ 311496 1 java/util/LinkedHashSet
+ 311496 1 java/util/Properties
+ 311496 1 java/util/concurrent/ConcurrentHashMap
+ 311496 1 java/util/concurrent/atomic/AtomicInteger
+ 311496 1 java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
+ 311496 1 java/util/jar/JarFile
+ 311496 1 java/util/jar/JarFile$JarFileEntry
+ 311496 1 java/util/jar/JavaUtilJarAccessImpl
+ 311496 1 java/util/zip/Inflater
+ 311496 1 java/util/zip/ZipEntry
+ 311496 1 java/util/zip/ZipFile$1
+ 311496 1 java/util/zip/ZipFile$ZipFileInputStream
+ 311496 1 sun/misc/FileURLMapper
+ 311496 1 sun/misc/Launcher
+ 311496 1 sun/misc/Launcher$AppClassLoader
+ 311496 1 sun/misc/Launcher$AppClassLoader$1
+ 311496 1 sun/misc/Launcher$ExtClassLoader
+ 311496 1 sun/misc/Launcher$ExtClassLoader$1
+ 311496 1 sun/misc/Launcher$Factory
+ 311496 1 sun/misc/SoftCache
+ 311496 1 sun/misc/URLClassPath$FileLoader
+ 311496 1 sun/misc/URLClassPath$FileLoader$1
+ 311496 1 sun/misc/URLClassPath$JarLoader$1
+ 311496 1 sun/misc/Unsafe
+ 311496 1 sun/net/www/MessageHeader
+ 311496 1 sun/net/www/protocol/file/FileURLConnection
+ 311496 1 sun/net/www/protocol/file/Handler
+ 311496 1 sun/nio/cs/StandardCharsets
+ 311496 1 sun/nio/cs/StandardCharsets$Aliases
+ 311496 1 sun/nio/cs/StandardCharsets$Cache
+ 311496 1 sun/nio/cs/StandardCharsets$Classes
+ 311496 1 sun/nio/cs/StreamDecoder
+ 311496 1 sun/nio/cs/US_ASCII
+ 311496 1 sun/reflect/ReflectionFactory
+ 311496 1 sun/reflect/ReflectionFactory$1
+ 311496 2 [Ljava/io/File;
+ 311496 2 [Ljava/lang/Thread;
+ 311496 2 [Ljava/lang/reflect/Constructor;
+ 311496 2 [Ljava/net/URL;
+ 311496 2 java/io/BufferedOutputStream
+ 311496 2 java/io/BufferedWriter
+ 311496 2 java/io/ExpiringCache
+ 311496 2 java/io/ExpiringCache$1
+ 311496 2 java/io/FileOutputStream
+ 311496 2 java/io/FilePermission
+ 311496 2 java/io/FilePermission$1
+ 311496 2 java/io/OutputStreamWriter
+ 311496 2 java/io/PrintStream
+ 311496 2 java/lang/Class$1
+ 311496 2 java/lang/ClassNotFoundException
+ 311496 2 java/lang/Shutdown$Lock
+ 311496 2 java/lang/ThreadGroup
+ 311496 2 java/lang/ref/ReferenceQueue
+ 311496 2 java/lang/ref/ReferenceQueue$Null
+ 311496 2 java/lang/ref/WeakReference
+ 311496 2 java/net/URLClassLoader$1
+ 311496 2 java/nio/ByteOrder
+ 311496 2 java/nio/charset/CoderResult
+ 311496 2 java/security/Permissions
+ 311496 2 java/util/AbstractList$Itr
+ 311496 2 java/util/HashSet
+ 311496 2 java/util/IdentityHashMap$KeyIterator
+ 311496 2 java/util/StringTokenizer
+ 311496 2 sun/misc/NativeSignalHandler
+ 311496 2 sun/misc/URLClassPath
+ 311496 2 sun/net/www/protocol/jar/Handler
+ 311496 2 sun/nio/cs/StreamEncoder
+ 311496 2 sun/nio/cs/Surrogate$Parser
+ 311496 2 sun/nio/cs/US_ASCII$Encoder
+ 311496 2 sun/reflect/DelegatingConstructorAccessorImpl
+ 311496 2 sun/reflect/NativeConstructorAccessorImpl
+ 311496 3 java/io/FileInputStream
+ 311496 3 java/lang/Boolean
+ 311496 3 java/lang/Class$3
+ 311496 3 java/lang/Integer
+ 311496 3 java/lang/RuntimePermission
+ 311496 3 java/lang/ThreadLocal
+ 311496 3 java/nio/charset/CodingErrorAction
+ 311496 3 java/util/Stack
+ 311496 3 sun/misc/Signal
+ 311496 4 [Ljava/lang/annotation/Annotation;
+ 311496 4 [Ljava/lang/reflect/Field;
+ 311496 4 java/lang/ref/ReferenceQueue$Lock
+ 311496 4 java/lang/reflect/Constructor
+ 311496 4 sun/misc/MetaIndex
+ 311496 4 sun/nio/cs/US_ASCII$Decoder
+ 311496 4 sun/reflect/ReflectionFactory$GetReflectionFactoryAction
+ 311496 5 java/io/FileDescriptor
+ 311496 5 sun/misc/URLClassPath$JarLoader
+ 311496 6 java/lang/Thread
+ 311496 6 java/nio/HeapByteBuffer
+ 311496 6 java/util/Hashtable
+ 311496 6 sun/misc/URLClassPath$3
+ 311496 7 java/lang/ref/SoftReference
+ 311496 8 [Ljava/io/ObjectStreamField;
+ 311496 8 java/lang/OutOfMemoryError
+ 311496 8 java/lang/ref/Finalizer
+ 311496 8 java/util/ArrayList
+ 311496 8 java/util/Vector
+ 311496 9 java/lang/StringBuffer
+ 311496 10 [Ljava/util/Hashtable$Entry;
+ 311496 10 java/io/ObjectStreamField
+ 311496 10 java/security/AccessControlContext
+ 311496 11 java/net/Parts
+ 311496 11 java/nio/HeapCharBuffer
+ 311496 12 [Ljava/lang/Class;
+ 311496 12 java/io/ExpiringCache$Entry
+ 311496 13 java/net/URL
+ 311496 14 java/util/HashMap
+ 311496 15 java/util/HashMap$Entry
+ 311496 15 java/util/LinkedHashMap$Entry
+ 311496 16 java/lang/Object
+ 311496 16 java/util/concurrent/ConcurrentHashMap$Segment
+ 311496 16 java/util/concurrent/locks/ReentrantLock$NonfairSync
+ 311496 17 [Ljava/util/HashMap$Entry;
+ 311496 17 sun/security/action/GetPropertyAction
+ 311496 19 java/util/Locale
+ 311496 22 [Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
+ 311496 23 java/util/concurrent/ConcurrentHashMap$HashEntry
+ 311496 37 java/io/File
+ 311496 37 java/lang/reflect/Field
+ 311496 57 [Ljava/lang/String;
+ 311496 57 java/util/Hashtable$Entry
+ 311496 73 java/lang/StringBuilder
+ 311496 326 [Ljava/lang/Object;
+ 311496 374 [I
+ 311496 395 java/lang/Class
+ 311496 406 [B
+ 311496 486 [S
+ 311496 541 [[I
+ 311496 931 java/lang/String
+ 311496 1076 [C
+
+In the first section - Java object allocation byte distributions by PID and
+class, you can see in graphical form the range of sizes of each type of
+object. For example:
+
+ 311496 [C
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@ 271
+ 32 |@@@@@@@@@@@@@@@@@@@@@ 573
+ 64 |@@@@@@ 150
+ 128 |@@@ 68
+ 256 | 8
+ 512 | 1
+ 1024 | 2
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 3
+ 32768 | 0
+
+shows that there were 271 objects of type [C and size 16 bytes to 31 bytes
+created. It is important to pay close attention to the third column,
+"count" as this will indicate if there were any instances in a particular
+size, even if the number is too small to show up on the histogram scale.
+
+In the second section - Java object allocation count by pid and class, you can
+easily see that there were 395 objects of java/lang/Class created, and 931
+objects of java/lang/String.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_package_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_package_example.txt
new file mode 100644
index 0000000..0d4da29
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_package_example.txt
@@ -0,0 +1,44 @@
+The following are examples of j_package.d.
+
+This script will show you the number of times a class is loaded from
+particular packages.
+
+Here you can see it running when Code/Java/Func_abc runs.
+
+# j_package.d
+Tracing... Hit Ctrl-C to end.
+
+ PID LOADS PACKAGE
+ 311500 1 .
+ 311500 1 java/lang/annotation
+ 311500 1 java/nio/charset/spi
+ 311500 1 java/security/cert
+ 311500 1 sun/net/www/protocol/jar
+ 311500 1 sun/nio
+ 311500 1 sun/reflect/misc
+ 311500 1 sun/security/action
+ 311500 1 sun/security/provider
+ 311500 1 sun/security/util
+ 311500 1 sun/util
+ 311500 2 sun/net/www/protocol/file
+ 311500 3 java/util/concurrent/atomic
+ 311500 3 sun/net/www
+ 311500 4 java/util/concurrent
+ 311500 4 java/util/jar
+ 311500 7 java/nio
+ 311500 7 java/util/concurrent/locks
+ 311500 7 java/util/zip
+ 311500 8 java/nio/charset
+ 311500 10 java/net
+ 311500 12 java/lang/ref
+ 311500 12 java/lang/reflect
+ 311500 13 sun/nio/cs
+ 311500 18 sun/reflect
+ 311500 19 java/security
+ 311500 34 sun/misc
+ 311500 38 java/io
+ 311500 46 java/util
+ 311500 69 java/lang
+
+You can see that 69 classes from the java/lang package were loaded during the
+time this script was running.
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_profile_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_profile_example.txt
new file mode 100644
index 0000000..bb45c4b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_profile_example.txt
@@ -0,0 +1,209 @@
+The following are examples of j_profile.d.
+
+This script samples on-CPU stack traces and prints them with Java
+translations. With DTrace, as well as tracing events, you can also sample
+them. Each approach has its own advantages and disadvantages and you are
+encouraged to try both when investigating performance issues (especially
+tracing). Sampling is inaccurate and can miss events, yet is a quick and
+easy way to discover a certain set of performance issues involving on-CPU
+load.
+
+This script samples at 101 Hertz, printing out the 25 most frequently seen
+stack traces down to 10 lines deep. All of these values can be tweaked in
+the script.
+
+Here we run the script on Code/Java/Func_loop. The argument fed to the script
+is the PID of the Java program we wish to investigate. Here the raw output is
+show, then again after filtering using c++filt.
+
+# j_profile.d -p 1312
+Sampling 10-level stacks at 101 Hertz... Hit Ctrl-C to end.
+^C
+
+Top 25 most frequently sampled stacks,
+
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 30
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 31
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 32
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 33
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 41
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 72
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
+ libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
+ libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
+ libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 116
+
+
+The most frequent stacks had Func_loop.func_c() on CPU, with a stack trace
+showing func_b() and func_a() - as expected from the source to Func_loop.java.
+
+
+Now passing that output through c++filt to translate the compiled C++ symbols
+of the JVM.
+
+# j_profile.d -p 1312 -o out.j_profile
+# c++filt out.j_profile
+Sampling 10-level stacks at 101 Hertz... Hit Ctrl-C to end.
+
+Top 25 most frequently sampled stacks,
+
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 10
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 13
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 19
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 21
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 29
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 53
+
+ Func_loop.func_c()V
+ Func_loop.func_b()V
+ Func_loop.func_a()V
+ Func_loop.main([Ljava/lang/String;)V
+ StubRoutines (1)
+ libjvm.so`void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x1a3
+ libjvm.so`void os::os_exception_wrapper(void(*)(JavaValue*,methodHandle*,JavaCallArguments*,Thread*),JavaValue*,methodHandle*,JavaCallArguments*,Thread*)+0x27
+ libjvm.so`void JavaCalls::call(JavaValue*,methodHandle,JavaCallArguments*,Thread*)+0x2f
+ libjvm.so`void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*)+0x1df
+ libjvm.so`jni_CallStaticVoidMethod+0x15d
+ 74
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_stat_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_stat_example.txt
new file mode 100644
index 0000000..6c7e12e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_stat_example.txt
@@ -0,0 +1,33 @@
+The following are examples of running j_stat.d.
+
+j_stat.d shows you the number of events per second that have happened since
+the last line output. The default interval is 1 second, but you can specify
+other intervals as arguments to the script.
+
+This shows the j_stat.d script reflecting the Code/Ruby/Func_abc script.
+
+# j_stat.d
+TIME EXEC/s THREAD/s METHOD/s OBJNEW/s CLOAD/s EXCP/s GC/s
+2007 Sep 24 04:00:34 0 0 0 0 0 0 0
+2007 Sep 24 04:00:35 2 6 11660 5306 318 41 0
+2007 Sep 24 04:00:36 0 0 124 4 0 2 0
+2007 Sep 24 04:00:37 0 0 124 4 0 2 0
+2007 Sep 24 04:00:38 0 0 123 75 9 1 0
+2007 Sep 24 04:00:39 0 0 0 0 0 0 0
+2007 Sep 24 04:00:40 0 0 0 0 0 0 0
+^C
+
+Here we can see that at 2007 Sep 24 04:00:35 there were 2 Java programs
+executed, (this number will include those without Java provider support),
+there were 6 threads created, 11,660 methods called, 5306 new objects created,
+318 class loads, 41 exceptions raised and no garbage collects.
+
+The numbers are per second counts for the interval specified. The default
+interval is 1 second.
+
+If you see a count in "EXECS" but not in the other columns, then your Java
+software is probably not running with the DTrace hotspot provider.
+
+If you see counts in "CLOAD" but not in "METHODS", then you Java software
+probably isn't running with "+ExtendedDTraceProbes".
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_syscalls_example.txt
new file mode 100644
index 0000000..911d4b0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_syscalls_example.txt
@@ -0,0 +1,165 @@
+The following are examples of j_syscalls.d.
+
+This is a simple script to count executed Java methods and system calls.
+Here it traces an example program, Code/Java/Func_abc.
+
+# j_syscalls.d -c 'java -XX:+ExtendedDTraceProbes Func_abc'
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+ PID TYPE NAME COUNT
+ 311536 method Func_abc.func_a 1
+ 311536 method Func_abc.func_b 1
+ 311536 method Func_abc.func_c 1
+ 311536 method Func_abc.main 1
+ 311536 method java/io/BufferedInputStream.<clinit> 1
+ 311536 method java/io/BufferedReader.<clinit> 1
+ 311536 method java/io/BufferedReader.close 1
+ 311536 method java/io/BufferedWriter.<clinit> 1
+ 311536 method java/io/Console$1$1.<init> 1
+ 311536 method java/io/Console$1$1.run 1
+ 311536 method java/io/Console$1.<init> 1
+ 311536 method java/io/Console$1.consoleRestoreHook 1
+ 311536 method java/io/Console.<clinit> 1
+ 311536 method java/io/Console.access$600 1
+ 311536 method java/io/DataInputStream.<init> 1
+ 311536 method java/io/DataInputStream.readFully 1
+ 311536 method java/io/DeleteOnExitHook.<clinit> 1
+ 311536 method java/io/DeleteOnExitHook.<init> 1
+ 311536 method java/io/DeleteOnExitHook.hook 1
+ 311536 method java/io/DeleteOnExitHook.run 1
+[... 900 lines truncated ...]
+ 311536 method java/io/ExpiringCache.get 18
+ 311536 method java/lang/Class.desiredAssertionStatus 18
+ 311536 method java/lang/Class.desiredAssertionStatus0 18
+ 311536 method java/lang/ClassLoader.findLoadedClass 18
+ 311536 method java/lang/ClassLoader.findLoadedClass0 18
+ 311536 method java/io/BufferedReader.ensureOpen 19
+ 311536 method java/lang/System.currentTimeMillis 19
+ 311536 method java/nio/Buffer.limit 19
+ 311536 method java/util/Locale.<init> 19
+ 311536 method java/util/Locale.createSingleton 19
+ 311536 method java/util/concurrent/ConcurrentHashMap$Segment.put 19
+ 311536 method java/util/concurrent/ConcurrentHashMap.put 19
+ 311536 method java/util/concurrent/locks/AbstractQueuedSynchronizer.compareAndSetState 19
+ 311536 method java/util/concurrent/locks/AbstractQueuedSynchronizer.release 19
+ 311536 method java/util/concurrent/locks/AbstractQueuedSynchronizer.setState 19
+ 311536 method java/util/concurrent/locks/ReentrantLock$NonfairSync.lock 19
+ 311536 method java/util/concurrent/locks/ReentrantLock$Sync.tryRelease 19
+ 311536 method java/util/concurrent/locks/ReentrantLock.lock 19
+ 311536 method java/util/concurrent/locks/ReentrantLock.unlock 19
+ 311536 method java/io/ObjectStreamField.<init> 20
+ 311536 method java/nio/ByteBuffer.array 20
+ 311536 method java/util/AbstractList.<init> 20
+ 311536 method java/util/BitSet.get 20
+ 311536 method java/util/concurrent/ConcurrentHashMap.hash 20
+ 311536 method java/util/concurrent/ConcurrentHashMap.segmentFor 20
+ 311536 method sun/misc/VM.isBooted 20
+ 311536 syscall memcntl 20
+ 311536 method java/io/File.getName 21
+ 311536 method java/io/UnixFileSystem.getBooleanAttributes 21
+ 311536 method java/io/UnixFileSystem.getBooleanAttributes0 21
+ 311536 method java/lang/StringBuffer.append 21
+ 311536 method java/nio/charset/Charset.atBugLevel 21
+ 311536 method java/util/concurrent/ConcurrentHashMap$HashEntry.newArray 22
+ 311536 method sun/misc/Unsafe.compareAndSwapInt 22
+ 311536 method java/util/HashMap.<init> 23
+ 311536 method java/util/concurrent/ConcurrentHashMap$HashEntry.<init> 23
+ 311536 syscall stat64 23
+ 311536 method java/nio/charset/CoderResult.isUnderflow 24
+ 311536 method java/util/AbstractMap.<init> 24
+ 311536 method java/util/Vector.elementAt 24
+ 311536 syscall munmap 24
+ 311536 method java/lang/Class.getClassLoader 25
+ 311536 syscall lwp_sigmask 25
+ 311536 syscall sigaction 25
+ 311536 method java/util/AbstractCollection.<init> 26
+ 311536 method java/util/ArrayList.add 26
+ 311536 method java/util/ArrayList.ensureCapacity 26
+ 311536 method java/lang/ClassLoader.loadClass 27
+ 311536 method java/net/URL.<init> 27
+ 311536 method java/lang/ClassLoader.check 28
+ 311536 method java/lang/ClassLoader.checkName 28
+ 311536 method java/lang/ref/Reference.<init> 28
+ 311536 method java/lang/String.endsWith 29
+ 311536 method sun/misc/VM.allowArraySyntax 29
+ 311536 method java/io/ExpiringCache.entryFor 30
+ 311536 method java/io/UnixFileSystem.resolve 30
+ 311536 method java/util/HashMap$Entry.<init> 30
+ 311536 method java/util/LinkedHashMap.get 30
+ 311536 syscall priocntlsys 30
+ 311536 method java/util/HashMap.put 33
+ 311536 method java/util/Vector.<init> 33
+ 311536 method java/io/UnixFileSystem.normalize 34
+ 311536 method java/lang/Class.getClassLoader0 34
+ 311536 method java/lang/String.toLowerCase 34
+ 311536 method sun/security/action/GetPropertyAction.run 34
+ 311536 method java/nio/CharBuffer.arrayOffset 36
+ 311536 method java/util/HashMap.getEntry 36
+ 311536 method java/io/File.<init> 37
+ 311536 method java/io/UnixFileSystem.prefixLength 37
+ 311536 method java/io/BufferedReader.readLine 38
+ 311536 method java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread 38
+ 311536 syscall resolvepath 38
+ 311536 method java/lang/CharacterDataLatin1.toLowerCase 41
+ 311536 method java/lang/CharacterDataLatin1.getProperties 43
+ 311536 method java/security/AccessController.doPrivileged 43
+ 311536 method java/util/Vector.size 43
+ 311536 method java/nio/Buffer.position 44
+ 311536 method java/nio/ByteBuffer.arrayOffset 44
+ 311536 method java/lang/System.getProperty 48
+ 311536 method java/util/Properties.getProperty 50
+ 311536 method java/util/BitSet.expandTo 51
+ 311536 method java/util/BitSet.set 51
+ 311536 syscall pollsys 55
+ 311536 method java/lang/System.checkKey 56
+ 311536 method java/lang/Thread.currentThread 57
+ 311536 method java/util/Hashtable$Entry.<init> 57
+ 311536 method java/util/Hashtable.get 59
+ 311536 method java/util/Hashtable.put 63
+ 311536 method java/util/BitSet.checkInvariants 71
+ 311536 method java/util/BitSet.wordIndex 72
+ 311536 method java/lang/StringBuilder.<init> 73
+ 311536 method java/lang/StringBuilder.toString 73
+ 311536 method java/lang/AbstractStringBuilder.expandCapacity 81
+ 311536 method java/util/HashMap.hash 81
+ 311536 method java/util/HashMap.indexFor 81
+ 311536 method java/lang/AbstractStringBuilder.<init> 82
+ 311536 method java/lang/Character.toLowerCase 82
+ 311536 method java/lang/String.startsWith 83
+ 311536 method java/util/Arrays.copyOf 87
+ 311536 method java/lang/String.lastIndexOf 90
+ 311536 method java/lang/String.substring 94
+ 311536 syscall brk 102
+ 311536 syscall ioctl 103
+ 311536 method java/util/Arrays.copyOfRange 107
+ 311536 syscall mmap 127
+ 311536 syscall open 129
+ 311536 syscall close 133
+ 311536 method java/lang/String.getChars 156
+ 311536 method java/lang/System.getSecurityManager 174
+ 311536 method java/lang/String.<init> 175
+ 311536 syscall xstat 188
+ 311536 method java/lang/String.equals 202
+ 311536 method java/lang/Math.min 208
+ 311536 method java/lang/String.hashCode 213
+ 311536 syscall lwp_exit 291
+ 311536 method java/lang/String.indexOf 302
+ 311536 method java/lang/System.arraycopy 360
+ 311536 method java/lang/StringBuilder.append 545
+ 311536 method java/lang/AbstractStringBuilder.append 561
+ 311536 syscall llseek 664
+ 311536 syscall read 668
+ 311536 method java/lang/Object.<init> 823
+ 311536 method java/lang/String.charAt 1987
+
+While tracing there were numerous system calls made, including 668 reads()'s,
+and 664 llseek()'s. Many Java methods were also called, with 1987
+java/lang/String.charAt being the most of a particular kind.
+
+This script can provide an insight to how an application is interacting
+with the system, by providing both application method calls and
+system calls in the same output.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_syscolors_example.txt
new file mode 100644
index 0000000..3b130ee
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_syscolors_example.txt
@@ -0,0 +1,1550 @@
+The following are examples of j_syscolors.d.
+
+This is a simple script to trace the method flow of Java methods within a
+program, and the system calls made. It watches Java method entries and
+returns, and indents child * method calls. It renders the output in color
+("colour") using terminal escape sequences (which you can tweak by modifying
+the script).
+
+Here it traces the example program, Code/Java/Func_abc.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+The fields in the output are, in order; CPU-id, Process ID/Thread ID, Elapsed
+time from previous line to current line, Type of call (func/syscall) and name
+of Java method or syscall.
+
+If the flow appears to jump, check the TID column - the JVM may have switched
+to another thread.
+
+WARNING: Watch the first column carefully, it prints the CPU-id. If it changes,
+then it is very likely that the output has been shuffled. Changes in TID will
+appear to shuffle output, as we change from one thread depth to the next. See
+Docs/Notes/ALLjavaflow.txt for additional notes.
+
+# j_syscolors.d -c 'java -XX:+ExtendedDTraceProbes Func_abc'
+C PID/TID DELTA(us) TYPE -- NAME
+0 311542/1 2 syscall -> munmap
+0 311542/1 33 syscall <- munmap
+0 311542/1 52 syscall -> mmap
+0 311542/1 16 syscall <- mmap
+0 311542/1 34 syscall -> setcontext
+0 311542/1 7 syscall <- setcontext
+0 311542/1 7 syscall -> getrlimit
+0 311542/1 7 syscall <- getrlimit
+0 311542/1 7 syscall -> getpid
+0 311542/1 6 syscall <- getpid
+0 311542/1 58 syscall -> setcontext
+0 311542/1 6 syscall <- setcontext
+0 311542/1 975 syscall -> sysi86
+0 311542/1 9 syscall <- sysi86
+0 311542/1 134 syscall -> brk
+0 311542/1 8 syscall <- brk
+0 311542/1 7 syscall -> brk
+0 311542/1 10 syscall <- brk
+0 311542/1 47 syscall -> sysconfig
+0 311542/1 6 syscall <- sysconfig
+0 311542/1 36 syscall -> resolvepath
+0 311542/1 31 syscall <- resolvepath
+0 311542/1 9 syscall -> resolvepath
+0 311542/1 18 syscall <- resolvepath
+0 311542/1 85 syscall -> access
+0 311542/1 20 syscall <- access
+0 311542/1 8 syscall -> access
+0 311542/1 24 syscall <- access
+0 311542/1 115 syscall -> open
+0 311542/1 27 syscall <- open
+0 311542/1 14 syscall -> fstat64
+0 311542/1 7 syscall <- fstat64
+0 311542/1 11 syscall -> fstat64
+0 311542/1 6 syscall <- fstat64
+0 311542/1 22 syscall -> ioctl
+0 311542/1 7 syscall <- ioctl
+0 311542/1 11 syscall -> read
+0 311542/1 43 syscall <- read
+0 311542/1 39 syscall -> read
+0 311542/1 7 syscall <- read
+0 311542/1 10 syscall -> llseek
+0 311542/1 7 syscall <- llseek
+0 311542/1 8 syscall -> close
+0 311542/1 9 syscall <- close
+0 311542/1 12 syscall -> sysconfig
+0 311542/1 6 syscall <- sysconfig
+0 311542/1 7 syscall -> sysconfig
+0 311542/1 6 syscall <- sysconfig
+0 311542/1 6 syscall -> sysconfig
+0 311542/1 6 syscall <- sysconfig
+0 311542/1 11 syscall -> xstat
+0 311542/1 27 syscall <- xstat
+0 311542/1 19 syscall -> exece
+0 311542/1 684 syscall <- exece
+0 311542/1 3320 syscall -> mmap
+0 311542/1 22 syscall <- mmap
+0 311542/1 26 syscall -> resolvepath
+0 311542/1 52 syscall <- resolvepath
+0 311542/1 8 syscall -> resolvepath
+0 311542/1 25 syscall <- resolvepath
+0 311542/1 7 syscall -> sysconfig
+0 311542/1 6 syscall <- sysconfig
+0 311542/1 9 syscall -> xstat
+0 311542/1 18 syscall <- xstat
+0 311542/1 7 syscall -> open
+0 311542/1 18 syscall <- open
+0 311542/1 7 syscall -> fxstat
+0 311542/1 7 syscall <- fxstat
+0 311542/1 6 syscall -> mmap
+0 311542/1 11 syscall <- mmap
+0 311542/1 7 syscall -> close
+0 311542/1 10 syscall <- close
+0 311542/1 42 syscall -> xstat
+0 311542/1 27 syscall <- xstat
+0 311542/1 8 syscall -> xstat
+0 311542/1 19 syscall <- xstat
+0 311542/1 7 syscall -> xstat
+0 311542/1 25 syscall <- xstat
+[... 31000 lines truncated ...]
+0 311542/2 10 method <- java/util/HashSet.add
+0 311542/2 10 method <- java/lang/ClassLoader.checkPackageAccess
+0 311542/2 28 method -> java/lang/reflect/Method.getModifiers
+0 311542/2 14 method <- java/lang/reflect/Method.getModifiers
+0 311542/2 17 method -> Func_abc.main
+0 311542/2 14 method -> Func_abc.func_a
+0 311542/2 12 method -> java/lang/ClassLoader.checkPackageAccess
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 11 method -> java/util/HashSet.add
+0 311542/2 10 method -> java/util/HashMap.put
+0 311542/2 9 method -> java/lang/Object.hashCode
+0 311542/2 10 method <- java/lang/Object.hashCode
+0 311542/2 10 method -> java/util/HashMap.hash
+0 311542/2 10 method <- java/util/HashMap.hash
+0 311542/2 10 method -> java/util/HashMap.indexFor
+0 311542/2 10 method <- java/util/HashMap.indexFor
+0 311542/2 10 method <- java/util/HashMap.put
+0 311542/2 10 method <- java/util/HashSet.add
+0 311542/2 10 method <- java/lang/ClassLoader.checkPackageAccess
+0 311542/2 20 syscall -> brk
+0 311542/2 15 syscall <- brk
+0 311542/2 13 syscall -> brk
+0 311542/2 17 syscall <- brk
+0 311542/2 47 method -> java/lang/ClassLoader.loadClassInternal
+0 311542/2 12 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> sun/misc/Launcher$AppClassLoader.loadClass
+0 311542/2 10 method -> java/lang/String.lastIndexOf
+0 311542/2 10 method -> java/lang/String.lastIndexOf
+0 311542/2 11 method <- java/lang/String.lastIndexOf
+0 311542/2 10 method <- java/lang/String.lastIndexOf
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 10 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 9 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 11 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 10 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 10 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass0
+0 311542/2 12 method <- java/lang/ClassLoader.findLoadedClass0
+0 311542/2 10 method <- java/lang/ClassLoader.findLoadedClass
+0 311542/2 11 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 9 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 10 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 9 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass0
+0 311542/2 11 method <- java/lang/ClassLoader.findLoadedClass0
+0 311542/2 10 method <- java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.findBootstrapClass0
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 10 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 10 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 9 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findBootstrapClass
+0 311542/2 12 method <- java/lang/ClassLoader.findBootstrapClass
+0 311542/2 10 method <- java/lang/ClassLoader.findBootstrapClass0
+0 311542/2 11 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- sun/misc/Launcher$AppClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClassInternal
+0 311542/2 14 method -> java/lang/ClassLoader.checkPackageAccess
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 10 method -> java/util/HashSet.add
+0 311542/2 10 method -> java/util/HashMap.put
+0 311542/2 10 method -> java/lang/Object.hashCode
+0 311542/2 9 method <- java/lang/Object.hashCode
+0 311542/2 10 method -> java/util/HashMap.hash
+0 311542/2 10 method <- java/util/HashMap.hash
+0 311542/2 10 method -> java/util/HashMap.indexFor
+0 311542/2 10 method <- java/util/HashMap.indexFor
+0 311542/2 11 method <- java/util/HashMap.put
+0 311542/2 10 method <- java/util/HashSet.add
+0 311542/2 10 method <- java/lang/ClassLoader.checkPackageAccess
+0 311542/2 18 method -> java/io/PrintStream.println
+0 311542/2 13 method -> java/io/PrintStream.print
+0 311542/2 12 method -> java/io/PrintStream.write
+0 311542/2 12 method -> java/io/PrintStream.ensureOpen
+0 311542/2 13 method <- java/io/PrintStream.ensureOpen
+0 311542/2 15 method -> java/io/Writer.write
+0 311542/2 16 method -> java/io/BufferedWriter.write
+0 311542/2 13 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 12 method -> java/io/BufferedWriter.min
+0 311542/2 10 method <- java/io/BufferedWriter.min
+0 311542/2 13 method -> java/lang/String.getChars
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 11 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 10 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 13 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 13 method -> java/io/OutputStreamWriter.write
+0 311542/2 13 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 13 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 13 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 14 method -> java/nio/CharBuffer.wrap
+0 311542/2 11 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 13 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 14 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 13 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 13 method -> java/nio/CharBuffer.hasArray
+0 311542/2 10 method <- java/nio/CharBuffer.hasArray
+0 311542/2 14 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 10 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 13 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 56 method -> java/nio/CharBuffer.array
+0 311542/2 11 method <- java/nio/CharBuffer.array
+0 311542/2 12 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 13 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 16 method -> java/nio/ByteBuffer.array
+0 311542/2 10 method <- java/nio/ByteBuffer.array
+0 311542/2 12 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 12 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 17 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 12 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 12 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 12 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 12 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 13 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 14 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 13 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 12 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 13 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 13 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 12 method -> java/nio/Buffer.flip
+0 311542/2 10 method <- java/nio/Buffer.flip
+0 311542/2 14 method -> java/nio/ByteBuffer.array
+0 311542/2 10 method <- java/nio/ByteBuffer.array
+0 311542/2 12 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 14 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 13 method -> java/io/BufferedOutputStream.write
+0 311542/2 15 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 12 method -> java/io/BufferedOutputStream.flush
+0 311542/2 12 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 15 method -> java/io/FileOutputStream.write
+0 311542/2 12 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 55 syscall -> write
+0 311542/2 160 syscall <- write
+0 311542/2 12 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 12 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 13 method <- java/io/BufferedOutputStream.flush
+0 311542/2 11 method <- java/io/PrintStream.write
+0 311542/2 13 method -> java/nio/Buffer.clear
+0 311542/2 11 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 15 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method <- java/io/PrintStream.print
+0 311542/2 12 method -> java/io/PrintStream.newLine
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 12 method -> java/io/BufferedWriter.newLine
+0 311542/2 12 method -> java/io/Writer.write
+0 311542/2 10 method -> java/io/BufferedWriter.write
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 11 method -> java/io/BufferedWriter.min
+0 311542/2 10 method <- java/io/BufferedWriter.min
+0 311542/2 10 method -> java/lang/String.getChars
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 10 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 10 method <- java/io/BufferedWriter.newLine
+0 311542/2 10 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method -> java/io/OutputStreamWriter.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 9 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method -> java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 10 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/CharBuffer.hasArray
+0 311542/2 9 method <- java/nio/CharBuffer.hasArray
+0 311542/2 10 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 9 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method -> java/nio/CharBuffer.array
+0 311542/2 9 method <- java/nio/CharBuffer.array
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.array
+0 311542/2 10 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 9 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method -> java/nio/Buffer.flip
+0 311542/2 9 method <- java/nio/Buffer.flip
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 9 method <- java/io/PrintStream.ensureOpen
+0 311542/2 10 method -> java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method -> java/io/FileOutputStream.write
+0 311542/2 10 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 12 syscall -> write
+0 311542/2 63 syscall <- write
+0 311542/2 8 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 11 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method -> java/nio/Buffer.clear
+0 311542/2 10 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.newLine
+0 311542/2 10 method <- java/io/PrintStream.println
+0 311542/2 23 method -> java/lang/ClassLoader.loadClassInternal
+0 311542/2 11 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> sun/misc/Launcher$AppClassLoader.loadClass
+0 311542/2 10 method -> java/lang/String.lastIndexOf
+0 311542/2 10 method -> java/lang/String.lastIndexOf
+0 311542/2 10 method <- java/lang/String.lastIndexOf
+0 311542/2 10 method <- java/lang/String.lastIndexOf
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 10 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 10 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 9 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 10 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass0
+0 311542/2 14 method <- java/lang/ClassLoader.findLoadedClass0
+0 311542/2 10 method <- java/lang/ClassLoader.findLoadedClass
+0 311542/2 12 method -> java/lang/ClassLoader.loadClass
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 9 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 9 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 10 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 9 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findLoadedClass0
+0 311542/2 12 method <- java/lang/ClassLoader.findLoadedClass0
+0 311542/2 10 method <- java/lang/ClassLoader.findLoadedClass
+0 311542/2 10 method -> java/lang/ClassLoader.findBootstrapClass0
+0 311542/2 10 method -> java/lang/ClassLoader.check
+0 311542/2 9 method <- java/lang/ClassLoader.check
+0 311542/2 10 method -> java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 9 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method -> sun/misc/VM.allowArraySyntax
+0 311542/2 10 method <- sun/misc/VM.allowArraySyntax
+0 311542/2 10 method -> java/lang/String.charAt
+0 311542/2 10 method <- java/lang/String.charAt
+0 311542/2 10 method <- java/lang/ClassLoader.checkName
+0 311542/2 10 method -> java/lang/ClassLoader.findBootstrapClass
+0 311542/2 15 method <- java/lang/ClassLoader.findBootstrapClass
+0 311542/2 10 method <- java/lang/ClassLoader.findBootstrapClass0
+0 311542/2 11 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- sun/misc/Launcher$AppClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClass
+0 311542/2 10 method <- java/lang/ClassLoader.loadClassInternal
+0 311542/2 17 method -> java/lang/ClassLoader.checkPackageAccess
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 11 method -> java/util/HashSet.add
+0 311542/2 10 method -> java/util/HashMap.put
+0 311542/2 10 method -> java/lang/Object.hashCode
+0 311542/2 10 method <- java/lang/Object.hashCode
+0 311542/2 10 method -> java/util/HashMap.hash
+0 311542/2 10 method <- java/util/HashMap.hash
+0 311542/2 10 method -> java/util/HashMap.indexFor
+0 311542/2 10 method <- java/util/HashMap.indexFor
+0 311542/2 11 method <- java/util/HashMap.put
+0 311542/2 10 method <- java/util/HashSet.add
+0 311542/2 10 method <- java/lang/ClassLoader.checkPackageAccess
+0 311542/2 20 method -> java/lang/Thread.currentThread
+0 311542/2 11 method <- java/lang/Thread.currentThread
+0 311542/2 13 method -> java/lang/Thread.sleep
+0 311542/2 21 syscall -> pollsys
+0 311542/10 59827 syscall <- pollsys
+0 311542/10 31 syscall -> pollsys
+0 311542/10 59842 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 60087 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59871 syscall <- pollsys
+0 311542/10 26 syscall -> pollsys
+0 311542/3 1008044 syscall <- lwp_cond_wait
+0 311542/3 37 syscall -> lwp_cond_wait
+0 311542/10 59402 syscall <- pollsys
+0 311542/10 18 syscall -> pollsys
+0 311542/10 59999 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59965 syscall <- pollsys
+0 311542/10 25 syscall -> pollsys
+0 311542/10 59979 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 51241 syscall <- pollsys
+0 311542/10 31 syscall -> pollsys
+0 311542/10 58679 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 50215 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59734 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59977 syscall <- pollsys
+0 311542/10 26 syscall -> pollsys
+0 311542/10 59970 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59966 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 60013 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59924 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+Function B
+0 311542/2 1003741 syscall <- pollsys
+0 311542/2 28 method <- java/lang/Thread.sleep
+0 311542/2 45 method -> Func_abc.func_b
+0 311542/2 36 method -> java/io/PrintStream.println
+0 311542/2 11 method -> java/io/PrintStream.print
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 11 method -> java/io/Writer.write
+0 311542/2 11 method -> java/io/BufferedWriter.write
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 12 method -> java/io/BufferedWriter.min
+0 311542/2 10 method <- java/io/BufferedWriter.min
+0 311542/2 11 method -> java/lang/String.getChars
+0 311542/2 11 method -> java/lang/System.arraycopy
+0 311542/2 11 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 11 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 10 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 11 method -> java/io/OutputStreamWriter.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 11 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method -> java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 11 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 11 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 11 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/CharBuffer.hasArray
+0 311542/2 10 method <- java/nio/CharBuffer.hasArray
+0 311542/2 11 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 10 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method -> java/nio/CharBuffer.array
+0 311542/2 10 method <- java/nio/CharBuffer.array
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 10 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 9 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 12 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 11 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method -> java/nio/Buffer.flip
+0 311542/2 9 method <- java/nio/Buffer.flip
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 9 method <- java/io/PrintStream.ensureOpen
+0 311542/2 11 method -> java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method -> java/io/FileOutputStream.write
+0 311542/2 10 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 17 syscall -> write
+0 311542/2 104 syscall <- write
+0 311542/2 9 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 11 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method -> java/nio/Buffer.clear
+0 311542/2 10 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 11 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 11 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method <- java/io/PrintStream.print
+0 311542/2 10 method -> java/io/PrintStream.newLine
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 10 method -> java/io/BufferedWriter.newLine
+0 311542/2 10 method -> java/io/Writer.write
+0 311542/2 10 method -> java/io/BufferedWriter.write
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 9 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method -> java/io/BufferedWriter.min
+0 311542/2 9 method <- java/io/BufferedWriter.min
+0 311542/2 10 method -> java/lang/String.getChars
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 10 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 10 method <- java/io/BufferedWriter.newLine
+0 311542/2 10 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 9 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method -> java/io/OutputStreamWriter.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method -> java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 9 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 10 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/CharBuffer.hasArray
+0 311542/2 10 method <- java/nio/CharBuffer.hasArray
+0 311542/2 10 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 10 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method -> java/nio/CharBuffer.array
+0 311542/2 10 method <- java/nio/CharBuffer.array
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 9 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method -> java/nio/Buffer.flip
+0 311542/2 10 method <- java/nio/Buffer.flip
+0 311542/2 10 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 9 method <- java/io/PrintStream.ensureOpen
+0 311542/2 10 method -> java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method -> java/io/FileOutputStream.write
+0 311542/2 10 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 11 syscall -> write
+0 311542/2 64 syscall <- write
+0 311542/2 8 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 11 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method -> java/nio/Buffer.clear
+0 311542/2 10 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.newLine
+0 311542/2 10 method <- java/io/PrintStream.println
+0 311542/2 10 method -> java/lang/Thread.currentThread
+0 311542/2 10 method <- java/lang/Thread.currentThread
+0 311542/2 10 method -> java/lang/Thread.sleep
+0 311542/2 14 syscall -> pollsys
+0 311542/10 59985 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59968 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59981 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59960 syscall <- pollsys
+0 311542/10 28 syscall -> pollsys
+0 311542/10 59967 syscall <- pollsys
+0 311542/10 22 syscall -> pollsys
+0 311542/3 1050003 syscall <- lwp_cond_wait
+0 311542/3 14 syscall -> lwp_cond_wait
+0 311542/10 59985 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59969 syscall <- pollsys
+0 311542/10 25 syscall -> pollsys
+0 311542/10 59980 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 51269 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 58678 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 50207 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59714 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59967 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59965 syscall <- pollsys
+0 311542/10 28 syscall -> pollsys
+0 311542/10 59970 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59952 syscall <- pollsys
+0 311542/10 31 syscall -> pollsys
+0 311542/10 59969 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+Function C
+0 311542/2 1006879 syscall <- pollsys
+0 311542/2 29 method <- java/lang/Thread.sleep
+0 311542/2 45 method -> Func_abc.func_c
+0 311542/2 36 method -> java/io/PrintStream.println
+0 311542/2 11 method -> java/io/PrintStream.print
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 11 method -> java/io/Writer.write
+0 311542/2 11 method -> java/io/BufferedWriter.write
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 12 method -> java/io/BufferedWriter.min
+0 311542/2 10 method <- java/io/BufferedWriter.min
+0 311542/2 11 method -> java/lang/String.getChars
+0 311542/2 11 method -> java/lang/System.arraycopy
+0 311542/2 11 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 11 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 10 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 11 method -> java/io/OutputStreamWriter.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 11 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method -> java/nio/CharBuffer.wrap
+0 311542/2 11 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 11 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 11 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 11 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/CharBuffer.hasArray
+0 311542/2 10 method <- java/nio/CharBuffer.hasArray
+0 311542/2 11 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 10 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method -> java/nio/CharBuffer.array
+0 311542/2 9 method <- java/nio/CharBuffer.array
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 10 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 12 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 11 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method -> java/nio/Buffer.flip
+0 311542/2 9 method <- java/nio/Buffer.flip
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 11 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 9 method <- java/io/PrintStream.ensureOpen
+0 311542/2 11 method -> java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 11 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method -> java/io/FileOutputStream.write
+0 311542/2 10 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 17 syscall -> write
+0 311542/2 143 syscall <- write
+0 311542/2 9 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 11 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method -> java/nio/Buffer.clear
+0 311542/2 10 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 11 method -> java/lang/String.indexOf
+0 311542/2 10 method -> java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/lang/String.indexOf
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method <- java/io/PrintStream.print
+0 311542/2 10 method -> java/io/PrintStream.newLine
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 10 method <- java/io/PrintStream.ensureOpen
+0 311542/2 10 method -> java/io/BufferedWriter.newLine
+0 311542/2 10 method -> java/io/Writer.write
+0 311542/2 10 method -> java/io/BufferedWriter.write
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 9 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method -> java/io/BufferedWriter.min
+0 311542/2 9 method <- java/io/BufferedWriter.min
+0 311542/2 10 method -> java/lang/String.getChars
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 10 method <- java/io/BufferedWriter.write
+0 311542/2 10 method <- java/io/Writer.write
+0 311542/2 10 method <- java/io/BufferedWriter.newLine
+0 311542/2 10 method -> java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method <- java/io/BufferedWriter.ensureOpen
+0 311542/2 10 method -> java/io/OutputStreamWriter.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.ensureOpen
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method -> java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method -> java/nio/CharBuffer.<init>
+0 311542/2 10 method -> java/nio/Buffer.<init>
+0 311542/2 9 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method -> java/nio/Buffer.limit
+0 311542/2 10 method <- java/nio/Buffer.limit
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.<init>
+0 311542/2 10 method <- java/nio/HeapCharBuffer.<init>
+0 311542/2 10 method <- java/nio/CharBuffer.wrap
+0 311542/2 10 method -> java/nio/Buffer.hasRemaining
+0 311542/2 10 method <- java/nio/Buffer.hasRemaining
+0 311542/2 10 method -> java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/CharBuffer.hasArray
+0 311542/2 10 method <- java/nio/CharBuffer.hasArray
+0 311542/2 10 method -> java/nio/ByteBuffer.hasArray
+0 311542/2 10 method <- java/nio/ByteBuffer.hasArray
+0 311542/2 10 method -> sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method -> java/nio/CharBuffer.array
+0 311542/2 10 method <- java/nio/CharBuffer.array
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 11 method -> java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/CharBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 9 method <- java/nio/Buffer.position
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/nio/Buffer.position
+0 311542/2 10 method <- java/nio/Buffer.position
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeArrayLoop
+0 311542/2 10 method <- sun/nio/cs/US_ASCII$Encoder.encodeLoop
+0 311542/2 10 method -> java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isOverflow
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CharsetEncoder.encode
+0 311542/2 10 method -> java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method <- java/nio/charset/CoderResult.isUnderflow
+0 311542/2 10 method -> java/nio/Buffer.remaining
+0 311542/2 10 method <- java/nio/Buffer.remaining
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implWrite
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.write
+0 311542/2 10 method <- java/io/OutputStreamWriter.write
+0 311542/2 10 method <- java/io/BufferedWriter.flushBuffer
+0 311542/2 10 method -> java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method -> sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method -> java/nio/Buffer.flip
+0 311542/2 10 method <- java/nio/Buffer.flip
+0 311542/2 10 method -> java/nio/ByteBuffer.array
+0 311542/2 9 method <- java/nio/ByteBuffer.array
+0 311542/2 10 method -> java/nio/ByteBuffer.arrayOffset
+0 311542/2 9 method <- java/nio/ByteBuffer.arrayOffset
+0 311542/2 10 method -> java/io/PrintStream.write
+0 311542/2 10 method -> java/io/PrintStream.ensureOpen
+0 311542/2 9 method <- java/io/PrintStream.ensureOpen
+0 311542/2 10 method -> java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/io/BufferedOutputStream.write
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method -> java/io/FileOutputStream.write
+0 311542/2 10 method -> java/io/FileOutputStream.writeBytes
+0 311542/2 11 syscall -> write
+0 311542/2 63 syscall <- write
+0 311542/2 8 method <- java/io/FileOutputStream.writeBytes
+0 311542/2 11 method <- java/io/FileOutputStream.write
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.write
+0 311542/2 10 method -> java/nio/Buffer.clear
+0 311542/2 10 method <- java/nio/Buffer.clear
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.writeBytes
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.implFlushBuffer
+0 311542/2 10 method <- sun/nio/cs/StreamEncoder.flushBuffer
+0 311542/2 10 method <- java/io/OutputStreamWriter.flushBuffer
+0 311542/2 10 method -> java/io/BufferedOutputStream.flush
+0 311542/2 10 method -> java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flushBuffer
+0 311542/2 10 method <- java/io/BufferedOutputStream.flush
+0 311542/2 10 method <- java/io/PrintStream.newLine
+0 311542/2 10 method <- java/io/PrintStream.println
+0 311542/2 10 method -> java/lang/Thread.currentThread
+0 311542/2 10 method <- java/lang/Thread.currentThread
+0 311542/2 11 method -> java/lang/Thread.sleep
+0 311542/2 14 syscall -> pollsys
+0 311542/10 59975 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59963 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59976 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59961 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 59968 syscall <- pollsys
+0 311542/10 22 syscall -> pollsys
+0 311542/3 1009924 syscall <- lwp_cond_wait
+0 311542/3 17 syscall -> lwp_cond_wait
+0 311542/10 50021 syscall <- pollsys
+0 311542/10 31 syscall -> pollsys
+0 311542/10 59941 syscall <- pollsys
+0 311542/10 27 syscall -> pollsys
+0 311542/10 60034 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 61298 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 58590 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 50205 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59723 syscall <- pollsys
+0 311542/10 29 syscall -> pollsys
+0 311542/10 60208 syscall <- pollsys
+0 311542/10 28 syscall -> pollsys
+0 311542/10 59733 syscall <- pollsys
+0 311542/10 28 syscall -> pollsys
+0 311542/10 59986 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59938 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/10 59968 syscall <- pollsys
+0 311542/10 30 syscall -> pollsys
+0 311542/2 1007088 syscall <- pollsys
+0 311542/2 30 method <- java/lang/Thread.sleep
+0 311542/2 28 method <- Func_abc.func_c
+0 311542/2 10 method <- Func_abc.func_b
+0 311542/2 10 method <- Func_abc.func_a
+0 311542/2 10 method <- Func_abc.main
+0 311542/2 27 method -> java/lang/Thread.exit
+0 311542/2 38 method -> java/lang/ThreadGroup.remove
+0 311542/2 19 method -> java/lang/System.arraycopy
+0 311542/2 11 method <- java/lang/System.arraycopy
+0 311542/2 14 method -> java/lang/Object.notifyAll
+0 311542/2 16 method <- java/lang/Object.notifyAll
+0 311542/2 11 method <- java/lang/ThreadGroup.remove
+0 311542/2 16 method <- java/lang/Thread.exit
+0 311542/2 22 syscall -> mprotect
+0 311542/2 19 syscall <- mprotect
+0 311542/2 19 syscall -> lwp_sigmask
+0 311542/2 7 syscall <- lwp_sigmask
+0 311542/2 25 syscall -> lwp_self
+0 311542/2 6 syscall <- lwp_self
+0 311542/2 7 syscall -> lwp_sigmask
+0 311542/2 5 syscall <- lwp_sigmask
+0 311542/2 6 syscall -> lwp_sigmask
+0 311542/2 6 syscall <- lwp_sigmask
+0 311542/2 124 method -> java/lang/Thread.<init>
+0 311542/2 12 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method -> java/lang/Thread.init
+0 311542/2 10 method -> java/lang/Thread.currentThread
+0 311542/2 10 method <- java/lang/Thread.currentThread
+0 311542/2 11 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 11 method -> java/lang/ThreadGroup.checkAccess
+0 311542/2 10 method -> java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/ThreadGroup.checkAccess
+0 311542/2 10 method -> java/lang/ThreadGroup.addUnstarted
+0 311542/2 10 method <- java/lang/ThreadGroup.addUnstarted
+0 311542/2 11 method -> java/lang/String.toCharArray
+0 311542/2 11 method -> java/lang/String.getChars
+0 311542/2 10 method -> java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/System.arraycopy
+0 311542/2 10 method <- java/lang/String.getChars
+0 311542/2 10 method <- java/lang/String.toCharArray
+0 311542/2 10 method -> java/lang/Thread.getContextClassLoader
+0 311542/2 10 method <- java/lang/Thread.getContextClassLoader
+0 311542/2 11 method -> java/security/AccessController.getContext
+0 311542/2 10 method -> java/security/AccessController.getStackAccessControlContext
+0 311542/2 17 method <- java/security/AccessController.getStackAccessControlContext
+0 311542/2 11 method -> java/security/AccessControlContext.optimize
+0 311542/2 10 method -> java/security/AccessController.getInheritedAccessControlContext
+0 311542/2 11 method <- java/security/AccessController.getInheritedAccessControlContext
+0 311542/2 11 method <- java/security/AccessControlContext.optimize
+0 311542/2 10 method <- java/security/AccessController.getContext
+0 311542/2 10 method -> java/lang/Thread.setPriority
+0 311542/2 10 method -> java/lang/Thread.checkAccess
+0 311542/2 9 method -> java/lang/System.getSecurityManager
+0 311542/2 9 method <- java/lang/System.getSecurityManager
+0 311542/2 10 method <- java/lang/Thread.checkAccess
+0 311542/2 11 method -> java/lang/Thread.setPriority0
+0 311542/2 15 syscall -> priocntlsys
+0 311542/2 9 syscall <- priocntlsys
+0 311542/2 7 syscall -> priocntlsys
+0 311542/2 8 syscall <- priocntlsys
+0 311542/2 7 method <- java/lang/Thread.setPriority0
+0 311542/2 10 method <- java/lang/Thread.setPriority
+0 311542/2 11 method -> java/lang/Thread.nextThreadID
+0 311542/2 11 method <- java/lang/Thread.nextThreadID
+0 311542/2 10 method <- java/lang/Thread.init
+0 311542/2 10 method <- java/lang/Thread.<init>
+0 311542/2 12 method -> java/lang/ThreadGroup.add
+0 311542/2 11 method <- java/lang/ThreadGroup.add
+0 311542/2 10 syscall -> mprotect
+0 311542/2 7 syscall <- mprotect
+0 311542/2 12 method -> java/lang/Shutdown.shutdown
+0 311542/2 15 method -> java/lang/Shutdown.sequence
+0 311542/2 12 method -> java/lang/Shutdown.runHooks
+0 311542/2 14 method -> java/util/AbstractList.iterator
+0 311542/2 30 syscall -> llseek
+0 311542/2 9 syscall <- llseek
+0 311542/2 8 syscall -> read
+0 311542/2 1709 syscall <- read
+0 311542/2 27 syscall -> llseek
+0 311542/2 14 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 23 syscall <- read
+0 311542/2 280 method -> java/util/AbstractList$Itr.<init>
+0 311542/2 28 method -> java/util/AbstractList$Itr.<init>
+0 311542/2 17 method -> java/lang/Object.<init>
+0 311542/2 12 method <- java/lang/Object.<init>
+0 311542/2 25 method <- java/util/AbstractList$Itr.<init>
+0 311542/2 11 method <- java/util/AbstractList$Itr.<init>
+0 311542/2 10 method <- java/util/AbstractList.iterator
+0 311542/2 17 method -> java/util/AbstractList$Itr.hasNext
+0 311542/2 16 method <- java/util/AbstractList$Itr.hasNext
+0 311542/2 13 method -> java/util/AbstractList$Itr.next
+0 311542/2 12 method -> java/util/AbstractList$Itr.checkForComodification
+0 311542/2 10 method <- java/util/AbstractList$Itr.checkForComodification
+0 311542/2 13 method -> java/util/ArrayList.get
+0 311542/2 11 method -> java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.get
+0 311542/2 10 method <- java/util/AbstractList$Itr.next
+0 311542/2 15 method -> java/io/Console$1$1.run
+0 311542/2 14 method -> java/io/Console.access$600
+0 311542/2 12 method <- java/io/Console.access$600
+0 311542/2 10 method <- java/io/Console$1$1.run
+0 311542/2 10 method -> java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method -> java/util/AbstractList$Itr.next
+0 311542/2 10 method -> java/util/AbstractList$Itr.checkForComodification
+0 311542/2 10 method <- java/util/AbstractList$Itr.checkForComodification
+0 311542/2 11 method -> java/util/ArrayList.get
+0 311542/2 10 method -> java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.get
+0 311542/2 10 method <- java/util/AbstractList$Itr.next
+0 311542/2 11 method -> java/lang/ApplicationShutdownHooks.run
+0 311542/2 16 method -> java/util/IdentityHashMap.keySet
+0 311542/2 27 syscall -> llseek
+0 311542/2 7 syscall <- llseek
+0 311542/2 8 syscall -> read
+0 311542/2 18 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 17 syscall <- read
+0 311542/2 139 method -> java/util/IdentityHashMap$KeySet.<init>
+0 311542/2 14 method -> java/util/IdentityHashMap$KeySet.<init>
+0 311542/2 14 method -> java/util/AbstractSet.<init>
+0 311542/2 10 method -> java/util/AbstractCollection.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method <- java/util/AbstractCollection.<init>
+0 311542/2 10 method <- java/util/AbstractSet.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeySet.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeySet.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap.keySet
+0 311542/2 14 method -> java/util/IdentityHashMap$KeySet.iterator
+0 311542/2 17 syscall -> llseek
+0 311542/2 7 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 15 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 12 syscall <- read
+0 311542/2 30 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 14 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 17 syscall <- read
+0 311542/2 125 method -> java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 14 method -> java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 14 method -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 13 method -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 57 method -> java/lang/Object.<init>
+0 311542/2 11 method <- java/lang/Object.<init>
+0 311542/2 15 method -> java/util/IdentityHashMap.access$000
+0 311542/2 11 method <- java/util/IdentityHashMap.access$000
+0 311542/2 15 method -> java/util/IdentityHashMap.access$200
+0 311542/2 11 method <- java/util/IdentityHashMap.access$200
+0 311542/2 13 method <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeySet.iterator
+0 311542/2 14 method -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+0 311542/2 11 method <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+0 311542/2 11 method -> java/util/IdentityHashMap$KeySet.iterator
+0 311542/2 10 method -> java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method -> java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method -> java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$IdentityHashMapIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/IdentityHashMap$KeySet.iterator
+0 311542/2 10 method -> java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+0 311542/2 10 method <- java/util/IdentityHashMap$IdentityHashMapIterator.hasNext
+0 311542/2 11 method <- java/lang/ApplicationShutdownHooks.run
+0 311542/2 10 method -> java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method -> java/util/AbstractList$Itr.next
+0 311542/2 10 method -> java/util/AbstractList$Itr.checkForComodification
+0 311542/2 10 method <- java/util/AbstractList$Itr.checkForComodification
+0 311542/2 11 method -> java/util/ArrayList.get
+0 311542/2 10 method -> java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.RangeCheck
+0 311542/2 10 method <- java/util/ArrayList.get
+0 311542/2 10 method <- java/util/AbstractList$Itr.next
+0 311542/2 11 method -> java/io/File$1.run
+0 311542/2 17 syscall -> llseek
+0 311542/2 8 syscall <- llseek
+0 311542/2 8 syscall -> read
+0 311542/2 17 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 12 syscall <- read
+0 311542/2 62 method -> java/io/DeleteOnExitHook.<clinit>
+0 311542/2 19 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 14 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 12 syscall <- read
+0 311542/2 130 method -> java/util/LinkedHashSet.<init>
+0 311542/2 15 method -> java/util/HashSet.<init>
+0 311542/2 10 method -> java/util/AbstractSet.<init>
+0 311542/2 10 method -> java/util/AbstractCollection.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method <- java/util/AbstractCollection.<init>
+0 311542/2 10 method <- java/util/AbstractSet.<init>
+0 311542/2 15 method -> java/util/LinkedHashMap.<init>
+0 311542/2 13 method -> java/util/HashMap.<init>
+0 311542/2 10 method -> java/util/AbstractMap.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/util/AbstractMap.<init>
+0 311542/2 12 method -> java/lang/Float.isNaN
+0 311542/2 10 method <- java/lang/Float.isNaN
+0 311542/2 15 method -> java/util/LinkedHashMap.init
+0 311542/2 10 method -> java/util/LinkedHashMap$Entry.<init>
+0 311542/2 10 method -> java/util/HashMap$Entry.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/util/HashMap$Entry.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap$Entry.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap.init
+0 311542/2 10 method <- java/util/HashMap.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap.<init>
+0 311542/2 10 method <- java/util/HashSet.<init>
+0 311542/2 10 method <- java/util/LinkedHashSet.<init>
+0 311542/2 12 method <- java/io/DeleteOnExitHook.<clinit>
+0 311542/2 13 method -> java/io/DeleteOnExitHook.hook
+0 311542/2 13 method -> java/io/DeleteOnExitHook.<init>
+0 311542/2 12 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/io/DeleteOnExitHook.<init>
+0 311542/2 10 method <- java/io/DeleteOnExitHook.hook
+0 311542/2 13 method -> java/io/DeleteOnExitHook.run
+0 311542/2 15 method -> java/util/ArrayList.<init>
+0 311542/2 10 method -> java/util/AbstractList.<init>
+0 311542/2 10 method -> java/util/AbstractCollection.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/util/AbstractCollection.<init>
+0 311542/2 10 method <- java/util/AbstractList.<init>
+0 311542/2 15 method -> java/util/AbstractCollection.toArray
+0 311542/2 13 method -> java/util/HashSet.size
+0 311542/2 12 method <- java/util/HashSet.size
+0 311542/2 13 method -> java/util/HashSet.iterator
+0 311542/2 12 method -> java/util/HashMap.keySet
+0 311542/2 19 syscall -> llseek
+0 311542/2 7 syscall <- llseek
+0 311542/2 8 syscall -> read
+0 311542/2 17 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 12 syscall <- read
+0 311542/2 68 method -> java/util/HashMap$KeySet.<init>
+0 311542/2 14 method -> java/util/HashMap$KeySet.<init>
+0 311542/2 14 method -> java/util/AbstractSet.<init>
+0 311542/2 10 method -> java/util/AbstractCollection.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 11 method <- java/util/AbstractCollection.<init>
+0 311542/2 10 method <- java/util/AbstractSet.<init>
+0 311542/2 10 method <- java/util/HashMap$KeySet.<init>
+0 311542/2 10 method <- java/util/HashMap$KeySet.<init>
+0 311542/2 10 method <- java/util/HashMap.keySet
+0 311542/2 13 method -> java/util/HashMap$KeySet.iterator
+0 311542/2 14 method -> java/util/LinkedHashMap.newKeyIterator
+0 311542/2 16 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 14 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 16 syscall <- read
+0 311542/2 81 syscall -> llseek
+0 311542/2 7 syscall <- llseek
+0 311542/2 7 syscall -> read
+0 311542/2 14 syscall <- read
+0 311542/2 7 syscall -> llseek
+0 311542/2 6 syscall <- llseek
+0 311542/2 6 syscall -> read
+0 311542/2 12 syscall <- read
+0 311542/2 77 method -> java/util/LinkedHashMap$KeyIterator.<init>
+0 311542/2 14 method -> java/util/LinkedHashMap$KeyIterator.<init>
+0 311542/2 14 method -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+0 311542/2 12 method -> java/util/LinkedHashMap$LinkedHashIterator.<init>
+0 311542/2 13 method -> java/lang/Object.<init>
+0 311542/2 10 method <- java/lang/Object.<init>
+0 311542/2 19 method <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+0 311542/2 11 method <- java/util/LinkedHashMap$LinkedHashIterator.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap$KeyIterator.<init>
+0 311542/2 10 method <- java/util/LinkedHashMap.newKeyIterator
+0 311542/2 10 method <- java/util/HashMap$KeySet.iterator
+0 311542/2 10 method <- java/util/HashSet.iterator
+0 311542/2 14 method -> java/util/LinkedHashMap$LinkedHashIterator.hasNext
+0 311542/2 11 method <- java/util/LinkedHashMap$LinkedHashIterator.hasNext
+0 311542/2 11 method <- java/util/AbstractCollection.toArray
+0 311542/2 11 method -> java/lang/Object.getClass
+0 311542/2 12 method <- java/lang/Object.getClass
+0 311542/2 11 method <- java/util/ArrayList.<init>
+0 311542/2 14 method -> java/util/Collections.reverse
+0 311542/2 15 method <- java/util/Collections.reverse
+0 311542/2 13 method -> java/util/AbstractList.iterator
+0 311542/2 11 method -> java/util/AbstractList$Itr.<init>
+0 311542/2 10 method -> java/util/AbstractList$Itr.<init>
+0 311542/2 10 method -> java/lang/Object.<init>
+0 311542/2 9 method <- java/lang/Object.<init>
+0 311542/2 10 method <- java/util/AbstractList$Itr.<init>
+0 311542/2 10 method <- java/util/AbstractList$Itr.<init>
+0 311542/2 10 method <- java/util/AbstractList.iterator
+0 311542/2 13 method -> java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/io/DeleteOnExitHook.run
+0 311542/2 10 method <- java/io/File$1.run
+0 311542/2 10 method -> java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/util/AbstractList$Itr.hasNext
+0 311542/2 10 method <- java/lang/Shutdown.runHooks
+0 311542/2 12 method <- java/lang/Shutdown.sequence
+0 311542/2 10 method <- java/lang/Shutdown.shutdown
+0 311542/2 16 syscall -> lwp_cond_wait
+0 311542/10 59973 syscall <- pollsys
+0 311542/10 31 syscall -> lwp_cond_signal
+0 311542/10 15 syscall <- lwp_cond_signal
+0 311542/10 12 syscall -> lwp_sigmask
+0 311542/10 7 syscall <- lwp_sigmask
+0 311542/10 29 syscall -> lwp_exit
+0 311542/2 13322 syscall <- lwp_cond_wait
+0 311542/2 22 syscall -> lwp_park
+0 311542/2 8 syscall <- lwp_park
+0 311542/2 17 syscall -> mprotect
+0 311542/2 16 syscall <- mprotect
+0 311542/2 12 syscall -> lwp_cond_signal
+0 311542/2 7 syscall <- lwp_cond_signal
+0 311542/2 8 syscall -> lwp_cond_wait
+0 311542/3 750221 syscall <- lwp_cond_wait
+0 311542/3 36 syscall -> mprotect
+0 311542/3 9 syscall <- mprotect
+0 311542/3 7 syscall -> mprotect
+0 311542/3 8 syscall <- mprotect
+0 311542/3 14 syscall -> mprotect
+0 311542/3 6 syscall <- mprotect
+0 311542/3 40 syscall -> lwp_cond_signal
+0 311542/3 7 syscall <- lwp_cond_signal
+0 311542/3 7 syscall -> lwp_sigmask
+0 311542/3 6 syscall <- lwp_sigmask
+0 311542/3 11 syscall -> lwp_exit
+0 311542/2 184 syscall <- lwp_cond_wait
+0 311542/2 16 syscall -> lwp_sigmask
+0 311542/2 6 syscall <- lwp_sigmask
+0 311542/2 108 syscall -> unlink
+0 311542/2 36 syscall <- unlink
+0 311542/2 9 syscall -> lwp_sigmask
+0 311542/2 6 syscall <- lwp_sigmask
+0 311542/2 50 syscall -> lwp_exit
+0 311542/1 6423404 syscall <- lwp_wait
+0 311542/1 40 syscall -> open64
+0 311542/1 101 syscall <- open64
+0 311542/1 8 syscall -> ioctl
+0 311542/1 14 syscall <- ioctl
+0 311542/1 10 syscall -> close
+0 311542/1 14 syscall <- close
+0 311542/1 8 syscall -> open64
+0 311542/1 31 syscall <- open64
+0 311542/1 7 syscall -> ioctl
+0 311542/1 7 syscall <- ioctl
+0 311542/1 7 syscall -> close
+0 311542/1 9 syscall <- close
+0 311542/1 27 syscall -> rexit
+0 311542/9 3298915 syscall <- lwp_cond_wait
+0 311542/8 3375816 syscall <- lwp_cond_wait
+0 311542/7 3376775 syscall <- lwp_cond_wait
+0 311542/5 3738267 syscall <- lwp_cond_wait
+0 311542/4 3760581 syscall <- lwp_cond_wait
+0 311542/6 3376767 syscall <- lwp_park
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_thread_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_thread_example.txt
new file mode 100644
index 0000000..3c5e83c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_thread_example.txt
@@ -0,0 +1,20 @@
+Following we see examples of the results of running j_thread.d.
+
+Here it is running while Code/Java/Func_abc is executing.
+
+# j_thread.d
+TIME PID/TID -- THREAD
+2007 Sep 24 04:01:34 311512/5 => Finalizer
+2007 Sep 24 04:01:34 311512/4 => Reference Handler
+2007 Sep 24 04:01:34 311512/7 => CompilerThread0
+2007 Sep 24 04:01:34 311512/6 => Signal Dispatcher
+2007 Sep 24 04:01:34 311512/8 => CompilerThread1
+2007 Sep 24 04:01:34 311512/9 => Low Memory Detector
+^C
+
+The fields of the output are, in order, Event time, Process ID/Thread ID,
+entry (=>) or exit (<=) and Thread name.
+
+In this example we see six different threads starting, but we do not see
+thread exit events as the JVM exited when the program stopped.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/j_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/j_who_example.txt
new file mode 100644
index 0000000..f765d48
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/j_who_example.txt
@@ -0,0 +1,17 @@
+In many cases, in order to get interesting or in-depth results the
+ExtendedDTraceProbes flag needs to be set when DTracing Java programs. In
+this case, because of the probes we have chosen to trace, running the program
+Code/Java/Func_abc, both with (PID 311517) and without (311526) this flag,
+and we can see that it has made no difference, with each reporting 35 lines
+executed.
+
+# j_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID CALLS ARGS
+ 194441 100 18 /usr/local/lib/opera/9.02-20060919.1/opera
+ 309790 100 20 java_vm
+ 311517 100 35 java -XX:+ExtendedDTraceProbes Func_abc
+ 311526 100 35 java Func_abc
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_calldist_example.txt
new file mode 100644
index 0000000..57058b7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_calldist_example.txt
@@ -0,0 +1,110 @@
+The following are examples of running js_calldist.d.
+
+Here it is running while the code at Code/JavaScript/func_clock.html is
+being executed.
+
+# js_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Elapsed times (us),
+ func_clock.html, obj-new, Date
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 16 | 0
+
+
+Exclusive function elapsed times (us),
+ func_clock.html, func, setTimeout
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 128 | 0
+
+ func_clock.html, func, getElementById
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@ 9
+ 32 |@@@@@@@@@@@@@@@@@@@@ 10
+ 64 | 0
+
+ func_clock.html, func, start
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2048 | 0
+
+ func_clock.html, func, func_a
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 32768 | 0
+
+ func_clock.html, func, func_b
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 65536 | 0
+
+ func_clock.html, func, func_c
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 65536 | 0
+
+
+Inclusive function elapsed times (us),
+ func_clock.html, func, setTimeout
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 128 | 0
+
+ func_clock.html, func, getElementById
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@ 9
+ 32 |@@@@@@@@@@@@@@@@@@@@ 10
+ 64 | 0
+
+ func_clock.html, func, func_c
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 65536 | 0
+
+ func_clock.html, func, func_a
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 131072 | 0
+
+ func_clock.html, func, func_b
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 131072 | 0
+
+ func_clock.html, func, start
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 131072 | 0
+
+The elapsed times show us that the script spent some small amount of time
+processing various events that were not functions. In this case there was
+five new Date objects, and each event took between 8 microseconds and 15
+microseconds.
+
+The exclusive function elapsed times show the time each of our functions
+takes, excluding the time spent in subroutines called by that function. We
+can see in this example that func_a took between 16384 microseconds and 32767
+microseconds.
+
+The inclusive function elapsed times show that func_a took between 65536
+microseconds and 131071 microseconds, including the time spent in any
+subroutines it calls.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_calls_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_calls_example.txt
new file mode 100644
index 0000000..848e436
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_calls_example.txt
@@ -0,0 +1,312 @@
+The following are examples of the results of running js_calls.d
+
+A JavaScript program that behaves like a clock is frequently used by these
+examples, since it can be left running in the background without browser
+input. Browser input, such as hitting the reload button or using menus,
+triggers many other JavaScript events since much of the browser uses
+JavaScript.
+
+With Code/JavaScript/func_clock.html loaded, we trace one second of activity:
+
+# js_calls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE TYPE NAME CALLS
+ func_clock.html exec . 1
+ func_clock.html func func_a 1
+ func_clock.html func func_b 1
+ func_clock.html func func_c 1
+ func_clock.html func setTimeout 1
+ func_clock.html func start 1
+ func_clock.html obj-new Date 1
+ func_clock.html func getElementById 4
+
+This shows the type of calls made, 1 exec, one obj-new, several func; a more
+descriptive name of each call; and a count of how many times a particular call
+was made.
+
+
+The following demonstrates what happens when a different program -
+Code/JavaScript/func_slow.html is reloaded by hitting the reload button on the
+browser. Apart from the func_slow.html JavaScript events, all those events
+from the browser caused by moving the mouse pointer over the screen etc. have
+been traced as well.
+
+# js_calls.d
+Tracing... Hit Ctrl-C to end.
+
+ FILE TYPE NAME CALLS
+ <null> obj-free BarProp 1
+ <null> obj-free CSSStyleDeclaration 1
+ <null> obj-free Global Scope Polluter 1
+ <null> obj-free HTMLCollection 1
+ <null> obj-free HTMLDocument 1
+ <null> obj-free HTMLHtmlElement 1
+ <null> obj-free KeyboardEvent 1
+ <null> obj-free Location 1
+ <null> obj-free NodeList 1
+ <null> obj-free StyleSheetList 1
+ <null> obj-free TreeSelection 1
+ <null> obj-free Window 1
+ <null> obj-free XULCommandDispatcher 1
+ <null> obj-free chrome://global/content/bindings/scrollbar.xml#scrollbar 8c35ec2 1
+ <null> obj-free nsXPCComponents_Classes 1
+ <null> obj-free xpcTempGlobalClass 1
+ <null> obj-new BarProp 1
+ <null> obj-new CSSStyleDeclaration 1
+ <null> obj-new Global Scope Polluter 1
+ <null> obj-new HTMLCollection 1
+ <null> obj-new HTMLDocument 1
+ <null> obj-new HTMLHtmlElement 1
+ <null> obj-new KeyboardEvent 1
+ <null> obj-new NodeList 1
+ <null> obj-new StyleSheetList 1
+ <null> obj-new TreeSelection 1
+ <null> obj-new Window 1
+ <null> obj-new XULCommandDispatcher 1
+ <null> obj-new chrome://global/content/bindings/popup.xml#popup 8befc22 1
+ <null> obj-new chrome://global/content/bindings/popup.xml#popup 8befcea 1
+ <null> obj-new chrome://global/content/bindings/scrollbar.xml#scrollbar 8ce1c1a 1
+ <null> obj-new nsXPCComponents_Classes 1
+ <null> obj-new xpcTempGlobalClass 1
+ autocomplete.xml func apply 1
+ autocomplete.xml func attachController 1
+ autocomplete.xml func detachController 1
+ autocomplete.xml func fireEvent 1
+ autocomplete.xml func getPreventDefault 1
+ autocomplete.xml func handleEnter 1
+ autocomplete.xml func onKeyPress 1
+ autocomplete.xml obj-new Object 1
+ browser.js func BrowserLoadURL 1
+ browser.js func SetPageProxyState 1
+ browser.js func URLBarFocusHandler 1
+ browser.js func UpdateBackForwardButtons 1
+ browser.js func addEventListener 1
+ browser.js func addToUrlbarHistory 1
+ browser.js func canonizeUrl 1
+ browser.js func charsetLoadListener 1
+ browser.js func checkForDirectoryListing 1
+ browser.js func contentAreaClick 1
+ browser.js func createExposableURI 1
+ browser.js func createFixupURI 1
+ browser.js func getShortcutOrURI 1
+ browser.js func getWebNavigation 1
+ browser.js func handleURLBarCommand 1
+ browser.js func isSuccessCode 1
+ browser.js func markPageAsTyped 1
+ browser.js func resolveKeyword 1
+ browser.js func search 1
+ browser.js func test 1
+ browser.js func updateLastVisitedDate 1
+ browser.js obj-new Object 1
+ browser.js obj-new XPC_WN_NoMods_Proto_JSClass 1
+ browser.js obj-new nsJSCID 1
+ browser.xml func attachFormFill 1
+ browser.xml func getAttribute 1
+ browser.xml func getBoolPref 1
+ consoleAPI.js obj-new Call 1
+ findBar.js func getElementById 1
+ firebug.js func addEventListener 1
+ firebug.js obj-new Constructor 1
+ firebug.js obj-new Location 1
+ firebug.js obj-new Object 1
+ firebug.js obj-new XPC_WN_ModsAllowed_Proto_JSClass 1
+ func_slow.html exec . 1
+ func_slow.html func func_a 1
+ func_slow.html func func_b 1
+ func_slow.html func func_c 1
+ func_slow.html obj-new Function 1
+ preferences.js obj-new nsJSCID 1
+ reporterOverlay.js func getElementById 1
+ reporterOverlay.js func setAttribute 1
+ tabbox.xml func getAttribute 1
+ tabbrowser.xml func QueryInterface 1
+ tabbrowser.xml func getAnonymousElementByAttribute 1
+ tabbrowser.xml func getBrowserIndexForDocument 1
+ tabbrowser.xml func indexOf 1
+ tabbrowser.xml func push 1
+ tabbrowser.xml func setIcon 1
+ tabbrowser.xml func setTabTitle 1
+ tabbrowser.xml func shouldLoadFavIcon 1
+ tabbrowser.xml func updateTitlebar 1
+ tabbrowser.xml func useDefaultIcon 1
+ tabbrowser.xml obj-new Array 1
+ tabbrowser.xml obj-new String 1
+ textbox.xml func hasAttribute 1
+ textbox.xml func setAttribute 1
+ webdeveloper.js func getAttribute 1
+ webdeveloper.js func hasAttribute 1
+ webdeveloper.js func toLowerCase 1
+ webdeveloper.js func webdeveloper_changeOptions 1
+ webdeveloper.js func webdeveloper_configureElement 1
+ webdeveloper.js func webdeveloper_openToolbarButton 1
+ webdeveloper.js func webdeveloper_updateMetaRedirects 1
+ webdeveloper.js func webdeveloper_updateRenderMode 1
+ webdeveloper.js obj-new Array 1
+ webdeveloper.js obj-new String 1
+ <null> obj-free BoxObject 2
+ <null> obj-free HTMLBodyElement 2
+ <null> obj-free JSOptions 2
+ <null> obj-free JavaArray 2
+ <null> obj-free JavaClass 2
+ <null> obj-free JavaMember 2
+ <null> obj-free JavaObject 2
+ <null> obj-free PageTransitionEvent 2
+ <null> obj-free nsJSCID 2
+ <null> obj-new BoxObject 2
+ <null> obj-new HTMLBodyElement 2
+ <null> obj-new JSOptions 2
+ <null> obj-new JavaArray 2
+ <null> obj-new JavaClass 2
+ <null> obj-new JavaMember 2
+ <null> obj-new JavaObject 2
+ <null> obj-new PageTransitionEvent 2
+ autocomplete.xml func ensureRowIsVisible 2
+ autocomplete.xml func initSearchNames 2
+ autocomplete.xml func select 2
+ autocomplete.xml obj-new Function 2
+ browser.js func PageProxyClearIcon 2
+ browser.js func PageProxySetIcon 2
+ browser.js func URLBarClickHandler 2
+ browser.js func URLBarMouseDownHandler 2
+ browser.js func XPCNativeWrapper function wrapper 2
+ browser.js func getService 2
+ browser.js func loadURI 2
+ browser.js func notifyObservers 2
+ css.js func <null> 2
+ dom.js func <null> 2
+ events.js func <null> 2
+ firebug.js func appendChild 2
+ firebug.js obj-new XPC_WN_NoMods_Proto_JSClass 2
+ general.xml func getAttribute 2
+ layout.js func <null> 2
+ preferences.js func webdeveloper_getStringPreference 2
+ progressmeter.xml func createEvent 2
+ progressmeter.xml func dispatchEvent 2
+ progressmeter.xml func initEvent 2
+ progressmeter.xml func setAttribute 2
+ reporterOverlay.js obj-new Function 2
+ scrollbar.xml func indexOf 2
+ source.js func <null> 2
+ style.js func <null> 2
+ tabbox.xml func setAttribute 2
+ tabbrowser.xml func getBoolPref 2
+ tabbrowser.xml func getBrowserAtIndex 2
+ tabbrowser.xml func schemeIs 2
+ tabbrowser.xml func setAttribute 2
+ textbox.xml func setSelectionRange 2
+ toolbar.xml func updateStatusText 2
+ tree.xml obj-new Function 2
+ webdeveloper.js func getElementsByTagName 2
+ webdeveloper.js func removeAttribute 2
+ <null> obj-free DOM Constructor.prototype 3
+ <null> obj-free With 3
+ <null> obj-free nsXPCComponents 3
+ <null> obj-new Array 3
+ <null> obj-new DOM Constructor.prototype 3
+ <null> obj-new With 3
+ <null> obj-new XPC_WN_NoMods_Proto_JSClass 3
+ <null> obj-new nsXPCComponents 3
+ autocomplete.xml func getAttribute 3
+ browser.js func QueryInterface 3
+ func_slow.html func write 3
+ globalOverlay.js obj-new Function 3
+ progressmeter.xml func getAttribute 3
+ progressmeter.xml func round 3
+ scrollbar.xml obj-new String 3
+ tabbrowser.xml func <null> 3
+ tabbrowser.xml func hasAttribute 3
+ tabbrowser.xml func updateIcon 3
+ text.xml func setAttribute 3
+ textbox.xml func removeAttribute 3
+ utils.js func join 3
+ utils.js func splice 3
+ utils.js func toLowerCase 3
+ utils.js obj-new Array 3
+ utils.js obj-new String 3
+ autocomplete.xml func closePopup 4
+ browser.js func indexOf 4
+ browser.js obj-new Call 4
+ browser.xml func getInterface 4
+ preferences.js func webdeveloper_getBooleanPreference 4
+ tabbrowser.xml func getAttribute 4
+ tabbrowser.xml func removeAttribute 4
+ utilityOverlay.js func goUpdateGlobalEditMenuItems 4
+ utils.js func isElement 4
+ <null> obj-free Call 5
+ view.js func <null> 5
+ <null> obj-free XPCNativeWrapper 6
+ <null> obj-free XPC_WN_NoMods_Proto_JSClass 6
+ <null> obj-new XPCNativeWrapper 6
+ XStringBundle func GetStringFromName 6
+ XStringBundle func getString 6
+ autocomplete.xml func createEvent 6
+ autocomplete.xml func dispatchEvent 6
+ autocomplete.xml func initEvent 6
+ browser.js func getBrowser 6
+ browser.js func setTimeout 6
+ browser.js obj-new String 6
+ preferences.js func getBranch 6
+ preferences.js func getService 6
+ preferences.js func prefHasUserValue 6
+ preferences.js func webdeveloper_isPreferenceSet 6
+ tabbrowser.xml func getBrowserForTab 6
+ utils.js func <null> 6
+ webdeveloper.js obj-new Function 6
+ <null> obj-new Object 7
+ firebug.js func removeAttribute 7
+ tabbrowser.xml obj-new Function 7
+ tree.xml func QueryInterface 7
+ <null> obj-free Array 8
+ browser.js func hasAttribute 8
+ globalOverlay.js func removeAttribute 8
+ reporterOverlay.js func <null> 8
+ browser.js func getElementById 9
+ browser.js func setAttribute 9
+ browser.xml obj-new Function 9
+ webdeveloper.js func getElementById 9
+ <null> obj-free Constructor 10
+ <null> obj-free Object 10
+ <null> obj-free XPC_WN_ModsAllowed_Proto_JSClass 10
+ <null> obj-new Constructor 10
+ <null> obj-new XPC_WN_ModsAllowed_Proto_JSClass 10
+ browser.js func removeAttribute 10
+ firebug.js obj-new Function 10
+ text.xml obj-new String 12
+ webdeveloper.js func item 14
+ firebug.js func getElementById 15
+ <null> obj-free XULElement 16
+ button.xml func hasAttribute 16
+ <null> obj-free Event 17
+ browser.js func <null> 17
+ <null> obj-new Event 18
+ text.xml func getAttribute 19
+ firebug.js func getAttribute 20
+ globalOverlay.js func setAttribute 20
+ <null> obj-free MouseEvent 22
+ <null> obj-new MouseEvent 22
+ globalOverlay.js func isCommandEnabled 22
+ webdeveloper.js func setAttribute 22
+ <null> obj-free String 26
+ firebug.js func setAttribute 26
+ <null> obj-free RegExp 28
+ <null> obj-new RegExp 28
+ globalOverlay.js func getControllerForCommand 28
+ globalOverlay.js func getElementById 28
+ globalOverlay.js func goSetCommandEnabled 28
+ globalOverlay.js func goUpdateCommand 28
+ text.xml func test 28
+ browser.js obj-new Function 30
+ <null> obj-free XPCWrappedNative_NoHelper 32
+ <null> obj-new XPCWrappedNative_NoHelper 32
+ consoleAPI.js obj-new Function 33
+ browser.xml func QueryInterface 38
+ <null> obj-free JavaPackage 41
+ <null> obj-new JavaPackage 41
+ scrollbar.xml obj-new Function 61
+ firebug.js func <null> 62
+ text.xml exec . 84
+ <null> obj-new XULElement 85
+ <null> obj-new Function 172
+ <null> obj-free Function 310
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_calltime_example.txt
new file mode 100644
index 0000000..0b69b76
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_calltime_example.txt
@@ -0,0 +1,60 @@
+The following are examples of js_calltime.d.
+
+This script traces the elapsed time of JavaScript functions and
+prints a report. Here it traces the example program,
+Code/JavaScript/func_clock.html
+
+# js_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ func_clock.html func func_a 3
+ func_clock.html func func_b 3
+ func_clock.html func func_c 3
+ func_clock.html func setTimeout 3
+ func_clock.html func start 3
+ func_clock.html obj-new Date 3
+ func_clock.html func getElementById 12
+ - total - 30
+
+Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ - total - 29
+ func_clock.html obj-new Date 29
+
+Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_clock.html func setTimeout 229
+ func_clock.html func getElementById 378
+ func_clock.html func start 4061
+ func_clock.html func func_a 51080
+ func_clock.html func func_b 102943
+ func_clock.html func func_c 153330
+ - total - 312024
+
+Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_clock.html func setTimeout 229
+ func_clock.html func getElementById 378
+ func_clock.html func func_c 153454
+ func_clock.html func func_b 256470
+ func_clock.html func func_a 307601
+ func_clock.html func start 312054
+
+Counts shows us how many times each different function was called, and how
+many functions were called in total.
+
+The elapsed time shows us the time spent not in a JavaScript function.
+
+The exclusive function elapsed times show the time that each function spent
+processing code - while not in other functions.
+
+The inclusive function elapsed times show the time that each function spent
+processing code, including the time spent in other calls.
+
+These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_cpudist_example.txt
new file mode 100644
index 0000000..c71a2ad
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_cpudist_example.txt
@@ -0,0 +1,112 @@
+The following are examples of js_cpudist.d.
+
+This script traces the on-CPU time of JavaScript functions and prints a report
+in the form of a histogram. Here it traces the example program,
+Code/JavaScript/func_clock.html
+
+# js_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Elapsed times (us),
+ func_clock.html, obj-new, Date
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 | 0
+
+
+Exclusive function on-CPU times (us),
+ func_clock.html, func, setTimeout
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@@@@@@@@ 2
+ 128 | 0
+
+ func_clock.html, func, getElementById
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@ 4
+ 16 |@@@@@@@@@@ 4
+ 32 |@@@@@@@@@@@@@@@@@@@@ 8
+ 64 | 0
+
+ func_clock.html, func, start
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 1024 | 0
+
+ func_clock.html, func, func_a
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 32768 | 0
+
+ func_clock.html, func, func_b
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 65536 | 0
+
+ func_clock.html, func, func_c
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 65536 | 0
+
+
+Inclusive function on-CPU times (us),
+ func_clock.html, func, setTimeout
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@@@@@@@@ 2
+ 128 | 0
+
+ func_clock.html, func, getElementById
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@ 4
+ 16 |@@@@@@@@@@ 4
+ 32 |@@@@@@@@@@@@@@@@@@@@ 8
+ 64 | 0
+
+ func_clock.html, func, func_c
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 65536 | 0
+
+ func_clock.html, func, func_a
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 131072 | 0
+
+ func_clock.html, func, func_b
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 131072 | 0
+
+ func_clock.html, func, start
+ value ------------- Distribution ------------- count
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 131072 | 0
+
+The first section, Exclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, not including time spent in subroutines. You can
+see here that func_a had four instances of being on-CPU between 16384
+microseconds and 32767 microseconds.
+
+The second section, Inclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, including that time spent in subroutines called
+by those functions. You can see that here func_a had four instances of being
+on-CPU between 65536 microseconds and 131071 microseconds.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly.
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_cputime_example.txt
new file mode 100644
index 0000000..dff42fd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_cputime_example.txt
@@ -0,0 +1,69 @@
+The following are examples of js_cputime.d.
+
+This script traces the on-CPU time of JavaScript functions and prints a report.
+Here it traces the example program, Code/JavaScript/func_clock.html
+
+# js_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ func_clock.html func func_a 5
+ func_clock.html func func_b 5
+ func_clock.html func func_c 5
+ func_clock.html func setTimeout 5
+ func_clock.html func start 5
+ func_clock.html obj-new Date 5
+ func_clock.html func getElementById 20
+ - total - 50
+
+Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ - total - 37
+ func_clock.html obj-new Date 37
+
+Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_clock.html func setTimeout 316
+ func_clock.html func getElementById 588
+ func_clock.html func start 4734
+ func_clock.html func func_a 83465
+ func_clock.html func func_b 166613
+ func_clock.html func func_c 247683
+ - total - 503402
+
+Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_clock.html func setTimeout 316
+ func_clock.html func getElementById 588
+ func_clock.html func func_c 247872
+ func_clock.html func func_b 414601
+ func_clock.html func func_a 498142
+ func_clock.html func start 503439
+
+You can see the results are printed in four sections.
+
+The first section reports how many times each subroutine was called, and it's
+type.
+
+The second section reports on the on-CPU time of anything that was not of type
+"func", in this case the only elements reported here are Date obj-new.
+
+The exclusive subroutine on-CPU times shows, amongst other results, that func_a
+spent around 83,000 microseconds on-CPU. This time excludes time spent in
+other subroutines.
+
+The inclusive subroutine on-CPU times show that func_a spent around 0.5
+seconds on-CPU. This includes the time spent in other subroutines
+called.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_execs_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_execs_example.txt
new file mode 100644
index 0000000..d555c1a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_execs_example.txt
@@ -0,0 +1,15 @@
+The following examples show the results of running the script js_execs.d.
+
+Here it runs on the program Code/JavaScript/func_clock.html. The script will
+show you every time something is executed, including page reloads and
+timeouts.
+
+# js_execs.d
+TIME FILE:LINENO
+2007 Sep 23 22:54:31 func_clock.html:32
+2007 Sep 23 22:54:32 func_clock.html:32
+2007 Sep 23 22:54:34 func_clock.html:32
+2007 Sep 23 22:54:35 func_clock.html:32
+2007 Sep 23 22:54:36 func_clock.html:32
+^C
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_flow_example.txt
new file mode 100644
index 0000000..7a9278d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_flow_example.txt
@@ -0,0 +1,41 @@
+The following are examples of js_flow.d.
+
+This is a simple script to trace the flow of JavaScript functions.
+Here it traces the example program, Code/JavaScript/func_clock.html
+
+# js_flow.d
+ C TIME(us) FILE -- FUNC
+ 0 3650471830941 func_clock.html -> start
+ 0 3650471831005 func_clock.html -> getElementById
+ 0 3650471831058 func_clock.html <- getElementById
+ 0 3650471831890 func_clock.html -> func_a
+ 0 3650471831906 func_clock.html -> getElementById
+ 0 3650471831929 func_clock.html <- getElementById
+ 0 3650471850084 func_clock.html -> func_b
+ 0 3650471850111 func_clock.html -> getElementById
+ 0 3650471850146 func_clock.html <- getElementById
+ 0 3650471886534 func_clock.html -> func_c
+ 0 3650471886573 func_clock.html -> getElementById
+ 0 3650471886624 func_clock.html <- getElementById
+ 0 3650471942212 func_clock.html <- func_c
+ 0 3650471942231 func_clock.html <- func_b
+ 0 3650471942242 func_clock.html <- func_a
+ 0 3650471942300 func_clock.html -> setTimeout
+ 0 3650471942392 func_clock.html <- setTimeout
+ 0 3650471942404 func_clock.html <- start
+^C
+
+The fourth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - the output above shows that
+func_a called func_b, which in turn called func_c.
+
+The TIME(us) column shows time from boot in microseconds.
+
+The FILE column shows the file that was being executed.
+
+If the output looks strange, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_flowinfo_example.txt
new file mode 100644
index 0000000..45970c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_flowinfo_example.txt
@@ -0,0 +1,42 @@
+Following are examples of js_flowinfo.d.
+
+This is a simple script to trace the flow of JavaScript functions. Here it
+traces the example program Code/JavaScript/func_clock.html
+
+# js_flowinfo.d
+ C PID DELTA(us) FILE:LINE TYPE -- FUNC
+ 0 11651 2 .:0 func -> start
+ 0 11651 75 func_clock.html:30 func -> getElementById
+ 0 11651 51 func_clock.html:- func <- getElementById
+ 0 11651 479 func_clock.html:31 func -> func_a
+ 0 11651 25 func_clock.html:21 func -> getElementById
+ 0 11651 23 func_clock.html:- func <- getElementById
+ 0 11651 30611 func_clock.html:25 func -> func_b
+ 0 11651 79 func_clock.html:13 func -> getElementById
+ 0 11651 51 func_clock.html:- func <- getElementById
+ 0 11651 33922 func_clock.html:17 func -> func_c
+ 0 11651 75 func_clock.html:6 func -> getElementById
+ 0 11651 50 func_clock.html:- func <- getElementById
+ 0 11651 50481 func_clock.html:- func <- func_c
+ 0 11651 24 func_clock.html:- func <- func_b
+ 0 11651 10 func_clock.html:- func <- func_a
+ 0 11651 39 func_clock.html:32 func -> setTimeout
+ 0 11651 118 func_clock.html:- func <- setTimeout
+ 0 11651 11 func_clock.html:- func <- start
+^C
+
+As each function is entered, the last column is indented by 2 spaces. This
+shows which function is calling which.
+
+The DELTA(us) column shows the change in time from the previous line to the
+current line.
+
+The FILE::LINE column shows which line in which file was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_flowtime_example.txt
new file mode 100644
index 0000000..46b2f2f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_flowtime_example.txt
@@ -0,0 +1,42 @@
+The following are examples of js_flowtime.d.
+
+This is a simple script to trace the flow of JavaScript functions.
+Here it traces the example program, Code/JavaScript/func_clock.html
+
+# js_flowtime.d
+ C TIME(us) FILE DELTA(us) -- FUNC
+ 0 3650523390654 func_clock.html 2 -> start
+ 0 3650523390721 func_clock.html 67 -> getElementById
+ 0 3650523390773 func_clock.html 51 <- getElementById
+ 0 3650523391609 func_clock.html 835 -> func_a
+ 0 3650523391627 func_clock.html 18 -> getElementById
+ 0 3650523391651 func_clock.html 23 <- getElementById
+ 0 3650523409735 func_clock.html 18084 -> func_b
+ 0 3650523409763 func_clock.html 27 -> getElementById
+ 0 3650523409795 func_clock.html 32 <- getElementById
+ 0 3650523445921 func_clock.html 36125 -> func_c
+ 0 3650523445959 func_clock.html 38 -> getElementById
+ 0 3650523446004 func_clock.html 44 <- getElementById
+ 0 3650523500557 func_clock.html 54552 <- func_c
+ 0 3650523500581 func_clock.html 24 <- func_b
+ 0 3650523500593 func_clock.html 11 <- func_a
+ 0 3650523500648 func_clock.html 54 -> setTimeout
+ 0 3650523500736 func_clock.html 88 <- setTimeout
+ 0 3650523500749 func_clock.html 12 <- start
+^C
+
+The fifth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which.
+
+The TIME(us) column shows time since boot.
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the second line of data output
+shows that a getElementById function happened 67 microseconds after start.
+
+The FILE column shows file that was being executed.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_objcpu_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_objcpu_example.txt
new file mode 100644
index 0000000..9e9a957
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_objcpu_example.txt
@@ -0,0 +1,317 @@
+The following are examples of running js_objcpu.d.
+
+This script will show the time on-CPU of object creation events in graphical
+format.
+
+Here we see it running on Code/JavaScript/func_clock.html
+
+# js_objcpu.d
+Tracing... Hit Ctrl-C to end.
+^C
+Total object creation on-CPU time (ms): 0
+
+Object creation on-CPU time distributions (us),
+
+ Date
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+
+We can see that there were two object creation events, both of type 'Date'
+that spent between 8 microseconds and 15 microseconds on-CPU each.
+
+
+Here we see the results of having Code/JavaScript/func_slow.html in a browser
+window and hitting reload. This includes events that happen due to mouse
+movement.
+
+# js_objcpu.d
+Tracing... Hit Ctrl-C to end.
+^C
+Total object creation on-CPU time (ms): 2
+
+Object creation on-CPU time distributions (us),
+
+ HTMLBodyElement
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ HTMLCollection
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ HTMLDocument
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ HTMLHtmlElement
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Location
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ NodeList
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ StyleSheetList
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Window
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ chrome://global/content/bindings/popup.xml#popup 8830492
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ chrome://global/content/bindings/scrollbar.xml#scrollbar 8beef52
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ BarProp
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ BoxObject
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ CSSStyleDeclaration
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ chrome://global/content/bindings/popup.xml#popup 8bef592
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ nsXPCComponents_Classes
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ nsJSCID
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ nsXPCComponents
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ Global Scope Polluter
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ JavaArray
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ JavaClass
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ JavaMember
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ JavaObject
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ KeyboardEvent
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ XPC_WN_NoMods_Proto_JSClass
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 |@@@@@@@@@@ 1
+ 8 | 0
+
+ PageTransitionEvent
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ JSOptions
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+
+ Call
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 8 | 0
+
+ DOM Constructor.prototype
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ With
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+
+ Constructor
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 4 |@@@@ 1
+ 8 | 0
+
+ Object
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@ 3
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 8 | 0
+
+ XPCNativeWrapper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 1
+ 16 | 0
+
+ XULElement
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@ 5
+ 4 |@@@@@@@@@@@@@@@@@@ 4
+ 8 | 0
+
+ Array
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 8 | 0
+
+ XPCWrappedNative_NoHelper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@ 3
+ 4 |@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@ 1
+ 16 | 0
+
+ XPC_WN_ModsAllowed_Proto_JSClass
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 4 |@@@@@@@@@@@@ 3
+ 8 |@@@@ 1
+ 16 | 0
+
+ MouseEvent
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@ 3
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 | 0
+
+ String
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 8 | 0
+
+ Event
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 8 |@@@@@@@@@ 3
+ 16 | 0
+
+ JavaPackage
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 40
+ 4 | 0
+ 8 |@ 1
+ 16 | 0
+
+ Function
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 246
+ 4 |@@@@@@@ 58
+ 8 |@ 8
+ 16 |@ 9
+ 32 | 0
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_objgc_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_objgc_example.txt
new file mode 100644
index 0000000..711b223
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_objgc_example.txt
@@ -0,0 +1,230 @@
+Following are examples of running js_objgc.d.
+
+This script reports on the garbage collection of Java objects. That is it
+will keep track of when resources are allocated to an object, and when
+resources are freed from an object. It is useful for providing information on
+when garbage collection is not working correctly, as this can cause the
+browser to have a memory leak.
+
+We trace object creation (+1) and destruction (-1), and provide a summary
+each second of the running tally of the object class and originating filename.
+
+Here we can see it running on Code/JavaScript/func_clock.html
+
+# js_objgc.d
+Tracing... Hit Ctrl-C to end.
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:24
+ func_clock.html 1 Date
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:25
+ func_clock.html 2 Date
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:26
+ func_clock.html 3 Date
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:27
+ func_clock.html 4 Date
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:28
+ func_clock.html 5 Date
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:29
+ browser.js 3 Function
+ <null> 5 Function
+ func_clock.html 6 Date
+ <null> 7 MouseEvent
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:30
+ browser.js 3 Function
+ <null> 5 Function
+ func_clock.html 7 Date
+ <null> 10 MouseEvent
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:31
+ <null> 1 Constructor
+ <null> 1 HTMLBodyElement
+ <null> 1 XPCNativeWrapper
+ <null> 1 XPC_WN_ModsAllowed_Proto_JSClass
+ browser.js 1 Array
+ browser.js 1 XPCNativeWrapper
+ popup.xml 1 Array
+ func_clock.html 7 Date
+ <null> 13 MouseEvent
+ <null> 18 Function
+ browser.js 20 Function
+
+ FILE TOTAL CLASS 2007 Sep 23 22:59:32
+ <null> 1 BoxObject
+ <null> 1 Constructor
+ <null> 1 HTMLBodyElement
+ <null> 1 NodeList
+ <null> 1 UIEvent
+ <null> 1 XPCNativeWrapper
+ <null> 1 XPC_WN_ModsAllowed_Proto_JSClass
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 84ff45a
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 8befbba
+ bookmarksMenu.js 1 Function
+ browser.js 1 Array
+ browser.js 1 XPCNativeWrapper
+ popup.xml 1 Function
+ scrollbox.xml 1 Function
+ <null> 2 Event
+ popup.xml 2 Array
+ bookmarks.js 3 With
+ firebug-service.js 3 Object
+ bookmarks.js 6 Object
+ bookmarks.js 6 XPCWrappedNative_NoHelper
+ func_clock.html 8 Date
+ firebug-service.js 10 Function
+ <null> 15 MouseEvent
+ bookmarks.js 19 Error
+ browser.js 20 Function
+ bookmarks.js 22 Function
+ <null> 39 XPCWrappedNative_NoHelper
+ <null> 44 Function
+ <null> 60 RegExp
+ <null> 191 XULElement
+
+[... 39 seconds deleted ...]
+
+ FILE TOTAL CLASS 2007 Sep 23 23:00:10
+ <null> 1 HTMLBodyElement
+ <null> 1 HTMLCollection
+ <null> 1 TreeColumns
+ <null> 1 XPCNativeWrapper
+ <null> 1 XPC_WN_NoMods_Proto_JSClass
+ <null> 1 XULTreeBuilder
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 84ff45a
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 8befbba
+ <null> 1 chrome://global/content/bindings/tree.xml#treebody 84caa3a
+ <null> 1 chrome://global/content/bindings/tree.xml#treebody 84e3a72
+ <null> 1 nsXPCComponents_Interfaces
+ <null> 1 nsXPCComponents_Results
+ bookmarksMenu.js 1 Function
+ browser.js 1 Array
+ browser.js 1 XPCNativeWrapper
+ browser.js 1 XPC_WN_NoMods_Proto_JSClass
+ nsUpdateService.js 1 XPC_WN_NoMods_Proto_JSClass
+ nsUpdateService.js 1 nsJSCID
+ popup.xml 1 Function
+ scrollbar.xml 1 String
+ scrollbox.xml 1 Function
+ tree.xml 1 Array
+ <null> 2 Constructor
+ <null> 2 UIEvent
+ <null> 2 XPC_WN_ModsAllowed_Proto_JSClass
+ <null> 2 nsXPCComponents_Classes
+ browser.js 2 nsJSCID
+ browser.js 2 nsJSIID
+ utilityOverlay.js 2 nsJSCID
+ utilityOverlay.js 2 nsJSIID
+ <null> 3 Array
+ <null> 3 NodeList
+ nsUpdateService.js 3 Array
+ nsUpdateService.js 3 Object
+ nsUpdateService.js 3 With
+ utilityOverlay.js 3 Call
+ tree.xml 4 Function
+ utilityOverlay.js 4 Function
+ nsUpdateService.js 7 nsJSIID
+ nsUpdateService.js 15 Function
+ bookmarks.js 22 Function
+ text.xml 23 String
+ <null> 36 BoxObject
+ func_clock.html 42 Date
+ bookmarks.js 57 With
+ firebug-service.js 57 Object
+ bookmarks.js 73 Error
+ browser.js 78 Function
+ popup.xml 82 Array
+ bookmarks.js 114 Object
+ bookmarks.js 114 XPCWrappedNative_NoHelper
+ <null> 157 MouseEvent
+ firebug-service.js 172 Function
+ <null> 307 XPCWrappedNative_NoHelper
+ <null> 388 RegExp
+ <null> 488 Event
+ <null> 876 XULElement
+ <null> 1221 Function
+
+ FILE TOTAL CLASS 2007 Sep 23 23:00:11
+ <missed> -94 Date
+ <missed> -34 Function
+ <missed> -4 MouseEvent
+ <missed> -2 Array
+ <missed> -1 HTMLBodyElement
+ <missed> -1 HTMLCollection
+ <missed> -1 XPCNativeWrapper
+ <missed> -1 XPC_WN_ModsAllowed_Proto_JSClass
+ <null> 0 Array
+ <null> 0 HTMLBodyElement
+ <null> 0 HTMLCollection
+ <null> 0 RegExp
+ <null> 0 TreeColumns
+ <null> 0 UIEvent
+ <null> 0 XPC_WN_NoMods_Proto_JSClass
+ <null> 0 XULTreeBuilder
+ <null> 0 nsXPCComponents_Classes
+ <null> 0 nsXPCComponents_Interfaces
+ <null> 0 nsXPCComponents_Results
+ browser.js 0 Array
+ browser.js 0 XPCNativeWrapper
+ browser.js 0 XPC_WN_NoMods_Proto_JSClass
+ browser.js 0 nsJSCID
+ nsUpdateService.js 0 Array
+ nsUpdateService.js 0 Function
+ nsUpdateService.js 0 Object
+ nsUpdateService.js 0 With
+ nsUpdateService.js 0 XPC_WN_NoMods_Proto_JSClass
+ nsUpdateService.js 0 nsJSCID
+ nsUpdateService.js 0 nsJSIID
+ scrollbar.xml 0 String
+ text.xml 0 String
+ tree.xml 0 Array
+ utilityOverlay.js 0 Call
+ utilityOverlay.js 0 Function
+ utilityOverlay.js 0 nsJSCID
+ <null> 1 NodeList
+ <null> 1 XPCNativeWrapper
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 84ff45a
+ <null> 1 chrome://global/content/bindings/menu.xml#menu-iconic 8befbba
+ <null> 1 chrome://global/content/bindings/tree.xml#treebody 84caa3a
+ <null> 1 chrome://global/content/bindings/tree.xml#treebody 84e3a72
+ bookmarksMenu.js 1 Function
+ browser.xul 1 Function
+ func_clock.html 1 Date
+ popup.xml 1 Function
+ scrollbox.xml 1 XULElement
+ scrollbox.xml 1 nsJSIID
+ <null> 2 Constructor
+ <null> 2 XPC_WN_ModsAllowed_Proto_JSClass
+ browser.js 2 nsJSIID
+ scrollbox.xml 2 Function
+ tree.xml 2 Function
+ utilityOverlay.js 2 nsJSIID
+ popup.xml 3 Array
+ bookmarks.js 5 With
+ firebug-service.js 5 Object
+ <null> 6 Event
+ <null> 6 MouseEvent
+ bookmarks.js 9 XPCWrappedNative_NoHelper
+ <null> 10 XPCWrappedNative_NoHelper
+ bookmarks.js 10 Object
+ browser.js 10 Function
+ bookmarks.js 15 Function
+ firebug-service.js 16 Function
+ <null> 18 BoxObject
+ bookmarks.js 75 Error
+ <null> 79 Function
+ <null> 315 XULElement
+^C
+
+Just after time 23:00:10, garbage collection fired cleaning up many objects.
+The final output shows a much reduced object count including a negative
+count for objects created before this script was tracing.
+
+If over the period of several minutes an object type is still steadily
+increasing, then that would be of interest. Be patient, depending on the rate
+of object creation it can take over ten minutes for garbage collect to kick in.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_objnew_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_objnew_example.txt
new file mode 100644
index 0000000..c3a8881
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_objnew_example.txt
@@ -0,0 +1,100 @@
+The following are examples of the results of running js_objnew.d.
+
+It reports on the class type of new objects created.
+
+Here we can see it running on the program Code/JavaScript/func_clock.html.
+
+# js_objnew.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE CLASS COUNT
+ func_clock.html Date 2
+
+The results are very simple, func_clock.html caused two new objects to be
+created, both of type 'Date'.
+
+
+Here is a more complicated example, running on the program
+Code/JavaScript/func_slow.html, with the results of that plus JavaScript caused
+by hitting reload on the browser.
+
+
+# js_objnew.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE CLASS COUNT
+ <null> BarProp 1
+ <null> CSSStyleDeclaration 1
+ <null> Global Scope Polluter 1
+ <null> HTMLBodyElement 1
+ <null> HTMLDocument 1
+ <null> HTMLHtmlElement 1
+ <null> NodeList 1
+ <null> StyleSheetList 1
+ <null> TreeSelection 1
+ <null> Window 1
+ <null> XULCommandDispatcher 1
+ <null> chrome://global/content/bindings/popup.xml#popup 8c35c92 1
+ <null> chrome://global/content/bindings/popup.xml#popup 8fb299a 1
+ <null> chrome://global/content/bindings/scrollbar.xml#scrollbar 8fb2ea2 1
+ <null> nsXPCComponents_Classes 1
+ <null> xpcTempGlobalClass 1
+ autocomplete.xml Object 1
+ browser.js Array 1
+ browser.js Object 1
+ browser.js XPC_WN_NoMods_Proto_JSClass 1
+ browser.js nsJSCID 1
+ consoleAPI.js Call 1
+ firebug.js Constructor 1
+ firebug.js Location 1
+ firebug.js Object 1
+ firebug.js XPC_WN_ModsAllowed_Proto_JSClass 1
+ func_slow.html Function 1
+ popup.xml Array 1
+ preferences.js nsJSCID 1
+ tabbrowser.xml Array 1
+ tabbrowser.xml String 1
+ webdeveloper.js Array 1
+ webdeveloper.js String 1
+ <null> BoxObject 2
+ <null> JSOptions 2
+ <null> JavaArray 2
+ <null> JavaClass 2
+ <null> JavaMember 2
+ <null> JavaObject 2
+ <null> PageTransitionEvent 2
+ autocomplete.xml Function 2
+ firebug.js XPC_WN_NoMods_Proto_JSClass 2
+ reporterOverlay.js Function 2
+ tree.xml Function 2
+ <null> Array 3
+ <null> DOM Constructor.prototype 3
+ <null> With 3
+ <null> XPC_WN_NoMods_Proto_JSClass 3
+ <null> nsXPCComponents 3
+ globalOverlay.js Function 3
+ scrollbar.xml String 3
+ utils.js Array 3
+ utils.js String 3
+ browser.js Call 4
+ func_clock.html Date 4
+ webdeveloper.js Function 4
+ <null> XPCNativeWrapper 5
+ browser.js String 6
+ <null> Object 7
+ tabbrowser.xml Function 7
+ <null> XPC_WN_ModsAllowed_Proto_JSClass 8
+ <null> Constructor 9
+ browser.xml Function 9
+ firebug.js Function 10
+ <null> MouseEvent 12
+ <null> XPCWrappedNative_NoHelper 13
+ <null> KeyboardEvent 14
+ <null> XULElement 16
+ <null> Event 29
+ browser.js Function 33
+ consoleAPI.js Function 33
+ <null> JavaPackage 41
+ scrollbar.xml Function 61
+ <null> Function 211
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_stat_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_stat_example.txt
new file mode 100644
index 0000000..b658b4f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_stat_example.txt
@@ -0,0 +1,35 @@
+The following are examples of running js_stat.d
+
+Here is the result after running the program Code/JavaScript/func_clock.html.
+
+# js_stat.d
+TIME EXEC/s FUNC/s OBJNEW/s OBJFRE/s
+2007 Sep 23 23:04:59 1 9 1 0
+2007 Sep 23 23:05:00 1 9 1 0
+2007 Sep 23 23:05:01 1 9 1 0
+2007 Sep 23 23:05:02 1 6 1 0
+2007 Sep 23 23:05:03 0 3 0 0
+2007 Sep 23 23:05:04 1 9 1 0
+2007 Sep 23 23:05:05 1 9 1 0
+2007 Sep 23 23:05:06 1 9 1 0
+^C
+
+We can see that at 2007 Sep 23 23:05:02 there was one JavaScript program
+executed, six functions called, one new object created and no objects freed.
+
+
+Here is the result after running the program Code/JavaScript/func_slow.html.
+This also includes browser JavaScript.
+
+# js_stat.d
+TIME EXEC/s FUNC/s OBJNEW/s OBJFRE/s
+2007 Sep 23 23:05:48 1 124 41 0
+2007 Sep 23 23:05:49 1 29 19 0
+2007 Sep 23 23:05:50 1 29 25 0
+2007 Sep 23 23:05:51 1 670 497 0
+2007 Sep 23 23:05:52 0 62 11 0
+2007 Sep 23 23:05:53 0 0 6 617
+2007 Sep 23 23:05:54 0 0 0 0
+2007 Sep 23 23:05:55 0 0 0 0
+^C
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/js_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/js_who_example.txt
new file mode 100644
index 0000000..06e3e31
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/js_who_example.txt
@@ -0,0 +1,59 @@
+The following examples are the results of running the js_who.d script while
+various JavaScript events happen.
+
+A JavaScript program that behaves like a clock is frequently used by these
+examples, since it can be left running in the background without browser
+input. Browser input, such as hitting the reload button or using menus,
+triggers many other JavaScript events since much of the browser uses
+JavaScript. This makes for interesting longer examples, but would be
+overwhelming for example #1.
+
+In the first example, we can see what happens when we run this program,
+Code/JavaScript/func_clock.html
+
+# js_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID FUNCS FILE
+ 10530 100 18 file:///export/home/brendan/Lang/JavaScript/func_clock.html
+
+
+The second example is more complex, the reason for this is that the program
+Code/Javascript/func_slow.html was loaded in the browser, and the reload
+button was pressed. This output captured the many browser events that occured
+when moving the mouse pointer to do so.
+
+# js_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID FUNCS FILE
+ 10530 100 2 chrome://firebug/content/views/css.js
+ 10530 100 2 chrome://firebug/content/views/dom.js
+ 10530 100 2 chrome://firebug/content/views/events.js
+ 10530 100 2 chrome://firebug/content/views/layout.js
+ 10530 100 2 chrome://firebug/content/views/source.js
+ 10530 100 2 chrome://firebug/content/views/style.js
+ 10530 100 2 chrome://global/content/bindings/scrollbar.xml
+ 10530 100 3 chrome://global/content/bindings/general.xml
+ 10530 100 3 chrome://global/content/bindings/tabbox.xml
+ 10530 100 3 chrome://global/content/bindings/text.xml
+ 10530 100 4 chrome://browser/content/utilityOverlay.js
+ 10530 100 5 chrome://firebug/content/views/view.js
+ 10530 100 6 file:///export/home/brendan/Lang/JavaScript/func_slow.html
+ 10530 100 7 chrome://global/content/bindings/textbox.xml
+ 10530 100 7 chrome://global/content/bindings/tree.xml
+ 10530 100 10 chrome://reporter/content/reporterOverlay.js
+ 10530 100 12 XStringBundle
+ 10530 100 14 chrome://global/content/bindings/progressmeter.xml
+ 10530 100 18 file:///export/home/brendan/Lang/JavaScript/func_clock.html
+ 10530 100 19 chrome://firebug/content/utils.js
+ 10530 100 30 chrome://webdeveloper/content/common/preferences.js
+ 10530 100 43 chrome://global/content/bindings/browser.xml
+ 10530 100 44 chrome://global/content/bindings/tabbrowser.xml
+ 10530 100 72 chrome://global/content/bindings/button.xml
+ 10530 100 88 chrome://global/content/bindings/autocomplete.xml
+ 10530 100 110 chrome://browser/content/browser.js
+ 10530 100 121 chrome://webdeveloper/content/webdeveloper.js
+ 10530 100 133 chrome://firebug/content/firebug.js
+ 10530 100 162 chrome://global/content/globalOverlay.js
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/kill_example.txt b/cddl/contrib/dtracetoolkit/Examples/kill_example.txt
new file mode 100644
index 0000000..f73621c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/kill_example.txt
@@ -0,0 +1,12 @@
+This is an example of the kill.d DTrace script,
+
+ # kill.d
+ FROM COMMAND SIG TO RESULT
+ 2344 bash 2 3117 0
+ 2344 bash 9 12345 -1
+ ^C
+
+In the above output, a kill -2 (Ctrl-C) was sent from the bash command
+to PID 3177. Then a kill -9 (SIGKILL) was sent to PID 12345 - which
+returned a "-1" for failure.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/kstat_types_example.txt b/cddl/contrib/dtracetoolkit/Examples/kstat_types_example.txt
new file mode 100644
index 0000000..8ffecbf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/kstat_types_example.txt
@@ -0,0 +1,1358 @@
+The following are demonstrations of the kstat_types.d script.
+
+
+Here kstat_types.d is used to trace the kstat activity of the vmstat command,
+
+ # ./kstat_types.d
+ CMD CLASS TYPE MOD:INS:NAME
+ vmstat . raw :0:kstat_headers
+ vmstat . raw :0:kstat_headers
+ vmstat misc named cpu_info:0:cpu_info0
+ vmstat misc named cpu:0:vm
+ vmstat misc named cpu:0:sys
+ vmstat disk io cmdk:0:cmdk0
+ vmstat disk io sd:0:sd0
+ vmstat misc raw unix:0:sysinfo
+ vmstat vm raw unix:0:vminfo
+ vmstat misc named unix:0:dnlcstats
+ vmstat misc named unix:0:system_misc
+ ^C
+
+Details of each lookup can be seen, including each disk device that
+was read.
+
+
+
+This is mpstat on a single CPU server,
+
+ # ./kstat_types.d
+ CMD CLASS TYPE MOD:INS:NAME
+ mpstat . raw :0:kstat_headers
+ mpstat . raw :0:kstat_headers
+ mpstat misc named cpu_info:0:cpu_info0
+ mpstat misc named cpu:0:vm
+ mpstat misc named cpu:0:sys
+ ^C
+
+The output shows that the focus was CPU statistics, as expected.
+
+
+
+The following has caught in.routed reading some statistics,
+
+ # ./kstat_types.d
+ CMD CLASS TYPE MOD:INS:NAME
+ in.routed . raw :0:kstat_headers
+ in.routed . raw :0:kstat_headers
+ in.routed net named lo:0:lo0
+ in.routed . raw :0:kstat_headers
+ in.routed . raw :0:kstat_headers
+ in.routed net named rtls:0:rtls0
+ in.routed . raw :0:kstat_headers
+ in.routed . raw :0:kstat_headers
+ in.routed net named rtls:0:rtls0
+ ^C
+
+Which shows that the network interfaces were checked.
+
+
+
+Finally, this is the kstats used when a "sar -u 1 1" command is run.
+ie, this thing,
+
+ $ sar -u 1 1
+
+ SunOS jupiter 5.10 Generic i86pc 04/21/2006
+
+ 23:28:53 %usr %sys %wio %idle
+ 23:28:54 1 3 0 96
+
+sar actually forks a child "sadc" to do the lookups. sadc caused the
+following kstat lookups (I'm not making this up),
+
+ # ./kstat_types.d
+ CMD CLASS TYPE MOD:INS:NAME
+ sadc . raw :0:kstat_headers
+ sadc . raw :0:kstat_headers
+ sadc misc named unix:0:system_misc
+ sadc kmem_cache named unix:0:file_cache
+ sadc vmem named vmem:16:kmem_oversize
+ sadc ufs named ufs:0:inode_cache
+ sadc misc raw unix:0:var
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc kmem_cache named unix:0:kmem_magazine_3
+ sadc kmem_cache named unix:0:kmem_magazine_7
+ sadc kmem_cache named unix:0:kmem_magazine_15
+ sadc kmem_cache named unix:0:kmem_magazine_31
+ sadc kmem_cache named unix:0:kmem_magazine_47
+ sadc kmem_cache named unix:0:kmem_magazine_63
+ sadc kmem_cache named unix:0:kmem_magazine_95
+ sadc kmem_cache named unix:0:kmem_magazine_143
+ sadc kmem_cache named unix:0:kmem_slab_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_audit_cache
+ sadc kmem_cache named unix:0:kmem_va_4096
+ sadc kmem_cache named unix:0:kmem_va_8192
+ sadc kmem_cache named unix:0:kmem_va_12288
+ sadc kmem_cache named unix:0:kmem_va_16384
+ sadc kmem_cache named unix:0:kmem_va_20480
+ sadc kmem_cache named unix:0:kmem_va_24576
+ sadc kmem_cache named unix:0:kmem_va_28672
+ sadc kmem_cache named unix:0:kmem_va_32768
+ sadc kmem_cache named unix:0:kmem_alloc_8
+ sadc kmem_cache named unix:0:kmem_alloc_16
+ sadc kmem_cache named unix:0:kmem_alloc_24
+ sadc kmem_cache named unix:0:kmem_alloc_32
+ sadc kmem_cache named unix:0:kmem_alloc_40
+ sadc kmem_cache named unix:0:kmem_alloc_48
+ sadc kmem_cache named unix:0:kmem_alloc_56
+ sadc kmem_cache named unix:0:kmem_alloc_64
+ sadc kmem_cache named unix:0:kmem_alloc_80
+ sadc kmem_cache named unix:0:kmem_alloc_96
+ sadc kmem_cache named unix:0:kmem_alloc_112
+ sadc kmem_cache named unix:0:kmem_alloc_128
+ sadc kmem_cache named unix:0:kmem_alloc_160
+ sadc kmem_cache named unix:0:kmem_alloc_192
+ sadc kmem_cache named unix:0:kmem_alloc_224
+ sadc kmem_cache named unix:0:kmem_alloc_256
+ sadc kmem_cache named unix:0:kmem_alloc_320
+ sadc kmem_cache named unix:0:kmem_alloc_384
+ sadc kmem_cache named unix:0:kmem_alloc_448
+ sadc kmem_cache named unix:0:kmem_alloc_512
+ sadc kmem_cache named unix:0:kmem_alloc_640
+ sadc kmem_cache named unix:0:kmem_alloc_768
+ sadc kmem_cache named unix:0:kmem_alloc_896
+ sadc kmem_cache named unix:0:kmem_alloc_1152
+ sadc kmem_cache named unix:0:kmem_alloc_1344
+ sadc kmem_cache named unix:0:kmem_alloc_1600
+ sadc kmem_cache named unix:0:kmem_alloc_2048
+ sadc kmem_cache named unix:0:kmem_alloc_2688
+ sadc kmem_cache named unix:0:kmem_alloc_4096
+ sadc kmem_cache named unix:0:kmem_alloc_8192
+ sadc kmem_cache named unix:0:kmem_alloc_12288
+ sadc kmem_cache named unix:0:kmem_alloc_16384
+ sadc kmem_cache named unix:0:streams_mblk
+ sadc kmem_cache named unix:0:streams_dblk_64
+ sadc kmem_cache named unix:0:streams_dblk_128
+ sadc kmem_cache named unix:0:streams_dblk_320
+ sadc kmem_cache named unix:0:streams_dblk_576
+ sadc kmem_cache named unix:0:streams_dblk_1088
+ sadc kmem_cache named unix:0:streams_dblk_1536
+ sadc kmem_cache named unix:0:streams_dblk_1984
+ sadc kmem_cache named unix:0:streams_dblk_2624
+ sadc kmem_cache named unix:0:streams_dblk_3968
+ sadc kmem_cache named unix:0:streams_dblk_8192
+ sadc kmem_cache named unix:0:streams_dblk_12160
+ sadc kmem_cache named unix:0:streams_dblk_16384
+ sadc kmem_cache named unix:0:streams_dblk_20352
+ sadc kmem_cache named unix:0:streams_dblk_24576
+ sadc kmem_cache named unix:0:streams_dblk_28544
+ sadc kmem_cache named unix:0:streams_dblk_32768
+ sadc kmem_cache named unix:0:streams_dblk_36736
+ sadc kmem_cache named unix:0:streams_dblk_40960
+ sadc kmem_cache named unix:0:streams_dblk_44928
+ sadc kmem_cache named unix:0:streams_dblk_49152
+ sadc kmem_cache named unix:0:streams_dblk_53120
+ sadc kmem_cache named unix:0:streams_dblk_57344
+ sadc kmem_cache named unix:0:streams_dblk_61312
+ sadc kmem_cache named unix:0:streams_dblk_65536
+ sadc kmem_cache named unix:0:streams_dblk_69504
+ sadc kmem_cache named unix:0:streams_dblk_73728
+ sadc kmem_cache named unix:0:streams_dblk_esb
+ sadc kmem_cache named unix:0:streams_fthdr
+ sadc kmem_cache named unix:0:streams_ftblk
+ sadc kmem_cache named unix:0:multidata
+ sadc kmem_cache named unix:0:multidata_pdslab
+ sadc kmem_cache named unix:0:multidata_pattbl
+ sadc kmem_cache named unix:0:taskq_ent_cache
+ sadc kmem_cache named unix:0:taskq_cache
+ sadc kmem_cache named unix:0:kmem_io_512M_128
+ sadc kmem_cache named unix:0:kmem_io_512M_256
+ sadc kmem_cache named unix:0:kmem_io_512M_512
+ sadc kmem_cache named unix:0:kmem_io_512M_1024
+ sadc kmem_cache named unix:0:kmem_io_512M_2048
+ sadc kmem_cache named unix:0:kmem_io_512M_4096
+ sadc kmem_cache named unix:0:kmem_io_16M_128
+ sadc kmem_cache named unix:0:kmem_io_16M_256
+ sadc kmem_cache named unix:0:kmem_io_16M_512
+ sadc kmem_cache named unix:0:kmem_io_16M_1024
+ sadc kmem_cache named unix:0:kmem_io_16M_2048
+ sadc kmem_cache named unix:0:kmem_io_16M_4096
+ sadc kmem_cache named unix:0:id32_cache
+ sadc kmem_cache named unix:0:bp_map_4096
+ sadc kmem_cache named unix:0:bp_map_8192
+ sadc kmem_cache named unix:0:bp_map_12288
+ sadc kmem_cache named unix:0:bp_map_16384
+ sadc kmem_cache named unix:0:bp_map_20480
+ sadc kmem_cache named unix:0:bp_map_24576
+ sadc kmem_cache named unix:0:bp_map_28672
+ sadc kmem_cache named unix:0:bp_map_32768
+ sadc kmem_cache named unix:0:mod_hash_entries
+ sadc kmem_cache named unix:0:ipp_mod
+ sadc kmem_cache named unix:0:ipp_action
+ sadc kmem_cache named unix:0:ipp_packet
+ sadc kmem_cache named unix:0:htable_t
+ sadc kmem_cache named unix:0:hment_t
+ sadc kmem_cache named unix:0:hat_t
+ sadc kmem_cache named unix:0:HatHash
+ sadc kmem_cache named unix:0:seg_cache
+ sadc kmem_cache named unix:0:snode_cache
+ sadc kmem_cache named unix:0:dv_node_cache
+ sadc kmem_cache named unix:0:dev_info_node_cache
+ sadc kmem_cache named unix:0:segkp_4096
+ sadc kmem_cache named unix:0:segkp_8192
+ sadc kmem_cache named unix:0:segkp_12288
+ sadc kmem_cache named unix:0:segkp_16384
+ sadc kmem_cache named unix:0:segkp_20480
+ sadc kmem_cache named unix:0:thread_cache
+ sadc kmem_cache named unix:0:lwp_cache
+ sadc kmem_cache named unix:0:turnstile_cache
+ sadc kmem_cache named unix:0:cred_cache
+ sadc kmem_cache named unix:0:rctl_cache
+ sadc kmem_cache named unix:0:rctl_val_cache
+ sadc kmem_cache named unix:0:task_cache
+ sadc kmem_cache named unix:0:cyclic_id_cache
+ sadc kmem_cache named unix:0:dnlc_space_cache
+ sadc kmem_cache named unix:0:vn_cache
+ sadc kmem_cache named unix:0:file_cache
+ sadc kmem_cache named unix:0:stream_head_cache
+ sadc kmem_cache named unix:0:queue_cache
+ sadc kmem_cache named unix:0:syncq_cache
+ sadc kmem_cache named unix:0:qband_cache
+ sadc kmem_cache named unix:0:linkinfo_cache
+ sadc kmem_cache named unix:0:ciputctrl_cache
+ sadc kmem_cache named unix:0:serializer_cache
+ sadc kmem_cache named unix:0:as_cache
+ sadc kmem_cache named unix:0:marker_cache
+ sadc kmem_cache named unix:0:anon_cache
+ sadc kmem_cache named unix:0:anonmap_cache
+ sadc kmem_cache named unix:0:segvn_cache
+ sadc kmem_cache named unix:0:flk_edges
+ sadc kmem_cache named unix:0:fdb_cache
+ sadc kmem_cache named unix:0:timer_cache
+ sadc kmem_cache named unix:0:physio_buf_cache
+ sadc kmem_cache named unix:0:ufs_inode_cache
+ sadc kmem_cache named unix:0:directio_buf_cache
+ sadc kmem_cache named unix:0:lufs_save
+ sadc kmem_cache named unix:0:lufs_bufs
+ sadc kmem_cache named unix:0:lufs_mapentry_cache
+ sadc misc raw cpu_stat:0:cpu_stat0
+ sadc kmem_cache named unix:0:kcf_sreq_cache
+ sadc kmem_cache named unix:0:kcf_areq_cache
+ sadc kmem_cache named unix:0:kcf_context_cache
+ sadc kmem_cache named unix:0:ipsec_actions
+ sadc kmem_cache named unix:0:ipsec_selectors
+ sadc kmem_cache named unix:0:ipsec_policy
+ sadc kmem_cache named unix:0:ipsec_info
+ sadc kmem_cache named unix:0:ip_minor_arena_1
+ sadc kmem_cache named unix:0:ipcl_conn_cache
+ sadc kmem_cache named unix:0:ipcl_tcpconn_cache
+ sadc kmem_cache named unix:0:ire_cache
+ sadc kmem_cache named unix:0:tcp_timercache
+ sadc kmem_cache named unix:0:tcp_sack_info_cache
+ sadc kmem_cache named unix:0:tcp_iphc_cache
+ sadc kmem_cache named unix:0:squeue_cache
+ sadc kmem_cache named unix:0:sctp_conn_cache
+ sadc kmem_cache named unix:0:sctp_faddr_cache
+ sadc kmem_cache named unix:0:sctp_set_cache
+ sadc kmem_cache named unix:0:sctp_ftsn_set_cache
+ sadc kmem_cache named unix:0:sctpsock
+ sadc kmem_cache named unix:0:sctp_assoc
+ sadc kmem_cache named unix:0:socktpi_cache
+ sadc kmem_cache named unix:0:socktpi_unix_cache
+ sadc kmem_cache named unix:0:ncafs_cache
+ sadc kmem_cache named unix:0:process_cache
+ sadc kmem_cache named unix:0:exacct_object_cache
+ sadc kmem_cache named unix:0:fctl_cache
+ sadc kmem_cache named unix:0:tl_cache
+ sadc kmem_cache named unix:0:keysock_1
+ sadc kmem_cache named unix:0:spdsock_1
+ sadc kmem_cache named unix:0:fnode_cache
+ sadc kmem_cache named unix:0:pipe_cache
+ sadc kmem_cache named unix:0:namefs_inodes_1
+ sadc kmem_cache named unix:0:port_cache
+ sadc kmem_cache named unix:0:lnode_cache
+ sadc kmem_cache named unix:0:clnt_clts_endpnt_cache
+ sadc kmem_cache named unix:0:pty_map
+ sadc kmem_cache named unix:0:sppptun_map
+ sadc kmem_cache named unix:0:dtrace_state_cache
+ sadc kmem_cache named unix:0:qif_head_cache
+ sadc kmem_cache named unix:0:udp_minor_1
+ sadc kmem_cache named unix:0:authkern_cache
+ sadc kmem_cache named unix:0:authloopback_cache
+ sadc kmem_cache named unix:0:authdes_cache_handle
+ sadc kmem_cache named unix:0:rnode_cache
+ sadc kmem_cache named unix:0:nfs_access_cache
+ sadc kmem_cache named unix:0:client_handle_cache
+ sadc kmem_cache named unix:0:rnode4_cache
+ sadc kmem_cache named unix:0:svnode_cache
+ sadc kmem_cache named unix:0:nfs4_access_cache
+ sadc kmem_cache named unix:0:client_handle4_cache
+ sadc kmem_cache named unix:0:nfs4_ace4vals_cache
+ sadc kmem_cache named unix:0:nfs4_ace4_list_cache
+ sadc kmem_cache named unix:0:NFS_idmap_cache
+ sadc kmem_cache named unix:0:lm_vnode
+ sadc kmem_cache named unix:0:lm_xprt
+ sadc kmem_cache named unix:0:lm_sysid
+ sadc kmem_cache named unix:0:lm_client
+ sadc kmem_cache named unix:0:lm_async
+ sadc kmem_cache named unix:0:lm_sleep
+ sadc kmem_cache named unix:0:lm_config
+ sadc kmem_cache named unix:0:nfslog_small_rec
+ sadc kmem_cache named unix:0:nfslog_medium_rec
+ sadc kmem_cache named unix:0:nfslog_large_rec
+ sadc kmem_cache named unix:0:exi_cache_handle
+ sadc kmem_cache named unix:0:Client_entry_cache
+ sadc kmem_cache named unix:0:OpenOwner_entry_cache
+ sadc kmem_cache named unix:0:OpenStateID_entry_cache
+ sadc kmem_cache named unix:0:LockStateID_entry_cache
+ sadc kmem_cache named unix:0:Lockowner_entry_cache
+ sadc kmem_cache named unix:0:File_entry_cache
+ sadc kmem_cache named unix:0:DelegStateID_entry_cache
+ sadc kmem_cache named unix:0:ip_minor_1
+ sadc kmem_cache named unix:0:ar_minor_1
+ sadc kmem_cache named unix:0:icmp_minor_1
+ sadc kmem_cache named unix:0:crypto_session_cache
+ sadc kmem_cache named unix:0:fcsm_job_cache
+ sadc kmem_cache named unix:0:sd0_cache
+ sadc kmem_cache named unix:0:hsfs_hsnode_cache
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc misc named unix:0:system_misc
+ sadc kmem_cache named unix:0:file_cache
+ sadc vmem named vmem:16:kmem_oversize
+ sadc ufs named ufs:0:inode_cache
+ sadc misc raw unix:0:var
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc kmem_cache named unix:0:kmem_magazine_3
+ sadc kmem_cache named unix:0:kmem_magazine_7
+ sadc kmem_cache named unix:0:kmem_magazine_15
+ sadc kmem_cache named unix:0:kmem_magazine_31
+ sadc kmem_cache named unix:0:kmem_magazine_47
+ sadc kmem_cache named unix:0:kmem_magazine_63
+ sadc kmem_cache named unix:0:kmem_magazine_95
+ sadc kmem_cache named unix:0:kmem_magazine_143
+ sadc kmem_cache named unix:0:kmem_slab_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_audit_cache
+ sadc kmem_cache named unix:0:kmem_va_4096
+ sadc kmem_cache named unix:0:kmem_va_8192
+ sadc kmem_cache named unix:0:kmem_va_12288
+ sadc kmem_cache named unix:0:kmem_va_16384
+ sadc kmem_cache named unix:0:kmem_va_20480
+ sadc kmem_cache named unix:0:kmem_va_24576
+ sadc kmem_cache named unix:0:kmem_va_28672
+ sadc kmem_cache named unix:0:kmem_va_32768
+ sadc kmem_cache named unix:0:kmem_alloc_8
+ sadc kmem_cache named unix:0:kmem_alloc_16
+ sadc kmem_cache named unix:0:kmem_alloc_24
+ sadc kmem_cache named unix:0:kmem_alloc_32
+ sadc kmem_cache named unix:0:kmem_alloc_40
+ sadc kmem_cache named unix:0:kmem_alloc_48
+ sadc kmem_cache named unix:0:kmem_alloc_56
+ sadc kmem_cache named unix:0:kmem_alloc_64
+ sadc kmem_cache named unix:0:kmem_alloc_80
+ sadc kmem_cache named unix:0:kmem_alloc_96
+ sadc kmem_cache named unix:0:kmem_alloc_112
+ sadc kmem_cache named unix:0:kmem_alloc_128
+ sadc kmem_cache named unix:0:kmem_alloc_160
+ sadc kmem_cache named unix:0:kmem_alloc_192
+ sadc kmem_cache named unix:0:kmem_alloc_224
+ sadc kmem_cache named unix:0:kmem_alloc_256
+ sadc kmem_cache named unix:0:kmem_alloc_320
+ sadc kmem_cache named unix:0:kmem_alloc_384
+ sadc kmem_cache named unix:0:kmem_alloc_448
+ sadc kmem_cache named unix:0:kmem_alloc_512
+ sadc kmem_cache named unix:0:kmem_alloc_640
+ sadc kmem_cache named unix:0:kmem_alloc_768
+ sadc kmem_cache named unix:0:kmem_alloc_896
+ sadc kmem_cache named unix:0:kmem_alloc_1152
+ sadc kmem_cache named unix:0:kmem_alloc_1344
+ sadc kmem_cache named unix:0:kmem_alloc_1600
+ sadc kmem_cache named unix:0:kmem_alloc_2048
+ sadc kmem_cache named unix:0:kmem_alloc_2688
+ sadc kmem_cache named unix:0:kmem_alloc_4096
+ sadc kmem_cache named unix:0:kmem_alloc_8192
+ sadc kmem_cache named unix:0:kmem_alloc_12288
+ sadc kmem_cache named unix:0:kmem_alloc_16384
+ sadc kmem_cache named unix:0:streams_mblk
+ sadc kmem_cache named unix:0:streams_dblk_64
+ sadc kmem_cache named unix:0:streams_dblk_128
+ sadc kmem_cache named unix:0:streams_dblk_320
+ sadc kmem_cache named unix:0:streams_dblk_576
+ sadc kmem_cache named unix:0:streams_dblk_1088
+ sadc kmem_cache named unix:0:streams_dblk_1536
+ sadc kmem_cache named unix:0:streams_dblk_1984
+ sadc kmem_cache named unix:0:streams_dblk_2624
+ sadc kmem_cache named unix:0:streams_dblk_3968
+ sadc kmem_cache named unix:0:streams_dblk_8192
+ sadc kmem_cache named unix:0:streams_dblk_12160
+ sadc kmem_cache named unix:0:streams_dblk_16384
+ sadc kmem_cache named unix:0:streams_dblk_20352
+ sadc kmem_cache named unix:0:streams_dblk_24576
+ sadc kmem_cache named unix:0:streams_dblk_28544
+ sadc kmem_cache named unix:0:streams_dblk_32768
+ sadc kmem_cache named unix:0:streams_dblk_36736
+ sadc kmem_cache named unix:0:streams_dblk_40960
+ sadc kmem_cache named unix:0:streams_dblk_44928
+ sadc kmem_cache named unix:0:streams_dblk_49152
+ sadc kmem_cache named unix:0:streams_dblk_53120
+ sadc kmem_cache named unix:0:streams_dblk_57344
+ sadc kmem_cache named unix:0:streams_dblk_61312
+ sadc kmem_cache named unix:0:streams_dblk_65536
+ sadc kmem_cache named unix:0:streams_dblk_69504
+ sadc kmem_cache named unix:0:streams_dblk_73728
+ sadc kmem_cache named unix:0:streams_dblk_esb
+ sadc kmem_cache named unix:0:streams_fthdr
+ sadc kmem_cache named unix:0:streams_ftblk
+ sadc kmem_cache named unix:0:multidata
+ sadc kmem_cache named unix:0:multidata_pdslab
+ sadc kmem_cache named unix:0:multidata_pattbl
+ sadc kmem_cache named unix:0:taskq_ent_cache
+ sadc kmem_cache named unix:0:taskq_cache
+ sadc kmem_cache named unix:0:kmem_io_512M_128
+ sadc kmem_cache named unix:0:kmem_io_512M_256
+ sadc kmem_cache named unix:0:kmem_io_512M_512
+ sadc kmem_cache named unix:0:kmem_io_512M_1024
+ sadc kmem_cache named unix:0:kmem_io_512M_2048
+ sadc kmem_cache named unix:0:kmem_io_512M_4096
+ sadc kmem_cache named unix:0:kmem_io_16M_128
+ sadc kmem_cache named unix:0:kmem_io_16M_256
+ sadc kmem_cache named unix:0:kmem_io_16M_512
+ sadc kmem_cache named unix:0:kmem_io_16M_1024
+ sadc kmem_cache named unix:0:kmem_io_16M_2048
+ sadc kmem_cache named unix:0:kmem_io_16M_4096
+ sadc kmem_cache named unix:0:id32_cache
+ sadc kmem_cache named unix:0:bp_map_4096
+ sadc kmem_cache named unix:0:bp_map_8192
+ sadc kmem_cache named unix:0:bp_map_12288
+ sadc kmem_cache named unix:0:bp_map_16384
+ sadc kmem_cache named unix:0:bp_map_20480
+ sadc kmem_cache named unix:0:bp_map_24576
+ sadc kmem_cache named unix:0:bp_map_28672
+ sadc kmem_cache named unix:0:bp_map_32768
+ sadc kmem_cache named unix:0:mod_hash_entries
+ sadc kmem_cache named unix:0:ipp_mod
+ sadc kmem_cache named unix:0:ipp_action
+ sadc kmem_cache named unix:0:ipp_packet
+ sadc kmem_cache named unix:0:htable_t
+ sadc kmem_cache named unix:0:hment_t
+ sadc kmem_cache named unix:0:hat_t
+ sadc kmem_cache named unix:0:HatHash
+ sadc kmem_cache named unix:0:seg_cache
+ sadc kmem_cache named unix:0:snode_cache
+ sadc kmem_cache named unix:0:dv_node_cache
+ sadc kmem_cache named unix:0:dev_info_node_cache
+ sadc kmem_cache named unix:0:segkp_4096
+ sadc kmem_cache named unix:0:segkp_8192
+ sadc kmem_cache named unix:0:segkp_12288
+ sadc kmem_cache named unix:0:segkp_16384
+ sadc kmem_cache named unix:0:segkp_20480
+ sadc kmem_cache named unix:0:thread_cache
+ sadc kmem_cache named unix:0:lwp_cache
+ sadc kmem_cache named unix:0:turnstile_cache
+ sadc kmem_cache named unix:0:cred_cache
+ sadc kmem_cache named unix:0:rctl_cache
+ sadc kmem_cache named unix:0:rctl_val_cache
+ sadc kmem_cache named unix:0:task_cache
+ sadc kmem_cache named unix:0:cyclic_id_cache
+ sadc kmem_cache named unix:0:dnlc_space_cache
+ sadc kmem_cache named unix:0:vn_cache
+ sadc kmem_cache named unix:0:file_cache
+ sadc kmem_cache named unix:0:stream_head_cache
+ sadc kmem_cache named unix:0:queue_cache
+ sadc kmem_cache named unix:0:syncq_cache
+ sadc kmem_cache named unix:0:qband_cache
+ sadc kmem_cache named unix:0:linkinfo_cache
+ sadc kmem_cache named unix:0:ciputctrl_cache
+ sadc kmem_cache named unix:0:serializer_cache
+ sadc kmem_cache named unix:0:as_cache
+ sadc kmem_cache named unix:0:marker_cache
+ sadc kmem_cache named unix:0:anon_cache
+ sadc kmem_cache named unix:0:anonmap_cache
+ sadc kmem_cache named unix:0:segvn_cache
+ sadc kmem_cache named unix:0:flk_edges
+ sadc kmem_cache named unix:0:fdb_cache
+ sadc kmem_cache named unix:0:timer_cache
+ sadc kmem_cache named unix:0:physio_buf_cache
+ sadc kmem_cache named unix:0:ufs_inode_cache
+ sadc kmem_cache named unix:0:directio_buf_cache
+ sadc kmem_cache named unix:0:lufs_save
+ sadc kmem_cache named unix:0:lufs_bufs
+ sadc kmem_cache named unix:0:lufs_mapentry_cache
+ sadc misc raw cpu_stat:0:cpu_stat0
+ sadc kmem_cache named unix:0:kcf_sreq_cache
+ sadc kmem_cache named unix:0:kcf_areq_cache
+ sadc kmem_cache named unix:0:kcf_context_cache
+ sadc kmem_cache named unix:0:ipsec_actions
+ sadc kmem_cache named unix:0:ipsec_selectors
+ sadc kmem_cache named unix:0:ipsec_policy
+ sadc kmem_cache named unix:0:ipsec_info
+ sadc kmem_cache named unix:0:ip_minor_arena_1
+ sadc kmem_cache named unix:0:ipcl_conn_cache
+ sadc kmem_cache named unix:0:ipcl_tcpconn_cache
+ sadc kmem_cache named unix:0:ire_cache
+ sadc kmem_cache named unix:0:tcp_timercache
+ sadc kmem_cache named unix:0:tcp_sack_info_cache
+ sadc kmem_cache named unix:0:tcp_iphc_cache
+ sadc kmem_cache named unix:0:squeue_cache
+ sadc kmem_cache named unix:0:sctp_conn_cache
+ sadc kmem_cache named unix:0:sctp_faddr_cache
+ sadc kmem_cache named unix:0:sctp_set_cache
+ sadc kmem_cache named unix:0:sctp_ftsn_set_cache
+ sadc kmem_cache named unix:0:sctpsock
+ sadc kmem_cache named unix:0:sctp_assoc
+ sadc kmem_cache named unix:0:socktpi_cache
+ sadc kmem_cache named unix:0:socktpi_unix_cache
+ sadc kmem_cache named unix:0:ncafs_cache
+ sadc kmem_cache named unix:0:process_cache
+ sadc kmem_cache named unix:0:exacct_object_cache
+ sadc kmem_cache named unix:0:fctl_cache
+ sadc kmem_cache named unix:0:tl_cache
+ sadc kmem_cache named unix:0:keysock_1
+ sadc kmem_cache named unix:0:spdsock_1
+ sadc kmem_cache named unix:0:fnode_cache
+ sadc kmem_cache named unix:0:pipe_cache
+ sadc kmem_cache named unix:0:namefs_inodes_1
+ sadc kmem_cache named unix:0:port_cache
+ sadc kmem_cache named unix:0:lnode_cache
+ sadc kmem_cache named unix:0:clnt_clts_endpnt_cache
+ sadc kmem_cache named unix:0:pty_map
+ sadc kmem_cache named unix:0:sppptun_map
+ sadc kmem_cache named unix:0:dtrace_state_cache
+ sadc kmem_cache named unix:0:qif_head_cache
+ sadc kmem_cache named unix:0:udp_minor_1
+ sadc kmem_cache named unix:0:authkern_cache
+ sadc kmem_cache named unix:0:authloopback_cache
+ sadc kmem_cache named unix:0:authdes_cache_handle
+ sadc kmem_cache named unix:0:rnode_cache
+ sadc kmem_cache named unix:0:nfs_access_cache
+ sadc kmem_cache named unix:0:client_handle_cache
+ sadc kmem_cache named unix:0:rnode4_cache
+ sadc kmem_cache named unix:0:svnode_cache
+ sadc kmem_cache named unix:0:nfs4_access_cache
+ sadc kmem_cache named unix:0:client_handle4_cache
+ sadc kmem_cache named unix:0:nfs4_ace4vals_cache
+ sadc kmem_cache named unix:0:nfs4_ace4_list_cache
+ sadc kmem_cache named unix:0:NFS_idmap_cache
+ sadc kmem_cache named unix:0:lm_vnode
+ sadc kmem_cache named unix:0:lm_xprt
+ sadc kmem_cache named unix:0:lm_sysid
+ sadc kmem_cache named unix:0:lm_client
+ sadc kmem_cache named unix:0:lm_async
+ sadc kmem_cache named unix:0:lm_sleep
+ sadc kmem_cache named unix:0:lm_config
+ sadc kmem_cache named unix:0:nfslog_small_rec
+ sadc kmem_cache named unix:0:nfslog_medium_rec
+ sadc kmem_cache named unix:0:nfslog_large_rec
+ sadc kmem_cache named unix:0:exi_cache_handle
+ sadc kmem_cache named unix:0:Client_entry_cache
+ sadc kmem_cache named unix:0:OpenOwner_entry_cache
+ sadc kmem_cache named unix:0:OpenStateID_entry_cache
+ sadc kmem_cache named unix:0:LockStateID_entry_cache
+ sadc kmem_cache named unix:0:Lockowner_entry_cache
+ sadc kmem_cache named unix:0:File_entry_cache
+ sadc kmem_cache named unix:0:DelegStateID_entry_cache
+ sadc kmem_cache named unix:0:ip_minor_1
+ sadc kmem_cache named unix:0:ar_minor_1
+ sadc kmem_cache named unix:0:icmp_minor_1
+ sadc kmem_cache named unix:0:crypto_session_cache
+ sadc kmem_cache named unix:0:fcsm_job_cache
+ sadc kmem_cache named unix:0:sd0_cache
+ sadc kmem_cache named unix:0:hsfs_hsnode_cache
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc misc raw unix:0:sysinfo
+ sadc vm raw unix:0:vminfo
+ sadc misc named unix:0:system_misc
+ sadc kmem_cache named unix:0:file_cache
+ sadc ufs named ufs:0:inode_cache
+ sadc misc raw cpu_stat:0:cpu_stat0
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc kmem_cache named unix:0:kmem_magazine_3
+ sadc kmem_cache named unix:0:kmem_magazine_7
+ sadc kmem_cache named unix:0:kmem_magazine_15
+ sadc kmem_cache named unix:0:kmem_magazine_31
+ sadc kmem_cache named unix:0:kmem_magazine_47
+ sadc kmem_cache named unix:0:kmem_magazine_63
+ sadc kmem_cache named unix:0:kmem_magazine_95
+ sadc kmem_cache named unix:0:kmem_magazine_143
+ sadc kmem_cache named unix:0:kmem_slab_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_audit_cache
+ sadc kmem_cache named unix:0:kmem_va_4096
+ sadc kmem_cache named unix:0:kmem_va_8192
+ sadc kmem_cache named unix:0:kmem_va_12288
+ sadc kmem_cache named unix:0:kmem_va_16384
+ sadc kmem_cache named unix:0:kmem_va_20480
+ sadc kmem_cache named unix:0:kmem_va_24576
+ sadc kmem_cache named unix:0:kmem_va_28672
+ sadc kmem_cache named unix:0:kmem_va_32768
+ sadc kmem_cache named unix:0:kmem_alloc_8
+ sadc kmem_cache named unix:0:kmem_alloc_16
+ sadc kmem_cache named unix:0:kmem_alloc_24
+ sadc kmem_cache named unix:0:kmem_alloc_32
+ sadc kmem_cache named unix:0:kmem_alloc_40
+ sadc kmem_cache named unix:0:kmem_alloc_48
+ sadc kmem_cache named unix:0:kmem_alloc_56
+ sadc kmem_cache named unix:0:kmem_alloc_64
+ sadc kmem_cache named unix:0:kmem_alloc_80
+ sadc kmem_cache named unix:0:kmem_alloc_96
+ sadc kmem_cache named unix:0:kmem_alloc_112
+ sadc kmem_cache named unix:0:kmem_alloc_128
+ sadc kmem_cache named unix:0:kmem_alloc_160
+ sadc kmem_cache named unix:0:kmem_alloc_192
+ sadc kmem_cache named unix:0:kmem_alloc_224
+ sadc kmem_cache named unix:0:kmem_alloc_256
+ sadc kmem_cache named unix:0:kmem_alloc_320
+ sadc kmem_cache named unix:0:kmem_alloc_384
+ sadc kmem_cache named unix:0:kmem_alloc_448
+ sadc kmem_cache named unix:0:kmem_alloc_512
+ sadc kmem_cache named unix:0:kmem_alloc_640
+ sadc kmem_cache named unix:0:kmem_alloc_768
+ sadc kmem_cache named unix:0:kmem_alloc_896
+ sadc kmem_cache named unix:0:kmem_alloc_1152
+ sadc kmem_cache named unix:0:kmem_alloc_1344
+ sadc kmem_cache named unix:0:kmem_alloc_1600
+ sadc kmem_cache named unix:0:kmem_alloc_2048
+ sadc kmem_cache named unix:0:kmem_alloc_2688
+ sadc kmem_cache named unix:0:kmem_alloc_4096
+ sadc kmem_cache named unix:0:kmem_alloc_8192
+ sadc kmem_cache named unix:0:kmem_alloc_12288
+ sadc kmem_cache named unix:0:kmem_alloc_16384
+ sadc kmem_cache named unix:0:streams_mblk
+ sadc kmem_cache named unix:0:streams_dblk_64
+ sadc kmem_cache named unix:0:streams_dblk_128
+ sadc kmem_cache named unix:0:streams_dblk_320
+ sadc kmem_cache named unix:0:streams_dblk_576
+ sadc kmem_cache named unix:0:streams_dblk_1088
+ sadc kmem_cache named unix:0:streams_dblk_1536
+ sadc kmem_cache named unix:0:streams_dblk_1984
+ sadc kmem_cache named unix:0:streams_dblk_2624
+ sadc kmem_cache named unix:0:streams_dblk_3968
+ sadc kmem_cache named unix:0:streams_dblk_8192
+ sadc kmem_cache named unix:0:streams_dblk_12160
+ sadc kmem_cache named unix:0:streams_dblk_16384
+ sadc kmem_cache named unix:0:streams_dblk_20352
+ sadc kmem_cache named unix:0:streams_dblk_24576
+ sadc kmem_cache named unix:0:streams_dblk_28544
+ sadc kmem_cache named unix:0:streams_dblk_32768
+ sadc kmem_cache named unix:0:streams_dblk_36736
+ sadc kmem_cache named unix:0:streams_dblk_40960
+ sadc kmem_cache named unix:0:streams_dblk_44928
+ sadc kmem_cache named unix:0:streams_dblk_49152
+ sadc kmem_cache named unix:0:streams_dblk_53120
+ sadc kmem_cache named unix:0:streams_dblk_57344
+ sadc kmem_cache named unix:0:streams_dblk_61312
+ sadc kmem_cache named unix:0:streams_dblk_65536
+ sadc kmem_cache named unix:0:streams_dblk_69504
+ sadc kmem_cache named unix:0:streams_dblk_73728
+ sadc kmem_cache named unix:0:streams_dblk_esb
+ sadc kmem_cache named unix:0:streams_fthdr
+ sadc kmem_cache named unix:0:streams_ftblk
+ sadc kmem_cache named unix:0:multidata
+ sadc kmem_cache named unix:0:multidata_pdslab
+ sadc kmem_cache named unix:0:multidata_pattbl
+ sadc kmem_cache named unix:0:taskq_ent_cache
+ sadc kmem_cache named unix:0:taskq_cache
+ sadc kmem_cache named unix:0:kmem_io_512M_128
+ sadc kmem_cache named unix:0:kmem_io_512M_256
+ sadc kmem_cache named unix:0:kmem_io_512M_512
+ sadc kmem_cache named unix:0:kmem_io_512M_1024
+ sadc kmem_cache named unix:0:kmem_io_512M_2048
+ sadc kmem_cache named unix:0:kmem_io_512M_4096
+ sadc kmem_cache named unix:0:kmem_io_16M_128
+ sadc kmem_cache named unix:0:kmem_io_16M_256
+ sadc kmem_cache named unix:0:kmem_io_16M_512
+ sadc kmem_cache named unix:0:kmem_io_16M_1024
+ sadc kmem_cache named unix:0:kmem_io_16M_2048
+ sadc kmem_cache named unix:0:kmem_io_16M_4096
+ sadc kmem_cache named unix:0:id32_cache
+ sadc kmem_cache named unix:0:bp_map_4096
+ sadc kmem_cache named unix:0:bp_map_8192
+ sadc kmem_cache named unix:0:bp_map_12288
+ sadc kmem_cache named unix:0:bp_map_16384
+ sadc kmem_cache named unix:0:bp_map_20480
+ sadc kmem_cache named unix:0:bp_map_24576
+ sadc kmem_cache named unix:0:bp_map_28672
+ sadc kmem_cache named unix:0:bp_map_32768
+ sadc kmem_cache named unix:0:mod_hash_entries
+ sadc kmem_cache named unix:0:ipp_mod
+ sadc kmem_cache named unix:0:ipp_action
+ sadc kmem_cache named unix:0:ipp_packet
+ sadc kmem_cache named unix:0:htable_t
+ sadc kmem_cache named unix:0:hment_t
+ sadc kmem_cache named unix:0:hat_t
+ sadc kmem_cache named unix:0:HatHash
+ sadc kmem_cache named unix:0:seg_cache
+ sadc kmem_cache named unix:0:snode_cache
+ sadc kmem_cache named unix:0:dv_node_cache
+ sadc kmem_cache named unix:0:dev_info_node_cache
+ sadc kmem_cache named unix:0:segkp_4096
+ sadc kmem_cache named unix:0:segkp_8192
+ sadc kmem_cache named unix:0:segkp_12288
+ sadc kmem_cache named unix:0:segkp_16384
+ sadc kmem_cache named unix:0:segkp_20480
+ sadc kmem_cache named unix:0:thread_cache
+ sadc kmem_cache named unix:0:lwp_cache
+ sadc kmem_cache named unix:0:turnstile_cache
+ sadc kmem_cache named unix:0:cred_cache
+ sadc kmem_cache named unix:0:rctl_cache
+ sadc kmem_cache named unix:0:rctl_val_cache
+ sadc kmem_cache named unix:0:task_cache
+ sadc kmem_cache named unix:0:cyclic_id_cache
+ sadc kmem_cache named unix:0:dnlc_space_cache
+ sadc kmem_cache named unix:0:vn_cache
+ sadc kmem_cache named unix:0:file_cache
+ sadc kmem_cache named unix:0:stream_head_cache
+ sadc kmem_cache named unix:0:queue_cache
+ sadc kmem_cache named unix:0:syncq_cache
+ sadc kmem_cache named unix:0:qband_cache
+ sadc kmem_cache named unix:0:linkinfo_cache
+ sadc kmem_cache named unix:0:ciputctrl_cache
+ sadc kmem_cache named unix:0:serializer_cache
+ sadc kmem_cache named unix:0:as_cache
+ sadc kmem_cache named unix:0:marker_cache
+ sadc kmem_cache named unix:0:anon_cache
+ sadc kmem_cache named unix:0:anonmap_cache
+ sadc kmem_cache named unix:0:segvn_cache
+ sadc kmem_cache named unix:0:flk_edges
+ sadc kmem_cache named unix:0:fdb_cache
+ sadc kmem_cache named unix:0:timer_cache
+ sadc kmem_cache named unix:0:physio_buf_cache
+ sadc kmem_cache named unix:0:ufs_inode_cache
+ sadc kmem_cache named unix:0:directio_buf_cache
+ sadc kmem_cache named unix:0:lufs_save
+ sadc kmem_cache named unix:0:lufs_bufs
+ sadc kmem_cache named unix:0:lufs_mapentry_cache
+ sadc kmem_cache named unix:0:kcf_sreq_cache
+ sadc kmem_cache named unix:0:kcf_areq_cache
+ sadc kmem_cache named unix:0:kcf_context_cache
+ sadc kmem_cache named unix:0:ipsec_actions
+ sadc kmem_cache named unix:0:ipsec_selectors
+ sadc kmem_cache named unix:0:ipsec_policy
+ sadc kmem_cache named unix:0:ipsec_info
+ sadc kmem_cache named unix:0:ip_minor_arena_1
+ sadc kmem_cache named unix:0:ipcl_conn_cache
+ sadc kmem_cache named unix:0:ipcl_tcpconn_cache
+ sadc kmem_cache named unix:0:ire_cache
+ sadc kmem_cache named unix:0:tcp_timercache
+ sadc kmem_cache named unix:0:tcp_sack_info_cache
+ sadc kmem_cache named unix:0:tcp_iphc_cache
+ sadc kmem_cache named unix:0:squeue_cache
+ sadc kmem_cache named unix:0:sctp_conn_cache
+ sadc kmem_cache named unix:0:sctp_faddr_cache
+ sadc kmem_cache named unix:0:sctp_set_cache
+ sadc kmem_cache named unix:0:sctp_ftsn_set_cache
+ sadc kmem_cache named unix:0:sctpsock
+ sadc kmem_cache named unix:0:sctp_assoc
+ sadc kmem_cache named unix:0:socktpi_cache
+ sadc kmem_cache named unix:0:socktpi_unix_cache
+ sadc kmem_cache named unix:0:ncafs_cache
+ sadc kmem_cache named unix:0:process_cache
+ sadc kmem_cache named unix:0:exacct_object_cache
+ sadc kmem_cache named unix:0:fctl_cache
+ sadc kmem_cache named unix:0:tl_cache
+ sadc kmem_cache named unix:0:keysock_1
+ sadc kmem_cache named unix:0:spdsock_1
+ sadc kmem_cache named unix:0:fnode_cache
+ sadc kmem_cache named unix:0:pipe_cache
+ sadc kmem_cache named unix:0:namefs_inodes_1
+ sadc kmem_cache named unix:0:port_cache
+ sadc kmem_cache named unix:0:lnode_cache
+ sadc kmem_cache named unix:0:clnt_clts_endpnt_cache
+ sadc kmem_cache named unix:0:pty_map
+ sadc kmem_cache named unix:0:sppptun_map
+ sadc kmem_cache named unix:0:dtrace_state_cache
+ sadc kmem_cache named unix:0:qif_head_cache
+ sadc kmem_cache named unix:0:udp_minor_1
+ sadc kmem_cache named unix:0:authkern_cache
+ sadc kmem_cache named unix:0:authloopback_cache
+ sadc kmem_cache named unix:0:authdes_cache_handle
+ sadc kmem_cache named unix:0:rnode_cache
+ sadc kmem_cache named unix:0:nfs_access_cache
+ sadc kmem_cache named unix:0:client_handle_cache
+ sadc kmem_cache named unix:0:rnode4_cache
+ sadc kmem_cache named unix:0:svnode_cache
+ sadc kmem_cache named unix:0:nfs4_access_cache
+ sadc kmem_cache named unix:0:client_handle4_cache
+ sadc kmem_cache named unix:0:nfs4_ace4vals_cache
+ sadc kmem_cache named unix:0:nfs4_ace4_list_cache
+ sadc kmem_cache named unix:0:NFS_idmap_cache
+ sadc kmem_cache named unix:0:lm_vnode
+ sadc kmem_cache named unix:0:lm_xprt
+ sadc kmem_cache named unix:0:lm_sysid
+ sadc kmem_cache named unix:0:lm_client
+ sadc kmem_cache named unix:0:lm_async
+ sadc kmem_cache named unix:0:lm_sleep
+ sadc kmem_cache named unix:0:lm_config
+ sadc kmem_cache named unix:0:nfslog_small_rec
+ sadc kmem_cache named unix:0:nfslog_medium_rec
+ sadc kmem_cache named unix:0:nfslog_large_rec
+ sadc kmem_cache named unix:0:exi_cache_handle
+ sadc kmem_cache named unix:0:Client_entry_cache
+ sadc kmem_cache named unix:0:OpenOwner_entry_cache
+ sadc kmem_cache named unix:0:OpenStateID_entry_cache
+ sadc kmem_cache named unix:0:LockStateID_entry_cache
+ sadc kmem_cache named unix:0:Lockowner_entry_cache
+ sadc kmem_cache named unix:0:File_entry_cache
+ sadc kmem_cache named unix:0:DelegStateID_entry_cache
+ sadc kmem_cache named unix:0:ip_minor_1
+ sadc kmem_cache named unix:0:ar_minor_1
+ sadc kmem_cache named unix:0:icmp_minor_1
+ sadc kmem_cache named unix:0:crypto_session_cache
+ sadc kmem_cache named unix:0:fcsm_job_cache
+ sadc kmem_cache named unix:0:sd0_cache
+ sadc kmem_cache named unix:0:hsfs_hsnode_cache
+ sadc vmem named vmem:16:kmem_oversize
+ sadc disk io cmdk:0:cmdk0
+ sadc nfs io nfs:1:nfs1
+ sadc disk io sd:0:sd0
+ sadc usb_byte_count io usba:0:uhci0,bulk
+ sadc usb_byte_count io usba:0:uhci0,ctrl
+ sadc usb_byte_count io usba:0:uhci0,intr
+ sadc usb_byte_count io usba:0:uhci0,isoch
+ sadc usb_byte_count io usba:0:uhci0,total
+ sadc usb_byte_count io usba:1:uhci1,bulk
+ sadc usb_byte_count io usba:1:uhci1,ctrl
+ sadc usb_byte_count io usba:1:uhci1,intr
+ sadc usb_byte_count io usba:1:uhci1,isoch
+ sadc usb_byte_count io usba:1:uhci1,total
+ sadc misc named unix:0:system_misc
+ sadc kmem_cache named unix:0:file_cache
+ sadc vmem named vmem:16:kmem_oversize
+ sadc ufs named ufs:0:inode_cache
+ sadc misc raw unix:0:var
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc kmem_cache named unix:0:kmem_magazine_3
+ sadc kmem_cache named unix:0:kmem_magazine_7
+ sadc kmem_cache named unix:0:kmem_magazine_15
+ sadc kmem_cache named unix:0:kmem_magazine_31
+ sadc kmem_cache named unix:0:kmem_magazine_47
+ sadc kmem_cache named unix:0:kmem_magazine_63
+ sadc kmem_cache named unix:0:kmem_magazine_95
+ sadc kmem_cache named unix:0:kmem_magazine_143
+ sadc kmem_cache named unix:0:kmem_slab_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_audit_cache
+ sadc kmem_cache named unix:0:kmem_va_4096
+ sadc kmem_cache named unix:0:kmem_va_8192
+ sadc kmem_cache named unix:0:kmem_va_12288
+ sadc kmem_cache named unix:0:kmem_va_16384
+ sadc kmem_cache named unix:0:kmem_va_20480
+ sadc kmem_cache named unix:0:kmem_va_24576
+ sadc kmem_cache named unix:0:kmem_va_28672
+ sadc kmem_cache named unix:0:kmem_va_32768
+ sadc kmem_cache named unix:0:kmem_alloc_8
+ sadc kmem_cache named unix:0:kmem_alloc_16
+ sadc kmem_cache named unix:0:kmem_alloc_24
+ sadc kmem_cache named unix:0:kmem_alloc_32
+ sadc kmem_cache named unix:0:kmem_alloc_40
+ sadc kmem_cache named unix:0:kmem_alloc_48
+ sadc kmem_cache named unix:0:kmem_alloc_56
+ sadc kmem_cache named unix:0:kmem_alloc_64
+ sadc kmem_cache named unix:0:kmem_alloc_80
+ sadc kmem_cache named unix:0:kmem_alloc_96
+ sadc kmem_cache named unix:0:kmem_alloc_112
+ sadc kmem_cache named unix:0:kmem_alloc_128
+ sadc kmem_cache named unix:0:kmem_alloc_160
+ sadc kmem_cache named unix:0:kmem_alloc_192
+ sadc kmem_cache named unix:0:kmem_alloc_224
+ sadc kmem_cache named unix:0:kmem_alloc_256
+ sadc kmem_cache named unix:0:kmem_alloc_320
+ sadc kmem_cache named unix:0:kmem_alloc_384
+ sadc kmem_cache named unix:0:kmem_alloc_448
+ sadc kmem_cache named unix:0:kmem_alloc_512
+ sadc kmem_cache named unix:0:kmem_alloc_640
+ sadc kmem_cache named unix:0:kmem_alloc_768
+ sadc kmem_cache named unix:0:kmem_alloc_896
+ sadc kmem_cache named unix:0:kmem_alloc_1152
+ sadc kmem_cache named unix:0:kmem_alloc_1344
+ sadc kmem_cache named unix:0:kmem_alloc_1600
+ sadc kmem_cache named unix:0:kmem_alloc_2048
+ sadc kmem_cache named unix:0:kmem_alloc_2688
+ sadc kmem_cache named unix:0:kmem_alloc_4096
+ sadc kmem_cache named unix:0:kmem_alloc_8192
+ sadc kmem_cache named unix:0:kmem_alloc_12288
+ sadc kmem_cache named unix:0:kmem_alloc_16384
+ sadc kmem_cache named unix:0:streams_mblk
+ sadc kmem_cache named unix:0:streams_dblk_64
+ sadc kmem_cache named unix:0:streams_dblk_128
+ sadc kmem_cache named unix:0:streams_dblk_320
+ sadc kmem_cache named unix:0:streams_dblk_576
+ sadc kmem_cache named unix:0:streams_dblk_1088
+ sadc kmem_cache named unix:0:streams_dblk_1536
+ sadc kmem_cache named unix:0:streams_dblk_1984
+ sadc kmem_cache named unix:0:streams_dblk_2624
+ sadc kmem_cache named unix:0:streams_dblk_3968
+ sadc kmem_cache named unix:0:streams_dblk_8192
+ sadc kmem_cache named unix:0:streams_dblk_12160
+ sadc kmem_cache named unix:0:streams_dblk_16384
+ sadc kmem_cache named unix:0:streams_dblk_20352
+ sadc kmem_cache named unix:0:streams_dblk_24576
+ sadc kmem_cache named unix:0:streams_dblk_28544
+ sadc kmem_cache named unix:0:streams_dblk_32768
+ sadc kmem_cache named unix:0:streams_dblk_36736
+ sadc kmem_cache named unix:0:streams_dblk_40960
+ sadc kmem_cache named unix:0:streams_dblk_44928
+ sadc kmem_cache named unix:0:streams_dblk_49152
+ sadc kmem_cache named unix:0:streams_dblk_53120
+ sadc kmem_cache named unix:0:streams_dblk_57344
+ sadc kmem_cache named unix:0:streams_dblk_61312
+ sadc kmem_cache named unix:0:streams_dblk_65536
+ sadc kmem_cache named unix:0:streams_dblk_69504
+ sadc kmem_cache named unix:0:streams_dblk_73728
+ sadc kmem_cache named unix:0:streams_dblk_esb
+ sadc kmem_cache named unix:0:streams_fthdr
+ sadc kmem_cache named unix:0:streams_ftblk
+ sadc kmem_cache named unix:0:multidata
+ sadc kmem_cache named unix:0:multidata_pdslab
+ sadc kmem_cache named unix:0:multidata_pattbl
+ sadc kmem_cache named unix:0:taskq_ent_cache
+ sadc kmem_cache named unix:0:taskq_cache
+ sadc kmem_cache named unix:0:kmem_io_512M_128
+ sadc kmem_cache named unix:0:kmem_io_512M_256
+ sadc kmem_cache named unix:0:kmem_io_512M_512
+ sadc kmem_cache named unix:0:kmem_io_512M_1024
+ sadc kmem_cache named unix:0:kmem_io_512M_2048
+ sadc kmem_cache named unix:0:kmem_io_512M_4096
+ sadc kmem_cache named unix:0:kmem_io_16M_128
+ sadc kmem_cache named unix:0:kmem_io_16M_256
+ sadc kmem_cache named unix:0:kmem_io_16M_512
+ sadc kmem_cache named unix:0:kmem_io_16M_1024
+ sadc kmem_cache named unix:0:kmem_io_16M_2048
+ sadc kmem_cache named unix:0:kmem_io_16M_4096
+ sadc kmem_cache named unix:0:id32_cache
+ sadc kmem_cache named unix:0:bp_map_4096
+ sadc kmem_cache named unix:0:bp_map_8192
+ sadc kmem_cache named unix:0:bp_map_12288
+ sadc kmem_cache named unix:0:bp_map_16384
+ sadc kmem_cache named unix:0:bp_map_20480
+ sadc kmem_cache named unix:0:bp_map_24576
+ sadc kmem_cache named unix:0:bp_map_28672
+ sadc kmem_cache named unix:0:bp_map_32768
+ sadc kmem_cache named unix:0:mod_hash_entries
+ sadc kmem_cache named unix:0:ipp_mod
+ sadc kmem_cache named unix:0:ipp_action
+ sadc kmem_cache named unix:0:ipp_packet
+ sadc kmem_cache named unix:0:htable_t
+ sadc kmem_cache named unix:0:hment_t
+ sadc kmem_cache named unix:0:hat_t
+ sadc kmem_cache named unix:0:HatHash
+ sadc kmem_cache named unix:0:seg_cache
+ sadc kmem_cache named unix:0:snode_cache
+ sadc kmem_cache named unix:0:dv_node_cache
+ sadc kmem_cache named unix:0:dev_info_node_cache
+ sadc kmem_cache named unix:0:segkp_4096
+ sadc kmem_cache named unix:0:segkp_8192
+ sadc kmem_cache named unix:0:segkp_12288
+ sadc kmem_cache named unix:0:segkp_16384
+ sadc kmem_cache named unix:0:segkp_20480
+ sadc kmem_cache named unix:0:thread_cache
+ sadc kmem_cache named unix:0:lwp_cache
+ sadc kmem_cache named unix:0:turnstile_cache
+ sadc kmem_cache named unix:0:cred_cache
+ sadc kmem_cache named unix:0:rctl_cache
+ sadc kmem_cache named unix:0:rctl_val_cache
+ sadc kmem_cache named unix:0:task_cache
+ sadc kmem_cache named unix:0:cyclic_id_cache
+ sadc kmem_cache named unix:0:dnlc_space_cache
+ sadc kmem_cache named unix:0:vn_cache
+ sadc kmem_cache named unix:0:file_cache
+ sadc kmem_cache named unix:0:stream_head_cache
+ sadc kmem_cache named unix:0:queue_cache
+ sadc kmem_cache named unix:0:syncq_cache
+ sadc kmem_cache named unix:0:qband_cache
+ sadc kmem_cache named unix:0:linkinfo_cache
+ sadc kmem_cache named unix:0:ciputctrl_cache
+ sadc kmem_cache named unix:0:serializer_cache
+ sadc kmem_cache named unix:0:as_cache
+ sadc kmem_cache named unix:0:marker_cache
+ sadc kmem_cache named unix:0:anon_cache
+ sadc kmem_cache named unix:0:anonmap_cache
+ sadc kmem_cache named unix:0:segvn_cache
+ sadc kmem_cache named unix:0:flk_edges
+ sadc kmem_cache named unix:0:fdb_cache
+ sadc kmem_cache named unix:0:timer_cache
+ sadc kmem_cache named unix:0:physio_buf_cache
+ sadc kmem_cache named unix:0:ufs_inode_cache
+ sadc kmem_cache named unix:0:directio_buf_cache
+ sadc kmem_cache named unix:0:lufs_save
+ sadc kmem_cache named unix:0:lufs_bufs
+ sadc kmem_cache named unix:0:lufs_mapentry_cache
+ sadc misc raw cpu_stat:0:cpu_stat0
+ sadc kmem_cache named unix:0:kcf_sreq_cache
+ sadc kmem_cache named unix:0:kcf_areq_cache
+ sadc kmem_cache named unix:0:kcf_context_cache
+ sadc kmem_cache named unix:0:ipsec_actions
+ sadc kmem_cache named unix:0:ipsec_selectors
+ sadc kmem_cache named unix:0:ipsec_policy
+ sadc kmem_cache named unix:0:ipsec_info
+ sadc kmem_cache named unix:0:ip_minor_arena_1
+ sadc kmem_cache named unix:0:ipcl_conn_cache
+ sadc kmem_cache named unix:0:ipcl_tcpconn_cache
+ sadc kmem_cache named unix:0:ire_cache
+ sadc kmem_cache named unix:0:tcp_timercache
+ sadc kmem_cache named unix:0:tcp_sack_info_cache
+ sadc kmem_cache named unix:0:tcp_iphc_cache
+ sadc kmem_cache named unix:0:squeue_cache
+ sadc kmem_cache named unix:0:sctp_conn_cache
+ sadc kmem_cache named unix:0:sctp_faddr_cache
+ sadc kmem_cache named unix:0:sctp_set_cache
+ sadc kmem_cache named unix:0:sctp_ftsn_set_cache
+ sadc kmem_cache named unix:0:sctpsock
+ sadc kmem_cache named unix:0:sctp_assoc
+ sadc kmem_cache named unix:0:socktpi_cache
+ sadc kmem_cache named unix:0:socktpi_unix_cache
+ sadc kmem_cache named unix:0:ncafs_cache
+ sadc kmem_cache named unix:0:process_cache
+ sadc kmem_cache named unix:0:exacct_object_cache
+ sadc kmem_cache named unix:0:fctl_cache
+ sadc kmem_cache named unix:0:tl_cache
+ sadc kmem_cache named unix:0:keysock_1
+ sadc kmem_cache named unix:0:spdsock_1
+ sadc kmem_cache named unix:0:fnode_cache
+ sadc kmem_cache named unix:0:pipe_cache
+ sadc kmem_cache named unix:0:namefs_inodes_1
+ sadc kmem_cache named unix:0:port_cache
+ sadc kmem_cache named unix:0:lnode_cache
+ sadc kmem_cache named unix:0:clnt_clts_endpnt_cache
+ sadc kmem_cache named unix:0:pty_map
+ sadc kmem_cache named unix:0:sppptun_map
+ sadc kmem_cache named unix:0:dtrace_state_cache
+ sadc kmem_cache named unix:0:qif_head_cache
+ sadc kmem_cache named unix:0:udp_minor_1
+ sadc kmem_cache named unix:0:authkern_cache
+ sadc kmem_cache named unix:0:authloopback_cache
+ sadc kmem_cache named unix:0:authdes_cache_handle
+ sadc kmem_cache named unix:0:rnode_cache
+ sadc kmem_cache named unix:0:nfs_access_cache
+ sadc kmem_cache named unix:0:client_handle_cache
+ sadc kmem_cache named unix:0:rnode4_cache
+ sadc kmem_cache named unix:0:svnode_cache
+ sadc kmem_cache named unix:0:nfs4_access_cache
+ sadc kmem_cache named unix:0:client_handle4_cache
+ sadc kmem_cache named unix:0:nfs4_ace4vals_cache
+ sadc kmem_cache named unix:0:nfs4_ace4_list_cache
+ sadc kmem_cache named unix:0:NFS_idmap_cache
+ sadc kmem_cache named unix:0:lm_vnode
+ sadc kmem_cache named unix:0:lm_xprt
+ sadc kmem_cache named unix:0:lm_sysid
+ sadc kmem_cache named unix:0:lm_client
+ sadc kmem_cache named unix:0:lm_async
+ sadc kmem_cache named unix:0:lm_sleep
+ sadc kmem_cache named unix:0:lm_config
+ sadc kmem_cache named unix:0:nfslog_small_rec
+ sadc kmem_cache named unix:0:nfslog_medium_rec
+ sadc kmem_cache named unix:0:nfslog_large_rec
+ sadc kmem_cache named unix:0:exi_cache_handle
+ sadc kmem_cache named unix:0:Client_entry_cache
+ sadc kmem_cache named unix:0:OpenOwner_entry_cache
+ sadc kmem_cache named unix:0:OpenStateID_entry_cache
+ sadc kmem_cache named unix:0:LockStateID_entry_cache
+ sadc kmem_cache named unix:0:Lockowner_entry_cache
+ sadc kmem_cache named unix:0:File_entry_cache
+ sadc kmem_cache named unix:0:DelegStateID_entry_cache
+ sadc kmem_cache named unix:0:ip_minor_1
+ sadc kmem_cache named unix:0:ar_minor_1
+ sadc kmem_cache named unix:0:icmp_minor_1
+ sadc kmem_cache named unix:0:crypto_session_cache
+ sadc kmem_cache named unix:0:fcsm_job_cache
+ sadc kmem_cache named unix:0:sd0_cache
+ sadc kmem_cache named unix:0:hsfs_hsnode_cache
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc misc raw unix:0:sysinfo
+ sadc vm raw unix:0:vminfo
+ sadc misc named unix:0:system_misc
+ sadc kmem_cache named unix:0:file_cache
+ sadc ufs named ufs:0:inode_cache
+ sadc misc raw cpu_stat:0:cpu_stat0
+ sadc kmem_cache named unix:0:kmem_magazine_1
+ sadc kmem_cache named unix:0:kmem_magazine_3
+ sadc kmem_cache named unix:0:kmem_magazine_7
+ sadc kmem_cache named unix:0:kmem_magazine_15
+ sadc kmem_cache named unix:0:kmem_magazine_31
+ sadc kmem_cache named unix:0:kmem_magazine_47
+ sadc kmem_cache named unix:0:kmem_magazine_63
+ sadc kmem_cache named unix:0:kmem_magazine_95
+ sadc kmem_cache named unix:0:kmem_magazine_143
+ sadc kmem_cache named unix:0:kmem_slab_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_cache
+ sadc kmem_cache named unix:0:kmem_bufctl_audit_cache
+ sadc kmem_cache named unix:0:kmem_va_4096
+ sadc kmem_cache named unix:0:kmem_va_8192
+ sadc kmem_cache named unix:0:kmem_va_12288
+ sadc kmem_cache named unix:0:kmem_va_16384
+ sadc kmem_cache named unix:0:kmem_va_20480
+ sadc kmem_cache named unix:0:kmem_va_24576
+ sadc kmem_cache named unix:0:kmem_va_28672
+ sadc kmem_cache named unix:0:kmem_va_32768
+ sadc kmem_cache named unix:0:kmem_alloc_8
+ sadc kmem_cache named unix:0:kmem_alloc_16
+ sadc kmem_cache named unix:0:kmem_alloc_24
+ sadc kmem_cache named unix:0:kmem_alloc_32
+ sadc kmem_cache named unix:0:kmem_alloc_40
+ sadc kmem_cache named unix:0:kmem_alloc_48
+ sadc kmem_cache named unix:0:kmem_alloc_56
+ sadc kmem_cache named unix:0:kmem_alloc_64
+ sadc kmem_cache named unix:0:kmem_alloc_80
+ sadc kmem_cache named unix:0:kmem_alloc_96
+ sadc kmem_cache named unix:0:kmem_alloc_112
+ sadc kmem_cache named unix:0:kmem_alloc_128
+ sadc kmem_cache named unix:0:kmem_alloc_160
+ sadc kmem_cache named unix:0:kmem_alloc_192
+ sadc kmem_cache named unix:0:kmem_alloc_224
+ sadc kmem_cache named unix:0:kmem_alloc_256
+ sadc kmem_cache named unix:0:kmem_alloc_320
+ sadc kmem_cache named unix:0:kmem_alloc_384
+ sadc kmem_cache named unix:0:kmem_alloc_448
+ sadc kmem_cache named unix:0:kmem_alloc_512
+ sadc kmem_cache named unix:0:kmem_alloc_640
+ sadc kmem_cache named unix:0:kmem_alloc_768
+ sadc kmem_cache named unix:0:kmem_alloc_896
+ sadc kmem_cache named unix:0:kmem_alloc_1152
+ sadc kmem_cache named unix:0:kmem_alloc_1344
+ sadc kmem_cache named unix:0:kmem_alloc_1600
+ sadc kmem_cache named unix:0:kmem_alloc_2048
+ sadc kmem_cache named unix:0:kmem_alloc_2688
+ sadc kmem_cache named unix:0:kmem_alloc_4096
+ sadc kmem_cache named unix:0:kmem_alloc_8192
+ sadc kmem_cache named unix:0:kmem_alloc_12288
+ sadc kmem_cache named unix:0:kmem_alloc_16384
+ sadc kmem_cache named unix:0:streams_mblk
+ sadc kmem_cache named unix:0:streams_dblk_64
+ sadc kmem_cache named unix:0:streams_dblk_128
+ sadc kmem_cache named unix:0:streams_dblk_320
+ sadc kmem_cache named unix:0:streams_dblk_576
+ sadc kmem_cache named unix:0:streams_dblk_1088
+ sadc kmem_cache named unix:0:streams_dblk_1536
+ sadc kmem_cache named unix:0:streams_dblk_1984
+ sadc kmem_cache named unix:0:streams_dblk_2624
+ sadc kmem_cache named unix:0:streams_dblk_3968
+ sadc kmem_cache named unix:0:streams_dblk_8192
+ sadc kmem_cache named unix:0:streams_dblk_12160
+ sadc kmem_cache named unix:0:streams_dblk_16384
+ sadc kmem_cache named unix:0:streams_dblk_20352
+ sadc kmem_cache named unix:0:streams_dblk_24576
+ sadc kmem_cache named unix:0:streams_dblk_28544
+ sadc kmem_cache named unix:0:streams_dblk_32768
+ sadc kmem_cache named unix:0:streams_dblk_36736
+ sadc kmem_cache named unix:0:streams_dblk_40960
+ sadc kmem_cache named unix:0:streams_dblk_44928
+ sadc kmem_cache named unix:0:streams_dblk_49152
+ sadc kmem_cache named unix:0:streams_dblk_53120
+ sadc kmem_cache named unix:0:streams_dblk_57344
+ sadc kmem_cache named unix:0:streams_dblk_61312
+ sadc kmem_cache named unix:0:streams_dblk_65536
+ sadc kmem_cache named unix:0:streams_dblk_69504
+ sadc kmem_cache named unix:0:streams_dblk_73728
+ sadc kmem_cache named unix:0:streams_dblk_esb
+ sadc kmem_cache named unix:0:streams_fthdr
+ sadc kmem_cache named unix:0:streams_ftblk
+ sadc kmem_cache named unix:0:multidata
+ sadc kmem_cache named unix:0:multidata_pdslab
+ sadc kmem_cache named unix:0:multidata_pattbl
+ sadc kmem_cache named unix:0:taskq_ent_cache
+ sadc kmem_cache named unix:0:taskq_cache
+ sadc kmem_cache named unix:0:kmem_io_512M_128
+ sadc kmem_cache named unix:0:kmem_io_512M_256
+ sadc kmem_cache named unix:0:kmem_io_512M_512
+ sadc kmem_cache named unix:0:kmem_io_512M_1024
+ sadc kmem_cache named unix:0:kmem_io_512M_2048
+ sadc kmem_cache named unix:0:kmem_io_512M_4096
+ sadc kmem_cache named unix:0:kmem_io_16M_128
+ sadc kmem_cache named unix:0:kmem_io_16M_256
+ sadc kmem_cache named unix:0:kmem_io_16M_512
+ sadc kmem_cache named unix:0:kmem_io_16M_1024
+ sadc kmem_cache named unix:0:kmem_io_16M_2048
+ sadc kmem_cache named unix:0:kmem_io_16M_4096
+ sadc kmem_cache named unix:0:id32_cache
+ sadc kmem_cache named unix:0:bp_map_4096
+ sadc kmem_cache named unix:0:bp_map_8192
+ sadc kmem_cache named unix:0:bp_map_12288
+ sadc kmem_cache named unix:0:bp_map_16384
+ sadc kmem_cache named unix:0:bp_map_20480
+ sadc kmem_cache named unix:0:bp_map_24576
+ sadc kmem_cache named unix:0:bp_map_28672
+ sadc kmem_cache named unix:0:bp_map_32768
+ sadc kmem_cache named unix:0:mod_hash_entries
+ sadc kmem_cache named unix:0:ipp_mod
+ sadc kmem_cache named unix:0:ipp_action
+ sadc kmem_cache named unix:0:ipp_packet
+ sadc kmem_cache named unix:0:htable_t
+ sadc kmem_cache named unix:0:hment_t
+ sadc kmem_cache named unix:0:hat_t
+ sadc kmem_cache named unix:0:HatHash
+ sadc kmem_cache named unix:0:seg_cache
+ sadc kmem_cache named unix:0:snode_cache
+ sadc kmem_cache named unix:0:dv_node_cache
+ sadc kmem_cache named unix:0:dev_info_node_cache
+ sadc kmem_cache named unix:0:segkp_4096
+ sadc kmem_cache named unix:0:segkp_8192
+ sadc kmem_cache named unix:0:segkp_12288
+ sadc kmem_cache named unix:0:segkp_16384
+ sadc kmem_cache named unix:0:segkp_20480
+ sadc kmem_cache named unix:0:thread_cache
+ sadc kmem_cache named unix:0:lwp_cache
+ sadc kmem_cache named unix:0:turnstile_cache
+ sadc kmem_cache named unix:0:cred_cache
+ sadc kmem_cache named unix:0:rctl_cache
+ sadc kmem_cache named unix:0:rctl_val_cache
+ sadc kmem_cache named unix:0:task_cache
+ sadc kmem_cache named unix:0:cyclic_id_cache
+ sadc kmem_cache named unix:0:dnlc_space_cache
+ sadc kmem_cache named unix:0:vn_cache
+ sadc kmem_cache named unix:0:file_cache
+ sadc kmem_cache named unix:0:stream_head_cache
+ sadc kmem_cache named unix:0:queue_cache
+ sadc kmem_cache named unix:0:syncq_cache
+ sadc kmem_cache named unix:0:qband_cache
+ sadc kmem_cache named unix:0:linkinfo_cache
+ sadc kmem_cache named unix:0:ciputctrl_cache
+ sadc kmem_cache named unix:0:serializer_cache
+ sadc kmem_cache named unix:0:as_cache
+ sadc kmem_cache named unix:0:marker_cache
+ sadc kmem_cache named unix:0:anon_cache
+ sadc kmem_cache named unix:0:anonmap_cache
+ sadc kmem_cache named unix:0:segvn_cache
+ sadc kmem_cache named unix:0:flk_edges
+ sadc kmem_cache named unix:0:fdb_cache
+ sadc kmem_cache named unix:0:timer_cache
+ sadc kmem_cache named unix:0:physio_buf_cache
+ sadc kmem_cache named unix:0:ufs_inode_cache
+ sadc kmem_cache named unix:0:directio_buf_cache
+ sadc kmem_cache named unix:0:lufs_save
+ sadc kmem_cache named unix:0:lufs_bufs
+ sadc kmem_cache named unix:0:lufs_mapentry_cache
+ sadc kmem_cache named unix:0:kcf_sreq_cache
+ sadc kmem_cache named unix:0:kcf_areq_cache
+ sadc kmem_cache named unix:0:kcf_context_cache
+ sadc kmem_cache named unix:0:ipsec_actions
+ sadc kmem_cache named unix:0:ipsec_selectors
+ sadc kmem_cache named unix:0:ipsec_policy
+ sadc kmem_cache named unix:0:ipsec_info
+ sadc kmem_cache named unix:0:ip_minor_arena_1
+ sadc kmem_cache named unix:0:ipcl_conn_cache
+ sadc kmem_cache named unix:0:ipcl_tcpconn_cache
+ sadc kmem_cache named unix:0:ire_cache
+ sadc kmem_cache named unix:0:tcp_timercache
+ sadc kmem_cache named unix:0:tcp_sack_info_cache
+ sadc kmem_cache named unix:0:tcp_iphc_cache
+ sadc kmem_cache named unix:0:squeue_cache
+ sadc kmem_cache named unix:0:sctp_conn_cache
+ sadc kmem_cache named unix:0:sctp_faddr_cache
+ sadc kmem_cache named unix:0:sctp_set_cache
+ sadc kmem_cache named unix:0:sctp_ftsn_set_cache
+ sadc kmem_cache named unix:0:sctpsock
+ sadc kmem_cache named unix:0:sctp_assoc
+ sadc kmem_cache named unix:0:socktpi_cache
+ sadc kmem_cache named unix:0:socktpi_unix_cache
+ sadc kmem_cache named unix:0:ncafs_cache
+ sadc kmem_cache named unix:0:process_cache
+ sadc kmem_cache named unix:0:exacct_object_cache
+ sadc kmem_cache named unix:0:fctl_cache
+ sadc kmem_cache named unix:0:tl_cache
+ sadc kmem_cache named unix:0:keysock_1
+ sadc kmem_cache named unix:0:spdsock_1
+ sadc kmem_cache named unix:0:fnode_cache
+ sadc kmem_cache named unix:0:pipe_cache
+ sadc kmem_cache named unix:0:namefs_inodes_1
+ sadc kmem_cache named unix:0:port_cache
+ sadc kmem_cache named unix:0:lnode_cache
+ sadc kmem_cache named unix:0:clnt_clts_endpnt_cache
+ sadc kmem_cache named unix:0:pty_map
+ sadc kmem_cache named unix:0:sppptun_map
+ sadc kmem_cache named unix:0:dtrace_state_cache
+ sadc kmem_cache named unix:0:qif_head_cache
+ sadc kmem_cache named unix:0:udp_minor_1
+ sadc kmem_cache named unix:0:authkern_cache
+ sadc kmem_cache named unix:0:authloopback_cache
+ sadc kmem_cache named unix:0:authdes_cache_handle
+ sadc kmem_cache named unix:0:rnode_cache
+ sadc kmem_cache named unix:0:nfs_access_cache
+ sadc kmem_cache named unix:0:client_handle_cache
+ sadc kmem_cache named unix:0:rnode4_cache
+ sadc kmem_cache named unix:0:svnode_cache
+ sadc kmem_cache named unix:0:nfs4_access_cache
+ sadc kmem_cache named unix:0:client_handle4_cache
+ sadc kmem_cache named unix:0:nfs4_ace4vals_cache
+ sadc kmem_cache named unix:0:nfs4_ace4_list_cache
+ sadc kmem_cache named unix:0:NFS_idmap_cache
+ sadc kmem_cache named unix:0:lm_vnode
+ sadc kmem_cache named unix:0:lm_xprt
+ sadc kmem_cache named unix:0:lm_sysid
+ sadc kmem_cache named unix:0:lm_client
+ sadc kmem_cache named unix:0:lm_async
+ sadc kmem_cache named unix:0:lm_sleep
+ sadc kmem_cache named unix:0:lm_config
+ sadc kmem_cache named unix:0:nfslog_small_rec
+ sadc kmem_cache named unix:0:nfslog_medium_rec
+ sadc kmem_cache named unix:0:nfslog_large_rec
+ sadc kmem_cache named unix:0:exi_cache_handle
+ sadc kmem_cache named unix:0:Client_entry_cache
+ sadc kmem_cache named unix:0:OpenOwner_entry_cache
+ sadc kmem_cache named unix:0:OpenStateID_entry_cache
+ sadc kmem_cache named unix:0:LockStateID_entry_cache
+ sadc kmem_cache named unix:0:Lockowner_entry_cache
+ sadc kmem_cache named unix:0:File_entry_cache
+ sadc kmem_cache named unix:0:DelegStateID_entry_cache
+ sadc kmem_cache named unix:0:ip_minor_1
+ sadc kmem_cache named unix:0:ar_minor_1
+ sadc kmem_cache named unix:0:icmp_minor_1
+ sadc kmem_cache named unix:0:crypto_session_cache
+ sadc kmem_cache named unix:0:fcsm_job_cache
+ sadc kmem_cache named unix:0:sd0_cache
+ sadc kmem_cache named unix:0:hsfs_hsnode_cache
+ sadc vmem named vmem:16:kmem_oversize
+ sadc disk io cmdk:0:cmdk0
+ sadc nfs io nfs:1:nfs1
+ sadc disk io sd:0:sd0
+ sadc usb_byte_count io usba:0:uhci0,bulk
+ sadc usb_byte_count io usba:0:uhci0,ctrl
+ sadc usb_byte_count io usba:0:uhci0,intr
+ sadc usb_byte_count io usba:0:uhci0,isoch
+ sadc usb_byte_count io usba:0:uhci0,total
+ sadc usb_byte_count io usba:1:uhci1,bulk
+ sadc usb_byte_count io usba:1:uhci1,ctrl
+ sadc usb_byte_count io usba:1:uhci1,intr
+ sadc usb_byte_count io usba:1:uhci1,isoch
+ sadc usb_byte_count io usba:1:uhci1,total
+
+Yep, to print the four fields from "sar -u 1 1", sadc read the ENTIRE
+KSTAT TREE FIVE TIMES.
+
+Comparing the effect of this to vmstat,
+
+ # ptime vmstat 1 6
+ kthr memory page disk faults cpu
+ r b w swap free re mf pi po fr de sr cd s0 -- -- in sy cs us sy id
+ 0 0 43 907784 115324 29 124 34 1 1 0 4 2 0 0 0 277 470 210 1 2 97
+ 0 0 38 750856 172304 1 40 0 0 0 0 0 0 0 0 0 230 224 130 1 1 98
+ 0 0 38 750856 172304 0 0 0 0 0 0 0 0 0 0 0 219 168 111 0 1 99
+ 0 0 38 750856 172304 0 0 0 0 0 0 0 0 0 0 0 226 109 113 0 0 100
+ 0 0 38 750856 172304 0 0 0 0 0 0 0 0 0 0 0 225 246 137 1 1 98
+ 0 0 38 750856 172304 0 0 0 0 0 0 0 0 0 0 0 222 175 119 0 1 99
+
+ real 5.060
+ user 0.006
+ sys 0.013
+
+Ok, so vmstat causes a total of 13 ms of sys time - much of which would
+be the fork and exec. Now lets try sar,
+
+ # ptime sar -u 1 5
+
+ SunOS jupiter 5.10 Generic i86pc 04/21/2006
+
+ 23:42:55 %usr %sys %wio %idle
+ 23:42:56 0 3 0 97
+ 23:42:57 1 2 0 97
+ 23:42:58 0 2 0 98
+ 23:42:59 1 3 0 96
+ 23:43:00 0 2 0 98
+
+ Average 0 2 0 97
+
+ real 5.148
+ user 0.010
+ sys 0.127
+
+Phwaorr - 127 ms of sys time to measure 5 samples. That is a LOT.
diff --git a/cddl/contrib/dtracetoolkit/Examples/lastwords_example.txt b/cddl/contrib/dtracetoolkit/Examples/lastwords_example.txt
new file mode 100644
index 0000000..5452d2e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/lastwords_example.txt
@@ -0,0 +1,81 @@
+The following is a demonstration of the lastwords command,
+
+
+Here we run lastwords to catch syscalls from processes named "bash" as they
+exit,
+
+ # ./lastwords bash
+ Tracing... Waiting for bash to exit...
+ 1091567219163679 1861 bash sigaction 0 0
+ 1091567219177487 1861 bash sigaction 0 0
+ 1091567219189692 1861 bash sigaction 0 0
+ 1091567219202085 1861 bash sigaction 0 0
+ 1091567219214553 1861 bash sigaction 0 0
+ 1091567219226690 1861 bash sigaction 0 0
+ 1091567219238786 1861 bash sigaction 0 0
+ 1091567219251697 1861 bash sigaction 0 0
+ 1091567219265770 1861 bash sigaction 0 0
+ 1091567219294110 1861 bash gtime 42a7c194 0
+ 1091567219428305 1861 bash write 5 0
+ 1091567219451138 1861 bash setcontext 0 0
+ 1091567219473911 1861 bash sigaction 0 0
+ 1091567219516487 1861 bash stat64 0 0
+ 1091567219547973 1861 bash open64 4 0
+ 1091567219638345 1861 bash write 5 0
+ 1091567219658886 1861 bash close 0 0
+ 1091567219689094 1861 bash open64 4 0
+ 1091567219704301 1861 bash fstat64 0 0
+ 1091567219731796 1861 bash read 2fe 0
+ 1091567219745541 1861 bash close 0 0
+ 1091567219768536 1861 bash lwp_sigmask ffbffeff 0
+ 1091567219787494 1861 bash ioctl 0 0
+ 1091567219801338 1861 bash setpgrp 6a3 0
+ 1091567219814067 1861 bash ioctl 0 0
+ 1091567219825791 1861 bash lwp_sigmask ffbffeff 0
+ 1091567219847778 1861 bash setpgrp 0 0
+ TIME PID EXEC SYSCALL RETURN ERR
+
+In another window, a bash shell was executed and then exited normally. The
+last few system calls that the bash shell made can be seen above.
+
+
+
+
+In the following example we moniter the exit of bash shells again, but this
+time the bash shell sends itself a "kill -8",
+
+ # ./lastwords bash
+ Tracing... Waiting for bash to exit...
+ 1091650185555391 1865 bash sigaction 0 0
+ 1091650185567963 1865 bash sigaction 0 0
+ 1091650185580316 1865 bash sigaction 0 0
+ 1091650185592381 1865 bash sigaction 0 0
+ 1091650185605046 1865 bash sigaction 0 0
+ 1091650185618451 1865 bash sigaction 0 0
+ 1091650185647663 1865 bash gtime 42a7c1e7 0
+ 1091650185794626 1865 bash kill 0 0
+ 1091650185836941 1865 bash lwp_sigmask ffbffeff 0
+ 1091650185884145 1865 bash stat64 0 0
+ 1091650185916135 1865 bash open64 4 0
+ 1091650186005673 1865 bash write b 0
+ 1091650186025782 1865 bash close 0 0
+ 1091650186052002 1865 bash open64 4 0
+ 1091650186067538 1865 bash fstat64 0 0
+ 1091650186094289 1865 bash read 309 0
+ 1091650186108086 1865 bash close 0 0
+ 1091650186129965 1865 bash lwp_sigmask ffbffeff 0
+ 1091650186149092 1865 bash ioctl 0 0
+ 1091650186162614 1865 bash setpgrp 6a3 0
+ 1091650186175457 1865 bash ioctl 0 0
+ 1091650186187206 1865 bash lwp_sigmask ffbffeff 0
+ 1091650186209514 1865 bash setpgrp 0 0
+ 1091650186225307 1865 bash sigaction 0 0
+ 1091650186238832 1865 bash getpid 749 0
+ 1091650186260149 1865 bash kill 0 0
+ 1091650186277925 1865 bash setcontext 0 0
+ TIME PID EXEC SYSCALL RETURN ERR
+
+The last few system calls are different, we can see the kill system call
+before bash exits.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/loads_example.txt b/cddl/contrib/dtracetoolkit/Examples/loads_example.txt
new file mode 100644
index 0000000..f369f96
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/loads_example.txt
@@ -0,0 +1,19 @@
+The following is a demonstration of the loads.d script.
+
+
+Here we run both loads.d and the uptime command for comparison,
+
+ # uptime
+ 1:30am up 14 day(s), 2:27, 3 users, load average: 3.52, 3.45, 3.05
+
+ # ./loads.d
+ 2005 Jun 11 01:30:49, load average: 3.52, 3.45, 3.05
+
+Both have returned the same load average, confirming that loads.d is
+behaving as expected.
+
+
+The point of loads.d is to demonstrate fetching the same data as uptime
+does, in the DTrace language. It is not intended as a replacement
+or substitute to the uptime(1) command.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/lockbydist_example.txt b/cddl/contrib/dtracetoolkit/Examples/lockbydist_example.txt
new file mode 100644
index 0000000..7310e5a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/lockbydist_example.txt
@@ -0,0 +1,114 @@
+The following is a demonstration of the lockbyproc.d script,
+
+ # lockbydist.d
+ dtrace: description 'lockstat:::adaptive-block ' matched 1 probe
+ ^C
+
+ metadata-manager
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ sched
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 65536 | 0
+
+ oracle
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@ 9
+ 65536 |@@@@@@@@@@@@@@@@@@@@@ 10
+ 131072 | 0
+
+In the above output, oracle can be seen to have blocked 10 times from
+65 to 131 microseconds, and 9 times from 32 to 65 microseconds. sched,
+the kernel, has blocked several times also. metadata-manager only
+blocked once, which was at least 262 microseconds.
+
+
+
+The following is a longer sample,
+
+ # lockbydist.d
+ dtrace: description 'lockstat:::adaptive-block ' matched 1 probe
+ ^C
+
+ svc.startd
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32768 | 0
+
+ java
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ oracle
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 65536 |@@@@@@@@@@@@@ 2
+ 131072 | 0
+
+ mysql-test-run
+ value ------------- Distribution ------------- count
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@@@@@ 1
+ 262144 |@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ pageout
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@ 1
+ 65536 | 0
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 524288 | 0
+
+ mysqltest
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@ 1
+ 65536 |@@@@@@@@@@@ 2
+ 131072 |@@@@@@@@@@@ 2
+ 262144 |@@@@@@@@@@@ 2
+ 524288 | 0
+
+ sched
+ value ------------- Distribution ------------- count
+ 8192 | 0
+ 16384 |@@@@@@@@@@@ 11
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 25
+ 65536 | 0
+ 131072 |@ 1
+ 262144 |@@ 2
+ 524288 | 0
+
+ mysqld
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@ 22
+ 65536 |@@@@@@@@@ 9
+ 131072 | 0
+ 262144 |@@@@ 4
+ 524288 | 0
+ 1048576 | 0
+ 2097152 | 0
+ 4194304 |@@ 2
+ 8388608 |@@@@ 4
+ 16777216 | 0
+
+The length of time threads were blocked, and the number of such blocks
+can be easily observed from the above output.
+
+mysqld can be seen to have many short blocks: 22 from 32 -> 65 microseconds,
+and a few larger blocks: 4 from 8 -> 16 ms.
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/lockbyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/lockbyproc_example.txt
new file mode 100644
index 0000000..1109235
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/lockbyproc_example.txt
@@ -0,0 +1,42 @@
+The following is a demonstration of the lockbyproc.d script,
+
+ # lockbyproc.d
+ dtrace: description 'lockstat:::adaptive-block ' matched 1 probe
+ ^C
+
+ pageout 49438
+ mysql-test-run 96414
+ oracle 149086
+ sched 220601
+
+The above output shows that threads belonging to sched, the kernel, spent
+a total of 220 microseconds waiting for an adaptive mutex lock.
+
+
+
+
+This example sampled for a longer interval,
+
+ # lockbyproc.d
+ dtrace: description 'lockstat:::adaptive-block ' matched 1 probe
+ ^C
+
+ init 136228
+ java 371896
+ oracle 783402
+ sched 2315779
+ mysqltest 9428277
+ mysql-test-run 10093658
+ mysqld 17412999
+ fsflush 19676738
+
+Here we can see threads belonging to fsflush have spent a total of 19.7 ms
+waiting for an adaptive mutex. Note: it's not easy to say that it means a
+19.7 ms delay in the completion of the fsflush program, as this value is
+the sum of the block times across all the threads. So it is possible that
+many threads were blocked at the same time, eg, it could have been 19 threads
+blocked during the same 1 ms.
+
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/minfbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/minfbypid_example.txt
new file mode 100644
index 0000000..c2fffb4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/minfbypid_example.txt
@@ -0,0 +1,20 @@
+The following is a demonstration of the minfbypid.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # minfbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD MINFAULTS
+ 11021 dtrace 54
+ 11023 ls 56
+ 11024 df 57
+ 11023 bash 75
+ 11022 bash 75
+ 11024 bash 76
+ 11022 find 91
+
+In the above output, we can see that each of the bash shells had about 75
+minor faults each. Minor faults are an indication of memory consumption.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/minfbyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/minfbyproc_example.txt
new file mode 100644
index 0000000..0c1ce84
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/minfbyproc_example.txt
@@ -0,0 +1,14 @@
+The following is an example of the minfbyproc.d script,
+
+ # minfbyproc.d
+ dtrace: description 'vminfo:::as_fault ' matched 1 probe
+ ^C
+
+ mozilla-bin 18
+ dtrace 57
+ find 64
+ bash 150
+ tar 501
+
+In the above output, tar processes caused 501 minor faults.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/mmapfiles_example.txt b/cddl/contrib/dtracetoolkit/Examples/mmapfiles_example.txt
new file mode 100644
index 0000000..eca4370
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/mmapfiles_example.txt
@@ -0,0 +1,109 @@
+The following is a demonstration of the mmapfiles.d script.
+
+Here we run mmapfiles.d while in another window a new bash shell is started.
+The files that were mapped in aren't suprising, they are the common shared
+librarios,
+
+ # mmapfiles.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ MMAPS CMD PATHNAME
+ 1 bash /lib/libdl.so.1
+ 3 bash /lib/libsocket.so.1
+ 3 bash /lib/libnsl.so.1
+ 3 bash /lib/libc.so.1
+ 3 bash /lib/libcurses.so.1
+
+
+
+Now we examine zsh. This time a number of extra libraries are mapped,
+
+ # mmapfiles.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ MMAPS CMD PATHNAME
+ 1 zsh /lib/libdl.so.1
+ 3 getent /lib/libc.so.1
+ 3 getent /lib/libnsl.so.1
+ 3 getent /lib/libsocket.so.1
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/parameter.so
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/zutil.so
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/complete.so
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/stat.so
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/zle.so
+ 3 tset /lib/libc.so.1
+ 3 tset /opt/sfw/lib/libncurses.so.5.2
+ 3 zsh /lib/libc.so.1
+ 3 zsh /lib/libm.so.2
+ 3 zsh /lib/libcurses.so.1
+ 3 zsh /lib/libnsl.so.1
+ 3 zsh /usr/sfw/lib/zsh/4.2.1/zsh/complist.so
+ 3 zsh /lib/libsocket.so.1
+
+
+
+Sometimes the output can be quite suprising. The following shows the mmaps
+caused by the "sdtaudiocontrol" tool, a java tool to change the volume levels
+on Solaris,
+
+ # mmapfiles.d
+ Tracing... Hit Ctrl-C to end.
+
+ MMAPS CMD PATHNAME
+ 1 java /usr/jdk/packages/jmf/lib/ext/jmplay.jar
+ 1 java /usr/dt/appconfig/sdtaudiocontrol/classes/SDtAudioControl.jar
+ 1 java /usr/dt/classes/xservices.jar
+ 1 java /usr/dt/classes/jhall.jar
+ 1 java /usr/dt/classes/jsearch.jar
+ 1 java /usr/jdk/packages/jmf/lib/ext/mp3plugin.jar
+ 1 java /usr/jdk/packages/jmf/lib/ext/jmfmp3.jar
+ 1 java /usr/jdk/packages/jmf/lib/ext/multiplayer.jar
+ 1 java /usr/jdk/packages/jmf/lib/ext/mediaplayer.jar
+ 1 java /usr/jdk/packages/jmf/lib/ext/jmf.jar
+ 1 java /usr/jdk/packages/jai-imageio/lib/ext/jai_imageio.jar
+ 1 java /usr/jdk/packages/jai-imageio/lib/ext/clibwrapper_jiio.jar
+ 1 java /usr/jdk/packages/jai/lib/ext/mlibwrapper_jai.jar
+ 1 java /usr/jdk/packages/jai/lib/ext/jai_core.jar
+ 1 java /usr/jdk/packages/jai/lib/ext/jai_codec.jar
+ 1 java /usr/jdk/packages/javax.help-2.0/lib/jhall.jar
+ 1 java /usr/jdk/instances/jdk1.5.0/jre/lib/ext/sunpkcs11.jar
+ 1 java /usr/jdk/instances/jdk1.5.0/jre/lib/ext/sunjce_provider.jar
+ 1 java /usr/jdk/instances/jdk1.5.0/jre/lib/ext/localedata.jar
+ 1 java /usr/jdk/instances/jdk1.5.0/jre/lib/ext/dnsns.jar
+ 1 java /tmp/hsperfdata_root/6464
+ 1 java /tmp/hsperfdata_root/6455
+ 2 java /usr/lib/libsched.so.1
+ 2 java /usr/jdk/instances/jdk1.5.0/jre/lib/charsets.jar
+ 2 java /usr/jdk/instances/jdk1.5.0/jre/lib/jce.jar
+ 2 java /usr/jdk/instances/jdk1.5.0/jre/lib/jsse.jar
+ 2 java /usr/jdk/instances/jdk1.5.0/jre/lib/rt.jar
+ 3 sdtaudiocontrol /lib/libc.so.1
+ 3 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/headless/libmawt.so
+ 3 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/libmlib_image.so
+ 3 ls /lib/libc.so.1
+ 3 rm /lib/libc.so.1
+ 3 java /usr/dt/appconfig/sdtaudiocontrol/lib/libAudioControl.so
+ 3 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/libawt.so
+ 4 java /lib/libdl.so.1
+ 6 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/libzip.so
+ 6 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/libjava.so
+ 6 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/libverify.so
+ 6 java /lib/libscf.so.1
+ 6 java /usr/lib/libCrun.so.1
+ 6 java /lib/libnsl.so.1
+ 6 java /lib/libm.so.1
+ 6 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/client/libjvm.so
+ 6 java /lib/libsocket.so.1
+ 6 java /lib/libuutil.so.1
+ 6 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/native_threads/libhpi.so
+ 6 java /lib/libmp.so.2
+ 6 java /lib/libmd5.so.1
+ 6 java /lib/libm.so.2
+ 6 java /lib/libdoor.so.1
+ 8 java /usr/jdk/instances/jdk1.5.0/jre/lib/i386/client/classes.jsa
+ 8 java /lib/libthread.so.1
+ 12 java /lib/libc.so.1
+ 21 awk /lib/libm.so.2
+ 21 awk /lib/libc.so.1
+ 65 java /devices/pseudo/mm@0:zero
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/modcalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/modcalls_example.txt
new file mode 100644
index 0000000..f920d20
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/modcalls_example.txt
@@ -0,0 +1,47 @@
+The following is an example of the modcalls.d oneliner,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # modcalls.d
+ dtrace: script './modcalls.d' matched 18437 probes
+ ^C
+
+ ptm 2
+ mntfs 2
+ pool 2
+ kcf 4
+ pts 5
+ portfs 6
+ pset 6
+ ttcompat 9
+ ptem 9
+ devfs 13
+ ipf 15
+ namefs 20
+ ctfs 22
+ procfs 22
+ ldterm 23
+ ipgpc 48
+ sockfs 58
+ flowacct 69
+ ata 70
+ gld 75
+ rtls 76
+ specfs 83
+ ip 201
+ uhci 294
+ TS 333
+ tmpfs 694
+ doorfs 897
+ ufs 1329
+ uppc 5617
+ unix 49794
+ genunix 53445
+
+The output lists kernel modules, and the number of function calls for
+each module. For example, "rtls" - the network driver, called 76 functions.
+
+This script may be useful to determine whether drivers are "thinking" when
+troubleshooting driver issues.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/newproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/newproc_example.txt
new file mode 100644
index 0000000..f392b05
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/newproc_example.txt
@@ -0,0 +1,19 @@
+The following is an example of the newproc.d script,
+
+ # ./newproc.d
+ dtrace: description 'proc:::exec-success ' matched 1 probe
+ CPU ID FUNCTION:NAME
+ 0 3297 exec_common:exec-success man ls
+ 0 3297 exec_common:exec-success sh -c cd /usr/share/man; tbl /usr/share/man/man1/ls.1 |neqn /usr/share/lib/pub/
+ 0 3297 exec_common:exec-success tbl /usr/share/man/man1/ls.1
+ 0 3297 exec_common:exec-success neqn /usr/share/lib/pub/eqnchar -
+ 0 3297 exec_common:exec-success nroff -u0 -Tlp -man -
+ 0 3297 exec_common:exec-success col -x
+ 0 3297 exec_common:exec-success sh -c trap '' 1 15; /usr/bin/mv -f/tmp/mpzIaOZF /usr/share/man/cat1/ls.1 2> /d
+ 0 3297 exec_common:exec-success /usr/bin/mv -f /tmp/mpzIaOZF /usr/share/man/cat1/ls.1
+ 0 3297 exec_common:exec-success sh -c more -s /tmp/mpzIaOZF
+ 0 3297 exec_common:exec-success more -s /tmp/mpzIaOZF
+
+The above output was caught when running "man ls". This identifies all the
+commands responsible for processing the man page.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/nfswizard_example.txt b/cddl/contrib/dtracetoolkit/Examples/nfswizard_example.txt
new file mode 100644
index 0000000..68fb185
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/nfswizard_example.txt
@@ -0,0 +1,67 @@
+The following is a demonstration of the NFS client wizard tool, nfswizard.d,
+
+
+
+ # nfswizard.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ NFS Client Wizard. 2005 Dec 2 14:59:07 -> 2005 Dec 2 14:59:14
+
+ Read: 4591616 bytes (4 Mb)
+ Write: 0 bytes (0 Mb)
+
+ Read: 640 Kb/sec
+ Write: 0 Kb/sec
+
+ NFS I/O events: 166
+ Avg response time: 8 ms
+ Max response time: 14 ms
+
+ Response times (us):
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 | 1
+ 512 |@@@ 14
+ 1024 |@ 4
+ 2048 |@@@@@@@ 30
+ 4096 |@@@@@ 20
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@ 97
+ 16384 | 0
+
+ Top 25 files accessed (bytes):
+ PATHNAME BYTES
+ /net/mars/var/tmp/adm/vold.log 4096
+ /net/mars/var/tmp/adm/uptime 4096
+ /net/mars/var/tmp/adm/mail 4096
+ /net/mars/var/tmp/adm/authlog.5 4096
+ /net/mars/var/tmp/adm/ftpd 12288
+ /net/mars/var/tmp/adm/spellhist 16384
+ /net/mars/var/tmp/adm/messages 16384
+ /net/mars/var/tmp/adm/utmpx 20480
+ /net/mars/var/tmp/adm/ftpd.2 20480
+ /net/mars/var/tmp/adm/ftpd.3 20480
+ /net/mars/var/tmp/adm/ftpd.1 24576
+ /net/mars/var/tmp/adm/ftpd.0 24576
+ /net/mars/var/tmp/adm/lastlog 28672
+ /net/mars/var/tmp/adm/ipf 61440
+ /net/mars/var/tmp/adm/loginlog 69632
+ /net/mars/var/tmp/adm/ipf.4 73728
+ /net/mars/var/tmp/adm/messages.20040906 81920
+ /net/mars/var/tmp/adm/ipf.3 102400
+ /net/mars/var/tmp/adm/ipf.1 110592
+ /net/mars/var/tmp/adm/ipf.5 114688
+ /net/mars/var/tmp/adm/ipf.2 114688
+ /net/mars/var/tmp/adm/ipf.0 122880
+ /net/mars/var/tmp/adm/route.log 266240
+ /net/mars/var/tmp/adm/pppd.log 425984
+ /net/mars/var/tmp/adm/wtmpx 2842624
+
+
+
+In the above demonstration, we run nfswizard.d for several seconds then hit
+Ctrl-C. The report contains useful information about NFS client activity,
+including response time statistics and file access details.
+
+Note: this is measuring activity caused by NFS client processes (which must
+be on the same server). It is not examining NFS server processes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/oneliners_examples.txt b/cddl/contrib/dtracetoolkit/Examples/oneliners_examples.txt
new file mode 100644
index 0000000..9ca0fa6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/oneliners_examples.txt
@@ -0,0 +1,307 @@
+#
+# DTrace OneLiners Examples
+#
+
+### New processes with arguments,
+
+# dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }'
+dtrace: description 'proc:::exec-success ' matched 1 probe
+CPU ID FUNCTION:NAME
+ 0 3297 exec_common:exec-success man ls
+ 0 3297 exec_common:exec-success sh -c cd /usr/share/man; tbl /usr/share/man/man1/ls.1 |neqn /usr/share/lib/pub/
+ 0 3297 exec_common:exec-success tbl /usr/share/man/man1/ls.1
+ 0 3297 exec_common:exec-success neqn /usr/share/lib/pub/eqnchar -
+ 0 3297 exec_common:exec-success nroff -u0 -Tlp -man -
+ 0 3297 exec_common:exec-success col -x
+ 0 3297 exec_common:exec-success sh -c trap '' 1 15; /usr/bin/mv -f /tmp/mpzIaOZF /usr/share/man/cat1/ls.1 2> /d
+ 0 3297 exec_common:exec-success /usr/bin/mv -f /tmp/mpzIaOZF /usr/share/man/cat1/ls.1
+ 0 3297 exec_common:exec-success sh -c more -s /tmp/mpzIaOZF
+ 0 3297 exec_common:exec-success more -s /tmp/mpzIaOZF
+
+
+### Files opened by process,
+
+# dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
+dtrace: description 'syscall::open*:entry ' matched 2 probes
+CPU ID FUNCTION:NAME
+ 0 14 open:entry gnome-netstatus- /dev/kstat
+ 0 14 open:entry man /var/ld/ld.config
+ 0 14 open:entry man /lib/libc.so.1
+ 0 14 open:entry man /usr/share/man/man.cf
+ 0 14 open:entry man /usr/share/man/windex
+ 0 14 open:entry man /usr/share/man/man1/ls.1
+ 0 14 open:entry man /usr/share/man/man1/ls.1
+ 0 14 open:entry man /tmp/mpqea4RF
+ 0 14 open:entry sh /var/ld/ld.config
+ 0 14 open:entry sh /lib/libc.so.1
+ 0 14 open:entry neqn /var/ld/ld.config
+ 0 14 open:entry neqn /lib/libc.so.1
+ 0 14 open:entry neqn /usr/share/lib/pub/eqnchar
+ 0 14 open:entry tbl /var/ld/ld.config
+ 0 14 open:entry tbl /lib/libc.so.1
+ 0 14 open:entry tbl /usr/share/man/man1/ls.1
+ 0 14 open:entry nroff /var/ld/ld.config
+[...]
+
+
+### Syscall count by program,
+
+# dtrace -n 'syscall:::entry { @num[execname] = count(); }'
+dtrace: description 'syscall:::entry ' matched 228 probes
+^C
+ snmpd 1
+ utmpd 2
+ inetd 2
+ nscd 7
+ svc.startd 11
+ sendmail 31
+ poold 133
+ dtrace 1720
+
+
+### Syscall count by syscall,
+
+# dtrace -n 'syscall:::entry { @num[probefunc] = count(); }'
+dtrace: description 'syscall:::entry ' matched 228 probes
+^C
+ fstat 1
+ setcontext 1
+ lwp_park 1
+ schedctl 1
+ mmap 1
+ sigaction 2
+ pset 2
+ lwp_sigmask 2
+ gtime 3
+ sysconfig 3
+ write 4
+ brk 6
+ pollsys 7
+ p_online 558
+ ioctl 579
+
+
+### Syscall count by process,
+
+# dtrace -n 'syscall:::entry { @num[pid,execname] = count(); }'
+dtrace: description 'syscall:::entry ' matched 228 probes
+^C
+ 1109 svc.startd 1
+ 4588 svc.startd 2
+ 7 svc.startd 2
+ 3950 svc.startd 2
+ 1626 nscd 2
+ 870 svc.startd 2
+ 82 nscd 6
+ 5011 sendmail 10
+ 6010 poold 74
+ 8707 dtrace 1720
+
+
+### Read bytes by process,
+
+# dtrace -n 'sysinfo:::readch { @bytes[execname] = sum(arg0); }'
+dtrace: description 'sysinfo:::readch ' matched 4 probes
+^C
+
+ mozilla-bin 16
+ gnome-smproxy 64
+ metacity 64
+ dsdm 64
+ wnck-applet 64
+ xscreensaver 96
+ gnome-terminal 900
+ ttymon 5952
+ Xorg 17544
+
+
+### Write bytes by process,
+
+# dtrace -n 'sysinfo:::writech { @bytes[execname] = sum(arg0); }'
+dtrace: description 'sysinfo:::writech ' matched 4 probes
+^C
+
+ dtrace 1
+ gnome-settings-d 8
+ xscreensaver 8
+ gnome-panel 8
+ nautilus 8
+ date 29
+ wnck-applet 120
+ bash 210
+ mozilla-bin 1497
+ ls 1947
+ metacity 3172
+ Xorg 7424
+ gnome-terminal 51955
+
+
+### Read size distribution by process,
+
+# dtrace -n 'sysinfo:::readch { @dist[execname] = quantize(arg0); }'
+dtrace: description 'sysinfo:::readch ' matched 4 probes
+^C
+[...]
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 64 |@@@ 1
+ 128 | 0
+
+ Xorg
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@ 26
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 |@@@@ 6
+ 16 |@ 2
+ 32 |@ 2
+ 64 | 0
+ 128 |@@@@@@@@ 11
+ 256 |@@@ 4
+ 512 | 0
+
+
+### Write size distribution by process,
+
+# dtrace -n 'sysinfo:::writech { @dist[execname] = quantize(arg0); }'
+dtrace: description 'sysinfo:::writech ' matched 4 probes
+^C
+[...]
+ Xorg
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 169
+ 64 |@@@ 16
+ 128 |@@ 10
+ 256 | 0
+
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@ 6
+ 2 | 0
+ 4 | 0
+ 8 | 1
+ 16 |@ 2
+ 32 |@@@ 7
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@ 63
+ 256 |@@@@ 10
+ 512 | 1
+ 1024 |@@@@@ 13
+ 2048 |@ 2
+ 4096 |@@@ 7
+
+
+### Disk size by process,
+
+# dtrace -n 'io:::start { printf("%d %s %d",pid,execname,args[0]->b_bcount); }'
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 2048
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 8192
+ 0 3271 bdev_strategy:start 16459 tar 8192
+ 0 3271 bdev_strategy:start 16459 tar 16384
+ 0 3271 bdev_strategy:start 16459 tar 2048
+ 0 3271 bdev_strategy:start 16459 tar 1024
+ 0 3271 bdev_strategy:start 16459 tar 1024
+
+
+### Pages paged in by process,
+
+# dtrace -n 'vminfo:::pgpgin { @pg[execname] = sum(arg0); }'
+dtrace: description 'vminfo:::pgpgin ' matched 1 probe
+^C
+
+ ttymon 1
+ bash 1
+ mozilla-bin 36
+ tar 6661
+
+
+### Minor faults by process,
+
+# dtrace -n 'vminfo:::as_fault { @mem[execname] = sum(arg0); }'
+dtrace: description 'vminfo:::as_fault ' matched 1 probe
+^C
+
+ mozilla-bin 18
+ dtrace 57
+ find 64
+ bash 150
+ tar 501
+
+
+### Interrupts by CPU,
+
+# dtrace -n 'sdt:::interrupt-start { @num[cpu] = count(); }'
+dtrace: description 'sdt:::interrupt-start ' matched 1 probe
+^C
+
+ 513 2
+ 515 4
+ 3 39
+ 2 39
+
+
+### New processes with arguments and time,
+
+# dtrace -qn 'syscall::exec*:return { printf("%Y %s\n",walltimestamp,curpsinfo->pr_psargs); }'
+2005 Apr 25 19:15:09 man ls
+2005 Apr 25 19:15:09 sh -c cd /usr/share/man; tbl /usr/share/man/man1/ls.1 |...
+2005 Apr 25 19:15:09 neqn /usr/share/lib/pub/eqnchar -
+2005 Apr 25 19:15:09 tbl /usr/share/man/man1/ls.1
+2005 Apr 25 19:15:09 nroff -u0 -Tlp -man -
+2005 Apr 25 19:15:09 col -x
+2005 Apr 25 19:15:10 sh -c trap '' 1 15; /usr/bin/mv -f /tmp/mpRZaqTF /usr/s...
+2005 Apr 25 19:15:10 /usr/bin/mv -f /tmp/mpRZaqTF /usr/share/man/cat1/ls.1
+2005 Apr 25 19:15:10 sh -c more -s /tmp/mpRZaqTF
+2005 Apr 25 19:15:10 more -s /tmp/mpRZaqTF
+[...]
+
+
+### Successful signal details,
+
+# dtrace -n 'proc:::signal-send /pid/ { printf("%s -%d %d",execname,args[2],args[1]->pr_pid); }'
+dtrace: description 'proc:::signal-send ' matched 1 probe
+CPU ID FUNCTION:NAME
+ 0 3303 sigtoproc:signal-send bash -15 16442
+ 0 3303 sigtoproc:signal-send bash -9 16443
+^C
+
+
+### Kernel function calls by module,
+
+# dtrace -n 'fbt:::entry { @calls[probemod] = count(); }'
+dtrace: description 'fbt:::entry ' matched 18437 probes
+^C
+
+ devfs 2
+ ptm 2
+ ipf 5
+ pts 5
+ ttcompat 9
+ ptem 9
+ ldterm 23
+ ipgpc 24
+ ufs 24
+ ata 25
+ sockfs 27
+ gld 32
+ rtls 34
+ flowacct 38
+ specfs 50
+ ip 84
+ TS 92
+ uhci 101
+ uppc 1758
+ unix 6347
+ genunix 10023
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/opensnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/opensnoop_example.txt
new file mode 100644
index 0000000..329d09b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/opensnoop_example.txt
@@ -0,0 +1,110 @@
+The following are examples of opensnoop. File open events are traced
+along with some process details.
+
+
+This first example is of the default output. The commands "cat", "cal",
+"ls" and "uname" were run. The returned file descriptor (or -1 for error) are
+shown, along with the filenames.
+
+ # ./opensnoop
+ UID PID COMM FD PATH
+ 100 3504 cat -1 /var/ld/ld.config
+ 100 3504 cat 3 /usr/lib/libc.so.1
+ 100 3504 cat 3 /etc/passwd
+ 100 3505 cal -1 /var/ld/ld.config
+ 100 3505 cal 3 /usr/lib/libc.so.1
+ 100 3505 cal 3 /usr/share/lib/zoneinfo/Australia/NSW
+ 100 3506 ls -1 /var/ld/ld.config
+ 100 3506 ls 3 /usr/lib/libc.so.1
+ 100 3507 uname -1 /var/ld/ld.config
+ 100 3507 uname 3 /usr/lib/libc.so.1
+ [...]
+
+
+Full command arguments can be fetched using -g,
+
+ # ./opensnoop -g
+ UID PID PATH FD ARGS
+ 100 3528 /var/ld/ld.config -1 cat /etc/passwd
+ 100 3528 /usr/lib/libc.so.1 3 cat /etc/passwd
+ 100 3528 /etc/passwd 3 cat /etc/passwd
+ 100 3529 /var/ld/ld.config -1 cal
+ 100 3529 /usr/lib/libc.so.1 3 cal
+ 100 3529 /usr/share/lib/zoneinfo/Australia/NSW 3 cal
+ 100 3530 /var/ld/ld.config -1 ls -l
+ 100 3530 /usr/lib/libc.so.1 3 ls -l
+ 100 3530 /var/run/name_service_door 3 ls -l
+ 100 3530 /usr/share/lib/zoneinfo/Australia/NSW 4 ls -l
+ 100 3531 /var/ld/ld.config -1 uname -a
+ 100 3531 /usr/lib/libc.so.1 3 uname -a
+ [...]
+
+
+
+The verbose option prints human readable timestamps,
+
+ # ./opensnoop -v
+ STRTIME UID PID COMM FD PATH
+ 2005 Jan 22 01:22:50 0 23212 df -1 /var/ld/ld.config
+ 2005 Jan 22 01:22:50 0 23212 df 3 /lib/libcmd.so.1
+ 2005 Jan 22 01:22:50 0 23212 df 3 /lib/libc.so.1
+ 2005 Jan 22 01:22:50 0 23212 df 3 /platform/SUNW,Sun-Fire-V210/lib/libc_psr.so.1
+ 2005 Jan 22 01:22:50 0 23212 df 3 /etc/mnttab
+ 2005 Jan 22 01:22:50 0 23211 dtrace 4 /usr/share/lib/zoneinfo/Australia/NSW
+ 2005 Jan 22 01:22:51 0 23213 uname -1 /var/ld/ld.config
+ 2005 Jan 22 01:22:51 0 23213 uname 3 /lib/libc.so.1
+ 2005 Jan 22 01:22:51 0 23213 uname 3 /platform/SUNW,Sun-Fire-V210/lib/libc_psr.so.1
+ [...]
+
+
+
+Particular files can be monitored using -f. For example,
+
+ # ./opensnoop -vgf /etc/passwd
+ STRTIME UID PID PATH FD ARGS
+ 2005 Jan 22 01:28:50 0 23242 /etc/passwd 3 cat /etc/passwd
+ 2005 Jan 22 01:28:54 0 23243 /etc/passwd 4 vi /etc/passwd
+ 2005 Jan 22 01:29:06 0 23244 /etc/passwd 3 passwd brendan
+ [...]
+
+
+
+This example is of opensnoop running on a quiet system. We can see as
+various daemons are opening files,
+
+ # ./opensnoop
+ UID PID COMM FD PATH
+ 0 253 nscd 5 /etc/user_attr
+ 0 253 nscd 5 /etc/hosts
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/rtls
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/rtls
+ 0 419 mibiisa 2 /dev/kstat
+ 0 253 nscd 5 /etc/user_attr
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/rtls
+ 0 419 mibiisa 2 /dev/kstat
+ 0 174 in.routed 8 /dev/kstat
+ 0 174 in.routed 8 /dev/kstat
+ 0 174 in.routed 6 /dev/ip
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/rtls
+ 0 419 mibiisa 2 /dev/kstat
+ 0 293 utmpd 4 /var/adm/utmpx
+ 0 293 utmpd 5 /var/adm/utmpx
+ 0 293 utmpd 6 /proc/442/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/567/psinfo
+ 0 293 utmpd 6 /proc/3013/psinfo
+ 0 419 mibiisa 2 /dev/kstat
+ 0 419 mibiisa 2 /dev/rtls
+ 0 419 mibiisa 2 /dev/kstat
+ [...]
diff --git a/cddl/contrib/dtracetoolkit/Examples/pathopens_example.txt b/cddl/contrib/dtracetoolkit/Examples/pathopens_example.txt
new file mode 100644
index 0000000..b5004dd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pathopens_example.txt
@@ -0,0 +1,32 @@
+The following is a demonstration of the pathopens.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # pathopens.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ COUNT PATHNAME
+ 1 /lib/libcmd.so.1
+ 1 /export/home/root/DTrace/Dexplorer/dexplorer
+ 1 /lib/libmd5.so.1
+ 1 /lib/libaio.so.1
+ 1 /lib/librt.so.1
+ 1 /etc/security/prof_attr
+ 1 /etc/mnttab
+ 2 /devices/pseudo/devinfo@0:devinfo
+ 2 /dev/kstat
+ 2 /lib/libnvpair.so.1
+ 2 /lib/libkstat.so.1
+ 2 /lib/libdevinfo.so.1
+ 2 /lib/libnsl.so.1
+ 4 /lib/libc.so.1
+ 4 /var/ld/ld.config
+ 8 /export/home/brendan/Utils_solx86/setiathome-3.08.i386-pc-solaris2.6/outfile.sah
+
+In the above output, many of the files would have been opened using
+absolute pathnames. However the "dexplorer" file was opened using a relative
+pathname - and the pathopens.d script has correctly printed the full path.
+
+The above shows that the outfile.sah file was opened successfully 8 times.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pfilestat_example.txt b/cddl/contrib/dtracetoolkit/Examples/pfilestat_example.txt
new file mode 100644
index 0000000..b2c54a0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pfilestat_example.txt
@@ -0,0 +1,200 @@
+The following are sample outputs of the pfilestat tool for various scenarios.
+
+
+
+Starting with something simple,
+
+Running: dd if=/dev/rdsk/c0d0s0 of=/dev/null bs=56k # x86, 32-bit
+
+ # ./pfilestat `pgrep -x dd`
+
+ STATE FDNUM Time Filename
+ read 3 2% /devices/pci@0,0/pci-ide@1f,1/ide@0/cmdk@0,0
+ write 4 3% /devices/pseudo/mm@0:null
+ waitcpu 0 7%
+ running 0 16%
+ sleep-r 0 69%
+
+ STATE FDNUM KB/s Filename
+ write 4 53479 /devices/pseudo/mm@0:null
+ read 3 53479 /devices/pci@0,0/pci-ide@1f,1/ide@0/cmdk@0,0
+
+ Total event time (ms): 4999 Total Mbytes/sec: 104
+
+Most of the time we are sleeping on read, which is to be expected as dd on
+the raw device is simple -> read:entry, strategy, biodone, read:return.
+CPU time in read() itself is small.
+
+
+
+Now for the dsk device,
+
+Running: dd if=/dev/dsk/c0d0s0 of=/dev/null bs=56k # x86, 32-bit
+
+ # ./pfilestat `pgrep -x dd`
+
+ STATE FDNUM Time Filename
+ write 4 5% /devices/pseudo/mm@0:null
+ waitcpu 0 8%
+ running 0 15%
+ sleep-r 0 18%
+ read 3 53% /devices/pci@0,0/pci-ide@1f,1/ide@0/cmdk@0,0
+
+ STATE FDNUM KB/s Filename
+ read 3 53492 /devices/pci@0,0/pci-ide@1f,1/ide@0/cmdk@0,0
+ write 4 53492 /devices/pseudo/mm@0:null
+
+ Total event time (ms): 4914 Total Mbytes/sec: 102
+
+Woah, we are now spending much more time in read()! I imagine segmap is
+a busy bee. The "running" and "write" times are hardly different.
+
+
+
+Now for a SPARC demo of the same,
+
+Running: dd if=/dev/dsk/c0d0s0 of=/dev/null bs=56k # SPARC, 64-bit
+
+ # ./pfilestat `pgrep -x dd`
+
+ STATE FDNUM Time Filename
+ write 4 3% /devices/pseudo/mm@0:zero
+ waitcpu 0 7%
+ running 0 17%
+ read 3 24% /devices/pci@1f,0/pci@1,1/ide@3/dad@0,0:a
+ sleep-r 0 54%
+
+ STATE FDNUM KB/s Filename
+ read 3 13594 /devices/pci@1f,0/pci@1,1/ide@3/dad@0,0:a
+ write 4 13606 /devices/pseudo/mm@0:zero
+
+ Total event time (ms): 4741 Total Mbytes/sec: 25
+
+I did prime the cache by running this a few times first. There is less
+read() time than with the x86 32-bit demo, as I would guess that the
+process is more often exhausting the (faster) segmap cache and getting
+to the point where it must sleep. (However, do take this comparison with
+a grain of salt - my development servers aren't ideal for comparing
+statistics: one is a 867 MHz Pentium, and the other a 360 MHz Ultra 5).
+
+The file system cache is faster on 64-bit systems due to the segkpm
+enhancement in Solaris 10. For details see,
+http://blogs.sun.com/roller/page/rmc?entry=solaris_10_fast_filesystem_cache
+
+
+
+Now, back to x86.
+
+Running: tar cf /dev/null /
+
+ # ./pfilestat `pgrep -x tar`
+
+ STATE FDNUM Time Filename
+ read 11 0% /extra1/test/amd64/libCstd.so.1
+ read 11 0% /extra1/test/amd64/libXm.so
+ read 11 0% /extra1/test/amd64/libXm.so.4
+ read 11 1% /extra1/test/amd64/libgtk-x11-2.0.so
+ read 11 2% /extra1/test/amd64/libgtk-x11-2.0.so.0
+ waitcpu 0 2%
+ read 9 4% /extra1/5000
+ write 3 7% /devices/pseudo/mm@0:null
+ running 0 19%
+ sleep-r 0 46%
+
+ STATE FDNUM KB/s Filename
+ read 11 293 /extra1/test/amd64/libgdk-x11-2.0.so
+ read 11 295 /extra1/test/amd64/libgdk-x11-2.0.so.0
+ read 9 476 /extra1/1000
+ read 11 526 /extra1/test/amd64/libCstd.so.1
+ read 11 594 /extra1/test/amd64/libXm.so.4
+ read 11 594 /extra1/test/amd64/libXm.so
+ read 11 1603 /extra1/test/amd64/libgtk-x11-2.0.so.0
+ read 11 1606 /extra1/test/amd64/libgtk-x11-2.0.so
+ read 9 4078 /extra1/5000
+ write 3 21254 /devices/pseudo/mm@0:null
+
+ Total event time (ms): 4903 Total Mbytes/sec: 41
+
+Fair enough. tar is crusing along at 21 Mbytes/sec (writes to fd 3!).
+
+
+
+More interesting is to do the following,
+
+Running: tar cf - / | gzip > /dev/null
+
+ # ./pfilestat `pgrep -x tar`
+
+ STATE FDNUM Time Filename
+ read 11 0% /extra1/test/amd64/libm.so
+ read 11 0% /extra1/test/amd64/libm.so.2
+ read 11 0% /extra1/test/amd64/libnsl.so
+ read 11 0% /extra1/test/amd64/libnsl.so.1
+ read 11 0% /extra1/test/amd64/libc.so.1
+ write 3 2% <none>
+ waitcpu 0 4%
+ sleep-r 0 4%
+ running 0 6%
+ sleep-w 0 78%
+
+ STATE FDNUM KB/s Filename
+ read 11 74 /extra1/test/amd64/libldap.so
+ read 11 75 /extra1/test/amd64/libldap.so.5
+ read 11 75 /extra1/test/amd64/libresolv.so.2
+ read 11 76 /extra1/test/amd64/libresolv.so
+ read 11 97 /extra1/test/amd64/libm.so.2
+ read 11 98 /extra1/test/amd64/libm.so
+ read 11 174 /extra1/test/amd64/libnsl.so
+ read 11 176 /extra1/test/amd64/libnsl.so.1
+ read 11 216 /extra1/test/amd64/libc.so.1
+ write 3 3022 <none>
+
+ Total event time (ms): 4911 Total Mbytes/sec: 6
+
+Woah now, tar is writing 3 Mbytes/sec - AND spending 78% of it's time on
+sleep-w, sleeping on writes! Of course, this is because we are piping the
+output to gzip, which is spending a while compressing the data. 78%
+matches the time gzip was on the CPU (using either "prstat -m" or dtrace
+to measure; procfs's pr_pctcpu would take too long to catch up).
+
+
+
+
+Also interesting is,
+
+Running: perl -e 'while (1) {;}' &
+Running: perl -e 'while (1) {;}' &
+Running: perl -e 'while (1) {;}' &
+Running: perl -e 'while (1) {;}' &
+Running: tar cf /dev/null /
+
+ # ./pfilestat `pgrep -x tar`
+
+ STATE FDNUM Time Filename
+ read 11 0% /extra1/test/amd64/libxml2.so.2
+ read 11 0% /extra1/test/amd64/libgdk-x11-2.0.so.0
+ read 11 0% /extra1/test/amd64/libgdk-x11-2.0.so
+ read 11 0% /extra1/test/amd64/libCstd.so.1
+ read 11 0% /extra1/test/amd64/libgtk-x11-2.0.so.0
+ read 11 2% /extra1/test/amd64/libgtk-x11-2.0.so
+ write 3 2% /devices/pseudo/mm@0:null
+ running 0 8%
+ sleep-r 0 22%
+ waitcpu 0 65%
+
+ STATE FDNUM KB/s Filename
+ read 11 182 /extra1/test/amd64/libsun_fc.so
+ read 11 264 /extra1/test/amd64/libglib-2.0.so
+ read 11 266 /extra1/test/amd64/libglib-2.0.so.0
+ read 11 280 /extra1/test/amd64/libxml2.so.2
+ read 11 293 /extra1/test/amd64/libgdk-x11-2.0.so
+ read 11 295 /extra1/test/amd64/libgdk-x11-2.0.so.0
+ read 11 526 /extra1/test/amd64/libCstd.so.1
+ read 11 761 /extra1/test/amd64/libgtk-x11-2.0.so.0
+ read 11 1606 /extra1/test/amd64/libgtk-x11-2.0.so
+ write 3 7881 /devices/pseudo/mm@0:null
+
+ Total event time (ms): 4596 Total Mbytes/sec: 13
+
+Now we have "waitcpu" as tar competes for CPU cycles along with the greedy
+infinite perl processes.
diff --git a/cddl/contrib/dtracetoolkit/Examples/pgpginbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/pgpginbypid_example.txt
new file mode 100644
index 0000000..8326b90
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pgpginbypid_example.txt
@@ -0,0 +1,14 @@
+The following is a demonstration of the pgpginbypid.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # pgpginbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD PAGES
+ 10692 find 128
+ 10693 tar 11928
+
+In the output above, we can see which processes are responsible for page ins,
+as well as the number of pages paged in.
diff --git a/cddl/contrib/dtracetoolkit/Examples/pgpginbyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/pgpginbyproc_example.txt
new file mode 100644
index 0000000..e8bb821
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pgpginbyproc_example.txt
@@ -0,0 +1,13 @@
+The following is a demonstration of the pgpginbyproc.d script,
+
+ # pgpginbyproc.d
+ dtrace: description 'vminfo:::pgpgin ' matched 1 probe
+ ^C
+
+ ttymon 1
+ bash 1
+ mozilla-bin 36
+ tar 6661
+
+In the above output, tar processes have paged in 6661 pages from the filesystem.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_calldist_example.txt
new file mode 100644
index 0000000..db3b0af
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_calldist_example.txt
@@ -0,0 +1,84 @@
+The following are examples of php_calldist.d.
+
+This script traces the elapsed time of PHP functions and prints a report
+containing distribution plots per subroutine. Here it traces the example program
+Code/Php/func_abc.php.
+
+# php_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive function elapsed times (us),
+ func_abc.php, func, func_a
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.php, func, func_b
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.php, func, func_c
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.php, func, sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+
+Inclusive function elapsed times (us),
+ func_abc.php, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.php, func, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_abc.php, func, sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+ func_abc.php, func, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+In total, 3 subroutines were called, one each of func_a(), func_b() and
+func_c(), and sleep was called 3 times. You can see this reflected in the
+"count" column on the right.
+
+The exclusive subroutine elapsed times show that each subroutine spent
+between 256 and 512 microseconds. This time excludes the time spent in
+other subroutines.
+
+The inclusive subroutine elapsed times show that func_c() took between 0.5
+seconds and 1 second, func_b() took between 1 second and 2.1 seconds, and
+func_a() took between 2.1 seconds and 4.2 seconds to execute. This time
+includes the time spent in other subroutines called, and since func_a() called
+func_b() which called func_c(), these times make sense.
+
+These elapsed times are the absolute time from when the subroutine began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_calltime_example.txt
new file mode 100644
index 0000000..d76cb6e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_calltime_example.txt
@@ -0,0 +1,51 @@
+The following is an example of running php_calltime.d and tracing the elapsed
+times for functions.
+
+We run php_calltime.d while running the program Code/Php/func_abc.php. We can
+see that there are three sections in the DTrace output
+
+# php_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ func_abc.php func func_a 1
+ func_abc.php func func_b 1
+ func_abc.php func func_c 1
+ func_abc.php func sleep 3
+ - total - 6
+
+Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.php func func_c 330
+ func_abc.php func func_b 367
+ func_abc.php func func_a 418
+ func_abc.php func sleep 3025644
+ - total - 3026761
+
+Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.php func func_c 1010119
+ func_abc.php func func_b 2020118
+ func_abc.php func sleep 3025644
+ func_abc.php func func_a 3026761
+
+Section 1 - Count shows us how many times each function was called in the
+Code/Php/func_abc.php program, with the last line giving us a total number of
+functions called (in this case, six).
+
+Section 2 - These elapsed times shows us how many microseconds the program
+spends in each function. This does not include the time spent in any
+sub-functions called by that particular function. Again the last line gives
+us the total time in microseconds.
+
+Section 3 - These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc. In particular, for this case it has
+included the time waiting for the sleep commands.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_cpudist_example.txt
new file mode 100644
index 0000000..6da7d29
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_cpudist_example.txt
@@ -0,0 +1,84 @@
+The following are examples of php_cpudist.d.
+
+This script traces the on-CPU time of PHP functions and prints a report
+containing distribution plots per subroutine. Here it traces the example
+program Code/Php/func_abc.php.
+
+# php_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive function on-CPU times (us),
+ func_abc.php, func, func_a
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ func_abc.php, func, func_b
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ func_abc.php, func, func_c
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ func_abc.php, func, sleep
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+
+Inclusive function on-CPU times (us),
+ func_abc.php, func, func_c
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ func_abc.php, func, sleep
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 32 | 0
+
+ func_abc.php, func, func_b
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_abc.php, func, func_a
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+In total, 3 subroutines were called, one each of func_a(), func_b() and
+func_c(), and sleep was called 3 times. You can see this reflected in the
+"count" column on the right.
+
+The exclusive subroutine elapsed times show that each subroutine spent
+between 16 and 31 microseconds on CPU. This time excludes the time spent in
+other subroutines.
+
+The inclusive subroutine elapsed times show that func_c() took between 32
+microseconds and 63 microseconds on CPU; sleep ran three times and each time
+took between 16 and 31 microseconds on CPU; func_b() took between 64 and 127
+microseconds on CPU; and func_a() took between 128 and 255 microseconds on
+CPU. This time includes the time spent in other subroutines called, and since
+func_a() called func_b() which called func_c(), these times make sense.
+
+These elapsed times are the on CPU time from when the subroutine began to
+when it completed.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_cputime_example.txt
new file mode 100644
index 0000000..db218e1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_cputime_example.txt
@@ -0,0 +1,58 @@
+The following are examples of php_cputime.d.
+
+This script traces the on-CPU time of PHP functions and prints a report.
+Here it traces the example program, Code/Php/func_abc.php.
+
+# php_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ func_abc.php func func_a 1
+ func_abc.php func func_b 1
+ func_abc.php func func_c 1
+ func_abc.php func sleep 3
+ - total - 6
+
+Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.php func func_c 17
+ func_abc.php func func_b 25
+ func_abc.php func func_a 74
+ func_abc.php func sleep 93
+ - total - 210
+
+Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.php func func_c 39
+ func_abc.php func func_b 87
+ func_abc.php func sleep 93
+ func_abc.php func func_a 210
+
+In total, six functions were called; sleep was called three times and there
+was one call each of func_a(), func_b() and func_c().
+
+The exclusive subroutine on-CPU times show that func_a() spent around 74
+microseconds on-CPU, func_b() spent 25 microseconds on-CPU, and func_c() spent
+17 microseconds on-CPU. This exclusive times excludes time spent in other
+subroutines.
+
+The inclusive subroutine on-CPU times show that func_c() spent around 39
+microseconds on-CPU, func_b() spent around 87 microseconds on-CPU and
+func_a() spent around 210 microseconds. This inclusive time includes the time
+spent in other functions called (including sleep), and since func_a() called
+func_b() which called func_c(), these times make perfect sense.
+
+These on-CPU times are the time the program spent running on a CPU, from when
+the function began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
+If you study the func_abc.php program alongside the above output, the numbers
+should make sense.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_flow_example.txt
new file mode 100644
index 0000000..6470daf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_flow_example.txt
@@ -0,0 +1,36 @@
+The following are examples of php_flow.d.
+
+This is a simple script to trace the flow of PHP functions.
+Here it traces the example program, Code/Php/func_abc.php
+
+# php_flow.d
+ C TIME(us) FILE -- FUNC
+ 0 3645535409575 func_abc.php -> func_a
+ 0 3645535409653 func_abc.php -> sleep
+ 0 3645536410511 func_abc.php <- sleep
+ 0 3645536410536 func_abc.php -> func_b
+ 0 3645536410557 func_abc.php -> sleep
+ 0 3645537420627 func_abc.php <- sleep
+ 0 3645537420652 func_abc.php -> func_c
+ 0 3645537420673 func_abc.php -> sleep
+ 0 3645538430106 func_abc.php <- sleep
+ 0 3645538430125 func_abc.php <- func_c
+ 0 3645538430134 func_abc.php <- func_b
+ 0 3645538430143 func_abc.php <- func_a
+^C
+
+The fourth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - the output above begins by
+showing that func_a() began; slept, and returned from sleep; and then called
+func_b().
+
+The TIME(us) column shows time from boot in microseconds.
+
+The FILE column shows the file that was being executed.
+
+If the output looks strange, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_flowinfo_example.txt
new file mode 100644
index 0000000..3b2e3c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_flowinfo_example.txt
@@ -0,0 +1,40 @@
+The following are examples of php_flowinfo.d.
+
+This is a simple script to trace the flow of PHP functions.
+Here it traces the example program, Code/Php/func_abc.php
+
+# php_flowinfo.d
+C PID/TID DELTA(us) FILE:LINE TYPE -- FUNC
+0 18422/1 9 func_abc.php:22 func -> func_a
+0 18422/1 35 func_abc.php:18 func -> sleep
+0 18422/1 1009146 func_abc.php:18 func <- sleep
+0 18422/1 35 func_abc.php:19 func -> func_b
+0 18422/1 24 func_abc.php:11 func -> sleep
+0 18422/1 1009803 func_abc.php:11 func <- sleep
+0 18422/1 34 func_abc.php:12 func -> func_c
+0 18422/1 24 func_abc.php:5 func -> sleep
+0 18422/1 1009953 func_abc.php:5 func <- sleep
+0 18422/1 28 func_abc.php:6 func <- func_c
+0 18422/1 11 func_abc.php:13 func <- func_b
+0 18422/1 10 func_abc.php:20 func <- func_a
+^C
+
+The third column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - the output above begins by
+showing that func_a() began; slept, and returned from sleep; and then called
+func_b().
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the second line of data output
+(skipping the header) reads as "the time from func_a() beginning to
+calling the sleep function beginning was 35 microseconds".
+
+The LINE column shows the line in the file what was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_flowtime_example.txt
new file mode 100644
index 0000000..57eb69c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_flowtime_example.txt
@@ -0,0 +1,41 @@
+The following are examples of php_flowtime.d.
+
+This is a simple script to trace the flow of PHP functions.
+Here it traces the example program, Code/Php/func_abc.php
+
+# php_flowtime.d
+ C TIME(us) FILE DELTA(us) -- FUNC
+ 0 3646108339057 func_abc.php 9 -> func_a
+ 0 3646108339090 func_abc.php 32 -> sleep
+ 0 3646109341043 func_abc.php 1001953 <- sleep
+ 0 3646109341074 func_abc.php 31 -> func_b
+ 0 3646109341098 func_abc.php 23 -> sleep
+ 0 3646110350712 func_abc.php 1009614 <- sleep
+ 0 3646110350745 func_abc.php 32 -> func_c
+ 0 3646110350768 func_abc.php 23 -> sleep
+ 0 3646111362323 func_abc.php 1011554 <- sleep
+ 0 3646111362351 func_abc.php 27 <- func_c
+ 0 3646111362361 func_abc.php 10 <- func_b
+ 0 3646111362370 func_abc.php 9 <- func_a
+^C
+
+The fifth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - the output above begins by
+showing that func_a() began; slept, and returned from sleep; and then called
+func_b().
+
+The TIME(us) column shows time since boot.
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the second line of data output
+(skipping the header) reads as "the time from func_a() beginning to
+calling the sleep function beginning was 32 microseconds".
+
+The FILE column shows file that was being executed.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_funccalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_funccalls_example.txt
new file mode 100644
index 0000000..7155a71
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_funccalls_example.txt
@@ -0,0 +1,17 @@
+The following are examples of php_funccalls.d.
+
+This is a simple script to count executed PHP functions. Here it traces
+an example program, Code/Php/func_abc.php
+
+# php_funccalls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE FUNC CALLS
+ func_abc.php func_a 1
+ func_abc.php func_b 1
+ func_abc.php func_c 1
+ func_abc.php sleep 3
+
+While tracing, func_a() from the program "func_abc.php" was executed once,
+as were func_b() and func_c(). sleep was executed three times.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_malloc_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_malloc_example.txt
new file mode 100644
index 0000000..853d082
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_malloc_example.txt
@@ -0,0 +1,23 @@
+Following are examples of running php_malloc.d.
+
+Here it is running on Code/Php/func_abc.php
+
+ # php_malloc.d -p 18523
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ PHP malloc byte distributions by engine caller,
+
+
+ PHP malloc byte distributions by PHP file and function,
+
+
+Theoretically this should show you mallocs. However there weren't any in this
+example. The rest of these example files would have been so much easier to
+write if they were all like this. I would have been finished by now and would
+have been flicking through the TV channels with a nice, cold beer in hand.
+
+
+... Fixing this example is on my todo list. Check for newer versions of the
+toolkit.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_syscalls_example.txt
new file mode 100644
index 0000000..c783420
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_syscalls_example.txt
@@ -0,0 +1,22 @@
+The following are examples of php_syscalls.d.
+
+This is a simple script to count executed PHP functions and system calls.
+Here it traces an example program, Code/Php/func_abc.php
+
+# php_syscalls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID FILE TYPE NAME COUNT
+ 18419 func_abc.php func func_a 1
+ 18419 func_abc.php func func_b 1
+ 18419 func_abc.php func func_c 1
+ 18419 func_abc.php func sleep 3
+ 18419 httpd syscall nanosleep 3
+
+While tracing, four functions were called - func_a(), func_b(), func_c(), and
+sleep. There were also three instances of the system call nanosleep().
+
+This script can provide an insight to how a PHP application is interacting
+with the system, by providing both application function calls and system calls
+in the same output.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_syscolors_example.txt
new file mode 100644
index 0000000..96b26a8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_syscolors_example.txt
@@ -0,0 +1,63 @@
+The following are examples of php_syscolors.d.
+
+This is a simple script to trace the flow of PHP functions and system
+calls made, and renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Php/func_abc.php.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# php_syscolors.d
+C PID/TID DELTA(us) FILE:LINE TYPE -- NAME
+0 18426/1 8 func_abc.php:22 func -> func_a
+0 18426/1 41 func_abc.php:18 func -> sleep
+0 18426/1 15 ":- syscall -> nanosleep
+0 18426/1 1008700 ":- syscall <- nanosleep
+0 18426/1 30 func_abc.php:18 func <- sleep
+0 18426/1 42 func_abc.php:19 func -> func_b
+0 18426/1 28 func_abc.php:11 func -> sleep
+0 18426/1 14 ":- syscall -> nanosleep
+0 18426/1 1010083 ":- syscall <- nanosleep
+0 18426/1 29 func_abc.php:11 func <- sleep
+0 18426/1 43 func_abc.php:12 func -> func_c
+0 18426/1 28 func_abc.php:5 func -> sleep
+0 18426/1 14 ":- syscall -> nanosleep
+0 18426/1 1009794 ":- syscall <- nanosleep
+0 18426/1 28 func_abc.php:5 func <- sleep
+0 18426/1 34 func_abc.php:6 func <- func_c
+0 18426/1 18 func_abc.php:13 func <- func_b
+0 18426/1 17 func_abc.php:20 func <- func_a
+0 18426/1 21 ":- syscall -> fchdir
+0 18426/1 19 ":- syscall <- fchdir
+0 18426/1 9 ":- syscall -> close
+0 18426/1 13 ":- syscall <- close
+0 18426/1 35 ":- syscall -> semsys
+0 18426/1 12 ":- syscall <- semsys
+0 18426/1 7 ":- syscall -> semsys
+0 18426/1 7 ":- syscall <- semsys
+0 18426/1 66 ":- syscall -> setitimer
+0 18426/1 8 ":- syscall <- setitimer
+0 18426/1 39 ":- syscall -> read
+0 18426/1 14 ":- syscall <- read
+0 18426/1 11 ":- syscall -> writev
+0 18426/1 22 ":- syscall <- writev
+0 18426/1 23 ":- syscall -> write
+0 18426/1 110 ":- syscall <- write
+0 18426/1 61 ":- syscall -> pollsys
+
+In this excerpt:
+0 18426/1 43 func_abc.php:12 func -> func_c
+0 18426/1 28 func_abc.php:5 func -> sleep
+0 18426/1 14 ":- syscall -> nanosleep
+0 18426/1 1009794 ":- syscall <- nanosleep
+0 18426/1 28 func_abc.php:5 func <- sleep
+0 18426/1 34 func_abc.php:6 func <- func_c
+
+we can see that we are at Line 12 of the program which invokes func_c. func_c
+then invokes sleep, which uses the syscall nanosleep. Approximately one
+second later nanosleep returns, then sleep finishes, then func_c finishes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/php_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/php_who_example.txt
new file mode 100644
index 0000000..cee32b2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/php_who_example.txt
@@ -0,0 +1,10 @@
+The following are examples of the results of running php_who.d.
+
+# php_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID FUNCS FILE
+ 158525 80 7 /opt/coolstack/apache2/htdocs/php/func_abc.php
+
+Running the php_who.d while the func_abc.php program runs, we can see that
+while func_abc.php was running, it called seven functions.
diff --git a/cddl/contrib/dtracetoolkit/Examples/pidpersec_example.txt b/cddl/contrib/dtracetoolkit/Examples/pidpersec_example.txt
new file mode 100644
index 0000000..11f6bd7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pidpersec_example.txt
@@ -0,0 +1,33 @@
+The following is a demonstration of the pidpersec.d script.
+
+
+Here the program is run on an idle system,
+
+ # ./pidpersec.d
+ TIME LASTPID PID/s
+ 2005 Jun 9 22:15:09 3010 0
+ 2005 Jun 9 22:15:10 3010 0
+ 2005 Jun 9 22:15:11 3010 0
+ 2005 Jun 9 22:15:12 3010 0
+ 2005 Jun 9 22:15:13 3010 0
+ ^C
+
+This shows that there are now new processes being created.
+
+
+
+Now the script is run on a busy system, that is creating many processes
+(which happen to be short-lived),
+
+ # ./pidpersec.d
+ TIME LASTPID PID/s
+ 2005 Jun 9 22:16:30 3051 13
+ 2005 Jun 9 22:16:31 3063 12
+ 2005 Jun 9 22:16:32 3073 10
+ 2005 Jun 9 22:16:33 3084 11
+ 2005 Jun 9 22:16:34 3096 12
+ ^C
+
+Now we can see that there are over 10 new processes created each second.
+The value for lastpid confirms the rates printed.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_calldist_example.txt
new file mode 100644
index 0000000..f53b7f5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_calldist_example.txt
@@ -0,0 +1,456 @@
+The following are examples of pl_calldist.d.
+
+This script traces the elapsed time of Perl subroutines (functions) and
+prints a report containing distribution plots per subroutine. Here it
+traces the example program, Code/Perl/func_abc.pl.
+
+ # pl_calldist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Exclusive subroutine elapsed times (us),
+ func_abc.pl, sub, func_a
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.pl, sub, func_b
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.pl, sub, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+
+ Inclusive subroutine elapsed times (us),
+ func_abc.pl, sub, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.pl, sub, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_abc.pl, sub, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+In total, 3 subroutines were called - func_a(), func_b(), and func_c().
+
+The exclusive subroutine elapsed times show that each subroutine spent
+between 524 and 1048 ms. This exclusive time excludes the time spent in
+other subroutines.
+
+The inclusive subroutine elapsed times show that func_c() took between 0.5 and
+1.0 seconds, func_b() took between 1.0 and 2.1 seconds, and func_a() took
+between 2.1 and 4.2 seconds to execute. This inclusive time includes the
+time spent in other subroutines called, and since func_a() called func_b()
+which called func_c(), these times make sense.
+
+These elapsed times are the absolute time from when the subroutine began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive subroutine elapsed times (us),
+ DynaLoader.pm, sub, dl_load_flags
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Config.pm, sub, TIEHASH
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ Config.pm, sub, DESTROY
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ Config.pm, sub, import
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ register.pm, sub, mkMask
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ Config.pm, sub, FETCH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ Config.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, import
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@ 2
+ 8 |@@@@@@@@ 1
+ 16 |@@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, bits
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 1
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, unimport
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 16 |@@@@@@@@@@ 1
+ 32 | 0
+
+ AutoLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@ 1
+ 4 |@@@@@@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@ 3
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ Std.pm, sub, getopts
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ register.pm, sub, import
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ vars.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ Exporter.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@ 1
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ DynaLoader.pm, sub, bootstrap
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ warnings.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ DynaLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@ 10
+ 128 |@@@@@@@@@@@@@@@@@@ 8
+ 256 | 0
+
+ vars.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@ 1
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ Kstat.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ nicstat, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@ 1
+ 512 |@@@@@@@@@@@@@ 1
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ nicstat, sub, fetch_net_data
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ nicstat, sub, find_nets
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+
+Inclusive subroutine elapsed times (us),
+ DynaLoader.pm, sub, dl_load_flags
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Config.pm, sub, TIEHASH
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ Config.pm, sub, DESTROY
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ Config.pm, sub, import
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ register.pm, sub, mkMask
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ Config.pm, sub, FETCH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ strict.pm, sub, bits
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 1
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, import
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ Config.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ Std.pm, sub, getopts
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ register.pm, sub, import
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ strict.pm, sub, unimport
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 32 | 0
+
+ vars.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ AutoLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@ 1
+ 4 |@@@@@@@ 1
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 3
+ 32 |@@@@@@@ 1
+ 64 | 0
+
+ Exporter.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@ 1
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ DynaLoader.pm, sub, bootstrap
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ warnings.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@ 10
+ 128 |@@@@@@@@@@@@@@@@@@ 8
+ 256 | 0
+
+ vars.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 |@@@@@@@@@@@@@ 1
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ DynaLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ Kstat.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@ 1
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ nicstat, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@ 1
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ nicstat, sub, fetch_net_data
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ nicstat, sub, find_nets
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+As an example of interpreting the output: the inclusive elapsed time for
+the "print_neat" subroutine in "nicstat",
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@ 10
+ 128 |@@@@@@@@@@@@@@@@@@ 8
+ 256 | 0
+
+shows that "print_neat" was called 18 times, 10 of which took between 64
+and 127 microseconds, and 8 of which took between 128 and 255 microseconds.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_calltime_example.txt
new file mode 100644
index 0000000..3cc5480
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_calltime_example.txt
@@ -0,0 +1,150 @@
+The following are examples of pl_calltime.d.
+
+This script traces the elapsed time of Perl subroutines (functions) and
+prints a report. Here it traces the example program, Code/Perl/func_abc.pl.
+
+ # pl_calltime.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Count,
+ FILE TYPE NAME COUNT
+ func_abc.pl sub func_a 1
+ func_abc.pl sub func_b 1
+ func_abc.pl sub func_c 1
+ - total - 3
+
+ Exclusive subroutine elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.pl sub func_a 1006119
+ func_abc.pl sub func_c 1009978
+ func_abc.pl sub func_b 1010273
+ - total - 3026371
+
+ Inclusive subroutine elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.pl sub func_c 1009978
+ func_abc.pl sub func_b 2020252
+ func_abc.pl sub func_a 3026371
+
+In total, 3 subroutines were called, one of each.
+
+The exclusive subroutine elapsed times show that each subroutine spent around
+1.0 seconds of time (~1000000 us) processing code - while not in other
+subroutines.
+
+The inclusive subroutine elapsed times show that func_a() took around 3.0
+seconds to execute, followed by func_b() at 2.0 seconds, and func_c() at 1.0.
+The inclusive time includes the time spent in other subroutines called, and
+since func_a() called func_b() which called func_c(), these times make
+perfect sense.
+
+These elapsed times are the absolute time from when the subroutine began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
+If you study the func_abc.pl program alongside the above output, the numbers
+should make sense.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ Config.pm sub DESTROY 1
+ Config.pm sub TIEHASH 1
+ Config.pm sub import 1
+ DynaLoader.pm sub bootstrap 1
+ DynaLoader.pm sub dl_load_flags 1
+ Std.pm sub getopts 1
+ nicstat sub fetch_net_data 1
+ nicstat sub find_nets 1
+ register.pm sub import 1
+ warnings.pm sub BEGIN 1
+ Config.pm sub BEGIN 2
+ DynaLoader.pm sub BEGIN 2
+ Exporter.pm sub import 2
+ register.pm sub mkMask 2
+ vars.pm sub import 2
+ Kstat.pm sub BEGIN 3
+ nicstat sub BEGIN 3
+ vars.pm sub BEGIN 3
+ Config.pm sub FETCH 4
+ strict.pm sub unimport 4
+ strict.pm sub import 5
+ AutoLoader.pm sub BEGIN 6
+ strict.pm sub bits 6
+ nicstat sub print_neat 18
+ - total - 72
+
+Exclusive subroutine elapsed times (us),
+ FILE TYPE NAME TOTAL
+ DynaLoader.pm sub dl_load_flags 2
+ Config.pm sub TIEHASH 3
+ Config.pm sub DESTROY 9
+ register.pm sub mkMask 11
+ Config.pm sub import 12
+ Config.pm sub FETCH 17
+ strict.pm sub import 38
+ Config.pm sub BEGIN 38
+ strict.pm sub bits 49
+ vars.pm sub import 59
+ strict.pm sub unimport 65
+ AutoLoader.pm sub BEGIN 70
+ Std.pm sub getopts 78
+ register.pm sub import 86
+ Exporter.pm sub import 112
+ warnings.pm sub BEGIN 680
+ DynaLoader.pm sub BEGIN 1131
+ DynaLoader.pm sub bootstrap 1221
+ nicstat sub print_neat 2450
+ vars.pm sub BEGIN 2608
+ Kstat.pm sub BEGIN 3171
+ nicstat sub BEGIN 3963
+ nicstat sub fetch_net_data 45424
+ nicstat sub find_nets 55737
+ - total - 117047
+
+Inclusive subroutine elapsed times (us),
+ FILE TYPE NAME TOTAL
+ DynaLoader.pm sub dl_load_flags 2
+ Config.pm sub TIEHASH 3
+ Config.pm sub DESTROY 9
+ register.pm sub mkMask 11
+ Config.pm sub import 12
+ Config.pm sub FETCH 17
+ strict.pm sub import 46
+ strict.pm sub bits 49
+ vars.pm sub import 59
+ Config.pm sub BEGIN 64
+ strict.pm sub unimport 87
+ register.pm sub import 97
+ Std.pm sub getopts 112
+ Exporter.pm sub import 112
+ AutoLoader.pm sub BEGIN 140
+ warnings.pm sub BEGIN 680
+ DynaLoader.pm sub bootstrap 1224
+ nicstat sub print_neat 2450
+ vars.pm sub BEGIN 3412
+ DynaLoader.pm sub BEGIN 4656
+ Kstat.pm sub BEGIN 8020
+ nicstat sub BEGIN 13313
+ nicstat sub fetch_net_data 45424
+ nicstat sub find_nets 55737
+
+The output showed that the most time was spent in the subroutine find_nets(),
+with a total exclusive elapsed time of 55.7 ms. This also matches the
+total inclusive time, suggesting that find_nets() didn't call other
+subroutines.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_cpudist_example.txt
new file mode 100644
index 0000000..a2ccff8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_cpudist_example.txt
@@ -0,0 +1,470 @@
+The following are examples of pl_cpudist.d.
+
+This script traces the on-CPU time of Perl subroutines (functions) and
+prints a report containing distribution plots per subroutine. Here it
+traces the example program, Code/Perl/func_slow.pl.
+
+ # pl_cpudist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Exclusive subroutine on-CPU times (us),
+ func_slow.pl, sub, func_a
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ func_slow.pl, sub, func_b
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_slow.pl, sub, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+
+ Inclusive subroutine on-CPU times (us),
+ func_slow.pl, sub, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_slow.pl, sub, func_a
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.pl, sub, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+The exclusive subroutine on-CPU times show that func_a() spent between
+262 ms and 524 ms on-CPU, while func_b() and func_c() both spent between
+524 ms and 1048 ms on-CPU.
+
+The inclusive subroutine on-CPU times show that func_c() spent between 0.5 and
+1.0 seconds, and both func_b() and func_a() spent between 1.0 and 2.1 seconds
+of CPU time. This inclusive time includes the time spent in other subroutines
+called, and since func_a() called func_b() which called func_c(), these times
+make sense.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_cpudist.pl
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive subroutine on-CPU times (us),
+ Config.pm, sub, TIEHASH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ DynaLoader.pm, sub, dl_load_flags
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Config.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+
+ Config.pm, sub, DESTROY
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ register.pm, sub, mkMask
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ Config.pm, sub, import
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ Config.pm, sub, FETCH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 |@@@@@@@@@@ 1
+ 8 | 0
+
+ strict.pm, sub, unimport
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 8 |@@@@@@@@@@ 1
+ 16 | 0
+
+ Std.pm, sub, getopts
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ register.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ strict.pm, sub, import
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@ 1
+ 8 |@@@@@@@@ 1
+ 16 |@@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, bits
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 1
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ AutoLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@ 2
+ 8 | 0
+ 16 | 0
+ 32 |@@@@@@@ 1
+ 64 | 0
+
+ vars.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ Exporter.pm, sub, import
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 32 |@@ 1
+ 64 |@@ 1
+ 128 | 0
+
+ DynaLoader.pm, sub, bootstrap
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ warnings.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ DynaLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ vars.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ Kstat.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ nicstat, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ nicstat, sub, fetch_net_data
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ nicstat, sub, find_nets
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+
+Inclusive subroutine on-CPU times (us),
+ Config.pm, sub, TIEHASH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ DynaLoader.pm, sub, dl_load_flags
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ Config.pm, sub, DESTROY
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ register.pm, sub, mkMask
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ Config.pm, sub, import
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ Config.pm, sub, FETCH
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 |@@@@@@@@@@ 1
+ 8 | 0
+
+ Config.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, unimport
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 | 0
+
+ strict.pm, sub, import
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@ 2
+ 16 |@@@@@@@@ 1
+ 32 | 0
+
+ strict.pm, sub, bits
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 1
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ Std.pm, sub, getopts
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ register.pm, sub, import
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ vars.pm, sub, import
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ AutoLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@ 1
+ 2 | 0
+ 4 |@@@@@@@ 1
+ 8 |@@@@@@@@@@@@@ 2
+ 16 |@@@@@@@ 1
+ 32 |@@@@@@@ 1
+ 64 | 0
+
+ Exporter.pm, sub, import
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 32 |@@ 1
+ 64 |@@ 1
+ 128 | 0
+
+ DynaLoader.pm, sub, bootstrap
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ warnings.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ vars.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 | 0
+ 4 | 0
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ DynaLoader.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ Kstat.pm, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+ 16 | 0
+ 32 |@@@@@@@@@@@@@ 1
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ nicstat, sub, BEGIN
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@ 1
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ nicstat, sub, fetch_net_data
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ nicstat, sub, find_nets
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+As an example of interpreting the output: the inclusive on-CPU time for
+the "print_neat" subroutine in "nicstat",
+
+ nicstat, sub, print_neat
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 32 |@@ 1
+ 64 |@@ 1
+ 128 | 0
+
+shows that "print_neat" was called 18 times, 16 of which spent between 16
+and 31 microseconds on-CPU, once between 32 and 63 microseconds, and once
+between 64 and 127 microseconds.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_cputime_example.txt
new file mode 100644
index 0000000..5dc56ee
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_cputime_example.txt
@@ -0,0 +1,151 @@
+The following are examples of pl_cputime.d.
+
+This script traces the on-CPU time of Perl subroutines (functions) and
+prints a report. Here it traces the example program, Code/Perl/func_slow.pl.
+
+ # pl_cputime.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Count,
+ FILE TYPE NAME COUNT
+ func_slow.pl sub func_a 1
+ func_slow.pl sub func_b 1
+ func_slow.pl sub func_c 1
+ - total - 3
+
+ Exclusive subroutine on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.pl sub func_a 264193
+ func_slow.pl sub func_b 538498
+ func_slow.pl sub func_c 798961
+ - total - 1601653
+
+ Inclusive subroutine on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.pl sub func_c 798961
+ func_slow.pl sub func_b 1337459
+ func_slow.pl sub func_a 1601653
+
+In total, 3 subroutines were called, one each of func_a(), func_b() and
+func_c().
+
+The exclusive subroutine on-CPU times show that func_a() spent around 264.2 ms
+on-CPU, func_b() spent 538.5 ms, and func_c() spent 799.0 ms. This exclusive
+times excludes time spent in other subroutines.
+
+The inclusive subroutine on-CPU times show that func_c() spent around 799.0 ms
+on-CPU, func_b() spent around 1.3 seconds, and func_a() spent around 1.6
+seconds. This inclusive time includes the time spent in other subroutines
+called, and since func_a() called func_b() which called func_c(), these
+times make perfect sense.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
+If you study the func_slow.pl program alongside the above output, the numbers
+should make sense.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_cputime.pl
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ Config.pm sub DESTROY 1
+ Config.pm sub TIEHASH 1
+ Config.pm sub import 1
+ DynaLoader.pm sub bootstrap 1
+ DynaLoader.pm sub dl_load_flags 1
+ Std.pm sub getopts 1
+ nicstat sub fetch_net_data 1
+ nicstat sub find_nets 1
+ register.pm sub import 1
+ warnings.pm sub BEGIN 1
+ Config.pm sub BEGIN 2
+ DynaLoader.pm sub BEGIN 2
+ Exporter.pm sub import 2
+ register.pm sub mkMask 2
+ vars.pm sub import 2
+ Kstat.pm sub BEGIN 3
+ nicstat sub BEGIN 3
+ vars.pm sub BEGIN 3
+ Config.pm sub FETCH 4
+ strict.pm sub unimport 4
+ strict.pm sub import 5
+ AutoLoader.pm sub BEGIN 6
+ strict.pm sub bits 6
+ nicstat sub print_neat 18
+ - total - 72
+
+Exclusive subroutine on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ DynaLoader.pm sub dl_load_flags 2
+ Config.pm sub TIEHASH 2
+ Config.pm sub DESTROY 6
+ Config.pm sub BEGIN 7
+ register.pm sub mkMask 8
+ Config.pm sub import 11
+ Config.pm sub FETCH 12
+ strict.pm sub unimport 17
+ strict.pm sub import 21
+ AutoLoader.pm sub BEGIN 22
+ Std.pm sub getopts 33
+ strict.pm sub bits 40
+ register.pm sub import 51
+ vars.pm sub import 65
+ Exporter.pm sub import 88
+ nicstat sub print_neat 426
+ warnings.pm sub BEGIN 598
+ DynaLoader.pm sub bootstrap 677
+ DynaLoader.pm sub BEGIN 1015
+ Kstat.pm sub BEGIN 2627
+ vars.pm sub BEGIN 2642
+ nicstat sub BEGIN 3033
+ nicstat sub fetch_net_data 42018
+ nicstat sub find_nets 52094
+ - total - 105526
+
+Inclusive subroutine on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ DynaLoader.pm sub dl_load_flags 2
+ Config.pm sub TIEHASH 2
+ Config.pm sub DESTROY 6
+ register.pm sub mkMask 8
+ Config.pm sub import 11
+ Config.pm sub FETCH 12
+ Config.pm sub BEGIN 19
+ strict.pm sub import 28
+ strict.pm sub unimport 35
+ strict.pm sub bits 40
+ AutoLoader.pm sub BEGIN 51
+ register.pm sub import 59
+ Std.pm sub getopts 63
+ vars.pm sub import 65
+ Exporter.pm sub import 88
+ nicstat sub print_neat 426
+ warnings.pm sub BEGIN 598
+ DynaLoader.pm sub bootstrap 680
+ vars.pm sub BEGIN 3313
+ DynaLoader.pm sub BEGIN 4401
+ Kstat.pm sub BEGIN 7124
+ nicstat sub BEGIN 10916
+ nicstat sub fetch_net_data 42018
+ nicstat sub find_nets 52094
+
+The output showed that the most CPU time was spent in the subroutine
+find_nets(), with a total exclusive on-CPU time of 52.1 ms. This also matches
+the total inclusive time, suggesting that find_nets() didn't call other
+subroutines.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_flow_example.txt
new file mode 100644
index 0000000..dcce6e0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_flow_example.txt
@@ -0,0 +1,179 @@
+The following are examples of pl_flow.d.
+
+This is a simple script to trace the flow of Perl subroutines (functions).
+Here it traces the example program, Code/Perl/func_abc.pl.
+
+ # pl_flow.d
+ C TIME(us) FILE -- SUB
+ 0 2979519183757 func_abc.pl -> func_a
+ 0 2979520190159 func_abc.pl -> func_b
+ 0 2979521200166 func_abc.pl -> func_c
+ 0 2979522210184 func_abc.pl <- func_c
+ 0 2979522210199 func_abc.pl <- func_b
+ 0 2979522210207 func_abc.pl <- func_a
+ ^C
+
+As each subroutine is entered, the third column is indented by 2 spaces. This
+shows which subroutine is calling who - the output abovebegins by showing that
+func_a() began, and then called func_b().
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_flow.d
+ C TIME(us) FILE -- SUB
+ 0 4181899422549 nicstat -> BEGIN
+ 0 4181899423048 strict.pm -> bits
+ 0 4181899423081 strict.pm <- bits
+ 0 4181899423105 strict.pm -> import
+ 0 4181899423126 strict.pm <- import
+ 0 4181899423133 nicstat <- BEGIN
+ 0 4181899423157 nicstat -> BEGIN
+ 0 4181899445634 Exporter.pm -> import
+ 0 4181899445730 Exporter.pm <- import
+ 0 4181899445743 nicstat <- BEGIN
+ 0 4181899445770 nicstat -> BEGIN
+ 0 4181899446066 Kstat.pm -> BEGIN
+ 0 4181899446076 strict.pm -> import
+ 0 4181899446087 strict.pm <- import
+ 0 4181899446094 Kstat.pm <- BEGIN
+ 0 4181899446116 Kstat.pm -> BEGIN
+ 0 4181899453669 DynaLoader.pm -> BEGIN
+ 0 4181899453810 vars.pm -> BEGIN
+ 0 4181899453821 vars.pm <- BEGIN
+ 0 4181899453921 vars.pm -> BEGIN
+ 0 4181899454494 warnings.pm -> BEGIN
+ 0 4181899455149 warnings.pm <- BEGIN
+ 0 4181899457183 register.pm -> import
+ 0 4181899457202 register.pm -> mkMask
+ 0 4181899457214 register.pm <- mkMask
+ 0 4181899457264 register.pm -> mkMask
+ 0 4181899457274 register.pm <- mkMask
+ 0 4181899457283 register.pm <- import
+ 0 4181899457290 vars.pm <- BEGIN
+ 0 4181899457316 vars.pm -> BEGIN
+ 0 4181899457324 strict.pm -> import
+ 0 4181899457332 strict.pm -> bits
+ 0 4181899457345 strict.pm <- bits
+ 0 4181899457353 strict.pm <- import
+ 0 4181899457359 vars.pm <- BEGIN
+ 0 4181899457652 vars.pm -> import
+ 0 4181899457703 vars.pm <- import
+ 0 4181899457710 DynaLoader.pm <- BEGIN
+ 0 4181899457758 DynaLoader.pm -> BEGIN
+ 0 4181899457883 Config.pm -> BEGIN
+ 0 4181899457890 strict.pm -> import
+ 0 4181899457899 strict.pm <- import
+ 0 4181899457906 Config.pm <- BEGIN
+ 0 4181899458038 Config.pm -> BEGIN
+ 0 4181899458045 strict.pm -> unimport
+ 0 4181899458053 strict.pm -> bits
+ 0 4181899458063 strict.pm <- bits
+ 0 4181899458077 strict.pm <- unimport
+ 0 4181899458084 Config.pm <- BEGIN
+ 0 4181899458426 Config.pm -> TIEHASH
+ 0 4181899458435 Config.pm <- TIEHASH
+ 0 4181899458476 Config.pm -> import
+ 0 4181899458493 Config.pm <- import
+ 0 4181899458500 DynaLoader.pm <- BEGIN
+ 0 4181899459978 AutoLoader.pm -> BEGIN
+ 0 4181899459990 strict.pm -> import
+ 0 4181899460033 strict.pm <- import
+ 0 4181899460064 AutoLoader.pm <- BEGIN
+ 0 4181899460088 AutoLoader.pm -> BEGIN
+ 0 4181899460096 AutoLoader.pm <- BEGIN
+ 0 4181899460187 AutoLoader.pm -> BEGIN
+ 0 4181899460199 AutoLoader.pm <- BEGIN
+ 0 4181899460582 AutoLoader.pm -> BEGIN
+ 0 4181899460590 strict.pm -> unimport
+ 0 4181899460598 strict.pm -> bits
+ 0 4181899460611 strict.pm <- bits
+ 0 4181899460619 strict.pm <- unimport
+ 0 4181899460625 AutoLoader.pm <- BEGIN
+ 0 4181899460830 AutoLoader.pm -> BEGIN
+ 0 4181899460838 strict.pm -> unimport
+ 0 4181899460845 strict.pm -> bits
+ 0 4181899460855 strict.pm <- bits
+ 0 4181899460862 strict.pm <- unimport
+ 0 4181899460869 AutoLoader.pm <- BEGIN
+ 0 4181899461092 AutoLoader.pm -> BEGIN
+ 0 4181899461100 strict.pm -> unimport
+ 0 4181899461107 strict.pm -> bits
+ 0 4181899461116 strict.pm <- bits
+ 0 4181899461124 strict.pm <- unimport
+ 0 4181899461130 AutoLoader.pm <- BEGIN
+ 0 4181899461238 Config.pm -> FETCH
+ 0 4181899461250 Config.pm <- FETCH
+ 0 4181899461264 Config.pm -> FETCH
+ 0 4181899461272 Config.pm <- FETCH
+ 0 4181899461282 Config.pm -> FETCH
+ 0 4181899461290 Config.pm <- FETCH
+ 0 4181899461299 Config.pm -> FETCH
+ 0 4181899461307 Config.pm <- FETCH
+ 0 4181899461403 Kstat.pm <- BEGIN
+ 0 4181899461432 Kstat.pm -> BEGIN
+ 0 4181899461440 vars.pm -> import
+ 0 4181899461476 vars.pm <- import
+ 0 4181899461483 Kstat.pm <- BEGIN
+ 0 4181899461539 DynaLoader.pm -> bootstrap
+ 0 4181899461769 DynaLoader.pm -> dl_load_flags
+ 0 4181899461777 DynaLoader.pm <- dl_load_flags
+ 0 4181899462208 DynaLoader.pm <- bootstrap
+ 0 4181899462231 nicstat <- BEGIN
+ 0 4181899468306 Std.pm -> getopts
+ 0 4181899468351 Exporter.pm -> import
+ 0 4181899468390 Exporter.pm <- import
+ 0 4181899468405 Std.pm <- getopts
+ 0 4181899468426 nicstat -> find_nets
+ 0 4181899521011 nicstat <- find_nets
+ 0 4181899521415 nicstat -> fetch_net_data
+ 0 4181899564973 nicstat <- fetch_net_data
+ 0 4181899565526 nicstat -> print_neat
+ 0 4181899565672 nicstat <- print_neat
+ 0 4181899565680 nicstat -> print_neat
+ 0 4181899565902 nicstat <- print_neat
+ 0 4181899565909 nicstat -> print_neat
+ 0 4181899566033 nicstat <- print_neat
+ 0 4181899566039 nicstat -> print_neat
+ 0 4181899566165 nicstat <- print_neat
+ 0 4181899566172 nicstat -> print_neat
+ 0 4181899566331 nicstat <- print_neat
+ 0 4181899566338 nicstat -> print_neat
+ 0 4181899566494 nicstat <- print_neat
+ 0 4181899566791 nicstat -> print_neat
+ 0 4181899566953 nicstat <- print_neat
+ 0 4181899566961 nicstat -> print_neat
+ 0 4181899567085 nicstat <- print_neat
+ 0 4181899567091 nicstat -> print_neat
+ 0 4181899567247 nicstat <- print_neat
+ 0 4181899567254 nicstat -> print_neat
+ 0 4181899567377 nicstat <- print_neat
+ 0 4181899567383 nicstat -> print_neat
+ 0 4181899567538 nicstat <- print_neat
+ 0 4181899567544 nicstat -> print_neat
+ 0 4181899567666 nicstat <- print_neat
+ 0 4181899567977 nicstat -> print_neat
+ 0 4181899568232 nicstat <- print_neat
+ 0 4181899568240 nicstat -> print_neat
+ 0 4181899568397 nicstat <- print_neat
+ 0 4181899568404 nicstat -> print_neat
+ 0 4181899568528 nicstat <- print_neat
+ 0 4181899568535 nicstat -> print_neat
+ 0 4181899568656 nicstat <- print_neat
+ 0 4181899568663 nicstat -> print_neat
+ 0 4181899568819 nicstat <- print_neat
+ 0 4181899568826 nicstat -> print_neat
+ 0 4181899568947 nicstat <- print_neat
+ 0 4181899572708 Config.pm -> DESTROY
+ 0 4181899572735 Config.pm <- DESTROY
+
+After initialising Perl libraries and modules, the "nicstat" program ran,
+the output matching what was expected from the source.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_flowinfo_example.txt
new file mode 100644
index 0000000..e4b406f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_flowinfo_example.txt
@@ -0,0 +1,188 @@
+The following are examples of pl_flowinfo.d.
+
+This is a simple script to trace the flow of Perl subroutines (functions).
+Here it traces the example program, Code/Perl/func_abc.pl.
+
+ # pl_flowinfo.d
+ C PID DELTA(us) FILE:LINE TYPE -- SUB
+ 0 305127 2 func_abc.pl:15 sub -> func_a
+ 0 305127 1008776 func_abc.pl:9 sub -> func_b
+ 0 305127 1010019 func_abc.pl:4 sub -> func_c
+ 0 305127 1009979 func_abc.pl:4 sub <- func_c
+ 0 305127 26 func_abc.pl:9 sub <- func_b
+ 0 305127 9 func_abc.pl:15 sub <- func_a
+ ^C
+
+As each subroutine is entered, the third column is indented by 2 spaces. This
+shows which subroutine is calling who - the output abovebegins by showing that
+func_a() began, and then called func_b().
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the second line of data output
+(skipping the header) reads as "the time from func_a() beginning to
+func_b() beginning was 1008776 us, or 1.01 seconds".
+
+The LINE column shows the line in the file what was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_flowinfo.d
+C PID DELTA(us) FILE:LINE TYPE -- SUB
+0 305132 2 nicstat:83 sub -> BEGIN
+0 305132 444 strict.pm:12 sub -> bits
+0 305132 34 strict.pm:12 sub <- bits
+0 305132 32 strict.pm:28 sub -> import
+0 305132 22 strict.pm:28 sub <- import
+0 305132 8 nicstat:83 sub <- BEGIN
+0 305132 26 nicstat:84 sub -> BEGIN
+0 305132 2339 Exporter.pm:30 sub -> import
+0 305132 83 Exporter.pm:30 sub <- import
+0 305132 14 nicstat:84 sub <- BEGIN
+0 305132 27 nicstat:85 sub -> BEGIN
+0 305132 205 Kstat.pm:34 sub -> BEGIN
+0 305132 11 strict.pm:28 sub -> import
+0 305132 11 strict.pm:28 sub <- import
+0 305132 8 Kstat.pm:34 sub <- BEGIN
+0 305132 23 Kstat.pm:35 sub -> BEGIN
+0 305132 187 DynaLoader.pm:18 sub -> BEGIN
+0 305132 73 vars.pm:3 sub -> BEGIN
+0 305132 9 vars.pm:3 sub <- BEGIN
+0 305132 34 vars.pm:7 sub -> BEGIN
+0 305132 470 warnings.pm:134 sub -> BEGIN
+0 305132 598 warnings.pm:134 sub <- BEGIN
+0 305132 2151 register.pm:37 sub -> import
+0 305132 23 register.pm:28 sub -> mkMask
+0 305132 13 register.pm:28 sub <- mkMask
+0 305132 53 register.pm:28 sub -> mkMask
+0 305132 11 register.pm:28 sub <- mkMask
+0 305132 11 register.pm:37 sub <- import
+0 305132 8 vars.pm:7 sub <- BEGIN
+0 305132 28 vars.pm:8 sub -> BEGIN
+0 305132 9 strict.pm:28 sub -> import
+0 305132 8 strict.pm:12 sub -> bits
+0 305132 13 strict.pm:12 sub <- bits
+0 305132 9 strict.pm:28 sub <- import
+0 305132 8 vars.pm:8 sub <- BEGIN
+0 305132 294 vars.pm:11 sub -> import
+0 305132 52 vars.pm:11 sub <- import
+0 305132 8 DynaLoader.pm:18 sub <- BEGIN
+0 305132 48 DynaLoader.pm:25 sub -> BEGIN
+0 305132 97 Config.pm:5 sub -> BEGIN
+0 305132 9 strict.pm:28 sub -> import
+0 305132 9 strict.pm:28 sub <- import
+0 305132 8 Config.pm:5 sub <- BEGIN
+0 305132 134 Config.pm:31 sub -> BEGIN
+0 305132 9 strict.pm:33 sub -> unimport
+0 305132 8 strict.pm:12 sub -> bits
+0 305132 11 strict.pm:12 sub <- bits
+0 305132 16 strict.pm:33 sub <- unimport
+0 305132 8 Config.pm:31 sub <- BEGIN
+0 305132 343 Config.pm:60 sub -> TIEHASH
+0 305132 10 Config.pm:60 sub <- TIEHASH
+0 305132 44 Config.pm:25 sub -> import
+0 305132 18 Config.pm:25 sub <- import
+0 305132 9 DynaLoader.pm:25 sub <- BEGIN
+0 305132 1301 AutoLoader.pm:3 sub -> BEGIN
+0 305132 11 strict.pm:28 sub -> import
+0 305132 10 strict.pm:28 sub <- import
+0 305132 9 AutoLoader.pm:3 sub <- BEGIN
+0 305132 22 AutoLoader.pm:4 sub -> BEGIN
+0 305132 9 AutoLoader.pm:4 sub <- BEGIN
+0 305132 89 AutoLoader.pm:14 sub -> BEGIN
+0 305132 13 AutoLoader.pm:14 sub <- BEGIN
+0 305132 375 AutoLoader.pm:95 sub -> BEGIN
+0 305132 9 strict.pm:33 sub -> unimport
+0 305132 8 strict.pm:12 sub -> bits
+0 305132 11 strict.pm:12 sub <- bits
+0 305132 9 strict.pm:33 sub <- unimport
+0 305132 8 AutoLoader.pm:95 sub <- BEGIN
+0 305132 203 AutoLoader.pm:128 sub -> BEGIN
+0 305132 9 strict.pm:33 sub -> unimport
+0 305132 8 strict.pm:12 sub -> bits
+0 305132 11 strict.pm:12 sub <- bits
+0 305132 9 strict.pm:33 sub <- unimport
+0 305132 8 AutoLoader.pm:128 sub <- BEGIN
+0 305132 220 AutoLoader.pm:173 sub -> BEGIN
+0 305132 9 strict.pm:33 sub -> unimport
+0 305132 8 strict.pm:12 sub -> bits
+0 305132 10 strict.pm:12 sub <- bits
+0 305132 9 strict.pm:33 sub <- unimport
+0 305132 8 AutoLoader.pm:173 sub <- BEGIN
+0 305132 103 Config.pm:52 sub -> FETCH
+0 305132 12 Config.pm:52 sub <- FETCH
+0 305132 16 Config.pm:52 sub -> FETCH
+0 305132 9 Config.pm:52 sub <- FETCH
+0 305132 11 Config.pm:52 sub -> FETCH
+0 305132 9 Config.pm:52 sub <- FETCH
+0 305132 11 Config.pm:52 sub -> FETCH
+0 305132 9 Config.pm:52 sub <- FETCH
+0 305132 95 Kstat.pm:35 sub <- BEGIN
+0 305132 29 Kstat.pm:36 sub -> BEGIN
+0 305132 10 vars.pm:11 sub -> import
+0 305132 33 vars.pm:11 sub <- import
+0 305132 8 Kstat.pm:36 sub <- BEGIN
+0 305132 56 DynaLoader.pm:133 sub -> bootstrap
+0 305132 314 DynaLoader.pm:48 sub -> dl_load_flags
+0 305132 11 DynaLoader.pm:48 sub <- dl_load_flags
+0 305132 1113 DynaLoader.pm:133 sub <- bootstrap
+0 305132 41 nicstat:85 sub <- BEGIN
+0 305132 6102 Std.pm:219 sub -> getopts
+0 305132 52 Exporter.pm:30 sub -> import
+0 305132 40 Exporter.pm:30 sub <- import
+0 305132 22 Std.pm:219 sub <- getopts
+0 305132 24 nicstat:264 sub -> find_nets
+0 305132 79662 nicstat:264 sub <- find_nets
+0 305132 420 nicstat:304 sub -> fetch_net_data
+0 305132 43871 nicstat:304 sub <- fetch_net_data
+0 305132 479 nicstat:372 sub -> print_neat
+0 305132 150 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 220 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 126 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 125 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 157 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 171 nicstat:372 sub <- print_neat
+0 305132 343 nicstat:372 sub -> print_neat
+0 305132 128 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 157 nicstat:372 sub <- print_neat
+0 305132 9 nicstat:372 sub -> print_neat
+0 305132 125 nicstat:372 sub <- print_neat
+0 305132 9 nicstat:372 sub -> print_neat
+0 305132 123 nicstat:372 sub <- print_neat
+0 305132 9 nicstat:372 sub -> print_neat
+0 305132 160 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 124 nicstat:372 sub <- print_neat
+0 305132 342 nicstat:372 sub -> print_neat
+0 305132 126 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 123 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 156 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 153 nicstat:372 sub <- print_neat
+0 305132 10 nicstat:372 sub -> print_neat
+0 305132 123 nicstat:372 sub <- print_neat
+0 305132 9 nicstat:372 sub -> print_neat
+0 305132 123 nicstat:372 sub <- print_neat
+0 305132 3736 Config.pm:63 sub -> DESTROY
+0 305132 32 Config.pm:63 sub <- DESTROY
+
+After initialising Perl libraries and modules, the "nicstat" program ran,
+the output matching what was expected from the source.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_flowtime_example.txt
new file mode 100644
index 0000000..24c53838
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_flowtime_example.txt
@@ -0,0 +1,199 @@
+The following are examples of pl_flowtime.d.
+
+This is a simple script to trace the flow of Perl subroutines (functions).
+Here it traces the example program, Code/Perl/func_abc.pl.
+
+ # pl_flowtime.d
+ C TIME(us) FILE DELTA(us) -- SUB
+ 0 4201460363351 func_abc.pl 2 -> func_a
+ 0 4201461370041 func_abc.pl 1006689 -> func_b
+ 0 4201462380038 func_abc.pl 1009997 -> func_c
+ 0 4201463390094 func_abc.pl 1010055 <- func_c
+ 0 4201463390117 func_abc.pl 23 <- func_b
+ 0 4201463390126 func_abc.pl 8 <- func_a
+ ^C
+
+As each subroutine is entered, the third column is indented by 2 spaces. This
+shows which subroutine is calling who - the output above begins by showing that
+func_a() began, and then called func_b().
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the second line of data output
+(skipping the header) reads as "the time from func_a() beginning to
+func_b() beginning was 1006689 us, or 1.01 seconds".
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+# pl_flowtime.d
+ C TIME(us) FILE DELTA(us) -- SUB
+ 0 4201691465151 nicstat 2 -> BEGIN
+ 0 4201691465593 strict.pm 441 -> bits
+ 0 4201691465625 strict.pm 32 <- bits
+ 0 4201691465655 strict.pm 29 -> import
+ 0 4201691465676 strict.pm 21 <- import
+ 0 4201691465684 nicstat 7 <- BEGIN
+ 0 4201691465710 nicstat 25 -> BEGIN
+ 0 4201691468038 Exporter.pm 2328 -> import
+ 0 4201691468121 Exporter.pm 82 <- import
+ 0 4201691468133 nicstat 12 <- BEGIN
+ 0 4201691468160 nicstat 26 -> BEGIN
+ 0 4201691468367 Kstat.pm 207 -> BEGIN
+ 0 4201691468378 strict.pm 10 -> import
+ 0 4201691468388 strict.pm 10 <- import
+ 0 4201691468396 Kstat.pm 8 <- BEGIN
+ 0 4201691468419 Kstat.pm 23 -> BEGIN
+ 0 4201691468612 DynaLoader.pm 192 -> BEGIN
+ 0 4201691468685 vars.pm 73 -> BEGIN
+ 0 4201691468694 vars.pm 8 <- BEGIN
+ 0 4201691468727 vars.pm 33 -> BEGIN
+ 0 4201691469199 warnings.pm 471 -> BEGIN
+ 0 4201691469863 warnings.pm 663 <- BEGIN
+ 0 4201691471965 register.pm 2102 -> import
+ 0 4201691471986 register.pm 21 -> mkMask
+ 0 4201691472000 register.pm 13 <- mkMask
+ 0 4201691472052 register.pm 52 -> mkMask
+ 0 4201691472063 register.pm 10 <- mkMask
+ 0 4201691472074 register.pm 10 <- import
+ 0 4201691472081 vars.pm 7 <- BEGIN
+ 0 4201691472109 vars.pm 28 -> BEGIN
+ 0 4201691472118 strict.pm 8 -> import
+ 0 4201691472126 strict.pm 8 -> bits
+ 0 4201691472139 strict.pm 12 <- bits
+ 0 4201691472148 strict.pm 9 <- import
+ 0 4201691472155 vars.pm 7 <- BEGIN
+ 0 4201691472450 vars.pm 294 -> import
+ 0 4201691472501 vars.pm 51 <- import
+ 0 4201691472509 DynaLoader.pm 7 <- BEGIN
+ 0 4201691472557 DynaLoader.pm 48 -> BEGIN
+ 0 4201691472650 Config.pm 92 -> BEGIN
+ 0 4201691472658 strict.pm 8 -> import
+ 0 4201691472667 strict.pm 8 <- import
+ 0 4201691472675 Config.pm 7 <- BEGIN
+ 0 4201691472809 Config.pm 133 -> BEGIN
+ 0 4201691472817 strict.pm 8 -> unimport
+ 0 4201691472825 strict.pm 8 -> bits
+ 0 4201691472852 strict.pm 26 <- bits
+ 0 4201691472868 strict.pm 16 <- unimport
+ 0 4201691472876 Config.pm 7 <- BEGIN
+ 0 4201691473222 Config.pm 345 -> TIEHASH
+ 0 4201691473231 Config.pm 9 <- TIEHASH
+ 0 4201691473275 Config.pm 43 -> import
+ 0 4201691473292 Config.pm 17 <- import
+ 0 4201691473301 DynaLoader.pm 8 <- BEGIN
+ 0 4201691474650 AutoLoader.pm 1349 -> BEGIN
+ 0 4201691474661 strict.pm 10 -> import
+ 0 4201691474670 strict.pm 9 <- import
+ 0 4201691474679 AutoLoader.pm 8 <- BEGIN
+ 0 4201691474701 AutoLoader.pm 21 -> BEGIN
+ 0 4201691474709 AutoLoader.pm 8 <- BEGIN
+ 0 4201691474797 AutoLoader.pm 88 -> BEGIN
+ 0 4201691474810 AutoLoader.pm 12 <- BEGIN
+ 0 4201691475186 AutoLoader.pm 376 -> BEGIN
+ 0 4201691475195 strict.pm 9 -> unimport
+ 0 4201691475203 strict.pm 7 -> bits
+ 0 4201691475214 strict.pm 10 <- bits
+ 0 4201691475223 strict.pm 8 <- unimport
+ 0 4201691475230 AutoLoader.pm 7 <- BEGIN
+ 0 4201691475435 AutoLoader.pm 204 -> BEGIN
+ 0 4201691475444 strict.pm 8 -> unimport
+ 0 4201691475451 strict.pm 7 -> bits
+ 0 4201691475462 strict.pm 10 <- bits
+ 0 4201691475470 strict.pm 8 <- unimport
+ 0 4201691475478 AutoLoader.pm 7 <- BEGIN
+ 0 4201691475697 AutoLoader.pm 219 -> BEGIN
+ 0 4201691475706 strict.pm 8 -> unimport
+ 0 4201691475714 strict.pm 7 -> bits
+ 0 4201691475724 strict.pm 10 <- bits
+ 0 4201691475732 strict.pm 8 <- unimport
+ 0 4201691475739 AutoLoader.pm 7 <- BEGIN
+ 0 4201691475842 Config.pm 102 -> FETCH
+ 0 4201691475854 Config.pm 11 <- FETCH
+ 0 4201691475870 Config.pm 15 -> FETCH
+ 0 4201691475879 Config.pm 9 <- FETCH
+ 0 4201691475890 Config.pm 10 -> FETCH
+ 0 4201691475898 Config.pm 8 <- FETCH
+ 0 4201691475909 Config.pm 10 -> FETCH
+ 0 4201691475917 Config.pm 8 <- FETCH
+ 0 4201691476012 Kstat.pm 94 <- BEGIN
+ 0 4201691476041 Kstat.pm 29 -> BEGIN
+ 0 4201691476051 vars.pm 9 -> import
+ 0 4201691476084 vars.pm 32 <- import
+ 0 4201691476091 Kstat.pm 7 <- BEGIN
+ 0 4201691476147 DynaLoader.pm 56 -> bootstrap
+ 0 4201691476373 DynaLoader.pm 225 -> dl_load_flags
+ 0 4201691476383 DynaLoader.pm 9 <- dl_load_flags
+ 0 4201691476813 DynaLoader.pm 430 <- bootstrap
+ 0 4201691476837 nicstat 23 <- BEGIN
+ 0 4201691483648 Std.pm 6811 -> getopts
+ 0 4201691483697 Exporter.pm 49 -> import
+ 0 4201691483737 Exporter.pm 39 <- import
+ 0 4201691483756 Std.pm 19 <- getopts
+ 0 4201691483780 nicstat 24 -> find_nets
+ 0 4201691539198 nicstat 55418 <- find_nets
+ 0 4201691539610 nicstat 411 -> fetch_net_data
+ 0 4201691583290 nicstat 43679 <- fetch_net_data
+ 0 4201691583781 nicstat 491 -> print_neat
+ 0 4201691583930 nicstat 149 <- print_neat
+ 0 4201691583996 nicstat 65 -> print_neat
+ 0 4201691584165 nicstat 169 <- print_neat
+ 0 4201691584174 nicstat 9 -> print_neat
+ 0 4201691584298 nicstat 124 <- print_neat
+ 0 4201691584308 nicstat 9 -> print_neat
+ 0 4201691584432 nicstat 124 <- print_neat
+ 0 4201691584473 nicstat 41 -> print_neat
+ 0 4201691584597 nicstat 123 <- print_neat
+ 0 4201691584607 nicstat 9 -> print_neat
+ 0 4201691584730 nicstat 123 <- print_neat
+ 0 4201691585091 nicstat 361 -> print_neat
+ 0 4201691585217 nicstat 125 <- print_neat
+ 0 4201691585226 nicstat 9 -> print_neat
+ 0 4201691585379 nicstat 152 <- print_neat
+ 0 4201691585389 nicstat 9 -> print_neat
+ 0 4201691585512 nicstat 123 <- print_neat
+ 0 4201691585521 nicstat 9 -> print_neat
+ 0 4201691585644 nicstat 123 <- print_neat
+ 0 4201691585653 nicstat 9 -> print_neat
+ 0 4201691585825 nicstat 171 <- print_neat
+ 0 4201691585834 nicstat 9 -> print_neat
+ 0 4201691585988 nicstat 154 <- print_neat
+ 0 4201691586274 nicstat 285 -> print_neat
+ 0 4201691586434 nicstat 160 <- print_neat
+ 0 4201691586443 nicstat 9 -> print_neat
+ 0 4201691586567 nicstat 123 <- print_neat
+ 0 4201691586576 nicstat 9 -> print_neat
+ 0 4201691586731 nicstat 154 <- print_neat
+ 0 4201691586740 nicstat 8 -> print_neat
+ 0 4201691586892 nicstat 151 <- print_neat
+ 0 4201691586901 nicstat 9 -> print_neat
+ 0 4201691587025 nicstat 123 <- print_neat
+ 0 4201691587034 nicstat 9 -> print_neat
+ 0 4201691587157 nicstat 123 <- print_neat
+ 0 4201691590909 Config.pm 3751 -> DESTROY
+ 0 4201691590938 Config.pm 29 <- DESTROY
+
+After initialising Perl libraries and modules, the "nicstat" program ran,
+the output matching what was expected from the source.
+
+The DELTA column shows that most time is spent in the find_nets() and
+fetch_nets_data() subroutines, with 55.4 ms and 44.7 ms of elapsed
+function time respectively. Those particular times were easy to interpret,
+since there were no child subroutines called, and the delta spanned
+the subroutine entry to its return.
+
+Some times get trickier to comprehend. The 2nd last line with a DELTA time
+of 3751 us, means "the time from the print_neat() subroutine completing
+to the DESTROY() subroutine starting, took 3751 us.". What is happening
+during this time? It is hard to say based on this output - since it isn't
+time within a function, rather it is time that Perl spent processing the
+main program. Since we have the last function called, we may guess where
+the program was at; or we could enhance this script to trace Perl engine
+internals as well (and/or syscalls).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_malloc_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_malloc_example.txt
new file mode 100644
index 0000000..a22a008
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_malloc_example.txt
@@ -0,0 +1,79 @@
+The following are examples of pl_malloc.d.
+
+This is an expiremental script that attepmts to identify who is calling
+malloc() from Perl, and to print byte distribution plots.
+
+Here it traces the example program, Code/Perl/func_malloc.pl.
+
+# pl_malloc.d -c ./func_malloc.pl
+Function A
+Function B
+Function C
+Tracing... Hit Ctrl-C to end.
+
+Perl malloc byte distributions by engine caller,
+
+ perl`perl_alloc, total bytes = 1
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ libc.so.1`_findbuf, total bytes = 520
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ perl`Perl_safesysmalloc, total bytes = 72106
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@ 26
+ 4 |@@@@@ 72
+ 8 |@@@@@@ 101
+ 16 |@@@@@@@@@@@@@@ 216
+ 32 |@@@@@@@@@@@ 178
+ 64 |@ 21
+ 128 | 6
+ 256 | 2
+ 512 | 4
+ 1024 | 1
+ 2048 |@ 11
+ 4096 | 1
+ 8192 | 0
+
+
+Perl malloc byte distributions by Perl file and subroutine,
+
+ func_malloc.pl, func_a, bytes total = 42504
+ value ------------- Distribution ------------- count
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ func_malloc.pl, func_b, bytes total = 100008
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 | 0
+ 65536 |@@@@@@@@@@@@@@@@@@@@ 1
+ 131072 | 0
+
+The func_malloc.pl program allocated around 100 Kbytes by creating a
+variable ($b) and populating it with 100,000 "b" characters. This has been
+identified in the last distribution plot printed, with one malloc event
+of between 64 Kbytes and 128 Kbytes in size. There was also a malloc event
+of between 4 and 7 bytes in size.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_subcalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_subcalls_example.txt
new file mode 100644
index 0000000..1ea0369
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_subcalls_example.txt
@@ -0,0 +1,53 @@
+The following are examples of pl_subcalls.d.
+
+This is a simple script to count executed Perl subroutines. Here it traces
+an example program, Code/Perl/func_abc.pl.
+
+ # pl_subcalls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE SUB CALLS
+ func_abc.pl func_a 1
+ func_abc.pl func_b 1
+ func_abc.pl func_c 1
+
+While tracing, func_a() from the program "func_abc.pl" was executed once,
+along with func_b() and func_c().
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+ # pl_subcalls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE SUB CALLS
+ Config.pm DESTROY 1
+ Config.pm TIEHASH 1
+ Config.pm import 1
+ DynaLoader.pm bootstrap 1
+ DynaLoader.pm dl_load_flags 1
+ Std.pm getopts 1
+ nicstat fetch_net_data 1
+ nicstat find_nets 1
+ register.pm import 1
+ warnings.pm BEGIN 1
+ Config.pm BEGIN 2
+ DynaLoader.pm BEGIN 2
+ Exporter.pm import 2
+ register.pm mkMask 2
+ vars.pm import 2
+ Kstat.pm BEGIN 3
+ nicstat BEGIN 3
+ vars.pm BEGIN 3
+ Config.pm FETCH 4
+ strict.pm unimport 4
+ strict.pm import 5
+ AutoLoader.pm BEGIN 6
+ strict.pm bits 6
+ nicstat print_neat 18
+
+The number of subroutines called by nicstat can be seen above, which includes
+subroutines from libraries and modules that the program used.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_syscalls_example.txt
new file mode 100644
index 0000000..8cd5094
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_syscalls_example.txt
@@ -0,0 +1,50 @@
+The following are examples of pl_syscalls.d.
+
+This is a simple script to count executed Perl subroutines and system calls.
+Here it traces an example program, Code/Perl/func_abc.pl.
+
+ # pl_syscalls.d -c ./func_abc.pl
+ Function A
+ Tracing... Hit Ctrl-C to end.
+ Function B
+ Function C
+
+ Calls for PID 305173,
+
+ FILE TYPE NAME COUNT
+ func_abc.pl sub func_a 1
+ func_abc.pl sub func_b 1
+ func_abc.pl sub func_c 1
+ func_abc.pl syscall fcntl 1
+ func_abc.pl syscall getrlimit 1
+ func_abc.pl syscall mmap 1
+ func_abc.pl syscall munmap 1
+ func_abc.pl syscall rexit 1
+ func_abc.pl syscall schedctl 1
+ func_abc.pl syscall sigpending 1
+ func_abc.pl syscall sysi86 1
+ func_abc.pl syscall getgid 2
+ func_abc.pl syscall getpid 2
+ func_abc.pl syscall getuid 2
+ func_abc.pl syscall sigaction 2
+ func_abc.pl syscall sysconfig 2
+ func_abc.pl syscall fstat64 3
+ func_abc.pl syscall nanosleep 3
+ func_abc.pl syscall read 3
+ func_abc.pl syscall setcontext 3
+ func_abc.pl syscall write 3
+ func_abc.pl syscall close 4
+ func_abc.pl syscall ioctl 4
+ func_abc.pl syscall open64 4
+ func_abc.pl syscall llseek 5
+ func_abc.pl syscall gtime 7
+ func_abc.pl syscall brk 20
+
+While tracing, three subroutines were called - func_a(), func_b() and func_c().
+There were numerous system calls made, including 20 brk()'s, 7 gtime()'s
+and 5 llseek()'s.
+
+This script can provide an insight to how an application is interacting
+with the system, by providing both application subroutine calls and
+system calls in the same output.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_syscolors_example.txt
new file mode 100644
index 0000000..3a5f249
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_syscolors_example.txt
@@ -0,0 +1,183 @@
+The following are examples of pl_syscolors.d.
+
+This is a simple script to trace the flow of Perl subroutines and system
+calls made, and renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Perl/func_abc.pl.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# pl_syscolors.d
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 305181 2 ":- syscall -> munmap
+0 305181 33 ":- syscall <- munmap
+0 305181 59 ":- syscall -> mmap
+0 305181 18 ":- syscall <- mmap
+0 305181 35 ":- syscall -> setcontext
+0 305181 8 ":- syscall <- setcontext
+0 305181 8 ":- syscall -> getrlimit
+0 305181 9 ":- syscall <- getrlimit
+0 305181 8 ":- syscall -> getpid
+0 305181 7 ":- syscall <- getpid
+0 305181 64 ":- syscall -> setcontext
+0 305181 6 ":- syscall <- setcontext
+0 305181 137 ":- syscall -> sigpending
+0 305181 8 ":- syscall <- sigpending
+0 305181 1148 ":- syscall -> sysi86
+0 305181 11 ":- syscall <- sysi86
+0 305181 105 ":- syscall -> open64
+0 305181 96 ":- syscall <- open64
+0 305181 13 ":- syscall -> ioctl
+0 305181 18 ":- syscall <- ioctl
+0 305181 14 ":- syscall -> close
+0 305181 14 ":- syscall <- close
+0 305181 123 ":- syscall -> sigaction
+0 305181 9 ":- syscall <- sigaction
+0 305181 49 ":- syscall -> brk
+0 305181 9 ":- syscall <- brk
+0 305181 8 ":- syscall -> brk
+0 305181 16 ":- syscall <- brk
+0 305181 63 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 43 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 141 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 8 ":- syscall -> brk
+0 305181 9 ":- syscall <- brk
+0 305181 24 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 30 ":- syscall -> getuid
+0 305181 7 ":- syscall <- getuid
+0 305181 10 ":- syscall -> getuid
+0 305181 6 ":- syscall <- getuid
+0 305181 10 ":- syscall -> getgid
+0 305181 7 ":- syscall <- getgid
+0 305181 9 ":- syscall -> getgid
+0 305181 6 ":- syscall <- getgid
+0 305181 117 ":- syscall -> sysconfig
+0 305181 9 ":- syscall <- sysconfig
+0 305181 19 ":- syscall -> open64
+0 305181 59 ":- syscall <- open64
+0 305181 15 ":- syscall -> read
+0 305181 11 ":- syscall <- read
+0 305181 8 ":- syscall -> close
+0 305181 8 ":- syscall <- close
+0 305181 34 ":- syscall -> gtime
+0 305181 7 ":- syscall <- gtime
+0 305181 34 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 9 ":- syscall <- brk
+0 305181 44 ":- syscall -> sysconfig
+0 305181 7 ":- syscall <- sysconfig
+0 305181 9 ":- syscall -> brk
+0 305181 6 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 145 ":- syscall -> open64
+0 305181 16 ":- syscall <- open64
+0 305181 16 ":- syscall -> fcntl
+0 305181 7 ":- syscall <- fcntl
+0 305181 10 ":- syscall -> sigaction
+0 305181 7 ":- syscall <- sigaction
+0 305181 8 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 9 ":- syscall <- brk
+0 305181 104 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 88 ":- syscall -> getpid
+0 305181 7 ":- syscall <- getpid
+0 305181 8 ":- syscall -> brk
+0 305181 6 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 8 ":- syscall <- brk
+0 305181 105 ":- syscall -> fstat64
+0 305181 10 ":- syscall <- fstat64
+0 305181 16 ":- syscall -> fstat64
+0 305181 7 ":- syscall <- fstat64
+0 305181 25 ":- syscall -> ioctl
+0 305181 8 ":- syscall <- ioctl
+0 305181 7 ":- syscall -> read
+0 305181 23 ":- syscall <- read
+0 305181 18 ":- syscall -> llseek
+0 305181 8 ":- syscall <- llseek
+0 305181 126 ":- syscall -> llseek
+0 305181 7 ":- syscall <- llseek
+0 305181 34 ":- syscall -> llseek
+0 305181 7 ":- syscall <- llseek
+0 305181 30 ":- syscall -> llseek
+0 305181 7 ":- syscall <- llseek
+0 305181 12 ":- syscall -> read
+0 305181 8 ":- syscall <- read
+0 305181 11 ":- syscall -> llseek
+0 305181 6 ":- syscall <- llseek
+0 305181 7 ":- syscall -> close
+0 305181 8 ":- syscall <- close
+0 305181 27 func_a:15 sub -> ./func_abc.pl
+0 305181 36 ":- syscall -> ioctl
+0 305181 7 ":- syscall <- ioctl
+0 305181 8 ":- syscall -> fstat64
+0 305181 8 ":- syscall <- fstat64
+0 305181 8 ":- syscall -> brk
+0 305181 7 ":- syscall <- brk
+0 305181 7 ":- syscall -> brk
+0 305181 9 ":- syscall <- brk
+0 305181 23 ":- syscall -> fstat64
+0 305181 7 ":- syscall <- fstat64
+0 305181 13 ":- syscall -> gtime
+0 305181 7 ":- syscall <- gtime
+0 305181 11 ":- syscall -> nanosleep
+0 305181 1007250 ":- syscall <- nanosleep
+0 305181 24 ":- syscall -> gtime
+0 305181 15 ":- syscall <- gtime
+0 305181 21 func_b:9 sub -> ./func_abc.pl
+0 305181 27 ":- syscall -> gtime
+0 305181 6 ":- syscall <- gtime
+0 305181 8 ":- syscall -> nanosleep
+0 305181 1009847 ":- syscall <- nanosleep
+0 305181 24 ":- syscall -> gtime
+0 305181 15 ":- syscall <- gtime
+0 305181 21 func_c:4 sub -> ./func_abc.pl
+0 305181 27 ":- syscall -> gtime
+0 305181 6 ":- syscall <- gtime
+0 305181 8 ":- syscall -> nanosleep
+Function A
+Function B
+Function C
+0 305181 1009916 ":- syscall <- nanosleep
+0 305181 24 ":- syscall -> gtime
+0 305181 15 ":- syscall <- gtime
+0 305181 20 func_c:4 sub <- ./func_abc.pl
+0 305181 29 func_b:9 sub <- ./func_abc.pl
+0 305181 12 func_a:15 sub <- ./func_abc.pl
+0 305181 51 ":- syscall -> schedctl
+0 305181 53 ":- syscall <- schedctl
+0 305181 16 ":- syscall -> setcontext
+0 305181 8 ":- syscall <- setcontext
+0 305181 21 ":- syscall -> write
+0 305181 97 ":- syscall <- write
+0 305181 28 ":- syscall -> open64
+0 305181 101 ":- syscall <- open64
+0 305181 9 ":- syscall -> ioctl
+0 305181 10 ":- syscall <- ioctl
+0 305181 10 ":- syscall -> close
+0 305181 15 ":- syscall <- close
+0 305181 35 ":- syscall -> rexit
+
+If the colors don't suit you (or you'd rather HTML colored output), it
+should be trivial to modify the script to do so.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/pl_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/pl_who_example.txt
new file mode 100644
index 0000000..4ef361d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pl_who_example.txt
@@ -0,0 +1,41 @@
+The following are examples of pl_who.d.
+
+This is a simple script to see who is executing Perl subroutines. Here it
+traces as a few examples programs are executed (from Code/Perl/*.pl).
+
+ # pl_who.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID UID SUBS FILE
+ 30817 100 3 ./func_abc.pl
+ 30818 100 3 ./func_slow.pl
+ 30819 100 3 ./func_slow.pl
+
+While tracing, the user with UID 100 executed three Perl programs;
+"func_abc.pl" once getting PID 130817, and "func_slow.pl" twice. All
+programs called three subroutines.
+
+
+
+The following traces a Perl network interface statistics tool, "nicstat"
+version 0.99,
+
+ # pl_who.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID UID SUBS FILE
+ 14977 100 1 lib/Getopt/Std.pm
+ 14977 100 1 lib/warnings.pm
+ 14977 100 2 lib/Exporter.pm
+ 14977 100 3 /usr/perl5/5.8.4/lib/Sun/Solaris/Kstat.pm
+ 14977 100 3 lib/warnings/register.pm
+ 14977 100 4 lib/DynaLoader.pm
+ 14977 100 5 lib/vars.pm
+ 14977 100 6 lib/AutoLoader.pm
+ 14977 100 9 lib/Config.pm
+ 14977 100 15 lib/strict.pm
+ 14977 100 23 /tmp/nicstat
+
+This shows the location of libraries and modules from where subroutines were
+called.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/priclass_example.txt b/cddl/contrib/dtracetoolkit/Examples/priclass_example.txt
new file mode 100644
index 0000000..bf63e09
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/priclass_example.txt
@@ -0,0 +1,82 @@
+The following is a demonstration of the priclass.d script.
+
+
+The script was run for several seconds then Ctrl-C was hit. During
+this time, other processes in different scheduling classes were
+running.
+
+ # ./priclass.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+
+ IA
+ value ------------- Distribution ------------- count
+ 40 | 0
+ 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 30
+ 60 | 0
+
+ SYS
+ value ------------- Distribution ------------- count
+ < 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4959
+ 0 | 0
+ 10 | 0
+ 20 | 0
+ 30 | 0
+ 40 | 0
+ 50 | 0
+ 60 | 30
+ 70 | 0
+ 80 | 0
+ 90 | 0
+ 100 | 0
+ 110 | 0
+ 120 | 0
+ 130 | 0
+ 140 | 0
+ 150 | 0
+ 160 | 50
+ >= 170 | 0
+
+ RT
+ value ------------- Distribution ------------- count
+ 90 | 0
+ 100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 110
+ 110 | 0
+
+ TS
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@ 2880
+ 10 |@@@@@@@ 1280
+ 20 |@@@@@ 990
+ 30 |@@@@@ 920
+ 40 |@@@@ 670
+ 50 |@@@@ 730
+ 60 | 0
+
+The output is quite interesting, and illustrates neatly the behaviour
+of different scheduling classes.
+
+The IA interactive class had 30 samples of a 50 to 59 priority, a fairly
+high priority. This class is used for interactive processes, such as
+the windowing system. I had clicked on a few windows to create this
+activity.
+
+The SYS system class has had 4959 samples at a < 0 priority - the lowest,
+which was for the idle thread. There are a few samples at higher
+priorities, including some in the 160 to 169 range (the highest), which
+are for interrupt threads. The system class is used by the kernel.
+
+The RT real time class had 110 samples in the 100 to 109 priority range.
+This class is designed for real-time applications, those that must have
+a consistant response time regardless of other process activity. For that
+reason, the RT class trumps both TS and IA. I created these events by
+running "prstat -R" as root, which runs prstat in the real time class.
+
+The TS time sharing class is the default scheduling class for the processes
+on a Solaris system. I ran an infinite shell loop to create heavy activity,
+"while :; do :; done", which shows a profile that leans towards lower
+priorities. This is deliberate behaivour from the time sharing class, which
+reduces the priority of CPU bound processes so that they interefere less
+with I/O bound processes. The result is more samples in the lower priority
+ranges.
diff --git a/cddl/contrib/dtracetoolkit/Examples/pridist_example.txt b/cddl/contrib/dtracetoolkit/Examples/pridist_example.txt
new file mode 100644
index 0000000..1f930ab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/pridist_example.txt
@@ -0,0 +1,238 @@
+The following are demonstrations of the pridist.d script.
+
+
+Here we run pridist.d for a few seconds then hit Ctrl-C,
+
+ # pridist.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CMD: setiathome PID: 2190
+
+ value ------------- Distribution ------------- count
+ -5 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6629
+ 5 | 0
+
+ CMD: sshd PID: 9172
+
+ value ------------- Distribution ------------- count
+ 50 | 0
+ 55 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 60 | 0
+
+ CMD: mozilla-bin PID: 3164
+
+ value ------------- Distribution ------------- count
+ 40 | 0
+ 45 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20
+ 50 | 0
+
+ CMD: perl PID: 11544
+
+ value ------------- Distribution ------------- count
+ 10 | 0
+ 15 |@@@@@@@@ 60
+ 20 | 0
+ 25 |@@@@@@@@@@@@@@@ 120
+ 30 | 0
+ 35 |@@@@@@@@@@ 80
+ 40 | 0
+ 45 |@@@@@ 40
+ 50 | 0
+ 55 |@@@ 20
+ 60 | 0
+
+During this sample there was a CPU bound process called "setiathome"
+running, and a new CPU bound "perl" process was executed.
+
+perl, executing an infinite loop, begins with a high priority of 55 to 59
+where it is sampled 20 times. pridist.d samples 1000 times per second,
+so this equates to 20 ms. The perl process has also been sampled for 40 ms
+at priority 45 to 49, for 80 ms at priority 35 to 39, down to 60 ms at a
+priority 15 to 19 - at which point I had hit Ctrl-C to end sampling.
+
+The output is spectacular as it matches the behaviour of the dispatcher
+table for the time sharing class perfectly!
+
+setiathome is running with the lowest priority, in the 0 to 4 range.
+
+... ok, so when I say 20 samples equates 20 ms, we know that's only an
+estimate. It really means that for 20 samples that process was the one on
+the CPU. In between the samples anything may have occured (I/O bound
+processes will context switch off the CPU). DTrace can certainly be used
+to measure this based on schedular events not samples (eg, cpudist),
+however DTrace can then sometimes consume a noticable portion of the CPUs
+(for example, 2%).
+
+
+
+
+The following is a longer sample. Again, I start a new CPU bound perl
+process,
+
+ # pridist.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CMD: setiathome PID: 2190
+
+ value ------------- Distribution ------------- count
+ -5 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1820
+ 5 | 0
+
+ CMD: mozilla-bin PID: 3164
+
+ value ------------- Distribution ------------- count
+ 40 | 0
+ 45 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 50 | 0
+
+ CMD: bash PID: 9185
+
+ value ------------- Distribution ------------- count
+ 50 | 0
+ 55 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 60 | 0
+
+ CMD: perl PID: 11547
+
+ value ------------- Distribution ------------- count
+ -5 | 0
+ 0 |@@@@@@@@@@@@@@@ 2020
+ 5 |@@ 200
+ 10 |@@@@@@@ 960
+ 15 |@ 160
+ 20 |@@@@@ 720
+ 25 |@ 120
+ 30 |@@@@ 480
+ 35 |@ 80
+ 40 |@@ 240
+ 45 | 40
+ 50 |@@ 240
+ 55 | 10
+ 60 | 0
+
+Now other behaviour can be observed as the perl process runs. The effect
+here is due to ts_maxwait triggering a priority boot to avoid CPU starvation;
+the priority is boosted to the 50 to 54 range, then decreases by 10 until
+it reaches 0 and another ts_maxwait is triggered. The process spends
+more time at lower priorities, as that is exactly how the TS dispatch table
+has been configured.
+
+
+
+
+Now we run prdist.d for a considerable time,
+
+ # pridist.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CMD: setiathome PID: 2190
+
+ value ------------- Distribution ------------- count
+ -5 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3060
+ 5 | 0
+
+ CMD: mozilla-bin PID: 3164
+
+ value ------------- Distribution ------------- count
+ 40 | 0
+ 45 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20
+ 50 | 0
+
+ CMD: perl PID: 11549
+
+ value ------------- Distribution ------------- count
+ -5 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@ 7680
+ 5 | 0
+ 10 |@@@@@@@ 3040
+ 15 | 70
+ 20 |@@@@@@ 2280
+ 25 | 120
+ 30 |@@@@ 1580
+ 35 | 80
+ 40 |@@ 800
+ 45 | 40
+ 50 |@@ 800
+ 55 | 20
+ 60 | 0
+
+The process has settled to a pattern of 0 priority, ts_maxwait boot to 50,
+drop back to 0.
+
+Run "dispadmin -c TS -g" for a printout of the time sharing dispatcher table.
+
+
+
+
+
+The following shows running pridist.d on a completely idle system,
+
+ # pridist.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CMD: sched PID: 0
+
+ value ------------- Distribution ------------- count
+ -10 | 0
+ -5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1190
+ 0 | 0
+
+Only the kernel "sched" was sampled. It would have been running the idle
+thread.
+
+
+
+
+The following is an unusual output that is worth mentioning,
+
+ # pridist.d
+ Sampling... Hit Ctrl-C to end.
+ ^C
+ CMD: sched PID: 0
+
+ value ------------- Distribution ------------- count
+ -10 | 0
+ -5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 940
+ 0 | 0
+ 5 | 0
+ 10 | 0
+ 15 | 0
+ 20 | 0
+ 25 | 0
+ 30 | 0
+ 35 | 0
+ 40 | 0
+ 45 | 0
+ 50 | 0
+ 55 | 0
+ 60 | 0
+ 65 | 0
+ 70 | 0
+ 75 | 0
+ 80 | 0
+ 85 | 0
+ 90 | 0
+ 95 | 0
+ 100 | 0
+ 105 | 0
+ 110 | 0
+ 115 | 0
+ 120 | 0
+ 125 | 0
+ 130 | 0
+ 135 | 0
+ 140 | 0
+ 145 | 0
+ 150 | 0
+ 155 | 0
+ 160 | 0
+ 165 | 10
+ >= 170 | 0
+
+Here we have sampled the kernel running at a priority of 165 to 169. This
+is the interrupt priority range, and would be an interrupt servicing thread.
+Eg, a network interrupt.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/procsystime_example.txt b/cddl/contrib/dtracetoolkit/Examples/procsystime_example.txt
new file mode 100644
index 0000000..89f98bb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/procsystime_example.txt
@@ -0,0 +1,149 @@
+This is a demonstration of the procsystime tool, which can give details
+on how processes make use of system calls.
+
+Here we run procsystime on processes which have the name "bash",
+
+ # procsystime -n bash
+ Tracing... Hit Ctrl-C to end...
+ ^C
+
+ Elapsed Times for process bash,
+
+ SYSCALL TIME (ns)
+ setpgrp 27768
+ gtime 28692
+ lwp_sigmask 148074
+ write 235814
+ sigaction 553556
+ ioctl 776691
+ read 857401243
+
+By default procsystime prints elapsed times, the time from when the syscall
+was issued to it's completion. In the above output, we can see the read()
+syscall took the most time for this process - 8.57 seconds for all the
+reads combined. This is because the read syscall is waiting for keystrokes.
+
+
+
+Here we try the "-o" option to print CPU overhead times on "bash",
+
+ # procsystime -o -n bash
+ Tracing... Hit Ctrl-C to end...
+ ^C
+
+ CPU Times for process bash,
+
+ SYSCALL TIME (ns)
+ setpgrp 6994
+ gtime 8054
+ lwp_sigmask 33865
+ read 154895
+ sigaction 259899
+ write 343825
+ ioctl 932280
+
+This identifies which syscall type from bash is consuming the most CPU time.
+This is ioctl, at 932 microseconds. Compare this output to the default in
+the first example - both are useful for different reasons, this CPU overhead
+output helps us see why processes are consuming a lot of sys time.
+
+
+
+This demonstrates using the "-a" for all details, this time with "ssh",
+
+ # procsystime -a -n ssh
+ Tracing... Hit Ctrl-C to end...
+ ^C
+
+ Elapsed Times for processes ssh,
+
+ SYSCALL TIME (ns)
+ read 115833
+ write 302419
+ pollsys 114616076
+ TOTAL: 115034328
+
+ CPU Times for processes ssh,
+
+ SYSCALL TIME (ns)
+ read 82381
+ pollsys 201818
+ write 280390
+ TOTAL: 564589
+
+ Syscall Counts for processes ssh,
+
+ SYSCALL COUNT
+ read 4
+ write 4
+ pollsys 8
+ TOTAL: 16
+
+Now we can see elapsed times, overhead times, and syscall counts in one
+report. Very handy. We can also see totals printed as "TOTAL:".
+
+
+
+procsystime also lets us just examine one PID. For example,
+
+ # procsystime -p 1304
+ Tracing... Hit Ctrl-C to end...
+ ^C
+
+ Elapsed Times for PID 1304,
+
+ SYSCALL TIME (ns)
+ fcntl 7323
+ fstat64 21349
+ ioctl 190683
+ read 238197
+ write 1276169
+ pollsys 1005360640
+
+
+
+Here is a longer example of running procsystime on mozilla,
+
+ # procsystime -a -n mozilla-bin
+ Tracing... Hit Ctrl-C to end...
+ ^C
+
+ Elapsed Times for processes mozilla-bin,
+
+ SYSCALL TIME (ns)
+ readv 677958
+ writev 1159088
+ yield 1298742
+ read 18019194
+ write 35679619
+ ioctl 108845685
+ lwp_park 38090969432
+ pollsys 65955258781
+ TOTAL: 104211908499
+
+ CPU Times for processes mozilla-bin,
+
+ SYSCALL TIME (ns)
+ yield 120345
+ readv 398046
+ writev 1117178
+ lwp_park 8591428
+ read 9752315
+ write 29043460
+ ioctl 37089349
+ pollsys 189933470
+ TOTAL: 276045591
+
+ Syscall Counts for processes mozilla-bin,
+
+ SYSCALL COUNT
+ writev 3
+ yield 9
+ readv 58
+ lwp_park 280
+ write 1317
+ read 1744
+ pollsys 8268
+ ioctl 16434
+ TOTAL: 28113
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/putnexts_example.txt b/cddl/contrib/dtracetoolkit/Examples/putnexts_example.txt
new file mode 100644
index 0000000..fd7fc3d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/putnexts_example.txt
@@ -0,0 +1,520 @@
+The following is an example of the putnexts.d script.
+
+
+When investigating the operation of kernel streams, it can be extreamly
+useful to trace who (which stack trace) is calling putnext to who (the
+kernel modele). This script does that,
+
+# putnexts.d
+dtrace: script './putnexts.d' matched 1 probe
+^C
+
+ bufmod
+ bufmod`sbrput+0xb9
+ unix`putnext+0x1b7
+ pts`ptswput+0x1e1
+ unix`putnext+0x1b7
+ ptem`ptemwput+0x22f
+ 1
+ ip
+ ip`ip_fanout_proto+0x4d2
+ ip`ip_proto_input+0x616
+ ip`ip_fanout_proto_again+0x160
+ ip`ip_proto_input+0x530
+ ip`ip_rput+0x50d
+ 1
+ ip
+ ip`ip_wput_ipsec_out+0x60a
+ ip`ipsec_out_process+0x322
+ ip`ip_wput_ire+0x18d0
+ ip`ip_output+0x70a
+ ip`ip_wput+0x14
+ 1
+ ip
+ ip`ip_wput_ire+0x17d1
+ ip`ip_output+0x70a
+ ip`tcp_send_data+0x68c
+ ip`tcp_ack_timer+0xb0
+ ip`tcp_timer_handler+0x1d
+ 1
+ ip
+ ip`ip_udp_input+0x4e4
+ ip`ip_rput+0x540
+ unix`putnext+0x1b7
+ gld`gld_recv_tagged+0xed
+ gld`gld_recv+0x10
+ 1
+ ldterm
+ genunix`putnextctl1+0x52
+ ldterm`ldterm_dosig+0x7b
+ ldterm`ldtermrput+0x6fe
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ 1
+ ldterm
+ ldterm`ldterm_ioctl_reply+0x93
+ ldterm`ldtermrput+0x186
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ 1
+ ldterm
+ ldterm`ldtermrput+0x12a
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ 1
+ ldterm
+ ldterm`ldterm_dosig+0x16f
+ ldterm`ldtermrput+0x6fe
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ unix`putnext+0x1b7
+ 1
+ ldterm
+ genunix`putnextctl1+0x52
+ ldterm`ldterm_dosig+0x124
+ ldterm`ldtermrput+0x6fe
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ 1
+ ldterm
+ ldterm`ldterm_do_ioctl+0xd8b
+ ldterm`ldtermwmsg+0x41
+ ldterm`ldtermwput+0x8e
+ unix`putnext+0x1b7
+ ttcompat`ttcompat_do_ioctl+0x425
+ 1
+ ldterm
+ genunix`putnextctl1+0x52
+ ldterm`ldterm_dosig+0xe3
+ ldterm`ldtermrput+0x6fe
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ 1
+ ptem
+ genunix`qreply+0x23
+ ptem`ptemwmsg+0x2b9
+ ptem`ptemwput+0xe1
+ unix`putnext+0x1b7
+ ldterm`ldterm_do_ioctl+0xd8b
+ 1
+ ptem
+ ptem`ptemwput+0x22f
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ unix`putnext+0x38e
+ 1
+ ptem
+ ptem`ptemrput+0xff
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ unix`putnext+0x38e
+ 1
+ ptem
+ ptem`ptemwmsg+0x44d
+ ptem`ptemwput+0xe1
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ 1
+ ptm
+ pts`ptswsrv+0x7c
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ genunix`stream_service+0x69
+ genunix`taskq_d_thread+0x8a
+ 1
+ ptm
+ pts`ptswput+0x1e1
+ unix`putnext+0x1b7
+ ptem`ptemwput+0x22f
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ 1
+ pts
+ genunix`qreply+0x23
+ pts`ptswput+0x201
+ unix`putnext+0x1b7
+ ptem`ptemwput+0x22f
+ genunix`qdrain_syncq+0x68
+ 1
+ strwhead
+ genunix`qreply+0x23
+ genunix`strrput_nondata+0x22d
+ genunix`strrput+0x256
+ unix`putnext+0x1b7
+ ttcompat`ttcompatrput+0x1d
+ 1
+ strwhead
+ genunix`strdoioctl+0x30d
+ genunix`strioctl+0x6ae
+ specfs`spec_ioctl+0x48
+ genunix`fop_ioctl+0x1e
+ genunix`ioctl+0x199
+ 1
+ tcp
+ ip`tcp_rput_data+0x2221
+ ip`tcp_input+0x39
+ ip`squeue_enter+0x1bf
+ ip`ip_tcp_input+0x9f8
+ ip`ip_rput+0x583
+ 1
+ ttcompat
+ ttcompat`ttcompat_ioctl_ack+0x398
+ ttcompat`ttcompatrput+0x39
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ 1
+ ttcompat
+ ttcompat`ttcompatrput+0x1d
+ unix`putnext+0x1b7
+ ldterm`ldtermrput+0x12a
+ unix`putnext+0x1b7
+ ptem`ptemrput+0xff
+ 1
+ ttcompat
+ ttcompat`ttcompatrput+0x1d
+ unix`putnext+0x1b7
+ genunix`putnextctl1+0x52
+ ldterm`ldterm_dosig+0x124
+ ldterm`ldtermrput+0x6fe
+ 1
+ ttcompat
+ ttcompat`ttcompatwput+0x32
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ genunix`putnext_tail+0x88
+ unix`putnext+0x38e
+ 1
+ ttcompat
+ ttcompat`ttcompat_do_ioctl+0x425
+ ttcompat`ttcompatwput+0x152
+ unix`putnext+0x1b7
+ genunix`strdoioctl+0x30d
+ genunix`strioctl+0x6ae
+ 1
+ ttcompat
+ ttcompat`ttcompatrput+0x1d
+ unix`putnext+0x1b7
+ genunix`putnextctl1+0x52
+ ldterm`ldterm_dosig+0xe3
+ ldterm`ldtermrput+0x6fe
+ 1
+ tun
+ tun`tun_rdata_v4+0x58c
+ tun`tun_rproc+0x256
+ tun`tun_rput+0x23
+ unix`putnext+0x1b7
+ ip`ip_fanout_proto+0x4d2
+ 1
+ tun
+ tun`tun_wputnext_v4+0x1f8
+ tun`tun_wproc_mdata+0x71
+ tun`tun_wproc+0xdf
+ tun`tun_wput+0x23
+ unix`putnext+0x1b7
+ 1
+ udp
+ udp`udp_rput+0x975
+ unix`putnext+0x1b7
+ ip`ip_udp_input+0x4e4
+ ip`ip_rput+0x540
+ unix`putnext+0x1b7
+ 1
+ conskbd
+ genunix`qreply+0x23
+ conskbd`conskbd_mux_upstream_msg+0x24f
+ conskbd`conskbd_lqs_ack_complete+0x65
+ conskbd`conskbdlrput+0x9d
+ unix`putnext+0x1b7
+ 2
+ conskbd
+ conskbd`conskbdlwserv+0x2d
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ genunix`stream_service+0x69
+ genunix`taskq_d_thread+0x8a
+ 2
+ kb8042
+ genunix`qreply+0x23
+ genunix`miocack+0x2a
+ kb8042`kb8042_ioctlmsg+0x281
+ kb8042`kb8042_wsrv+0xcb
+ genunix`runservice+0x2a
+ 2
+ strwhead
+ genunix`strdoioctl+0x30d
+ genunix`strioctl+0x587
+ specfs`spec_ioctl+0x48
+ genunix`fop_ioctl+0x1e
+ genunix`ioctl+0x199
+ 2
+ consms
+ consms`consmslrput+0x15a
+ unix`putnext+0x1b7
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`sendButtonEvent+0x58
+ vuid3ps2`vuid3ps2+0x8ee
+ 4
+ vuid3ps2
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`sendButtonEvent+0x58
+ vuid3ps2`vuid3ps2+0x8ee
+ vuid3ps2`vuidmice_rsrv+0x69
+ genunix`runservice+0x2a
+ 4
+ ip
+ ip`tcp_send_data+0x55d
+ ip`tcp_ack_timer+0xb0
+ ip`tcp_timer_handler+0x1d
+ ip`squeue_drain+0xbb
+ ip`squeue_worker+0xeb
+ 10
+ ip
+ ip`tcp_send_data+0x55d
+ ip`tcp_rput_data+0x259e
+ ip`squeue_enter+0x1bf
+ ip`ip_tcp_input+0xcfb
+ ip`ip_rput+0x583
+ 11
+ ip
+ ip`ip_fanout_udp_conn+0x14b
+ ip`ip_fanout_udp+0x373
+ ip`ip_wput_local+0x16f
+ ip`ip_wput_ire+0x1436
+ ip`ip_output+0x70a
+ 14
+ strwhead
+ genunix`strput+0x168
+ genunix`strputmsg+0x1d5
+ genunix`msgio+0x142
+ genunix`putmsg+0x6e
+ unix`sys_sysenter+0xdc
+ 14
+ timod
+ timod`timodwput+0xea
+ unix`putnext+0x1b7
+ genunix`strput+0x168
+ genunix`strputmsg+0x1d5
+ genunix`msgio+0x142
+ 14
+ timod
+ timod`timodrput+0xa9
+ unix`putnext+0x1b7
+ udp`udp_rput+0x975
+ unix`putnext+0x1b7
+ ip`ip_fanout_udp_conn+0x14b
+ 14
+ udp
+ udp`udp_rput+0x975
+ unix`putnext+0x1b7
+ ip`ip_fanout_udp_conn+0x14b
+ ip`ip_fanout_udp+0x373
+ ip`ip_wput_local+0x16f
+ 14
+ udp
+ udp`udp_wput+0x378
+ unix`putnext+0x1b7
+ timod`timodwput+0xea
+ unix`putnext+0x1b7
+ genunix`strput+0x168
+ 14
+ bufmod
+ bufmod`sbsendit+0x5a
+ bufmod`sbclosechunk+0x2e
+ bufmod`sbrput+0xee
+ genunix`qdrain_syncq+0x68
+ genunix`drain_syncq+0x1a4
+ 21
+ conskbd
+ kbtrans`kbtrans_queueevent+0x5c
+ kbtrans`kbtrans_keyreleased+0x3d
+ kbtrans`kbtrans_untrans_keyreleased_raw+0x10
+ kbtrans`kbtrans_processkey+0x20
+ kbtrans`kbtrans_streams_key+0x95
+ 22
+ kb8042
+ kbtrans`kbtrans_queueevent+0x5c
+ kbtrans`kbtrans_keyreleased+0x3d
+ kbtrans`kbtrans_untrans_keyreleased_raw+0x10
+ kbtrans`kbtrans_processkey+0x20
+ kbtrans`kbtrans_streams_key+0x95
+ 22
+ ldterm
+ ldterm`ldterm_msg_upstream+0x2c
+ ldterm`vmin_satisfied+0x5e
+ ldterm`ldterm_dononcanon+0x230
+ ldterm`ldtermrmsg+0x252
+ ldterm`ldtermrput+0x7e9
+ 22
+ ttcompat
+ ttcompat`ttcompatrput+0x1d
+ unix`putnext+0x1b7
+ ldterm`ldterm_msg_upstream+0x2c
+ ldterm`vmin_satisfied+0x5e
+ ldterm`ldterm_dononcanon+0x230
+ 22
+ bufmod
+ bufmod`sbwput+0x33
+ unix`putnext+0x1b7
+ genunix`strput+0x168
+ genunix`strwrite+0x151
+ specfs`spec_write+0x4e
+ 23
+ ptem
+ ptem`ptemrput+0xff
+ unix`putnext+0x1b7
+ ptm`ptmwsrv+0x90
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ 23
+ pts
+ ptm`ptmwsrv+0x90
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ genunix`stream_runservice+0x96
+ genunix`strput+0x171
+ 23
+ conskbd
+ kbtrans`kbtrans_queueevent+0x5c
+ kbtrans`kbtrans_queuepress+0x5f
+ kbtrans`kbtrans_untrans_keypressed_raw+0x36
+ kbtrans`kbtrans_processkey+0x30
+ kbtrans`kbtrans_streams_key+0x95
+ 24
+ kb8042
+ kbtrans`kbtrans_queueevent+0x5c
+ kbtrans`kbtrans_queuepress+0x5f
+ kbtrans`kbtrans_untrans_keypressed_raw+0x36
+ kbtrans`kbtrans_processkey+0x30
+ kbtrans`kbtrans_streams_key+0x95
+ 24
+ ip
+ ip`tcp_send_data+0x55d
+ ip`tcp_output+0x562
+ ip`squeue_enter+0x1bf
+ ip`tcp_wput+0x234
+ unix`putnext+0x1b7
+ 32
+ ldterm
+ ldterm`ldtermwmsg+0x100
+ ldterm`ldtermwput+0x8e
+ unix`putnext+0x1b7
+ ttcompat`ttcompatwput+0x32
+ unix`putnext+0x1b7
+ 36
+ ptem
+ ptem`ptemwmsg+0x44d
+ ptem`ptemwput+0xe1
+ unix`putnext+0x1b7
+ ldterm`ldtermwmsg+0x100
+ ldterm`ldtermwput+0x8e
+ 36
+ ptm
+ pts`ptswsrv+0x7c
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ genunix`stream_runservice+0x96
+ genunix`strput+0x171
+ 36
+ ttcompat
+ ttcompat`ttcompatwput+0x32
+ unix`putnext+0x1b7
+ genunix`strput+0x168
+ genunix`strwrite+0x151
+ specfs`spec_write+0x4e
+ 36
+ tcp
+ ip`tcp_rput_data+0x2221
+ ip`squeue_enter+0x1bf
+ ip`ip_tcp_input+0xcfb
+ ip`ip_rput+0x583
+ unix`putnext+0x1b7
+ 40
+ rtls
+ gld`gld_recv_tagged+0xed
+ gld`gld_recv+0x10
+ rtls`rtls_receive+0x18f
+ rtls`rtls_gld_intr+0x133
+ gld`gld_intr+0x1e
+ 46
+ consms
+ consms`consmslrput+0x15a
+ unix`putnext+0x1b7
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`vuid3ps2+0x82b
+ vuid3ps2`vuidmice_rsrv+0x69
+ 59
+ strwhead
+ genunix`strput+0x168
+ genunix`strwrite+0x151
+ specfs`spec_write+0x4e
+ genunix`fop_write+0x1b
+ genunix`write+0x29a
+ 59
+ vuid3ps2
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`vuid3ps2+0x82b
+ vuid3ps2`vuidmice_rsrv+0x69
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ 59
+ consms
+ consms`consmslrput+0x15a
+ unix`putnext+0x1b7
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`vuid3ps2+0x809
+ vuid3ps2`vuidmice_rsrv+0x69
+ 77
+ vuid3ps2
+ vuid3ps2`vuid3ps2_putnext+0x94
+ vuid3ps2`vuid3ps2+0x809
+ vuid3ps2`vuidmice_rsrv+0x69
+ genunix`runservice+0x2a
+ genunix`queue_service+0x30
+ 77
+ strwhead
+ genunix`strput+0x168
+ genunix`strwrite+0x151
+ sockfs`socktpi_write+0xcb
+ genunix`fop_write+0x1b
+ genunix`writev+0x308
+ 108
+ rtls
+ gld`gld_passon+0x9e
+ gld`gld_sendup+0xfc
+ gld`gld_recv_tagged+0x15f
+ gld`gld_recv+0x10
+ rtls`rtls_receive+0x18f
+ 124
+ strwhead
+ genunix`strput+0x168
+ genunix`strwrite+0x151
+ sockfs`socktpi_write+0xcb
+ genunix`fop_write+0x1b
+ genunix`write+0x29a
+ 138
+ tl
+ tl`tl_wput_data_ser+0x5e
+ genunix`serializer_exec+0x1d
+ genunix`serializer_enter+0x81
+ tl`tl_serializer_enter+0x40
+ tl`tl_wput+0x1c7
+ 214
+ mouse8042
+ mouse8042`mouse8042_intr+0x68
+ i8042`i8042_intr+0xa6
+ unix`intr_thread+0x107
+ 261
+
+Highlights of the above output include,
+
+- gld calling putnext to rtls (my laptop network device driver)
+- ip receive path calling putnext to tcp
+- tcp_send_data() calling putnext to ip
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_calldist_example.txt
new file mode 100644
index 0000000..da44430
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_calldist_example.txt
@@ -0,0 +1,966 @@
+The following are examples of py_calldist.d.
+
+This script traces the elapsed time of Python functions and prints a report in
+the form of a histogram. Here it traces the example program,
+Code/Python/func_abc.py
+
+The results are displayed in two sections, the first, Exclusive function
+elapsed times, shows us the time spent in each functions, not including time
+spent in subroutines.
+
+The third section, Inclusive function elapsed times, shows us the time spent
+in each function, this time including that time spent in subroutines called
+by those functions.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly.
+
+# py_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive function elapsed times (us),
+ UserDict.py, func, IterableUserDict
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ __init__.py, func, CodecRegistryError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamConverter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, getregentry
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Helper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, aliasmbcs
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setencoding
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, sethelper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ types.py, func, _C
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _OptionError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _processoptions
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ UserDict.py, func, __init__
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, Codec
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReaderWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamRecoder
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ os.py, func, _Environ
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, _Printer
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, setquit
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ copy_reg.py, func, constructor
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ site.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ warnings.py, func, simplefilter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ __init__.py, func, normalize_encoding
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ linecache.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, dirname
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, split
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ stat.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ stat.py, func, S_IFMT
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 4 | 0
+
+ UserDict.py, func, UserDict
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ os.py, func, __init__
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, basename
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, normcase
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@ 6
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 4 | 0
+
+ aliases.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ copy_reg.py, func, pickle
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 16 |@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ <string>, func, ?
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 4 | 0
+ 8 | 0
+ 16 |@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, isabs
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 21
+ 4 |@@ 1
+ 8 | 0
+
+ stat.py, func, S_ISDIR
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 16 |@@@@@@@ 1
+ 32 | 0
+
+ UserDict.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ ascii.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ site.py, func, addsitepackages
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ site.py, func, removeduppaths
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ site.py, func, setcopyright
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ types.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ posixpath.py, func, join
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 4 |@@@@@@@@@@@@ 6
+ 8 |@@ 1
+ 16 | 0
+ 32 |@@ 1
+ 64 | 0
+
+ UserDict.py, func, DictMixin
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ __init__.py, func, search_function
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ codecs.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ copy_reg.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ os.py, func, _get_exports_list
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, _init_pathinfo
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, abs__file__
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, main
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ warnings.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, normpath
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+ 16 | 0
+
+ posixpath.py, func, isdir
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 32 |@@@@@ 1
+ 64 |@@@@@ 1
+ 128 | 0
+
+ site.py, func, addpackage
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@ 1
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 256 | 0
+
+ posixpath.py, func, abspath
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 21
+ 32 |@@ 1
+ 64 | 0
+
+ site.py, func, makepath
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 64 | 0
+
+ posixpath.py, func, ?
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, ?
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, execsitecustomize
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, addsitedir
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ os.py, func, _exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 32 |@@@@@@@@ 2
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@ 1
+ 1024 | 0
+
+ __init__.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ os.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ func_abc.py, func, ?
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ func_abc.py, func, func_a
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.py, func, func_b
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.py, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+
+Inclusive function elapsed times (us),
+ UserDict.py, func, IterableUserDict
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ __init__.py, func, CodecRegistryError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamConverter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, getregentry
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Helper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, aliasmbcs
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setencoding
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, sethelper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ types.py, func, _C
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _OptionError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _processoptions
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ UserDict.py, func, __init__
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, Codec
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReaderWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamRecoder
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ os.py, func, _Environ
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, _Printer
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, setquit
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ copy_reg.py, func, constructor
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ site.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ warnings.py, func, simplefilter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ __init__.py, func, normalize_encoding
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ linecache.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, split
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ stat.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ stat.py, func, S_IFMT
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 4 | 0
+
+ UserDict.py, func, UserDict
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ os.py, func, __init__
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, basename
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, dirname
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ posixpath.py, func, normcase
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@ 6
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 4 | 0
+
+ aliases.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ posixpath.py, func, exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ copy_reg.py, func, pickle
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ posixpath.py, func, isabs
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 21
+ 4 |@@ 1
+ 8 | 0
+
+ ascii.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ site.py, func, setcopyright
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ stat.py, func, S_ISDIR
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 |@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ types.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ posixpath.py, func, join
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 4 |@@@@@@@@@@@@ 6
+ 8 |@@ 1
+ 16 | 0
+ 32 |@@ 1
+ 64 | 0
+
+ UserDict.py, func, DictMixin
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ codecs.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ os.py, func, _get_exports_list
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, normpath
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+ 16 | 0
+
+ UserDict.py, func, ?
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ __init__.py, func, search_function
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ copy_reg.py, func, ?
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, func, abs__file__
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, func, removeduppaths
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ warnings.py, func, ?
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ posixpath.py, func, isdir
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@ 1
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 64 |@@@@@@@@@@ 2
+ 128 | 0
+
+ posixpath.py, func, ?
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, _init_pathinfo
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, execsitecustomize
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ posixpath.py, func, abspath
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+ 64 | 0
+
+ os.py, func, _exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@ 4
+ 32 |@@@@@@@@@@@@@@@@@@@@ 5
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@ 1
+ 1024 | 0
+
+ site.py, func, makepath
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 128 | 0
+
+ __init__.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ <string>, func, ?
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 |@@@@ 1
+ 2048 | 0
+
+ site.py, func, addpackage
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@ 1
+ 256 |@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ os.py, func, ?
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ site.py, func, addsitepackages
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ site.py, func, addsitedir
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ site.py, func, main
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ site.py, func, ?
+ value ------------- Distribution ------------- count
+ 4096 | 0
+ 8192 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16384 | 0
+
+ func_abc.py, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.py, func, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_abc.py, func, ?
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ func_abc.py, func, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_calltime_example.txt
new file mode 100644
index 0000000..bda8ea8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_calltime_example.txt
@@ -0,0 +1,255 @@
+The following are examples of py_calltime.d.
+
+This script traces the elapsed time of Python functions and prints a report.
+Here it traces the example program, Code/Python/func_abc.py
+
+# py_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ UserDict.py func ? 1
+ UserDict.py func DictMixin 1
+ UserDict.py func IterableUserDict 1
+ UserDict.py func UserDict 1
+ UserDict.py func __init__ 1
+ __init__.py func ? 1
+ __init__.py func CodecRegistryError 1
+ __init__.py func normalize_encoding 1
+ __init__.py func search_function 1
+ aliases.py func ? 1
+ ascii.py func ? 1
+ ascii.py func Codec 1
+ ascii.py func StreamConverter 1
+ ascii.py func StreamReader 1
+ ascii.py func StreamWriter 1
+ ascii.py func getregentry 1
+ codecs.py func ? 1
+ codecs.py func Codec 1
+ codecs.py func StreamReader 1
+ codecs.py func StreamReaderWriter 1
+ codecs.py func StreamRecoder 1
+ codecs.py func StreamWriter 1
+ copy_reg.py func ? 1
+ func_abc.py func ? 1
+ func_abc.py func func_a 1
+ func_abc.py func func_b 1
+ func_abc.py func func_c 1
+ linecache.py func ? 1
+ os.py func ? 1
+ os.py func _Environ 1
+ os.py func __init__ 1
+ os.py func _get_exports_list 1
+ posixpath.py func ? 1
+ posixpath.py func basename 1
+ posixpath.py func dirname 1
+ site.py func ? 1
+ site.py func _Helper 1
+ site.py func _Printer 1
+ site.py func _init_pathinfo 1
+ site.py func abs__file__ 1
+ site.py func addsitepackages 1
+ site.py func aliasmbcs 1
+ site.py func execsitecustomize 1
+ site.py func main 1
+ site.py func removeduppaths 1
+ site.py func setcopyright 1
+ site.py func setencoding 1
+ site.py func sethelper 1
+ site.py func setquit 1
+ stat.py func ? 1
+ types.py func ? 1
+ types.py func _C 1
+ warnings.py func ? 1
+ warnings.py func _OptionError 1
+ warnings.py func _processoptions 1
+ posixpath.py func exists 2
+ posixpath.py func split 2
+ site.py func addsitedir 2
+ warnings.py func simplefilter 2
+ copy_reg.py func constructor 3
+ copy_reg.py func pickle 3
+ site.py func __init__ 3
+ site.py func addpackage 3
+ stat.py func S_IFMT 6
+ stat.py func S_ISDIR 6
+ posixpath.py func isdir 8
+ os.py func _exists 10
+ <string> func ? 11
+ posixpath.py func normcase 14
+ site.py func makepath 14
+ posixpath.py func join 20
+ posixpath.py func abspath 22
+ posixpath.py func isabs 22
+ posixpath.py func normpath 22
+ - total - 230
+
+Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ ascii.py func StreamWriter 2
+ ascii.py func StreamReader 2
+ site.py func setencoding 2
+ UserDict.py func IterableUserDict 2
+ __init__.py func CodecRegistryError 2
+ ascii.py func getregentry 2
+ site.py func aliasmbcs 2
+ warnings.py func _OptionError 3
+ types.py func _C 3
+ site.py func sethelper 3
+ warnings.py func _processoptions 3
+ ascii.py func StreamConverter 3
+ ascii.py func Codec 3
+ site.py func _Helper 3
+ site.py func setquit 4
+ codecs.py func StreamWriter 4
+ UserDict.py func __init__ 4
+ site.py func _Printer 4
+ codecs.py func Codec 4
+ os.py func _Environ 4
+ codecs.py func StreamRecoder 5
+ codecs.py func StreamReaderWriter 6
+ codecs.py func StreamReader 6
+ copy_reg.py func constructor 7
+ __init__.py func normalize_encoding 9
+ site.py func __init__ 10
+ warnings.py func simplefilter 11
+ linecache.py func ? 11
+ posixpath.py func split 13
+ stat.py func ? 14
+ stat.py func S_IFMT 14
+ posixpath.py func dirname 16
+ posixpath.py func basename 24
+ os.py func __init__ 26
+ posixpath.py func normcase 29
+ UserDict.py func UserDict 32
+ posixpath.py func exists 37
+ aliases.py func ? 46
+ <string> func ? 56
+ copy_reg.py func pickle 59
+ UserDict.py func ? 84
+ site.py func addsitepackages 85
+ posixpath.py func isabs 87
+ site.py func setcopyright 94
+ stat.py func S_ISDIR 98
+ posixpath.py func join 105
+ types.py func ? 106
+ site.py func removeduppaths 115
+ ascii.py func ? 122
+ os.py func _get_exports_list 136
+ site.py func _init_pathinfo 155
+ site.py func abs__file__ 158
+ codecs.py func ? 182
+ UserDict.py func DictMixin 184
+ __init__.py func search_function 205
+ site.py func main 218
+ posixpath.py func normpath 231
+ copy_reg.py func ? 239
+ posixpath.py func isdir 285
+ site.py func addpackage 419
+ site.py func addsitedir 473
+ warnings.py func ? 500
+ posixpath.py func ? 546
+ site.py func execsitecustomize 558
+ site.py func makepath 608
+ posixpath.py func abspath 646
+ os.py func _exists 925
+ __init__.py func ? 1289
+ os.py func ? 1473
+ site.py func ? 1510
+ func_abc.py func ? 1517
+ func_abc.py func func_c 1000071
+ func_abc.py func func_a 1005706
+ func_abc.py func func_b 1010158
+ - total - 3029815
+
+Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ ascii.py func StreamWriter 2
+ ascii.py func StreamReader 2
+ site.py func setencoding 2
+ UserDict.py func IterableUserDict 2
+ __init__.py func CodecRegistryError 2
+ ascii.py func getregentry 2
+ site.py func aliasmbcs 2
+ warnings.py func _OptionError 3
+ types.py func _C 3
+ site.py func sethelper 3
+ warnings.py func _processoptions 3
+ ascii.py func StreamConverter 3
+ ascii.py func Codec 3
+ site.py func _Helper 3
+ site.py func setquit 4
+ codecs.py func StreamWriter 4
+ UserDict.py func __init__ 4
+ site.py func _Printer 4
+ codecs.py func Codec 4
+ os.py func _Environ 4
+ codecs.py func StreamRecoder 5
+ codecs.py func StreamReaderWriter 6
+ codecs.py func StreamReader 6
+ copy_reg.py func constructor 7
+ __init__.py func normalize_encoding 9
+ site.py func __init__ 10
+ warnings.py func simplefilter 11
+ linecache.py func ? 11
+ posixpath.py func split 13
+ stat.py func ? 14
+ stat.py func S_IFMT 14
+ posixpath.py func dirname 22
+ posixpath.py func normcase 29
+ os.py func __init__ 31
+ posixpath.py func basename 31
+ UserDict.py func UserDict 32
+ posixpath.py func exists 37
+ aliases.py func ? 46
+ copy_reg.py func pickle 66
+ posixpath.py func isabs 87
+ posixpath.py func join 105
+ types.py func ? 109
+ stat.py func S_ISDIR 113
+ site.py func setcopyright 132
+ ascii.py func ? 133
+ os.py func _get_exports_list 136
+ UserDict.py func DictMixin 184
+ codecs.py func ? 210
+ posixpath.py func normpath 231
+ UserDict.py func ? 303
+ __init__.py func search_function 350
+ copy_reg.py func ? 377
+ posixpath.py func isdir 399
+ warnings.py func ? 530
+ site.py func abs__file__ 540
+ site.py func execsitecustomize 558
+ posixpath.py func ? 560
+ site.py func removeduppaths 565
+ site.py func _init_pathinfo 899
+ os.py func _exists 953
+ posixpath.py func abspath 966
+ site.py func makepath 1296
+ __init__.py func ? 1548
+ <string> func ? 1808
+ site.py func addsitepackages 2471
+ site.py func addpackage 2475
+ os.py func ? 3879
+ site.py func addsitedir 4026
+ site.py func main 4532
+ site.py func ? 9930
+ func_abc.py func func_c 1000071
+ func_abc.py func func_b 2010230
+ func_abc.py func func_a 3015936
+ func_abc.py func ? 3017454
+
+Counts shows us how many times each different function was called, and how
+many functions were called in total.
+
+The exclusive function elapsed times show the time that each function spent
+processing code - while not in other functions.
+
+The inclusive function elapsed times show the time that each function spent
+processing code, including the time spent in other calls.
+
+These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_cpudist_example.txt
new file mode 100644
index 0000000..3272e90
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_cpudist_example.txt
@@ -0,0 +1,966 @@
+The following are examples of py_cpudist.d.
+
+This script traces the on-CPU time of Python functions and prints a report
+in the form of a histogram. Here it traces the example program,
+Code/Python/func_slow.py
+
+# py_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Exclusive function on-CPU times (us),
+ UserDict.py, func, IterableUserDict
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ __init__.py, func, CodecRegistryError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, getregentry
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ site.py, func, aliasmbcs
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ site.py, func, sethelper
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ types.py, func, _C
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ warnings.py, func, _OptionError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ UserDict.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamConverter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ codecs.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ codecs.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ os.py, func, _Environ
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ posixpath.py, func, basename
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ posixpath.py, func, dirname
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Helper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Printer
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setencoding
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setquit
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _processoptions
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ copy_reg.py, func, constructor
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ codecs.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReaderWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamRecoder
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ func_slow.py, func, ?
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ os.py, func, __init__
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ stat.py, func, S_IFMT
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 2 | 0
+
+ warnings.py, func, simplefilter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ __init__.py, func, normalize_encoding
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ copy_reg.py, func, pickle
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ linecache.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, split
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ stat.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ stat.py, func, S_ISDIR
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 4 | 0
+
+ posixpath.py, func, normcase
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 2 | 0
+
+ UserDict.py, func, ?
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ UserDict.py, func, UserDict
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ site.py, func, _init_pathinfo
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ site.py, func, addsitepackages
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ site.py, func, setcopyright
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ <string>, func, ?
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@ 5
+ 2 |@@@@@@@@@@@@@@@@@@ 5
+ 4 |@@@@ 1
+ 8 | 0
+
+ posixpath.py, func, isabs
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20
+ 2 |@@@@ 2
+ 4 | 0
+
+ aliases.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ ascii.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ posixpath.py, func, exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ site.py, func, abs__file__
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ site.py, func, removeduppaths
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ site.py, func, makepath
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 8 | 0
+
+ posixpath.py, func, join
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 2 |@@@@@@@@@@ 5
+ 4 |@@@@ 2
+ 8 | 0
+ 16 | 0
+ 32 |@@ 1
+ 64 | 0
+
+ codecs.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ site.py, func, main
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ types.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ posixpath.py, func, abspath
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+ 8 | 0
+
+ UserDict.py, func, DictMixin
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ __init__.py, func, search_function
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ copy_reg.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ os.py, func, _get_exports_list
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ warnings.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, isdir
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@ 1
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 32 | 0
+ 64 |@@@@@ 1
+ 128 | 0
+
+ posixpath.py, func, normpath
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 21
+ 16 | 0
+
+ site.py, func, addpackage
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, addsitedir
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 256 | 0
+
+ site.py, func, ?
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ site.py, func, execsitecustomize
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ os.py, func, _exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@ 1
+ 1024 | 0
+
+ __init__.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ os.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ func_slow.py, func, func_a
+ value ------------- Distribution ------------- count
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 262144 | 0
+
+ func_slow.py, func, func_b
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ func_slow.py, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+
+Inclusive function on-CPU times (us),
+ UserDict.py, func, IterableUserDict
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ __init__.py, func, CodecRegistryError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ascii.py, func, getregentry
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ site.py, func, aliasmbcs
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ site.py, func, sethelper
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ types.py, func, _C
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ warnings.py, func, _OptionError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ UserDict.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ascii.py, func, StreamConverter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ codecs.py, func, Codec
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ codecs.py, func, StreamWriter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ os.py, func, _Environ
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Helper
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, _Printer
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setencoding
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ site.py, func, setquit
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ warnings.py, func, _processoptions
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ copy_reg.py, func, constructor
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ codecs.py, func, StreamReader
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamReaderWriter
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ codecs.py, func, StreamRecoder
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, func, __init__
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4 | 0
+
+ stat.py, func, S_IFMT
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 2 | 0
+
+ warnings.py, func, simplefilter
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ __init__.py, func, normalize_encoding
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ linecache.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ os.py, func, __init__
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, basename
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, dirname
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ posixpath.py, func, split
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ stat.py, func, ?
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ copy_reg.py, func, pickle
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 8 | 0
+
+ posixpath.py, func, normcase
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 2 | 0
+
+ UserDict.py, func, UserDict
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ stat.py, func, S_ISDIR
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 4 |@@@@@@@@@@@@@ 2
+ 8 | 0
+
+ posixpath.py, func, isabs
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20
+ 2 |@@@@ 2
+ 4 | 0
+
+ aliases.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ ascii.py, func, ?
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ posixpath.py, func, exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ site.py, func, setcopyright
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ posixpath.py, func, join
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 2 |@@@@@@@@@@ 5
+ 4 |@@@@ 2
+ 8 | 0
+ 16 | 0
+ 32 |@@ 1
+ 64 | 0
+
+ codecs.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ types.py, func, ?
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ UserDict.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ UserDict.py, func, DictMixin
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ __init__.py, func, search_function
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ os.py, func, _get_exports_list
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, abs__file__
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ site.py, func, removeduppaths
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ warnings.py, func, ?
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ posixpath.py, func, normpath
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 21
+ 16 | 0
+
+ posixpath.py, func, isdir
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 32 | 0
+ 64 |@@@@@ 1
+ 128 | 0
+
+ posixpath.py, func, abspath
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 17
+ 16 |@@@@@@@@@ 5
+ 32 | 0
+
+ copy_reg.py, func, ?
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, func, _init_pathinfo
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, func, makepath
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 13
+ 32 | 0
+ 64 |@@@ 1
+ 128 | 0
+
+ site.py, func, execsitecustomize
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ <string>, func, ?
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@ 5
+ 2 |@@@@@@@@@@@@@@@@@@ 5
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@ 1
+ 1024 | 0
+
+ os.py, func, _exists
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 32 |@@@@ 1
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@ 1
+ 1024 | 0
+
+ site.py, func, addpackage
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 256 | 0
+ 512 |@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ __init__.py, func, ?
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ site.py, func, addsitepackages
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ site.py, func, addsitedir
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ os.py, func, ?
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ site.py, func, main
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ site.py, func, ?
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ func_slow.py, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_slow.py, func, ?
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.py, func, func_a
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.py, func, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+The first section, Exclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, not including time spent in subroutines. You can
+see here that func_a had one instance of being on-CPU between 0.13 seconds and
+0.25 seconds.
+
+The second section, Inclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, including that time spent in subroutines called
+by those functions. You can see that here func_a had an instance of being
+on-CPU between 1.0 seconds and 2.1 seconds.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_cputime_example.txt
new file mode 100644
index 0000000..2f25922
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_cputime_example.txt
@@ -0,0 +1,262 @@
+The following are examples of py_cputime.d.
+
+This script traces the on-CPU time of JavaScript functions and prints a
+report. Here it traces the example program, Code/Python/func_slow.py
+
+# py_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ UserDict.py func ? 1
+ UserDict.py func DictMixin 1
+ UserDict.py func IterableUserDict 1
+ UserDict.py func UserDict 1
+ UserDict.py func __init__ 1
+ __init__.py func ? 1
+ __init__.py func CodecRegistryError 1
+ __init__.py func normalize_encoding 1
+ __init__.py func search_function 1
+ aliases.py func ? 1
+ ascii.py func ? 1
+ ascii.py func Codec 1
+ ascii.py func StreamConverter 1
+ ascii.py func StreamReader 1
+ ascii.py func StreamWriter 1
+ ascii.py func getregentry 1
+ codecs.py func ? 1
+ codecs.py func Codec 1
+ codecs.py func StreamReader 1
+ codecs.py func StreamReaderWriter 1
+ codecs.py func StreamRecoder 1
+ codecs.py func StreamWriter 1
+ copy_reg.py func ? 1
+ func_slow.py func ? 1
+ func_slow.py func func_a 1
+ func_slow.py func func_b 1
+ func_slow.py func func_c 1
+ linecache.py func ? 1
+ os.py func ? 1
+ os.py func _Environ 1
+ os.py func __init__ 1
+ os.py func _get_exports_list 1
+ posixpath.py func ? 1
+ posixpath.py func basename 1
+ posixpath.py func dirname 1
+ site.py func ? 1
+ site.py func _Helper 1
+ site.py func _Printer 1
+ site.py func _init_pathinfo 1
+ site.py func abs__file__ 1
+ site.py func addsitepackages 1
+ site.py func aliasmbcs 1
+ site.py func execsitecustomize 1
+ site.py func main 1
+ site.py func removeduppaths 1
+ site.py func setcopyright 1
+ site.py func setencoding 1
+ site.py func sethelper 1
+ site.py func setquit 1
+ stat.py func ? 1
+ types.py func ? 1
+ types.py func _C 1
+ warnings.py func ? 1
+ warnings.py func _OptionError 1
+ warnings.py func _processoptions 1
+ posixpath.py func exists 2
+ posixpath.py func split 2
+ site.py func addsitedir 2
+ warnings.py func simplefilter 2
+ copy_reg.py func constructor 3
+ copy_reg.py func pickle 3
+ site.py func __init__ 3
+ site.py func addpackage 3
+ stat.py func S_IFMT 6
+ stat.py func S_ISDIR 6
+ posixpath.py func isdir 8
+ os.py func _exists 10
+ <string> func ? 11
+ posixpath.py func normcase 14
+ site.py func makepath 14
+ posixpath.py func join 20
+ posixpath.py func abspath 22
+ posixpath.py func isabs 22
+ posixpath.py func normpath 22
+ - total - 230
+
+Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ ascii.py func StreamWriter 1
+ __init__.py func CodecRegistryError 1
+ ascii.py func StreamReader 1
+ site.py func setencoding 1
+ warnings.py func _OptionError 1
+ UserDict.py func IterableUserDict 1
+ site.py func aliasmbcs 1
+ warnings.py func _processoptions 1
+ types.py func _C 1
+ ascii.py func getregentry 1
+ site.py func _Helper 2
+ ascii.py func Codec 2
+ ascii.py func StreamConverter 2
+ site.py func sethelper 2
+ codecs.py func Codec 2
+ UserDict.py func __init__ 3
+ posixpath.py func dirname 3
+ posixpath.py func basename 3
+ site.py func _Printer 3
+ os.py func _Environ 3
+ codecs.py func StreamWriter 3
+ site.py func setquit 3
+ copy_reg.py func constructor 3
+ codecs.py func StreamRecoder 4
+ codecs.py func StreamReaderWriter 5
+ codecs.py func StreamReader 5
+ os.py func __init__ 6
+ func_slow.py func ? 6
+ __init__.py func normalize_encoding 7
+ site.py func __init__ 7
+ linecache.py func ? 7
+ warnings.py func simplefilter 7
+ stat.py func S_IFMT 9
+ stat.py func ? 10
+ copy_reg.py func pickle 12
+ posixpath.py func split 12
+ posixpath.py func normcase 15
+ stat.py func S_ISDIR 17
+ site.py func addsitepackages 20
+ UserDict.py func ? 20
+ site.py func setcopyright 23
+ site.py func main 24
+ <string> func ? 28
+ UserDict.py func UserDict 31
+ site.py func _init_pathinfo 33
+ posixpath.py func exists 35
+ ascii.py func ? 38
+ posixpath.py func isabs 42
+ aliases.py func ? 43
+ site.py func removeduppaths 51
+ site.py func abs__file__ 56
+ codecs.py func ? 75
+ types.py func ? 83
+ posixpath.py func join 85
+ site.py func makepath 97
+ posixpath.py func abspath 99
+ os.py func _get_exports_list 132
+ __init__.py func search_function 142
+ warnings.py func ? 171
+ UserDict.py func DictMixin 182
+ posixpath.py func ? 192
+ copy_reg.py func ? 196
+ posixpath.py func normpath 209
+ posixpath.py func isdir 255
+ site.py func addpackage 375
+ site.py func addsitedir 506
+ site.py func execsitecustomize 540
+ site.py func ? 725
+ os.py func _exists 802
+ os.py func ? 1138
+ __init__.py func ? 1199
+ func_slow.py func func_a 229669
+ func_slow.py func func_b 456371
+ func_slow.py func func_c 686056
+ - total - 1379951
+
+Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ ascii.py func StreamWriter 1
+ __init__.py func CodecRegistryError 1
+ ascii.py func StreamReader 1
+ site.py func setencoding 1
+ warnings.py func _OptionError 1
+ UserDict.py func IterableUserDict 1
+ site.py func aliasmbcs 1
+ warnings.py func _processoptions 1
+ types.py func _C 1
+ ascii.py func getregentry 1
+ site.py func _Helper 2
+ ascii.py func Codec 2
+ ascii.py func StreamConverter 2
+ site.py func sethelper 2
+ codecs.py func Codec 2
+ UserDict.py func __init__ 3
+ site.py func _Printer 3
+ os.py func _Environ 3
+ codecs.py func StreamWriter 3
+ site.py func setquit 3
+ copy_reg.py func constructor 3
+ codecs.py func StreamRecoder 4
+ codecs.py func StreamReaderWriter 5
+ codecs.py func StreamReader 5
+ __init__.py func normalize_encoding 7
+ site.py func __init__ 7
+ linecache.py func ? 7
+ warnings.py func simplefilter 7
+ stat.py func S_IFMT 9
+ os.py func __init__ 9
+ posixpath.py func basename 9
+ posixpath.py func dirname 10
+ stat.py func ? 10
+ posixpath.py func split 12
+ posixpath.py func normcase 15
+ copy_reg.py func pickle 15
+ stat.py func S_ISDIR 26
+ UserDict.py func UserDict 31
+ posixpath.py func exists 35
+ posixpath.py func isabs 42
+ aliases.py func ? 43
+ site.py func setcopyright 44
+ ascii.py func ? 45
+ types.py func ? 85
+ posixpath.py func join 85
+ codecs.py func ? 97
+ os.py func _get_exports_list 132
+ site.py func removeduppaths 171
+ UserDict.py func DictMixin 182
+ site.py func abs__file__ 184
+ warnings.py func ? 190
+ __init__.py func search_function 196
+ posixpath.py func ? 202
+ posixpath.py func normpath 209
+ UserDict.py func ? 235
+ posixpath.py func isdir 281
+ copy_reg.py func ? 288
+ posixpath.py func abspath 351
+ site.py func _init_pathinfo 392
+ site.py func makepath 395
+ site.py func execsitecustomize 540
+ os.py func _exists 819
+ <string> func ? 973
+ __init__.py func ? 1341
+ site.py func addpackage 1470
+ site.py func addsitepackages 1562
+ site.py func addsitedir 2420
+ site.py func main 2546
+ os.py func ? 2839
+ site.py func ? 6118
+ func_slow.py func func_c 686056
+ func_slow.py func func_b 1142427
+ func_slow.py func func_a 1372097
+ func_slow.py func ? 1372104
+
+You can see the results are printed in three sections.
+
+The first section reports how many times each function was called.
+
+The exclusive function on-CPU times shows, amongst other results that func_a
+spent around 0.22 seconds on-CPU. This times excludes time spent in
+other functions.
+
+The inclusive function on-CPU times show that func_a spent around 1.4
+seconds on-CPU. This includes the time spent in other functions called.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_flow_example.txt
new file mode 100644
index 0000000..d62269e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_flow_example.txt
@@ -0,0 +1,485 @@
+The following are examples of py_flow.d.
+
+This is a simple script to trace the flow of Python functions.
+Here it traces the example program, Code/Python/func_abc.py
+
+# py_flow.d
+ C TIME(us) FILE -- FUNC
+ 0 3064371810154 site.py -> ?
+ 0 3064371830069 os.py -> ?
+ 0 3064371840076 posixpath.py -> ?
+ 0 3064371840298 stat.py -> ?
+ 0 3064371840319 stat.py <- ?
+ 0 3064371840345 posixpath.py <- ?
+ 0 3064371840364 os.py -> _get_exports_list
+ 0 3064371840510 os.py <- _get_exports_list
+ 0 3064371849994 UserDict.py -> ?
+ 0 3064371850011 UserDict.py -> UserDict
+ 0 3064371850051 UserDict.py <- UserDict
+ 0 3064371850067 UserDict.py -> IterableUserDict
+ 0 3064371850075 UserDict.py <- IterableUserDict
+ 0 3064371850088 UserDict.py -> DictMixin
+ 0 3064371850291 UserDict.py <- DictMixin
+ 0 3064371850300 UserDict.py <- ?
+ 0 3064371850320 os.py -> _Environ
+ 0 3064371850330 os.py <- _Environ
+ 0 3064371850342 os.py -> __init__
+ 0 3064371850353 UserDict.py -> __init__
+ 0 3064371850363 UserDict.py <- __init__
+ 0 3064371850372 os.py <- __init__
+ 0 3064371850381 os.py -> _exists
+ 0 3064371851137 <string> -> ?
+ 0 3064371851146 <string> <- ?
+ 0 3064371851155 os.py <- _exists
+ 0 3064371851162 os.py -> _exists
+ 0 3064371851186 <string> -> ?
+ 0 3064371851195 <string> <- ?
+ 0 3064371851213 os.py <- _exists
+ 0 3064371851220 os.py -> _exists
+ 0 3064371851242 <string> -> ?
+ 0 3064371851249 <string> <- ?
+ 0 3064371851257 os.py <- _exists
+ 0 3064371851266 os.py -> _exists
+ 0 3064371851286 <string> -> ?
+ 0 3064371851293 <string> <- ?
+ 0 3064371851300 os.py <- _exists
+ 0 3064371851310 os.py -> _exists
+ 0 3064371851330 <string> -> ?
+ 0 3064371851337 <string> <- ?
+ 0 3064371851344 os.py <- _exists
+ 0 3064371851354 os.py -> _exists
+ 0 3064371851374 <string> -> ?
+ 0 3064371851381 <string> <- ?
+ 0 3064371851388 os.py <- _exists
+ 0 3064371851395 os.py -> _exists
+ 0 3064371851415 <string> -> ?
+ 0 3064371851423 <string> <- ?
+ 0 3064371851436 os.py <- _exists
+ 0 3064371851445 os.py -> _exists
+ 0 3064371851465 <string> -> ?
+ 0 3064371851473 <string> <- ?
+ 0 3064371851485 os.py <- _exists
+ 0 3064371851493 os.py -> _exists
+ 0 3064371851514 <string> -> ?
+ 0 3064371851522 <string> <- ?
+ 0 3064371851534 os.py <- _exists
+ 0 3064371851785 copy_reg.py -> ?
+ 0 3064371851996 types.py -> ?
+ 0 3064371852063 types.py -> _C
+ 0 3064371852073 types.py <- _C
+ 0 3064371852108 types.py <- ?
+ 0 3064371852129 copy_reg.py -> pickle
+ 0 3064371852139 copy_reg.py -> constructor
+ 0 3064371852147 copy_reg.py <- constructor
+ 0 3064371852155 copy_reg.py <- pickle
+ 0 3064371852166 copy_reg.py <- ?
+ 0 3064371852179 copy_reg.py -> pickle
+ 0 3064371852188 copy_reg.py -> constructor
+ 0 3064371852196 copy_reg.py <- constructor
+ 0 3064371852204 copy_reg.py <- pickle
+ 0 3064371852212 copy_reg.py -> pickle
+ 0 3064371852221 copy_reg.py -> constructor
+ 0 3064371852229 copy_reg.py <- constructor
+ 0 3064371852236 copy_reg.py <- pickle
+ 0 3064371852244 os.py -> _exists
+ 0 3064371852269 <string> -> ?
+ 0 3064371852277 <string> <- ?
+ 0 3064371852289 os.py <- _exists
+ 0 3064371852297 os.py <- ?
+ 0 3064371852330 site.py -> _Printer
+ 0 3064371852340 site.py <- _Printer
+ 0 3064371852376 site.py -> _Helper
+ 0 3064371852384 site.py <- _Helper
+ 0 3064371852416 site.py -> main
+ 0 3064371852423 site.py -> abs__file__
+ 0 3064371852434 posixpath.py -> abspath
+ 0 3064371852442 posixpath.py -> isabs
+ 0 3064371852452 posixpath.py <- isabs
+ 0 3064371852460 posixpath.py -> normpath
+ 0 3064371852482 posixpath.py <- normpath
+ 0 3064371852490 posixpath.py <- abspath
+ 0 3064371852504 posixpath.py -> abspath
+ 0 3064371852511 posixpath.py -> isabs
+ 0 3064371852520 posixpath.py <- isabs
+ 0 3064371852527 posixpath.py -> normpath
+ 0 3064371852543 posixpath.py <- normpath
+ 0 3064371852552 posixpath.py <- abspath
+ 0 3064371852560 posixpath.py -> abspath
+ 0 3064371852567 posixpath.py -> isabs
+ 0 3064371852576 posixpath.py <- isabs
+ 0 3064371852583 posixpath.py -> normpath
+ 0 3064371852598 posixpath.py <- normpath
+ 0 3064371852607 posixpath.py <- abspath
+ 0 3064371852615 posixpath.py -> abspath
+ 0 3064371852622 posixpath.py -> isabs
+ 0 3064371852631 posixpath.py <- isabs
+ 0 3064371852638 posixpath.py -> normpath
+ 0 3064371852653 posixpath.py <- normpath
+ 0 3064371852661 posixpath.py <- abspath
+ 0 3064371852674 posixpath.py -> abspath
+ 0 3064371852682 posixpath.py -> isabs
+ 0 3064371852690 posixpath.py <- isabs
+ 0 3064371852697 posixpath.py -> normpath
+ 0 3064371852713 posixpath.py <- normpath
+ 0 3064371852721 posixpath.py <- abspath
+ 0 3064371852741 posixpath.py -> abspath
+ 0 3064371852748 posixpath.py -> isabs
+ 0 3064371852757 posixpath.py <- isabs
+ 0 3064371852764 posixpath.py -> normpath
+ 0 3064371852779 posixpath.py <- normpath
+ 0 3064371852787 posixpath.py <- abspath
+ 0 3064371852804 posixpath.py -> abspath
+ 0 3064371852811 posixpath.py -> isabs
+ 0 3064371852819 posixpath.py <- isabs
+ 0 3064371852826 posixpath.py -> normpath
+ 0 3064371852842 posixpath.py <- normpath
+ 0 3064371852850 posixpath.py <- abspath
+ 0 3064371852858 posixpath.py -> abspath
+ 0 3064371852865 posixpath.py -> isabs
+ 0 3064371852874 posixpath.py <- isabs
+ 0 3064371852881 posixpath.py -> normpath
+ 0 3064371852896 posixpath.py <- normpath
+ 0 3064371852904 posixpath.py <- abspath
+ 0 3064371852915 site.py <- abs__file__
+ 0 3064371852922 site.py -> removeduppaths
+ 0 3064371852931 site.py -> makepath
+ 0 3064371852940 posixpath.py -> join
+ 0 3064371852948 posixpath.py <- join
+ 0 3064371852955 posixpath.py -> abspath
+ 0 3064371852963 posixpath.py -> isabs
+ 0 3064371852972 posixpath.py <- isabs
+ 0 3064371852980 posixpath.py -> normpath
+ 0 3064371852995 posixpath.py <- normpath
+ 0 3064371853002 posixpath.py <- abspath
+ 0 3064371853010 posixpath.py -> normcase
+ 0 3064371853018 posixpath.py <- normcase
+ 0 3064371853025 site.py <- makepath
+ 0 3064371853065 site.py -> makepath
+ 0 3064371853073 posixpath.py -> join
+ 0 3064371853081 posixpath.py <- join
+ 0 3064371853088 posixpath.py -> abspath
+ 0 3064371853096 posixpath.py -> isabs
+ 0 3064371853104 posixpath.py <- isabs
+ 0 3064371853111 posixpath.py -> normpath
+ 0 3064371853126 posixpath.py <- normpath
+ 0 3064371853134 posixpath.py <- abspath
+ 0 3064371853142 posixpath.py -> normcase
+ 0 3064371853150 posixpath.py <- normcase
+ 0 3064371853157 site.py <- makepath
+ 0 3064371853165 site.py -> makepath
+ 0 3064371853173 posixpath.py -> join
+ 0 3064371853181 posixpath.py <- join
+ 0 3064371853188 posixpath.py -> abspath
+ 0 3064371853195 posixpath.py -> isabs
+ 0 3064371853203 posixpath.py <- isabs
+ 0 3064371853210 posixpath.py -> normpath
+ 0 3064371853226 posixpath.py <- normpath
+ 0 3064371853234 posixpath.py <- abspath
+ 0 3064371853241 posixpath.py -> normcase
+ 0 3064371853249 posixpath.py <- normcase
+ 0 3064371853256 site.py <- makepath
+ 0 3064371853265 site.py -> makepath
+ 0 3064371853272 posixpath.py -> join
+ 0 3064371853280 posixpath.py <- join
+ 0 3064371853287 posixpath.py -> abspath
+ 0 3064371853294 posixpath.py -> isabs
+ 0 3064371853303 posixpath.py <- isabs
+ 0 3064371853310 posixpath.py -> normpath
+ 0 3064371853325 posixpath.py <- normpath
+ 0 3064371853333 posixpath.py <- abspath
+ 0 3064371853341 posixpath.py -> normcase
+ 0 3064371853348 posixpath.py <- normcase
+ 0 3064371853356 site.py <- makepath
+ 0 3064371853364 site.py -> makepath
+ 0 3064371853372 posixpath.py -> join
+ 0 3064371853380 posixpath.py <- join
+ 0 3064371853387 posixpath.py -> abspath
+ 0 3064371853394 posixpath.py -> isabs
+ 0 3064371853402 posixpath.py <- isabs
+ 0 3064371853409 posixpath.py -> normpath
+ 0 3064371853425 posixpath.py <- normpath
+ 0 3064371853433 posixpath.py <- abspath
+ 0 3064371853440 posixpath.py -> normcase
+ 0 3064371853448 posixpath.py <- normcase
+ 0 3064371853455 site.py <- makepath
+ 0 3064371853466 site.py <- removeduppaths
+ 0 3064371853476 posixpath.py -> basename
+ 0 3064371853484 posixpath.py -> split
+ 0 3064371853498 posixpath.py <- split
+ 0 3064371853505 posixpath.py <- basename
+ 0 3064371853513 site.py -> addsitepackages
+ 0 3064371853524 posixpath.py -> join
+ 0 3064371853538 posixpath.py <- join
+ 0 3064371853546 posixpath.py -> join
+ 0 3064371853557 posixpath.py <- join
+ 0 3064371853566 posixpath.py -> isdir
+ 0 3064371853597 stat.py -> S_ISDIR
+ 0 3064371853604 stat.py -> S_IFMT
+ 0 3064371853612 stat.py <- S_IFMT
+ 0 3064371853620 stat.py <- S_ISDIR
+ 0 3064371853627 posixpath.py <- isdir
+ 0 3064371853636 site.py -> addsitedir
+ 0 3064371853643 site.py -> makepath
+ 0 3064371853651 posixpath.py -> join
+ 0 3064371853659 posixpath.py <- join
+ 0 3064371853666 posixpath.py -> abspath
+ 0 3064371853674 posixpath.py -> isabs
+ 0 3064371853683 posixpath.py <- isabs
+ 0 3064371853691 posixpath.py -> normpath
+ 0 3064371853707 posixpath.py <- normpath
+ 0 3064371853715 posixpath.py <- abspath
+ 0 3064371853723 posixpath.py -> normcase
+ 0 3064371853730 posixpath.py <- normcase
+ 0 3064371853738 site.py <- makepath
+ 0 3064371853938 site.py -> addpackage
+ 0 3064371853948 posixpath.py -> join
+ 0 3064371853958 posixpath.py <- join
+ 0 3064371854087 <string> -> ?
+ 0 3064371854098 site.py -> addsitedir
+ 0 3064371854106 site.py -> _init_pathinfo
+ 0 3064371854115 posixpath.py -> isdir
+ 0 3064371854195 posixpath.py <- isdir
+ 0 3064371854204 posixpath.py -> isdir
+ 0 3064371854224 stat.py -> S_ISDIR
+ 0 3064371854232 stat.py -> S_IFMT
+ 0 3064371854240 stat.py <- S_IFMT
+ 0 3064371854247 stat.py <- S_ISDIR
+ 0 3064371854254 posixpath.py <- isdir
+ 0 3064371854262 site.py -> makepath
+ 0 3064371854271 posixpath.py -> join
+ 0 3064371854279 posixpath.py <- join
+ 0 3064371854286 posixpath.py -> abspath
+ 0 3064371854293 posixpath.py -> isabs
+ 0 3064371854302 posixpath.py <- isabs
+ 0 3064371854309 posixpath.py -> normpath
+ 0 3064371854325 posixpath.py <- normpath
+ 0 3064371854333 posixpath.py <- abspath
+ 0 3064371854341 posixpath.py -> normcase
+ 0 3064371854349 posixpath.py <- normcase
+ 0 3064371854356 site.py <- makepath
+ 0 3064371854364 posixpath.py -> isdir
+ 0 3064371854386 stat.py -> S_ISDIR
+ 0 3064371854393 stat.py -> S_IFMT
+ 0 3064371854400 stat.py <- S_IFMT
+ 0 3064371854408 stat.py <- S_ISDIR
+ 0 3064371854415 posixpath.py <- isdir
+ 0 3064371854423 site.py -> makepath
+ 0 3064371854431 posixpath.py -> join
+ 0 3064371854438 posixpath.py <- join
+ 0 3064371854446 posixpath.py -> abspath
+ 0 3064371854453 posixpath.py -> isabs
+ 0 3064371854461 posixpath.py <- isabs
+ 0 3064371854469 posixpath.py -> normpath
+ 0 3064371854485 posixpath.py <- normpath
+ 0 3064371854493 posixpath.py <- abspath
+ 0 3064371854500 posixpath.py -> normcase
+ 0 3064371854508 posixpath.py <- normcase
+ 0 3064371854516 site.py <- makepath
+ 0 3064371854524 posixpath.py -> isdir
+ 0 3064371854556 stat.py -> S_ISDIR
+ 0 3064371854563 stat.py -> S_IFMT
+ 0 3064371854571 stat.py <- S_IFMT
+ 0 3064371854578 stat.py <- S_ISDIR
+ 0 3064371854585 posixpath.py <- isdir
+ 0 3064371854593 site.py -> makepath
+ 0 3064371854601 posixpath.py -> join
+ 0 3064371854609 posixpath.py <- join
+ 0 3064371854616 posixpath.py -> abspath
+ 0 3064371854624 posixpath.py -> isabs
+ 0 3064371854632 posixpath.py <- isabs
+ 0 3064371854639 posixpath.py -> normpath
+ 0 3064371854655 posixpath.py <- normpath
+ 0 3064371854663 posixpath.py <- abspath
+ 0 3064371854671 posixpath.py -> normcase
+ 0 3064371854679 posixpath.py <- normcase
+ 0 3064371854686 site.py <- makepath
+ 0 3064371854694 posixpath.py -> isdir
+ 0 3064371854715 stat.py -> S_ISDIR
+ 0 3064371854722 stat.py -> S_IFMT
+ 0 3064371854730 stat.py <- S_IFMT
+ 0 3064371854737 stat.py <- S_ISDIR
+ 0 3064371854744 posixpath.py <- isdir
+ 0 3064371854752 site.py -> makepath
+ 0 3064371854759 posixpath.py -> join
+ 0 3064371854767 posixpath.py <- join
+ 0 3064371854774 posixpath.py -> abspath
+ 0 3064371854782 posixpath.py -> isabs
+ 0 3064371854790 posixpath.py <- isabs
+ 0 3064371854797 posixpath.py -> normpath
+ 0 3064371854813 posixpath.py <- normpath
+ 0 3064371854821 posixpath.py <- abspath
+ 0 3064371854829 posixpath.py -> normcase
+ 0 3064371854837 posixpath.py <- normcase
+ 0 3064371854844 site.py <- makepath
+ 0 3064371854852 posixpath.py -> isdir
+ 0 3064371854872 stat.py -> S_ISDIR
+ 0 3064371854879 stat.py -> S_IFMT
+ 0 3064371854887 stat.py <- S_IFMT
+ 0 3064371854894 stat.py <- S_ISDIR
+ 0 3064371854901 posixpath.py <- isdir
+ 0 3064371854909 site.py -> makepath
+ 0 3064371854917 posixpath.py -> join
+ 0 3064371854925 posixpath.py <- join
+ 0 3064371854932 posixpath.py -> abspath
+ 0 3064371854939 posixpath.py -> isabs
+ 0 3064371854947 posixpath.py <- isabs
+ 0 3064371854954 posixpath.py -> normpath
+ 0 3064371854970 posixpath.py <- normpath
+ 0 3064371854978 posixpath.py <- abspath
+ 0 3064371854986 posixpath.py -> normcase
+ 0 3064371854994 posixpath.py <- normcase
+ 0 3064371855001 site.py <- makepath
+ 0 3064371855009 site.py <- _init_pathinfo
+ 0 3064371855016 site.py -> makepath
+ 0 3064371855024 posixpath.py -> join
+ 0 3064371855032 posixpath.py <- join
+ 0 3064371855039 posixpath.py -> abspath
+ 0 3064371855047 posixpath.py -> isabs
+ 0 3064371855055 posixpath.py <- isabs
+ 0 3064371855063 posixpath.py -> normpath
+ 0 3064371855078 posixpath.py <- normpath
+ 0 3064371855086 posixpath.py <- abspath
+ 0 3064371855094 posixpath.py -> normcase
+ 0 3064371855101 posixpath.py <- normcase
+ 0 3064371855144 site.py <- makepath
+ 0 3064371855318 site.py -> addpackage
+ 0 3064371855327 posixpath.py -> join
+ 0 3064371855337 posixpath.py <- join
+ 0 3064371855411 site.py -> makepath
+ 0 3064371855420 posixpath.py -> join
+ 0 3064371855430 posixpath.py <- join
+ 0 3064371855437 posixpath.py -> abspath
+ 0 3064371855445 posixpath.py -> isabs
+ 0 3064371855453 posixpath.py <- isabs
+ 0 3064371855460 posixpath.py -> normpath
+ 0 3064371855477 posixpath.py <- normpath
+ 0 3064371855485 posixpath.py <- abspath
+ 0 3064371855493 posixpath.py -> normcase
+ 0 3064371855501 posixpath.py <- normcase
+ 0 3064371855509 site.py <- makepath
+ 0 3064371855517 posixpath.py -> exists
+ 0 3064371855542 posixpath.py <- exists
+ 0 3064371855591 site.py <- addpackage
+ 0 3064371855611 site.py -> addpackage
+ 0 3064371855618 posixpath.py -> join
+ 0 3064371855628 posixpath.py <- join
+ 0 3064371855683 site.py -> makepath
+ 0 3064371855692 posixpath.py -> join
+ 0 3064371855739 posixpath.py <- join
+ 0 3064371855747 posixpath.py -> abspath
+ 0 3064371855754 posixpath.py -> isabs
+ 0 3064371855763 posixpath.py <- isabs
+ 0 3064371855770 posixpath.py -> normpath
+ 0 3064371855788 posixpath.py <- normpath
+ 0 3064371855796 posixpath.py <- abspath
+ 0 3064371855803 posixpath.py -> normcase
+ 0 3064371855811 posixpath.py <- normcase
+ 0 3064371855818 site.py <- makepath
+ 0 3064371855826 posixpath.py -> exists
+ 0 3064371855851 posixpath.py <- exists
+ 0 3064371855880 site.py <- addpackage
+ 0 3064371855892 site.py <- addsitedir
+ 0 3064371855900 <string> <- ?
+ 0 3064371855915 site.py <- addpackage
+ 0 3064371855923 site.py <- addsitedir
+ 0 3064371855932 posixpath.py -> isdir
+ 0 3064371855965 posixpath.py <- isdir
+ 0 3064371855973 site.py <- addsitepackages
+ 0 3064371855982 site.py -> setquit
+ 0 3064371855993 site.py <- setquit
+ 0 3064371856000 site.py -> setcopyright
+ 0 3064371856009 site.py -> __init__
+ 0 3064371856019 site.py <- __init__
+ 0 3064371856028 site.py -> __init__
+ 0 3064371856037 site.py <- __init__
+ 0 3064371856045 posixpath.py -> dirname
+ 0 3064371856052 posixpath.py -> split
+ 0 3064371856065 posixpath.py <- split
+ 0 3064371856073 posixpath.py <- dirname
+ 0 3064371856085 posixpath.py -> join
+ 0 3064371856096 posixpath.py <- join
+ 0 3064371856104 site.py -> __init__
+ 0 3064371856113 site.py <- __init__
+ 0 3064371856121 site.py <- setcopyright
+ 0 3064371856128 site.py -> sethelper
+ 0 3064371856136 site.py <- sethelper
+ 0 3064371856143 site.py -> aliasmbcs
+ 0 3064371856151 site.py <- aliasmbcs
+ 0 3064371856158 site.py -> setencoding
+ 0 3064371856166 site.py <- setencoding
+ 0 3064371856173 site.py -> execsitecustomize
+ 0 3064371871773 site.py <- execsitecustomize
+ 0 3064371871794 site.py <- main
+ 0 3064371871805 site.py <- ?
+ 0 3064371872141 warnings.py -> ?
+ 0 306437187232e linecache.py -> ?
+ 0 3064371872336 linecache.py <- ?
+ 0 3064371872352 warnings.py -> _OptionError
+ 0 3064371872361 warnings.py <- _OptionError
+ 0 3064371872378 warnings.py -> _processoptions
+ 0 3064371872387 warnings.py <- _processoptions
+ 0 3064371872397 warnings.py -> simplefilter
+ 0 3064371872410 warnings.py <- simplefilter
+ 0 3064371872418 warnings.py -> simplefilter
+ 0 3064371872428 warnings.py <- simplefilter
+ 0 3064371872436 warnings.py <- ?
+ 0 3064371886557 __init__.py -> ?
+ 0 3064371891761 codecs.py -> ?
+ 0 3064371891836 codecs.py -> Codec
+ 0 3064371891848 codecs.py <- Codec
+ 0 3064371891864 codecs.py -> StreamWriter
+ 0 3064371891874 codecs.py <- StreamWriter
+ 0 3064371891885 codecs.py -> StreamReader
+ 0 3064371891897 codecs.py <- StreamReader
+ 0 3064371891907 codecs.py -> StreamReaderWriter
+ 0 3064371891918 codecs.py <- StreamReaderWriter
+ 0 3064371891926 codecs.py -> StreamRecoder
+ 0 3064371891938 codecs.py <- StreamRecoder
+ 0 3064371891953 codecs.py <- ?
+ 0 3064371902521 aliases.py -> ?
+ 0 3064371902580 aliases.py <- ?
+ 0 3064371902605 __init__.py -> CodecRegistryError
+ 0 3064371902614 __init__.py <- CodecRegistryError
+ 0 3064371902636 __init__.py <- ?
+ 0 3064371902655 __init__.py -> search_function
+ 0 3064371902666 __init__.py -> normalize_encoding
+ 0 3064371902682 __init__.py <- normalize_encoding
+ 0 3064371902888 ascii.py -> ?
+ 0 3064371902900 ascii.py -> Codec
+ 0 3064371902909 ascii.py <- Codec
+ 0 3064371902922 ascii.py -> StreamWriter
+ 0 3064371902930 ascii.py <- StreamWriter
+ 0 3064371902941 ascii.py -> StreamReader
+ 0 3064371902949 ascii.py <- StreamReader
+ 0 3064371902972 ascii.py -> StreamConverter
+ 0 3064371902981 ascii.py <- StreamConverter
+ 0 3064371902993 ascii.py <- ?
+ 0 3064371903009 ascii.py -> getregentry
+ 0 3064371903018 ascii.py <- getregentry
+ 0 3064371903044 __init__.py <- search_function
+ 0 3064371903414 func_abc.py -> ?
+ 0 3064371933251 func_abc.py -> func_a
+ 0 3064372940696 func_abc.py -> func_b
+ 0 3064373950608 func_abc.py -> func_c
+ 0 3064374960497 func_abc.py <- func_c
+ 0 3064374960512 func_abc.py <- func_b
+ 0 3064374960520 func_abc.py <- func_a
+ 0 3064374960528 func_abc.py <- ?
+^C
+
+Here we can see that Python has done extensive pre-processing before it runs
+the Code/Python/func_abc.py program itself.
+
+This shows which function is calling which - the output above ends by
+showing that func_a called func_b which in turn called func_c etc.
+
+The TIME(us) column shows time from boot in microseconds.
+
+The FILE column shows the file that was being executed.
+
+If the output looks strange, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_flowinfo_example.txt
new file mode 100644
index 0000000..f93dc09
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_flowinfo_example.txt
@@ -0,0 +1,485 @@
+Following are examples of py_flowinfo.d.
+
+This is a simple script to trace the flow of Python functions. Here it traces
+the flow into and out of libraries and the example program,
+Code/Python/func_abc.py.
+
+# py_flowinfo.d
+C PID DELTA(us) FILE:LINE TYPE -- FUNC
+0 145424 3 site.py:58 func -> ?
+0 145424 1375 os.py:22 func -> ?
+0 145424 692 posixpath.py:11 func -> ?
+0 145424 184 stat.py:4 func -> ?
+0 145424 21 stat.py:86 func <- ?
+0 145424 32 posixpath.py:454 func <- ?
+0 145424 18 os.py:34 func -> _get_exports_list
+0 145424 135 os.py:38 func <- _get_exports_list
+0 145424 261 UserDict.py:1 func -> ?
+0 145424 11 UserDict.py:3 func -> UserDict
+0 145424 36 UserDict.py:71 func <- UserDict
+0 145424 16 UserDict.py:73 func -> IterableUserDict
+0 145424 9 UserDict.py:74 func <- IterableUserDict
+0 145424 13 UserDict.py:77 func -> DictMixin
+0 145424 174 UserDict.py:169 func <- DictMixin
+0 145424 11 UserDict.py:77 func <- ?
+0 145424 17 os.py:458 func -> _Environ
+0 145424 11 os.py:489 func <- _Environ
+0 145424 13 os.py:459 func -> __init__
+0 145424 11 UserDict.py:4 func -> __init__
+0 145424 11 UserDict.py:9 func <- __init__
+0 145424 10 os.py:461 func <- __init__
+0 145424 11 os.py:501 func -> _exists
+0 145424 604 <string>:0 func -> ?
+0 145424 10 <string>:0 func <- ?
+0 145424 9 os.py:504 func <- _exists
+0 145424 9 os.py:501 func -> _exists
+0 145424 24 <string>:0 func -> ?
+0 145424 9 <string>:0 func <- ?
+0 145424 15 os.py:506 func <- _exists
+0 145424 9 os.py:501 func -> _exists
+0 145424 23 <string>:0 func -> ?
+0 145424 8 <string>:0 func <- ?
+0 145424 9 os.py:504 func <- _exists
+0 145424 26 os.py:501 func -> _exists
+0 145424 23 <string>:0 func -> ?
+0 145424 8 <string>:0 func <- ?
+0 145424 8 os.py:504 func <- _exists
+0 145424 11 os.py:501 func -> _exists
+0 145424 22 <string>:0 func -> ?
+0 145424 8 <string>:0 func <- ?
+0 145424 8 os.py:504 func <- _exists
+0 145424 11 os.py:501 func -> _exists
+0 145424 22 <string>:0 func -> ?
+0 145424 8 <string>:0 func <- ?
+0 145424 8 os.py:504 func <- _exists
+0 145424 9 os.py:501 func -> _exists
+0 145424 21 <string>:0 func -> ?
+0 145424 9 <string>:0 func <- ?
+0 145424 14 os.py:506 func <- _exists
+0 145424 10 os.py:501 func -> _exists
+0 145424 22 <string>:0 func -> ?
+0 145424 9 <string>:0 func <- ?
+0 145424 13 os.py:506 func <- _exists
+0 145424 11 os.py:501 func -> _exists
+0 145424 22 <string>:0 func -> ?
+0 145424 8 <string>:0 func <- ?
+0 145424 13 os.py:506 func <- _exists
+0 145424 181 copy_reg.py:5 func -> ?
+0 145424 181 types.py:4 func -> ?
+0 145424 64 types.py:55 func -> _C
+0 145424 10 types.py:56 func <- _C
+0 145424 35 types.py:89 func <- ?
+0 145424 22 copy_reg.py:14 func -> pickle
+0 145424 11 copy_reg.py:27 func -> constructor
+0 145424 9 copy_reg.py:29 func <- constructor
+0 145424 9 copy_reg.py:25 func <- pickle
+0 145424 12 copy_reg.py:175 func <- ?
+0 145424 15 copy_reg.py:14 func -> pickle
+0 145424 10 copy_reg.py:27 func -> constructor
+0 145424 9 copy_reg.py:29 func <- constructor
+0 145424 9 copy_reg.py:25 func <- pickle
+0 145424 10 copy_reg.py:14 func -> pickle
+0 145424 10 copy_reg.py:27 func -> constructor
+0 145424 9 copy_reg.py:29 func <- constructor
+0 145424 9 copy_reg.py:25 func <- pickle
+0 145424 9 os.py:501 func -> _exists
+0 145424 26 <string>:0 func -> ?
+0 145424 9 <string>:0 func <- ?
+0 145424 14 os.py:506 func <- _exists
+0 145424 9 os.py:711 func <- ?
+0 145424 33 site.py:238 func -> _Printer
+0 145424 11 site.py:279 func <- _Printer
+0 145424 38 site.py:317 func -> _Helper
+0 145424 9 site.py:326 func <- _Helper
+0 145424 34 site.py:376 func -> main
+0 145424 8 site.py:69 func -> abs__file__
+0 145424 11 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 11 posixpath.py:49 func <- isabs
+0 145424 10 posixpath.py:374 func -> normpath
+0 145424 22 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 16 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 15 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 22 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 18 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 12 site.py:75 func <- abs__file__
+0 145424 9 site.py:77 func -> removeduppaths
+0 145424 11 site.py:65 func -> makepath
+0 145424 10 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 10 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 42 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 8 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 8 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 8 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 16 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 8 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 12 site.py:93 func <- removeduppaths
+0 145424 11 posixpath.py:110 func -> basename
+0 145424 10 posixpath.py:74 func -> split
+0 145424 14 posixpath.py:81 func <- split
+0 145424 9 posixpath.py:112 func <- basename
+0 145424 9 site.py:171 func -> addsitepackages
+0 145424 13 posixpath.py:56 func -> join
+0 145424 15 posixpath.py:66 func <- join
+0 145424 10 posixpath.py:56 func -> join
+0 145424 12 posixpath.py:66 func <- join
+0 145424 11 posixpath.py:192 func -> isdir
+0 145424 34 stat.py:45 func -> S_ISDIR
+0 145424 9 stat.py:29 func -> S_IFMT
+0 145424 9 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 9 posixpath.py:198 func <- isdir
+0 145424 11 site.py:148 func -> addsitedir
+0 145424 9 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 10 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 222 site.py:117 func -> addpackage
+0 145424 12 posixpath.py:56 func -> join
+0 145424 12 posixpath.py:66 func <- join
+0 145424 132 <string>:1 func -> ?
+0 145424 13 site.py:148 func -> addsitedir
+0 145424 9 site.py:105 func -> _init_pathinfo
+0 145424 11 posixpath.py:192 func -> isdir
+0 145424 84 posixpath.py:197 func <- isdir
+0 145424 12 posixpath.py:192 func -> isdir
+0 145424 23 stat.py:45 func -> S_ISDIR
+0 145424 9 stat.py:29 func -> S_IFMT
+0 145424 9 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 9 posixpath.py:198 func <- isdir
+0 145424 10 site.py:65 func -> makepath
+0 145424 10 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 10 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:192 func -> isdir
+0 145424 23 stat.py:45 func -> S_ISDIR
+0 145424 8 stat.py:29 func -> S_IFMT
+0 145424 8 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 9 posixpath.py:198 func <- isdir
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:192 func -> isdir
+0 145424 24 stat.py:45 func -> S_ISDIR
+0 145424 8 stat.py:29 func -> S_IFMT
+0 145424 8 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 8 posixpath.py:198 func <- isdir
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:192 func -> isdir
+0 145424 23 stat.py:45 func -> S_ISDIR
+0 145424 8 stat.py:29 func -> S_IFMT
+0 145424 8 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 9 posixpath.py:198 func <- isdir
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:192 func -> isdir
+0 145424 22 stat.py:45 func -> S_ISDIR
+0 145424 8 stat.py:29 func -> S_IFMT
+0 145424 8 stat.py:30 func <- S_IFMT
+0 145424 9 stat.py:46 func <- S_ISDIR
+0 145424 8 posixpath.py:198 func <- isdir
+0 145424 10 site.py:65 func -> makepath
+0 145424 9 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 8 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 site.py:115 func <- _init_pathinfo
+0 145424 9 site.py:65 func -> makepath
+0 145424 10 posixpath.py:56 func -> join
+0 145424 9 posixpath.py:66 func <- join
+0 145424 9 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 10 posixpath.py:374 func -> normpath
+0 145424 17 posixpath.py:398 func <- normpath
+0 145424 9 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 170 site.py:117 func -> addpackage
+0 145424 11 posixpath.py:56 func -> join
+0 145424 12 posixpath.py:66 func <- join
+0 145424 73 site.py:65 func -> makepath
+0 145424 11 posixpath.py:56 func -> join
+0 145424 11 posixpath.py:66 func <- join
+0 145424 10 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 19 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 9 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:168 func -> exists
+0 145424 41 posixpath.py:174 func <- exists
+0 145424 53 site.py:146 func <- addpackage
+0 145424 21 site.py:117 func -> addpackage
+0 145424 9 posixpath.py:56 func -> join
+0 145424 11 posixpath.py:66 func <- join
+0 145424 48 site.py:65 func -> makepath
+0 145424 10 posixpath.py:56 func -> join
+0 145424 47 posixpath.py:66 func <- join
+0 145424 10 posixpath.py:401 func -> abspath
+0 145424 9 posixpath.py:47 func -> isabs
+0 145424 9 posixpath.py:49 func <- isabs
+0 145424 9 posixpath.py:374 func -> normpath
+0 145424 18 posixpath.py:398 func <- normpath
+0 145424 10 posixpath.py:405 func <- abspath
+0 145424 10 posixpath.py:39 func -> normcase
+0 145424 9 posixpath.py:41 func <- normcase
+0 145424 9 site.py:67 func <- makepath
+0 145424 10 posixpath.py:168 func -> exists
+0 145424 25 posixpath.py:174 func <- exists
+0 145424 32 site.py:146 func <- addpackage
+0 145424 14 site.py:169 func <- addsitedir
+0 145424 10 <string>:1 func <- ?
+0 145424 16 site.py:146 func <- addpackage
+0 145424 10 site.py:169 func <- addsitedir
+0 145424 10 posixpath.py:192 func -> isdir
+0 145424 34 posixpath.py:197 func <- isdir
+0 145424 10 site.py:204 func <- addsitepackages
+0 145424 11 site.py:224 func -> setquit
+0 145424 11 site.py:235 func <- setquit
+0 145424 9 site.py:299 func -> setcopyright
+0 145424 11 site.py:244 func -> __init__
+0 145424 10 site.py:249 func <- __init__
+0 145424 12 site.py:244 func -> __init__
+0 145424 9 site.py:249 func <- __init__
+0 145424 10 posixpath.py:117 func -> dirname
+0 145424 9 posixpath.py:74 func -> split
+0 145424 14 posixpath.py:81 func <- split
+0 145424 9 posixpath.py:119 func <- dirname
+0 145424 14 posixpath.py:56 func -> join
+0 145424 11 posixpath.py:66 func <- join
+0 145424 11 site.py:244 func -> __init__
+0 145424 9 site.py:249 func <- __init__
+0 145424 9 site.py:314 func <- setcopyright
+0 145424 9 site.py:330 func -> sethelper
+0 145424 9 site.py:331 func <- sethelper
+0 145424 9 site.py:333 func -> aliasmbcs
+0 145424 9 site.py:346 func <- aliasmbcs
+0 145424 9 site.py:348 func -> setencoding
+0 145424 9 site.py:365 func <- setencoding
+0 145424 9 site.py:368 func -> execsitecustomize
+0 145424 706 site.py:373 func <- execsitecustomize
+0 145424 16 site.py:395 func <- main
+0 145424 12 site.py:406 func <- ?
+0 145424 289 warnings.py:1 func -> ?
+0 145424 158 linecache.py:6 func -> ?
+0 145424 17 linecache.py:66 func <- ?
+0 145424 20 warnings.py:179 func -> _OptionError
+0 145424 9 warnings.py:180 func <- _OptionError
+0 145424 19 warnings.py:184 func -> _processoptions
+0 145424 10 warnings.py:189 func <- _processoptions
+0 145424 12 warnings.py:160 func -> simplefilter
+0 145424 13 warnings.py:173 func <- simplefilter
+0 145424 10 warnings.py:160 func -> simplefilter
+0 145424 11 warnings.py:173 func <- simplefilter
+0 145424 9 warnings.py:259 func <- ?
+0 145424 492 __init__.py:28 func -> ?
+0 145424 599 codecs.py:8 func -> ?
+0 145424 61 codecs.py:76 func -> Codec
+0 145424 12 codecs.py:117 func <- Codec
+0 145424 18 codecs.py:147 func -> StreamWriter
+0 145424 11 codecs.py:200 func <- StreamWriter
+0 145424 13 codecs.py:209 func -> StreamReader
+0 145424 13 codecs.py:436 func <- StreamReader
+0 145424 12 codecs.py:445 func -> StreamReaderWriter
+0 145424 13 codecs.py:509 func <- StreamReaderWriter
+0 145424 11 codecs.py:518 func -> StreamRecoder
+0 145424 12 codecs.py:619 func <- StreamRecoder
+0 145424 17 codecs.py:817 func <- ?
+0 145424 625 aliases.py:17 func -> ?
+0 145424 54 aliases.py:18 func <- ?
+0 145424 21 __init__.py:43 func -> CodecRegistryError
+0 145424 10 __init__.py:45 func <- CodecRegistryError
+0 145424 19 __init__.py:145 func <- ?
+0 145424 18 __init__.py:69 func -> search_function
+0 145424 12 __init__.py:47 func -> normalize_encoding
+0 145424 16 __init__.py:67 func <- normalize_encoding
+0 145424 120 ascii.py:8 func -> ?
+0 145424 14 ascii.py:13 func -> Codec
+0 145424 10 ascii.py:18 func <- Codec
+0 145424 15 ascii.py:20 func -> StreamWriter
+0 145424 9 ascii.py:21 func <- StreamWriter
+0 145424 13 ascii.py:23 func -> StreamReader
+0 145424 9 ascii.py:24 func <- StreamReader
+0 145424 24 ascii.py:26 func -> StreamConverter
+0 145424 10 ascii.py:29 func <- StreamConverter
+0 145424 14 ascii.py:33 func <- ?
+0 145424 17 ascii.py:33 func -> getregentry
+0 145424 10 ascii.py:35 func <- getregentry
+0 145424 26 __init__.py:142 func <- search_function
+0 145424 367 func_abc.py:3 func -> ?
+0 145424 1722 func_abc.py:14 func -> func_a
+0 145424 1005677 func_abc.py:9 func -> func_b
+0 145424 1000271 func_abc.py:5 func -> func_c
+0 145424 1009739 func_abc.py:7 func <- func_c
+0 145424 25 func_abc.py:12 func <- func_b
+0 145424 9 func_abc.py:17 func <- func_a
+0 145424 9 func_abc.py:19 func <- ?
+^C
+
+As each function is entered, the last column is indented by 2 spaces. This
+shows which function is calling which.
+
+The DELTA(us) column shows the change in time from the previous line to the
+current line.
+
+The FILE::LINE column shows which line in which file was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_flowtime_example.txt
new file mode 100644
index 0000000..5ac494b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_flowtime_example.txt
@@ -0,0 +1,487 @@
+The following are examples of py_flowtime.d.
+
+This is a simple script to trace the flow of Python functions. Here it traces
+the example program, Code/Python/func_abc.py
+
+# py_flowtime.d
+ C TIME(us) FILE DELTA(us) -- FUNC
+ 0 3064660319556 site.py 3 -> ?
+ 0 3064660320224 os.py 667 -> ?
+ 0 3064660321335 posixpath.py 1111 -> ?
+ 0 3064660321526 stat.py 190 -> ?
+ 0 3064660321546 stat.py 20 <- ?
+ 0 3064660321576 posixpath.py 29 <- ?
+ 0 3064660321593 os.py 17 -> _get_exports_list
+ 0 3064660321728 os.py 134 <- _get_exports_list
+ 0 3064660321989 UserDict.py 260 -> ?
+ 0 3064660322000 UserDict.py 10 -> UserDict
+ 0 3064660322035 UserDict.py 34 <- UserDict
+ 0 3064660322050 UserDict.py 15 -> IterableUserDict
+ 0 3064660322058 UserDict.py 8 <- IterableUserDict
+ 0 3064660322071 UserDict.py 12 -> DictMixin
+ 0 3064660322247 UserDict.py 176 <- DictMixin
+ 0 3064660322258 UserDict.py 10 <- ?
+ 0 3064660322275 os.py 16 -> _Environ
+ 0 3064660322285 os.py 10 <- _Environ
+ 0 3064660322298 os.py 13 -> __init__
+ 0 3064660322308 UserDict.py 10 -> __init__
+ 0 3064660322319 UserDict.py 10 <- __init__
+ 0 3064660322328 os.py 9 <- __init__
+ 0 3064660322338 os.py 10 -> _exists
+ 0 3064660322946 <string> 607 -> ?
+ 0 3064660322955 <string> 8 <- ?
+ 0 3064660322963 os.py 8 <- _exists
+ 0 3064660322972 os.py 8 -> _exists
+ 0 3064660322996 <string> 23 -> ?
+ 0 3064660323005 <string> 8 <- ?
+ 0 3064660323020 os.py 14 <- _exists
+ 0 3064660323029 os.py 8 -> _exists
+ 0 3064660323051 <string> 22 -> ?
+ 0 3064660323059 <string> 7 <- ?
+ 0 3064660323067 os.py 8 <- _exists
+ 0 3064660323077 os.py 10 -> _exists
+ 0 3064660323098 <string> 21 -> ?
+ 0 3064660323106 <string> 7 <- ?
+ 0 3064660323114 os.py 8 <- _exists
+ 0 3064660323125 os.py 10 -> _exists
+ 0 3064660323146 <string> 21 -> ?
+ 0 3064660323154 <string> 7 <- ?
+ 0 3064660323162 os.py 8 <- _exists
+ 0 3064660323173 os.py 10 -> _exists
+ 0 3064660323194 <string> 21 -> ?
+ 0 3064660323202 <string> 7 <- ?
+ 0 3064660323210 os.py 8 <- _exists
+ 0 3064660323218 os.py 8 -> _exists
+ 0 3064660323239 <string> 21 -> ?
+ 0 3064660323247 <string> 8 <- ?
+ 0 3064660323261 os.py 13 <- _exists
+ 0 3064660323271 os.py 10 -> _exists
+ 0 3064660323293 <string> 21 -> ?
+ 0 3064660323301 <string> 8 <- ?
+ 0 3064660323314 os.py 12 <- _exists
+ 0 3064660323324 os.py 10 -> _exists
+ 0 3064660323345 <string> 21 -> ?
+ 0 3064660323354 <string> 8 <- ?
+ 0 3064660323366 os.py 12 <- _exists
+ 0 3064660323545 copy_reg.py 178 -> ?
+ 0 3064660323726 types.py 180 -> ?
+ 0 3064660323790 types.py 64 -> _C
+ 0 3064660323800 types.py 9 <- _C
+ 0 3064660323834 types.py 33 <- ?
+ 0 3064660323855 copy_reg.py 21 -> pickle
+ 0 3064660323866 copy_reg.py 10 -> constructor
+ 0 3064660323874 copy_reg.py 8 <- constructor
+ 0 3064660323883 copy_reg.py 8 <- pickle
+ 0 3064660323895 copy_reg.py 11 <- ?
+ 0 3064660323909 copy_reg.py 14 -> pickle
+ 0 3064660323919 copy_reg.py 9 -> constructor
+ 0 3064660323927 copy_reg.py 8 <- constructor
+ 0 3064660323936 copy_reg.py 8 <- pickle
+ 0 3064660323946 copy_reg.py 9 -> pickle
+ 0 3064660323955 copy_reg.py 9 -> constructor
+ 0 3064660323963 copy_reg.py 8 <- constructor
+ 0 3064660323972 copy_reg.py 8 <- pickle
+ 0 3064660323981 os.py 9 -> _exists
+ 0 3064660324006 <string> 25 -> ?
+ 0 3064660324015 <string> 8 <- ?
+ 0 3064660324028 os.py 13 <- _exists
+ 0 3064660324037 os.py 8 <- ?
+ 0 3064660324069 site.py 31 -> _Printer
+ 0 3064660324080 site.py 10 <- _Printer
+ 0 3064660324118 site.py 38 -> _Helper
+ 0 3064660324127 site.py 9 <- _Helper
+ 0 3064660324160 site.py 33 -> main
+ 0 3064660324168 site.py 8 -> abs__file__
+ 0 3064660324179 posixpath.py 10 -> abspath
+ 0 3064660324187 posixpath.py 8 -> isabs
+ 0 3064660324197 posixpath.py 9 <- isabs
+ 0 3064660324207 posixpath.py 9 -> normpath
+ 0 3064660324228 posixpath.py 21 <- normpath
+ 0 3064660324238 posixpath.py 9 <- abspath
+ 0 3064660324253 posixpath.py 15 -> abspath
+ 0 3064660324261 posixpath.py 8 -> isabs
+ 0 3064660324270 posixpath.py 8 <- isabs
+ 0 3064660324278 posixpath.py 8 -> normpath
+ 0 3064660324295 posixpath.py 16 <- normpath
+ 0 3064660324304 posixpath.py 9 <- abspath
+ 0 3064660324314 posixpath.py 9 -> abspath
+ 0 3064660324322 posixpath.py 8 -> isabs
+ 0 3064660324331 posixpath.py 8 <- isabs
+ 0 3064660324339 posixpath.py 8 -> normpath
+ 0 3064660324355 posixpath.py 15 <- normpath
+ 0 3064660324364 posixpath.py 8 <- abspath
+ 0 3064660324374 posixpath.py 9 -> abspath
+ 0 3064660324382 posixpath.py 8 -> isabs
+ 0 3064660324391 posixpath.py 8 <- isabs
+ 0 3064660324399 posixpath.py 8 -> normpath
+ 0 3064660324415 posixpath.py 15 <- normpath
+ 0 3064660324424 posixpath.py 8 <- abspath
+ 0 3064660324439 posixpath.py 14 -> abspath
+ 0 3064660324447 posixpath.py 8 -> isabs
+ 0 3064660324456 posixpath.py 8 <- isabs
+ 0 3064660324464 posixpath.py 8 -> normpath
+ 0 3064660324480 posixpath.py 15 <- normpath
+ 0 3064660324489 posixpath.py 8 <- abspath
+ 0 3064660324511 posixpath.py 21 -> abspath
+ 0 3064660324519 posixpath.py 8 -> isabs
+ 0 3064660324528 posixpath.py 8 <- isabs
+ 0 3064660324536 posixpath.py 8 -> normpath
+ 0 3064660324552 posixpath.py 15 <- normpath
+ 0 3064660324561 posixpath.py 9 <- abspath
+ 0 3064660324579 posixpath.py 17 -> abspath
+ 0 3064660324588 posixpath.py 8 -> isabs
+ 0 3064660324596 posixpath.py 8 <- isabs
+ 0 3064660324605 posixpath.py 8 -> normpath
+ 0 3064660324621 posixpath.py 15 <- normpath
+ 0 3064660324630 posixpath.py 8 <- abspath
+ 0 3064660324639 posixpath.py 9 -> abspath
+ 0 3064660324648 posixpath.py 8 -> isabs
+ 0 3064660324656 posixpath.py 8 <- isabs
+ 0 3064660324665 posixpath.py 8 -> normpath
+ 0 3064660324681 posixpath.py 15 <- normpath
+ 0 3064660324690 posixpath.py 9 <- abspath
+ 0 3064660324701 site.py 11 <- abs__file__
+ 0 3064660324709 site.py 8 -> removeduppaths
+ 0 3064660324719 site.py 10 -> makepath
+ 0 3064660324729 posixpath.py 9 -> join
+ 0 3064660324738 posixpath.py 8 <- join
+ 0 3064660324746 posixpath.py 8 -> abspath
+ 0 3064660324755 posixpath.py 8 -> isabs
+ 0 3064660324764 posixpath.py 8 <- isabs
+ 0 3064660324773 posixpath.py 9 -> normpath
+ 0 3064660324789 posixpath.py 15 <- normpath
+ 0 3064660324797 posixpath.py 8 <- abspath
+ 0 3064660324806 posixpath.py 8 -> normcase
+ 0 3064660324814 posixpath.py 8 <- normcase
+ 0 3064660324823 site.py 8 <- makepath
+ 0 3064660324864 site.py 40 -> makepath
+ 0 3064660324873 posixpath.py 8 -> join
+ 0 3064660324881 posixpath.py 8 <- join
+ 0 3064660324889 posixpath.py 8 -> abspath
+ 0 3064660324898 posixpath.py 8 -> isabs
+ 0 3064660324906 posixpath.py 8 <- isabs
+ 0 3064660324915 posixpath.py 8 -> normpath
+ 0 3064660324931 posixpath.py 15 <- normpath
+ 0 3064660324939 posixpath.py 8 <- abspath
+ 0 3064660324948 posixpath.py 8 -> normcase
+ 0 3064660324957 posixpath.py 8 <- normcase
+ 0 3064660324965 site.py 8 <- makepath
+ 0 3064660324974 site.py 9 -> makepath
+ 0 3064660324983 posixpath.py 8 -> join
+ 0 3064660324991 posixpath.py 8 <- join
+ 0 3064660325000 posixpath.py 8 -> abspath
+ 0 3064660325008 posixpath.py 8 -> isabs
+ 0 3064660325017 posixpath.py 8 <- isabs
+ 0 3064660325025 posixpath.py 8 -> normpath
+ 0 3064660325041 posixpath.py 15 <- normpath
+ 0 3064660325050 posixpath.py 8 <- abspath
+ 0 3064660325059 posixpath.py 8 -> normcase
+ 0 3064660325067 posixpath.py 8 <- normcase
+ 0 3064660325075 site.py 8 <- makepath
+ 0 3064660325084 site.py 9 -> makepath
+ 0 3064660325093 posixpath.py 8 -> join
+ 0 3064660325102 posixpath.py 8 <- join
+ 0 3064660325110 posixpath.py 8 -> abspath
+ 0 3064660325118 posixpath.py 8 -> isabs
+ 0 3064660325127 posixpath.py 8 <- isabs
+ 0 3064660325135 posixpath.py 8 -> normpath
+ 0 3064660325151 posixpath.py 15 <- normpath
+ 0 3064660325160 posixpath.py 8 <- abspath
+ 0 3064660325169 posixpath.py 8 -> normcase
+ 0 3064660325177 posixpath.py 7 <- normcase
+ 0 3064660325185 site.py 8 <- makepath
+ 0 3064660325194 site.py 9 -> makepath
+ 0 3064660325203 posixpath.py 8 -> join
+ 0 3064660325212 posixpath.py 8 <- join
+ 0 3064660325220 posixpath.py 8 -> abspath
+ 0 3064660325228 posixpath.py 8 -> isabs
+ 0 3064660325237 posixpath.py 8 <- isabs
+ 0 3064660325245 posixpath.py 8 -> normpath
+ 0 3064660325261 posixpath.py 15 <- normpath
+ 0 3064660325270 posixpath.py 8 <- abspath
+ 0 3064660325279 posixpath.py 8 -> normcase
+ 0 3064660325287 posixpath.py 8 <- normcase
+ 0 3064660325295 site.py 8 <- makepath
+ 0 3064660325307 site.py 11 <- removeduppaths
+ 0 3064660325317 posixpath.py 10 -> basename
+ 0 3064660325327 posixpath.py 9 -> split
+ 0 3064660325340 posixpath.py 13 <- split
+ 0 3064660325349 posixpath.py 8 <- basename
+ 0 3064660325358 site.py 8 -> addsitepackages
+ 0 3064660325370 posixpath.py 12 -> join
+ 0 3064660325385 posixpath.py 14 <- join
+ 0 3064660325394 posixpath.py 9 -> join
+ 0 3064660325406 posixpath.py 11 <- join
+ 0 3064660325416 posixpath.py 10 -> isdir
+ 0 3064660325447 stat.py 31 -> S_ISDIR
+ 0 3064660325456 stat.py 8 -> S_IFMT
+ 0 3064660325464 stat.py 8 <- S_IFMT
+ 0 3064660325473 stat.py 8 <- S_ISDIR
+ 0 3064660325481 posixpath.py 7 <- isdir
+ 0 3064660325491 site.py 10 -> addsitedir
+ 0 3064660325500 site.py 8 -> makepath
+ 0 3064660325508 posixpath.py 8 -> join
+ 0 3064660325517 posixpath.py 8 <- join
+ 0 3064660325525 posixpath.py 8 -> abspath
+ 0 3064660325534 posixpath.py 8 -> isabs
+ 0 3064660325543 posixpath.py 8 <- isabs
+ 0 3064660325552 posixpath.py 9 -> normpath
+ 0 3064660325569 posixpath.py 16 <- normpath
+ 0 3064660325578 posixpath.py 8 <- abspath
+ 0 3064660325587 posixpath.py 8 -> normcase
+ 0 3064660325595 posixpath.py 8 <- normcase
+ 0 3064660325604 site.py 8 <- makepath
+ 0 3064660325823 site.py 219 -> addpackage
+ 0 3064660325834 posixpath.py 10 -> join
+ 0 3064660325844 posixpath.py 10 <- join
+ 0 3064660325972 <string> 127 -> ?
+ 0 3064660325985 site.py 13 -> addsitedir
+ 0 3064660325994 site.py 8 -> _init_pathinfo
+ 0 3064660326004 posixpath.py 10 -> isdir
+ 0 3064660326086 posixpath.py 81 <- isdir
+ 0 3064660326097 posixpath.py 10 -> isdir
+ 0 3064660326118 stat.py 21 -> S_ISDIR
+ 0 3064660326127 stat.py 9 -> S_IFMT
+ 0 3064660326136 stat.py 8 <- S_IFMT
+ 0 3064660326144 stat.py 8 <- S_ISDIR
+ 0 3064660326152 posixpath.py 7 <- isdir
+ 0 3064660326161 site.py 9 -> makepath
+ 0 3064660326171 posixpath.py 9 -> join
+ 0 3064660326179 posixpath.py 8 <- join
+ 0 3064660326188 posixpath.py 8 -> abspath
+ 0 3064660326196 posixpath.py 8 -> isabs
+ 0 3064660326205 posixpath.py 9 <- isabs
+ 0 3064660326215 posixpath.py 9 -> normpath
+ 0 3064660326231 posixpath.py 16 <- normpath
+ 0 3064660326240 posixpath.py 8 <- abspath
+ 0 3064660326249 posixpath.py 9 -> normcase
+ 0 3064660326258 posixpath.py 8 <- normcase
+ 0 3064660326266 site.py 8 <- makepath
+ 0 3064660326276 posixpath.py 9 -> isdir
+ 0 3064660326298 stat.py 22 -> S_ISDIR
+ 0 3064660326306 stat.py 8 -> S_IFMT
+ 0 3064660326314 stat.py 7 <- S_IFMT
+ 0 3064660326322 stat.py 8 <- S_ISDIR
+ 0 3064660326330 posixpath.py 8 <- isdir
+ 0 3064660326340 site.py 9 -> makepath
+ 0 3064660326349 posixpath.py 8 -> join
+ 0 3064660326357 posixpath.py 8 <- join
+ 0 3064660326382 posixpath.py 24 -> abspath
+ 0 3064660326390 posixpath.py 8 -> isabs
+ 0 3064660326399 posixpath.py 8 <- isabs
+ 0 3064660326408 posixpath.py 8 -> normpath
+ 0 3064660326425 posixpath.py 16 <- normpath
+ 0 3064660326434 posixpath.py 9 <- abspath
+ 0 3064660326443 posixpath.py 9 -> normcase
+ 0 3064660326451 posixpath.py 8 <- normcase
+ 0 3064660326460 site.py 8 <- makepath
+ 0 3064660326469 posixpath.py 9 -> isdir
+ 0 3064660326493 stat.py 23 -> S_ISDIR
+ 0 3064660326501 stat.py 8 -> S_IFMT
+ 0 3064660326509 stat.py 7 <- S_IFMT
+ 0 3064660326517 stat.py 8 <- S_ISDIR
+ 0 3064660326525 posixpath.py 7 <- isdir
+ 0 3064660326534 site.py 9 -> makepath
+ 0 3064660326542 posixpath.py 8 -> join
+ 0 3064660326551 posixpath.py 8 <- join
+ 0 3064660326559 posixpath.py 8 -> abspath
+ 0 3064660326568 posixpath.py 8 -> isabs
+ 0 3064660326576 posixpath.py 8 <- isabs
+ 0 3064660326585 posixpath.py 8 -> normpath
+ 0 3064660326602 posixpath.py 16 <- normpath
+ 0 3064660326610 posixpath.py 8 <- abspath
+ 0 3064660326619 posixpath.py 8 -> normcase
+ 0 3064660326628 posixpath.py 8 <- normcase
+ 0 3064660326636 site.py 8 <- makepath
+ 0 3064660326646 posixpath.py 9 -> isdir
+ 0 3064660326668 stat.py 22 -> S_ISDIR
+ 0 3064660326676 stat.py 8 -> S_IFMT
+ 0 3064660326684 stat.py 7 <- S_IFMT
+ 0 3064660326692 stat.py 8 <- S_ISDIR
+ 0 3064660326700 posixpath.py 8 <- isdir
+ 0 3064660326709 site.py 9 -> makepath
+ 0 3064660326718 posixpath.py 8 -> join
+ 0 3064660326726 posixpath.py 8 <- join
+ 0 3064660326735 posixpath.py 8 -> abspath
+ 0 3064660326743 posixpath.py 8 -> isabs
+ 0 3064660326752 posixpath.py 8 <- isabs
+ 0 3064660326760 posixpath.py 8 -> normpath
+ 0 3064660326777 posixpath.py 16 <- normpath
+ 0 3064660326786 posixpath.py 9 <- abspath
+ 0 3064660326795 posixpath.py 9 -> normcase
+ 0 3064660326803 posixpath.py 8 <- normcase
+ 0 3064660326811 site.py 8 <- makepath
+ 0 3064660326821 posixpath.py 9 -> isdir
+ 0 3064660326842 stat.py 21 -> S_ISDIR
+ 0 3064660326850 stat.py 8 -> S_IFMT
+ 0 3064660326858 stat.py 7 <- S_IFMT
+ 0 3064660326866 stat.py 8 <- S_ISDIR
+ 0 3064660326874 posixpath.py 7 <- isdir
+ 0 3064660326883 site.py 9 -> makepath
+ 0 3064660326892 posixpath.py 8 -> join
+ 0 3064660326901 posixpath.py 8 <- join
+ 0 3064660326909 posixpath.py 8 -> abspath
+ 0 3064660326917 posixpath.py 8 -> isabs
+ 0 3064660326926 posixpath.py 8 <- isabs
+ 0 3064660326935 posixpath.py 8 -> normpath
+ 0 3064660326951 posixpath.py 16 <- normpath
+ 0 3064660326960 posixpath.py 8 <- abspath
+ 0 3064660326970 posixpath.py 9 -> normcase
+ 0 3064660326978 posixpath.py 8 <- normcase
+ 0 3064660326986 site.py 8 <- makepath
+ 0 3064660326995 site.py 8 <- _init_pathinfo
+ 0 3064660327004 site.py 8 -> makepath
+ 0 3064660327013 posixpath.py 9 -> join
+ 0 3064660327021 posixpath.py 8 <- join
+ 0 3064660327030 posixpath.py 8 -> abspath
+ 0 3064660327038 posixpath.py 8 -> isabs
+ 0 3064660327047 posixpath.py 8 <- isabs
+ 0 3064660327056 posixpath.py 8 -> normpath
+ 0 3064660327072 posixpath.py 15 <- normpath
+ 0 3064660327081 posixpath.py 9 <- abspath
+ 0 3064660327090 posixpath.py 8 -> normcase
+ 0 3064660327098 posixpath.py 8 <- normcase
+ 0 3064660327106 site.py 8 <- makepath
+ 0 3064660327278 site.py 171 -> addpackage
+ 0 3064660327289 posixpath.py 10 -> join
+ 0 3064660327300 posixpath.py 10 <- join
+ 0 3064660327372 site.py 72 -> makepath
+ 0 3064660327382 posixpath.py 10 -> join
+ 0 3064660327393 posixpath.py 10 <- join
+ 0 3064660327402 posixpath.py 9 -> abspath
+ 0 3064660327410 posixpath.py 8 -> isabs
+ 0 3064660327419 posixpath.py 8 <- isabs
+ 0 3064660327427 posixpath.py 8 -> normpath
+ 0 3064660327445 posixpath.py 17 <- normpath
+ 0 3064660327454 posixpath.py 9 <- abspath
+ 0 3064660327463 posixpath.py 9 -> normcase
+ 0 3064660327472 posixpath.py 8 <- normcase
+ 0 3064660327480 site.py 8 <- makepath
+ 0 3064660327489 posixpath.py 9 -> exists
+ 0 3064660327515 posixpath.py 26 <- exists
+ 0 3064660327567 site.py 51 <- addpackage
+ 0 3064660327588 site.py 20 -> addpackage
+ 0 3064660327597 posixpath.py 8 -> join
+ 0 3064660327607 posixpath.py 10 <- join
+ 0 3064660327654 site.py 46 -> makepath
+ 0 3064660327663 posixpath.py 9 -> join
+ 0 3064660327710 posixpath.py 46 <- join
+ 0 3064660327720 posixpath.py 9 -> abspath
+ 0 3064660327728 posixpath.py 8 -> isabs
+ 0 3064660327737 posixpath.py 9 <- isabs
+ 0 3064660327746 posixpath.py 8 -> normpath
+ 0 3064660327764 posixpath.py 17 <- normpath
+ 0 3064660327773 posixpath.py 9 <- abspath
+ 0 3064660327782 posixpath.py 9 -> normcase
+ 0 3064660327791 posixpath.py 8 <- normcase
+ 0 3064660327799 site.py 8 <- makepath
+ 0 3064660327808 posixpath.py 9 -> exists
+ 0 3064660327833 posixpath.py 24 <- exists
+ 0 3064660327864 site.py 31 <- addpackage
+ 0 3064660327878 site.py 13 <- addsitedir
+ 0 3064660327887 <string> 9 <- ?
+ 0 3064660327903 site.py 15 <- addpackage
+ 0 3064660327913 site.py 9 <- addsitedir
+ 0 3064660327923 posixpath.py 10 -> isdir
+ 0 3064660327955 posixpath.py 32 <- isdir
+ 0 3064660327965 site.py 9 <- addsitepackages
+ 0 3064660327976 site.py 10 -> setquit
+ 0 3064660327986 site.py 10 <- setquit
+ 0 3064660327995 site.py 8 -> setcopyright
+ 0 3064660328005 site.py 10 -> __init__
+ 0 3064660328015 site.py 9 <- __init__
+ 0 3064660328026 site.py 11 -> __init__
+ 0 3064660328035 site.py 8 <- __init__
+ 0 3064660328045 posixpath.py 9 -> dirname
+ 0 3064660328053 posixpath.py 8 -> split
+ 0 3064660328066 posixpath.py 13 <- split
+ 0 3064660328075 posixpath.py 8 <- dirname
+ 0 3064660328089 posixpath.py 13 -> join
+ 0 3064660328099 posixpath.py 10 <- join
+ 0 3064660328109 site.py 10 -> __init__
+ 0 3064660328118 site.py 9 <- __init__
+ 0 3064660328127 site.py 8 <- setcopyright
+ 0 3064660328136 site.py 8 -> sethelper
+ 0 3064660328145 site.py 8 <- sethelper
+ 0 3064660328153 site.py 8 -> aliasmbcs
+ 0 3064660328161 site.py 8 <- aliasmbcs
+ 0 3064660328170 site.py 8 -> setencoding
+ 0 3064660328178 site.py 7 <- setencoding
+ 0 3064660328186 site.py 8 -> execsitecustomize
+ 0 3064660328736 site.py 549 <- execsitecustomize
+ 0 3064660328748 site.py 12 <- main
+ 0 3064660328758 site.py 9 <- ?
+ 0 3064660329029 warnings.py 270 -> ?
+ 0 3064660329184 linecache.py 155 -> ?
+ 0 3064660329201 linecache.py 16 <- ?
+ 0 3064660329220 warnings.py 18 -> _OptionError
+ 0 3064660329228 warnings.py 8 <- _OptionError
+ 0 3064660329246 warnings.py 17 -> _processoptions
+ 0 3064660329255 warnings.py 8 <- _processoptions
+ 0 3064660329266 warnings.py 10 -> simplefilter
+ 0 3064660329278 warnings.py 12 <- simplefilter
+ 0 3064660329288 warnings.py 9 -> simplefilter
+ 0 3064660329298 warnings.py 10 <- simplefilter
+ 0 3064660329307 warnings.py 8 <- ?
+ 0 3064660329533 __init__.py 226 -> ?
+ 0 3064660330090 codecs.py 557 -> ?
+ 0 3064660330148 codecs.py 57 -> Codec
+ 0 3064660330158 codecs.py 10 <- Codec
+ 0 3064660330171 codecs.py 13 -> StreamWriter
+ 0 3064660330182 codecs.py 10 <- StreamWriter
+ 0 3064660330194 codecs.py 11 -> StreamReader
+ 0 3064660330206 codecs.py 12 <- StreamReader
+ 0 3064660330217 codecs.py 11 -> StreamReaderWriter
+ 0 3064660330229 codecs.py 11 <- StreamReaderWriter
+ 0 3064660330239 codecs.py 10 -> StreamRecoder
+ 0 3064660330251 codecs.py 11 <- StreamRecoder
+ 0 3064660330267 codecs.py 16 <- ?
+ 0 3064660331439 aliases.py 1171 -> ?
+ 0 3064660331500 aliases.py 61 <- ?
+ 0 3064660331526 __init__.py 25 -> CodecRegistryError
+ 0 3064660331535 __init__.py 9 <- CodecRegistryError
+ 0 3064660331557 __init__.py 21 <- ?
+ 0 3064660331577 __init__.py 20 -> search_function
+ 0 3064660331590 __init__.py 12 -> normalize_encoding
+ 0 3064660331605 __init__.py 15 <- normalize_encoding
+ 0 3064660331728 ascii.py 122 -> ?
+ 0 3064660331742 ascii.py 13 -> Codec
+ 0 3064660331752 ascii.py 9 <- Codec
+ 0 3064660331766 ascii.py 13 -> StreamWriter
+ 0 3064660331774 ascii.py 8 <- StreamWriter
+ 0 3064660331787 ascii.py 13 -> StreamReader
+ 0 3064660331796 ascii.py 8 <- StreamReader
+ 0 3064660331819 ascii.py 23 -> StreamConverter
+ 0 3064660331829 ascii.py 9 <- StreamConverter
+ 0 3064660331842 ascii.py 13 <- ?
+ 0 3064660331860 ascii.py 17 -> getregentry
+ 0 3064660331869 ascii.py 9 <- getregentry
+ 0 3064660331897 __init__.py 27 <- search_function
+ 0 3064660332263 func_abc.py 366 -> ?
+ 0 3064660333735 func_abc.py 1471 -> func_a
+ 0 3064661340597 func_abc.py 1006862 -> func_b
+ 0 3064662350504 func_abc.py 1009906 -> func_c
+ 0 3064663350678 func_abc.py 1000174 <- func_c
+ 0 3064663350700 func_abc.py 22 <- func_b
+ 0 3064663350709 func_abc.py 8 <- func_a
+ 0 3064663350717 func_abc.py 8 <- ?
+^C
+
+The fifth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - first a whole lot of
+pre-processing, then working through the func_abc.py program.
+
+The TIME(us) column shows time since boot.
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the third last line of data output
+shows the time elapsing between func_c returning and func_b returning as 22
+microseconds.
+
+The FILE column shows file that was being executed.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_funccalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_funccalls_example.txt
new file mode 100644
index 0000000..0ac8780
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_funccalls_example.txt
@@ -0,0 +1,89 @@
+The following are examples of py_funccalls.d.
+
+This is a simple script to count executed PHP functions. Here it traces
+an example program, Code/Python/func_abc.py
+
+# py_funccalls.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ FILE FUNC CALLS
+ UserDict.py ? 1
+ UserDict.py DictMixin 1
+ UserDict.py IterableUserDict 1
+ UserDict.py UserDict 1
+ UserDict.py __init__ 1
+ __init__.py ? 1
+ __init__.py CodecRegistryError 1
+ __init__.py normalize_encoding 1
+ __init__.py search_function 1
+ aliases.py ? 1
+ ascii.py ? 1
+ ascii.py Codec 1
+ ascii.py StreamConverter 1
+ ascii.py StreamReader 1
+ ascii.py StreamWriter 1
+ ascii.py getregentry 1
+ codecs.py ? 1
+ codecs.py Codec 1
+ codecs.py StreamReader 1
+ codecs.py StreamReaderWriter 1
+ codecs.py StreamRecoder 1
+ codecs.py StreamWriter 1
+ copy_reg.py ? 1
+ func_abc.py ? 1
+ func_abc.py func_a 1
+ func_abc.py func_b 1
+ func_abc.py func_c 1
+ linecache.py ? 1
+ os.py ? 1
+ os.py _Environ 1
+ os.py __init__ 1
+ os.py _get_exports_list 1
+ posixpath.py ? 1
+ posixpath.py basename 1
+ posixpath.py dirname 1
+ site.py ? 1
+ site.py _Helper 1
+ site.py _Printer 1
+ site.py _init_pathinfo 1
+ site.py abs__file__ 1
+ site.py addsitepackages 1
+ site.py aliasmbcs 1
+ site.py execsitecustomize 1
+ site.py main 1
+ site.py removeduppaths 1
+ site.py setcopyright 1
+ site.py setencoding 1
+ site.py sethelper 1
+ site.py setquit 1
+ stat.py ? 1
+ types.py ? 1
+ types.py _C 1
+ warnings.py ? 1
+ warnings.py _OptionError 1
+ warnings.py _processoptions 1
+ posixpath.py exists 2
+ posixpath.py split 2
+ site.py addsitedir 2
+ warnings.py simplefilter 2
+ copy_reg.py constructor 3
+ copy_reg.py pickle 3
+ site.py __init__ 3
+ site.py addpackage 3
+ stat.py S_IFMT 6
+ stat.py S_ISDIR 6
+ posixpath.py isdir 8
+ os.py _exists 10
+ <string> ? 11
+ posixpath.py normcase 14
+ site.py makepath 14
+ posixpath.py join 20
+ posixpath.py abspath 22
+ posixpath.py isabs 22
+ posixpath.py normpath 22
+
+It tells you how many times each function was called, and which file this
+function was associated with. In this case you can see most of the function
+calls come from functions within the posixpath.py library.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_malloc_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_malloc_example.txt
new file mode 100644
index 0000000..be8fc25
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_malloc_example.txt
@@ -0,0 +1,508 @@
+The following are examples of py_malloc.d
+
+This is an experimental script to identify who is calling malloc() for memory
+allocation, and to print distribution plots of the requested bytes. Here you
+can see it running on Code/Python/func_abc.py
+
+# py_malloc.d -c ./func_abc.py
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+
+Python malloc byte distributions by engine caller,
+
+ libpython2.4.so.1.0`_PyUnicode_New, total bytes = 2
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ libpython2.4.so.1.0`find_key, total bytes = 16
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ libpython2.4.so.1.0`PyInterpreterState_New, total bytes = 36
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ libpython2.4.so.1.0`_PyImport_Init, total bytes = 60
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ libpython2.4.so.1.0`PyThreadState_New, total bytes = 84
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ libpython2.4.so.1.0`pmerge, total bytes = 132
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@ 1
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16
+ 16 | 0
+
+ libpython2.4.so.1.0`PyThread_allocate_lock, total bytes = 144
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 64 | 0
+
+ libpython2.4.so.1.0`convertsimple, total bytes = 210
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 64 | 0
+
+ libc.so.1`strdup, total bytes = 451
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@ 1
+ 4 |@@@ 1
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 8
+ 32 |@@@@@@@@@@@@@@@ 6
+ 64 | 0
+
+ libpython2.4.so.1.0`PyList_New, total bytes = 528
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@ 22
+ 8 |@@@@@@@@@@@@@@@@@ 21
+ 16 |@@@@@ 6
+ 32 | 0
+ 64 | 0
+ 128 |@ 1
+ 256 | 0
+
+ libpython2.4.so.1.0`PyTokenizer_FromFile, total bytes = 1024
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ libpython2.4.so.1.0`_PyExc_Init, total bytes = 1058
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 40
+ 32 |@@ 2
+ 64 | 0
+
+ libpython2.4.so.1.0`tok_new, total bytes = 1832
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1024 | 0
+
+ libpython2.4.so.1.0`fill_free_list, total bytes = 1976
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1024 | 0
+
+ libpython2.4.so.1.0`PyParser_New, total bytes = 12024
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8192 | 0
+
+ libpython2.4.so.1.0`PyObject_Malloc, total bytes = 35152
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@ 20
+ 512 |@@@@@@@ 7
+ 1024 |@@@@@@@@@@ 11
+ 2048 |@@@@ 4
+ 4096 | 0
+
+ libpython2.4.so.1.0`PyMem_Malloc, total bytes = 50683
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@ 2
+ 16 |@@@@@@@ 4
+ 32 |@@ 1
+ 64 |@@@@@@@@@@@@@ 8
+ 128 |@@@@@ 3
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@@@@@@@@@ 6
+ 16384 | 0
+
+ libc.so.1`_findbuf, total bytes = 51800
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@ 4
+ 1024 |@@@@ 1
+ 2048 | 0
+ 4096 |@@@@@@@ 2
+ 8192 |@@@@@@@@@@@@@@@ 4
+ 16384 | 0
+
+ libpython2.4.so.1.0`dictresize, total bytes = 178752
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@ 1
+ 256 |@@@@@@@@@@@@@@@@@@@@@ 29
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@ 19
+ 2048 |@ 1
+ 4096 |@ 2
+ 8192 | 0
+ 16384 |@ 1
+ 32768 | 0
+ 65536 |@ 1
+ 131072 | 0
+
+ libpython2.4.so.1.0`new_arena, total bytes = 262208
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 | 0
+ 65536 | 0
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+
+Python malloc byte distributions by Python file and function,
+
+ site.py, addsitepackages, bytes total = 4
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ site.py, abs__file__, bytes total = 60
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ posixpath.py, exists, bytes total = 83
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ stat.py, S_ISDIR, bytes total = 364
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, _init_pathinfo, bytes total = 380
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ UserDict.py, DictMixin, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ codecs.py, StreamReader, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ codecs.py, StreamReaderWriter, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ codecs.py, StreamRecoder, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ codecs.py, StreamWriter, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ os.py, _Environ, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, _Printer, bytes total = 384
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ site.py, addsitedir, bytes total = 388
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ linecache.py, ?, bytes total = 396
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ posixpath.py, isdir, bytes total = 608
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@ 2
+ 4 | 0
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 32 |@@@@@@@ 2
+ 64 | 0
+ 128 | 0
+ 256 |@@@ 1
+ 512 | 0
+
+ os.py, _get_exports_list, bytes total = 612
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ posixpath.py, abspath, bytes total = 728
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 512 | 0
+
+ site.py, execsitecustomize, bytes total = 790
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 64 | 0
+ 128 | 0
+ 256 |@@@@ 1
+ 512 | 0
+
+ UserDict.py, UserDict, bytes total = 1920
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ stat.py, ?, bytes total = 1920
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ types.py, ?, bytes total = 2680
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@ 1
+ 8 |@@@@@@@@@@@ 2
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@ 3
+ 512 | 0
+ 1024 |@@@@@@ 1
+ 2048 | 0
+
+ posixpath.py, ?, bytes total = 3306
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@ 2
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@ 1
+ 4096 | 0
+
+ copy_reg.py, ?, bytes total = 3547
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@ 1
+ 512 |@@@@@@@@ 1
+ 1024 | 0
+ 2048 |@@@@@@@@ 1
+ 4096 | 0
+
+ warnings.py, ?, bytes total = 3924
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@ 1
+ 32 |@@@@@@@@ 1
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@ 2
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@ 1
+ 4096 | 0
+
+ func_abc.py, func_a, bytes total = 5100
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ codecs.py, ?, bytes total = 5612
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@ 1
+ 128 |@@@@@@ 1
+ 256 |@@@@@@@@@@@ 2
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@ 3
+ 2048 | 0
+
+ aliases.py, ?, bytes total = 8064
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@ 1
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ func_abc.py, ?, bytes total = 16105
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@ 1
+ 8 |@@@@@ 2
+ 16 |@@@@@@@@@ 4
+ 32 |@@@@@ 2
+ 64 | 0
+ 128 |@@ 1
+ 256 |@@@@@@@ 3
+ 512 |@@ 1
+ 1024 |@@@@@ 2
+ 2048 | 0
+ 4096 | 0
+ 8192 |@@ 1
+ 16384 | 0
+
+ os.py, ?, bytes total = 58957
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@ 3
+ 8 |@@@@@ 6
+ 16 |@ 1
+ 32 |@@ 2
+ 64 | 0
+ 128 |@ 1
+ 256 |@@@@@@@@@@@@@@@@@@ 23
+ 512 |@@ 3
+ 1024 |@@@@@ 7
+ 2048 | 0
+ 4096 |@@@ 4
+ 8192 |@ 1
+ 16384 | 0
+
+ site.py, ?, bytes total = 62589
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@ 2
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20
+ 512 |@ 1
+ 1024 |@@@ 2
+ 2048 |@ 1
+ 4096 | 0
+ 8192 | 0
+ 16384 |@@@ 2
+ 32768 | 0
+
+ __init__.py, ?, bytes total = 62593
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@ 1
+ 2 | 0
+ 4 | 0
+ 8 | 0
+ 16 |@@@ 2
+ 32 |@@ 1
+ 64 | 0
+ 128 | 0
+ 256 |@@@@@@@@@@@ 7
+ 512 |@@@@@@@@@@@@@@@@ 10
+ 1024 |@@@ 2
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 |@@@ 2
+ 32768 | 0
+
+ posixpath.py, join, bytes total = 262144
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ os.py, _exists, bytes total = 362768
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@ 10
+ 8 |@ 10
+ 16 |@@ 20
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 |@ 7
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 447
+ 1024 |@@ 20
+ 2048 | 0
+ 4096 |@ 10
+ 8192 | 0
+
+
+The results are divided into two sections. If a malloc() occurred while in a
+Python function, then that function is identified as responsible; and the
+results will appear in the second section - Python malloc byte distributions
+by Python file and function.
+
+Otherwise the caller of malloc() is identified as responsible - which will be
+a function from the Python engine, and these are noted in the first section -
+Python malloc byte distributions by engine caller.
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_mallocstk_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_mallocstk_example.txt
new file mode 100644
index 0000000..a466737
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_mallocstk_example.txt
@@ -0,0 +1,314 @@
+Following are examples of running py_mallocstk.d. This traces malloc() from
+Python, printing byte distributions by user stack trace.
+
+Here we see the script runnin on the program Code/Python/func_abc.py
+
+# py_mallocstk.d -c ./func_abc.py
+
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+
+Python malloc byte distributions by stack trace,
+
+
+
+ libc.so.1`malloc
+ libpython2.4.so.1.0`r_object+0x52f
+ libpython2.4.so.1.0`r_object+0x491
+ libpython2.4.so.1.0`r_object+0xd3
+ libpython2.4.so.1.0`r_object+0x491
+ libpython2.4.so.1.0`r_object+0xd3
+ libpython2.4.so.1.0`r_object+0x491
+ libpython2.4.so.1.0`r_object+0xd3
+ libpython2.4.so.1.0`PyMarshal_ReadObjectFromString+0x36
+ libpython2.4.so.1.0`PyMarshal_ReadLastObjectFromFile+0x6a
+ libpython2.4.so.1.0`read_compiled_module+0xf
+ libpython2.4.so.1.0`load_source_module+0x63
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xee
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`builtin___import__+0x4e
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`PyEval_CallObjectWithKeywords+0xb8
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xd3c
+ [ /usr/lib/python2.4/encodings/__init__.py:28 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`PyImport_ExecCodeModuleEx+0xc0
+ libpython2.4.so.1.0`load_source_module+0xe6
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`load_package+0xef
+ libpython2.4.so.1.0`load_module+0x6a
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xa2
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`_PyCodecRegistry_Init+0xce
+ libpython2.4.so.1.0`_PyCodec_Lookup+0x2a
+ libpython2.4.so.1.0`PyCodec_Encoder+0xf
+ libpython2.4.so.1.0`Py_InitializeEx+0x257
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+ python`main+0x11
+ python`_start+0x7a
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+
+ libc.so.1`malloc
+ libpython2.4.so.1.0`_PyUnicode_New+0xb2
+ libpython2.4.so.1.0`_PyUnicodeUCS2_Init+0x19
+ libpython2.4.so.1.0`Py_InitializeEx+0x11c
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+ python`main+0x11
+ python`_start+0x7a
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+
+ libc.so.1`malloc
+ libc.so.1`_real_gettext_u+0x81
+ libc.so.1`dgettext+0x5e
+ libc.so.1`strerror+0x40
+ libpython2.4.so.1.0`PyErr_SetFromErrnoWithFilenameObject+0x2d
+ libpython2.4.so.1.0`PyErr_SetFromErrnoWithFilename+0x27
+ libpython2.4.so.1.0`posix_error_with_allocated_filename+0x17
+ libpython2.4.so.1.0`posix_do_stat+0x21f
+ libpython2.4.so.1.0`posix_stat+0x1f
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`call_function+0x406
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/posixpath.py:195 (isdir) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:202 (addsitepackages) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:382 (main) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:397 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`PyImport_ExecCodeModuleEx+0xc0
+ libpython2.4.so.1.0`load_source_module+0xe6
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xa2
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`builtin___import__+0x4e
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`PyObject_CallFunction+0x90
+ libpython2.4.so.1.0`PyImport_Import+0x163
+ libpython2.4.so.1.0`PyImport_ImportModule+0x1f
+ libpython2.4.so.1.0`initsite+0x10
+ libpython2.4.so.1.0`Py_InitializeEx+0x1ea
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+ python`main+0x11
+ python`_start+0x7a
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+[... around 17000 lines truncated ...]
+
+
+ libc.so.1`malloc
+ libpython2.4.so.1.0`PyObject_Malloc+0x126
+ libpython2.4.so.1.0`fixstate+0x26
+ libpython2.4.so.1.0`fixdfa+0x2a
+ libpython2.4.so.1.0`PyGrammar_AddAccelerators+0x1b
+ libpython2.4.so.1.0`PyParser_New+0x18
+ libpython2.4.so.1.0`parsetok+0x17
+ libpython2.4.so.1.0`PyParser_ParseStringFlagsFilename+0x72
+ libpython2.4.so.1.0`PyParser_ParseStringFlags+0x1c
+ libpython2.4.so.1.0`PyParser_SimpleParseStringFlags+0x23
+ libpython2.4.so.1.0`PyRun_StringFlags+0x2c
+ libpython2.4.so.1.0`builtin_eval+0x273
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`call_function+0x406
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/os.py:503 (_exists) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/os.py:509 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`PyImport_ExecCodeModuleEx+0xc0
+ libpython2.4.so.1.0`load_source_module+0xe6
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xa2
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`builtin___import__+0x4e
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`PyEval_CallObjectWithKeywords+0xb8
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xd3c
+ [ /usr/lib/python2.4/site.py:58 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`PyImport_ExecCodeModuleEx+0xc0
+ libpython2.4.so.1.0`load_source_module+0xe6
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xa2
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`builtin___import__+0x4e
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`PyObject_CallFunction+0x90
+ libpython2.4.so.1.0`PyImport_Import+0x163
+ libpython2.4.so.1.0`PyImport_ImportModule+0x1f
+ libpython2.4.so.1.0`initsite+0x10
+ libpython2.4.so.1.0`Py_InitializeEx+0x1ea
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+ python`main+0x11
+ python`_start+0x7a
+
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 331
+ 1024 | 0
+
+
+ libc.so.1`malloc
+ libpython2.4.so.1.0`new_arena+0x13
+ libpython2.4.so.1.0`PyObject_Malloc+0x91
+ libpython2.4.so.1.0`string_concat+0x109
+ libpython2.4.so.1.0`PyString_Concat+0x3b
+ libpython2.4.so.1.0`string_concatenate+0x150
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x27cc
+ [ /usr/lib/python2.4/posixpath.py:62 (join) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`function_call+0x15e
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`ext_do_call+0xfb
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xb4f
+ [ /usr/lib/python2.4/site.py:66 (makepath) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`fast_function+0x112
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:138 (addpackage) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`fast_function+0x112
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:166 (addsitedir) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`fast_function+0x112
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ <string>:1 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ libpython2.4.so.1.0`run_err_node+0x1f
+ libpython2.4.so.1.0`PyRun_String+0x27
+ libpython2.4.so.1.0`exec_statement+0x2b0
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x15d6
+ [ /usr/lib/python2.4/site.py:134 (addpackage) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`fast_function+0x112
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:166 (addsitedir) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`fast_function+0x112
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:203 (addsitepackages) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:382 (main) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ /usr/lib/python2.4/site.py:397 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`PyImport_ExecCodeModuleEx+0xc0
+ libpython2.4.so.1.0`load_source_module+0xe6
+ libpython2.4.so.1.0`load_module+0xac
+ libpython2.4.so.1.0`import_submodule+0xfb
+ libpython2.4.so.1.0`load_next+0xa2
+ libpython2.4.so.1.0`import_module_ex+0x48
+ libpython2.4.so.1.0`PyImport_ImportModuleEx+0x1d
+ libpython2.4.so.1.0`builtin___import__+0x4e
+ libpython2.4.so.1.0`PyCFunction_Call+0x15f
+ libpython2.4.so.1.0`PyObject_Call+0x1d
+ libpython2.4.so.1.0`PyObject_CallFunction+0x90
+ libpython2.4.so.1.0`PyImport_Import+0x163
+ libpython2.4.so.1.0`PyImport_ImportModule+0x1f
+ libpython2.4.so.1.0`initsite+0x10
+ libpython2.4.so.1.0`Py_InitializeEx+0x1ea
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+
+ libc.so.1`malloc
+ libpython2.4.so.1.0`new_arena+0x13
+ libpython2.4.so.1.0`PyObject_Malloc+0x91
+ libpython2.4.so.1.0`_PyObject_GC_Malloc+0x13
+ libpython2.4.so.1.0`_PyObject_GC_NewVar+0x24
+ libpython2.4.so.1.0`PyTuple_New+0x78
+ libpython2.4.so.1.0`PyType_Ready+0x98
+ libpython2.4.so.1.0`PyType_Ready+0x60
+ libpython2.4.so.1.0`_Py_ReadyTypes+0x10
+ libpython2.4.so.1.0`Py_InitializeEx+0xed
+ libpython2.4.so.1.0`Py_Initialize+0xd
+ libpython2.4.so.1.0`Py_Main+0x4db
+ python`main+0x11
+ python`_start+0x7a
+
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+
+This output looks a little unusual at first glance, and can be confusing for
+people unfamiliar with stack tracing and Python engine internals.
+
+Start by looking at the distribution plots below each stack trace - each plot
+shows how many bytes were requested as a histogram by byte size. This should
+indicated to you if python is malloc()ing much memory or not, and whether it
+is doing so in a few large malloc()s or many small ones.
+
+With this information in mind you can inspect the stack traces - these explain
+why Python called malloc() in that instance, along with translations of Python
+functions buried in the stack trace. The stack traces can be hard to read at
+first (or even at second or at third) - since you are examining Python engine
+internals. Try looking for lines in square brackets - those are Python language
+frames, and will show where (or if) the malloc() was caused by Python code.
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_profile_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_profile_example.txt
new file mode 100644
index 0000000..04c0688
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_profile_example.txt
@@ -0,0 +1,399 @@
+The following are examples of py_profile.d.
+
+This samples stack traces for the process specified. This stack trace will
+cross the Python engine and system libraries, and insert translations for
+Python stack frames where appropriate. Here you can see it running on
+Code/Python/func_slow.py
+
+# py_profile.d -c ./func_slow.py
+Sampling 10-level stacks at 1001 Hertz... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+Top 25 most frequently sampled stacks,
+
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x266
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 11
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x278
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 11
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x278a
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 11
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x205
+ [ ./func_slow.py:18 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ libpython2.4.so.1.0`run_err_node+0x1f
+ libpython2.4.so.1.0`PyRun_FileExFlags+0x5e
+ libpython2.4.so.1.0`PyRun_SimpleFileExFlags+0x12f
+ 12
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x1fe
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 13
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x35d
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 13
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x1f5
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 14
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x149
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 14
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x5aa
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 14
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x58f
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 15
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x58f
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 15
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x254
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 17
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x286
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 17
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x2fbf
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 17
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x35d
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 18
+
+ libc.so.1`ioctl+0x7
+ libpython2.4.so.1.0`_init+0x25
+ ld.so.1`call_init+0xff
+ ld.so.1`setup+0xf93
+ ld.so.1`_setup+0x310
+ ld.so.1`_rt_boot+0x56
+ 0x8047e5c
+ 19
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x5a4
+ [ ./func_slow.py:18 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ libpython2.4.so.1.0`run_err_node+0x1f
+ libpython2.4.so.1.0`PyRun_FileExFlags+0x5e
+ libpython2.4.so.1.0`PyRun_SimpleFileExFlags+0x12f
+ 20
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x5ba
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 20
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x583
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 22
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x5a4
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 22
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x278a
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 24
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x205
+ [ ./func_slow.py:10 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ libpython2.4.so.1.0`PyEval_EvalCodeEx+0x732
+ libpython2.4.so.1.0`PyEval_EvalCode+0x22
+ libpython2.4.so.1.0`run_node+0x35
+ 25
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x583
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 35
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x5a4
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 47
+
+ libpython2.4.so.1.0`PyEval_EvalFrame+0x205
+ [ ./func_slow.py:3 (func_c) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:16 (func_b) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:24 (func_a) ]
+ libpython2.4.so.1.0`fast_function+0xa8
+ libpython2.4.so.1.0`call_function+0xda
+ libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ [ ./func_slow.py:26 (?) ]
+ 50
+
+ The lines in square brackets are the native Python frames, the rest
+ are the Python engine.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_syscalls_example.txt
new file mode 100644
index 0000000..3aac3d2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_syscalls_example.txt
@@ -0,0 +1,129 @@
+The following are examples of py_syscalls.d.
+
+This is a simple script to count executed Python functions and system calls.
+Here it traces an example program, Code/Pythong/func_abc.py.
+
+# py_syscalls.d -c ./func_abc.py
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+
+Calls for PID 145538,
+
+ FILE TYPE NAME COUNT
+ UserDict.py func ? 1
+ UserDict.py func DictMixin 1
+ UserDict.py func IterableUserDict 1
+ UserDict.py func UserDict 1
+ UserDict.py func __init__ 1
+ __init__.py func ? 1
+ __init__.py func CodecRegistryError 1
+ __init__.py func normalize_encoding 1
+ __init__.py func search_function 1
+ aliases.py func ? 1
+ ascii.py func ? 1
+ ascii.py func Codec 1
+ ascii.py func StreamConverter 1
+ ascii.py func StreamReader 1
+ ascii.py func StreamWriter 1
+ ascii.py func getregentry 1
+ codecs.py func ? 1
+ codecs.py func Codec 1
+ codecs.py func StreamReader 1
+ codecs.py func StreamReaderWriter 1
+ codecs.py func StreamRecoder 1
+ codecs.py func StreamWriter 1
+ copy_reg.py func ? 1
+ func_abc.py func ? 1
+ func_abc.py func func_a 1
+ func_abc.py func func_b 1
+ func_abc.py func func_c 1
+ func_abc.py syscall getrlimit 1
+ func_abc.py syscall gtime 1
+ func_abc.py syscall memcntl 1
+ func_abc.py syscall rexit 1
+ func_abc.py syscall sigpending 1
+ func_abc.py syscall sysi86 1
+ func_abc.py syscall write 1
+ func_abc.py syscall xstat 1
+ linecache.py func ? 1
+ os.py func ? 1
+ os.py func _Environ 1
+ os.py func __init__ 1
+ os.py func _get_exports_list 1
+ posixpath.py func ? 1
+ posixpath.py func basename 1
+ posixpath.py func dirname 1
+ site.py func ? 1
+ site.py func _Helper 1
+ site.py func _Printer 1
+ site.py func _init_pathinfo 1
+ site.py func abs__file__ 1
+ site.py func addsitepackages 1
+ site.py func aliasmbcs 1
+ site.py func execsitecustomize 1
+ site.py func main 1
+ site.py func removeduppaths 1
+ site.py func setcopyright 1
+ site.py func setencoding 1
+ site.py func sethelper 1
+ site.py func setquit 1
+ stat.py func ? 1
+ types.py func ? 1
+ types.py func _C 1
+ warnings.py func ? 1
+ warnings.py func _OptionError 1
+ warnings.py func _processoptions 1
+ func_abc.py syscall fcntl 2
+ func_abc.py syscall fsat 2
+ func_abc.py syscall getcwd 2
+ func_abc.py syscall getpid 2
+ func_abc.py syscall mprotect 2
+ func_abc.py syscall readlink 2
+ func_abc.py syscall resolvepath 2
+ func_abc.py syscall setcontext 2
+ posixpath.py func exists 2
+ posixpath.py func split 2
+ site.py func addsitedir 2
+ warnings.py func simplefilter 2
+ copy_reg.py func constructor 3
+ copy_reg.py func pickle 3
+ func_abc.py syscall munmap 3
+ func_abc.py syscall pollsys 3
+ site.py func __init__ 3
+ site.py func addpackage 3
+ func_abc.py syscall getdents64 4
+ func_abc.py syscall open 4
+ func_abc.py syscall sysconfig 4
+ func_abc.py syscall mmap 5
+ func_abc.py syscall lwp_exit 6
+ stat.py func S_IFMT 6
+ stat.py func S_ISDIR 6
+ posixpath.py func isdir 8
+ os.py func _exists 10
+ <string> func ? 11
+ posixpath.py func normcase 14
+ site.py func makepath 14
+ posixpath.py func join 20
+ posixpath.py func abspath 22
+ posixpath.py func isabs 22
+ posixpath.py func normpath 22
+ func_abc.py syscall ioctl 28
+ func_abc.py syscall llseek 34
+ func_abc.py syscall read 36
+ func_abc.py syscall close 41
+ func_abc.py syscall sigaction 52
+ func_abc.py syscall brk 58
+ func_abc.py syscall fstat64 74
+ func_abc.py syscall stat64 77
+ func_abc.py syscall open64 173
+
+While tracing there were numerous system calls made, including 173 open64()'s,
+and 77 stat64()'s. There were also many functions called, including 22 each
+of abspath, isabs, and normpath by the posixpath.py library.
+
+This script can provide an insight to how an application is interacting
+with the system, by providing both application function calls and
+system calls in the same output.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_syscolors_example.txt
new file mode 100644
index 0000000..0a6367f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_syscolors_example.txt
@@ -0,0 +1,584 @@
+The following are examples of py_syscolors.d.
+
+This is a simple script to trace the flow of Python functons and system
+calls made, and renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Python/func_abc.py.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# py_syscolors.d -c ./func_abc.py
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 145544 2 ":- syscall -> munmap
+0 145544 34 ":- syscall <- munmap
+0 145544 56 ":- syscall -> mmap
+0 145544 19 ":- syscall <- mmap
+0 145544 42 ":- syscall -> setcontext
+0 145544 10 ":- syscall <- setcontext
+0 145544 9 ":- syscall -> getrlimit
+0 145544 10 ":- syscall <- getrlimit
+0 145544 9 ":- syscall -> getpid
+0 145544 8 ":- syscall <- getpid
+0 145544 68 ":- syscall -> setcontext
+0 145544 8 ":- syscall <- setcontext
+0 145544 121 ":- syscall -> sigpending
+0 145544 9 ":- syscall <- sigpending
+0 145544 172 ":- syscall -> open64
+0 145544 114 ":- syscall <- open64
+0 145544 14 ":- syscall -> ioctl
+0 145544 28209 ":- syscall <- ioctl
+0 145544 285 ":- syscall -> close
+0 145544 31 ":- syscall <- close
+0 145544 41 ":- syscall -> open64
+0 145544 88 ":- syscall <- open64
+0 145544 9 ":- syscall -> ioctl
+0 145544 293 ":- syscall <- ioctl
+0 145544 11 ":- syscall -> close
+0 145544 13 ":- syscall <- close
+0 145544 1182 ":- syscall -> sysi86
+0 145544 12 ":- syscall <- sysi86
+0 145544 143 ":- syscall -> sysconfig
+0 145544 53 ":- syscall <- sysconfig
+0 145544 95 ":- syscall -> open64
+0 145544 22 ":- syscall <- open64
+0 145544 11 ":- syscall -> fstat64
+0 145544 10 ":- syscall <- fstat64
+0 145544 31 ":- syscall -> ioctl
+0 145544 42 ":- syscall <- ioctl
+0 145544 24 ":- syscall -> brk
+0 145544 10 ":- syscall <- brk
+0 145544 8 ":- syscall -> brk
+0 145544 17 ":- syscall <- brk
+0 145544 30 ":- syscall -> sysconfig
+0 145544 8 ":- syscall <- sysconfig
+0 145544 32 ":- syscall -> brk
+0 145544 7 ":- syscall <- brk
+0 145544 8 ":- syscall -> brk
+
+[... 1400 lines truncated ...]
+
+0 145544 8 ":- syscall -> fstat64
+0 145544 7 ":- syscall <- fstat64
+0 145544 11 ":- syscall -> read
+0 145544 8 ":- syscall <- read
+0 145544 29 ":- syscall -> brk
+0 145544 8 ":- syscall <- brk
+0 145544 8 ":- syscall -> brk
+0 145544 10 ":- syscall <- brk
+0 145544 393 ":- syscall -> llseek
+0 145544 8 ":- syscall <- llseek
+0 145544 9 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 14 aliases.py:17 func -> ?
+0 145544 57 aliases.py:18 func <- ?
+0 145544 20 ":- syscall -> llseek
+0 145544 8 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 8 ":- syscall <- close
+0 145544 15 __init__.py:43 func -> CodecRegistryError
+0 145544 12 __init__.py:45 func <- CodecRegistryError
+0 145544 26 __init__.py:145 func <- ?
+0 145544 18 ":- syscall -> llseek
+0 145544 8 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 13 __init__.py:69 func -> search_function
+0 145544 14 __init__.py:47 func -> normalize_encoding
+0 145544 18 __init__.py:67 func <- normalize_encoding
+0 145544 29 ":- syscall -> stat64
+0 145544 20 ":- syscall <- stat64
+0 145544 10 ":- syscall -> open64
+0 145544 18 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 17 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 18 ":- syscall <- open64
+0 145544 9 ":- syscall -> fstat64
+0 145544 8 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> open64
+0 145544 18 ":- syscall <- open64
+0 145544 8 ":- syscall -> fstat64
+0 145544 8 ":- syscall <- fstat64
+0 145544 9 ":- syscall -> fstat64
+0 145544 7 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> ioctl
+0 145544 7 ":- syscall <- ioctl
+0 145544 8 ":- syscall -> read
+0 145544 19 ":- syscall <- read
+0 145544 8 ":- syscall -> fstat64
+0 145544 8 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> read
+0 145544 8 ":- syscall <- read
+0 145544 22 ":- syscall -> llseek
+0 145544 8 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 12 ascii.py:8 func -> ?
+0 145544 16 ascii.py:13 func -> Codec
+0 145544 12 ascii.py:18 func <- Codec
+0 145544 22 ascii.py:20 func -> StreamWriter
+0 145544 11 ascii.py:21 func <- StreamWriter
+0 145544 20 ascii.py:23 func -> StreamReader
+0 145544 11 ascii.py:24 func <- StreamReader
+0 145544 32 ascii.py:26 func -> StreamConverter
+0 145544 12 ascii.py:29 func <- StreamConverter
+0 145544 21 ascii.py:33 func <- ?
+0 145544 17 ":- syscall -> llseek
+0 145544 8 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 8 ":- syscall <- close
+0 145544 13 ascii.py:33 func -> getregentry
+0 145544 12 ascii.py:35 func <- getregentry
+0 145544 34 __init__.py:142 func <- search_function
+0 145544 23 ":- syscall -> ioctl
+0 145544 42 ":- syscall <- ioctl
+0 145544 11 ":- syscall -> ioctl
+0 145544 9 ":- syscall <- ioctl
+0 145544 12 ":- syscall -> readlink
+0 145544 16 ":- syscall <- readlink
+0 145544 20 ":- syscall -> resolvepath
+0 145544 18 ":- syscall <- resolvepath
+0 145544 12 ":- syscall -> getcwd
+0 145544 20 ":- syscall <- getcwd
+0 145544 27 ":- syscall -> ioctl
+0 145544 8 ":- syscall <- ioctl
+0 145544 14 ":- syscall -> llseek
+0 145544 7 ":- syscall <- llseek
+0 145544 8 ":- syscall -> fstat64
+0 145544 8 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> fstat64
+0 145544 7 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> ioctl
+0 145544 7 ":- syscall <- ioctl
+0 145544 8 ":- syscall -> read
+0 145544 19 ":- syscall <- read
+0 145544 9 ":- syscall -> llseek
+0 145544 7 ":- syscall <- llseek
+0 145544 8 ":- syscall -> llseek
+0 145544 7 ":- syscall <- llseek
+0 145544 12 ":- syscall -> read
+0 145544 13 ":- syscall <- read
+0 145544 105 ":- syscall -> read
+0 145544 9 ":- syscall <- read
+0 145544 10 ":- syscall -> llseek
+0 145544 7 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 117 func_abc.py:3 func -> ?
+0 145544 20 ":- syscall -> stat64
+0 145544 15 ":- syscall <- stat64
+0 145544 10 ":- syscall -> stat64
+0 145544 13 ":- syscall <- stat64
+0 145544 10 ":- syscall -> open64
+0 145544 15 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 9 ":- syscall -> stat64
+0 145544 13 ":- syscall <- stat64
+0 145544 9 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 13 ":- syscall <- open64
+0 145544 9 ":- syscall -> stat64
+0 145544 15 ":- syscall <- stat64
+0 145544 8 ":- syscall -> open64
+0 145544 15 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 15 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 15 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 15 ":- syscall <- open64
+0 145544 9 ":- syscall -> stat64
+0 145544 17 ":- syscall <- stat64
+0 145544 9 ":- syscall -> open64
+0 145544 17 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 8 ":- syscall -> stat64
+0 145544 17 ":- syscall <- stat64
+0 145544 8 ":- syscall -> open64
+0 145544 17 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 8 ":- syscall -> open64
+0 145544 16 ":- syscall <- open64
+0 145544 9 ":- syscall -> stat64
+0 145544 17 ":- syscall <- stat64
+0 145544 8 ":- syscall -> open64
+0 145544 19 ":- syscall <- open64
+0 145544 14 ":- syscall -> fstat64
+0 145544 9 ":- syscall <- fstat64
+0 145544 20 ":- syscall -> xstat
+0 145544 18 ":- syscall <- xstat
+0 145544 8 ":- syscall -> resolvepath
+0 145544 19 ":- syscall <- resolvepath
+0 145544 10 ":- syscall -> open
+0 145544 19 ":- syscall <- open
+0 145544 10 ":- syscall -> mmap
+0 145544 21 ":- syscall <- mmap
+0 145544 33 ":- syscall -> mmap
+0 145544 13 ":- syscall <- mmap
+0 145544 9 ":- syscall -> mmap
+0 145544 16 ":- syscall <- mmap
+0 145544 8 ":- syscall -> mmap
+0 145544 11 ":- syscall <- mmap
+0 145544 34 ":- syscall -> munmap
+0 145544 11 ":- syscall <- munmap
+0 145544 43 ":- syscall -> memcntl
+0 145544 13 ":- syscall <- memcntl
+0 145544 8 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 30 ":- syscall -> mprotect
+0 145544 13 ":- syscall <- mprotect
+0 145544 169 ":- syscall -> mprotect
+0 145544 13 ":- syscall <- mprotect
+0 145544 2 ":- syscall <- nosys
+0 145544 280 ":- syscall -> open
+0 145544 90 ":- syscall <- open
+0 145544 154 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 301 ":- syscall <- ioctl
+0 145544 186 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 210 ":- syscall -> close
+0 145544 18 ":- syscall <- close
+0 145544 146 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 208 ":- syscall -> open
+0 145544 73 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 209 ":- syscall -> ioctl
+0 145544 45 ":- syscall <- ioctl
+0 145544 171 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 194 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 203 ":- syscall -> open
+0 145544 63 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 209 ":- syscall -> ioctl
+0 145544 280 ":- syscall <- ioctl
+0 145544 185 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 193 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 230 ":- syscall -> open
+0 145544 82 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 210 ":- syscall -> ioctl
+0 145544 45 ":- syscall <- ioctl
+0 145544 171 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 195 ":- syscall -> close
+0 145544 18 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 204 ":- syscall -> open
+0 145544 64 ":- syscall <- open
+0 145544 149 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 208 ":- syscall -> ioctl
+0 145544 283 ":- syscall <- ioctl
+0 145544 184 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 192 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 146 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 209 ":- syscall -> open
+0 145544 72 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 209 ":- syscall -> ioctl
+0 145544 45 ":- syscall <- ioctl
+0 145544 171 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 198 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 860 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 223 ":- syscall -> open
+0 145544 83 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 281 ":- syscall <- ioctl
+0 145544 187 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 196 ":- syscall -> close
+0 145544 19 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 209 ":- syscall -> open
+0 145544 69 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 47 ":- syscall <- ioctl
+0 145544 173 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 199 ":- syscall -> close
+0 145544 18 ":- syscall <- close
+0 145544 144 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 212 ":- syscall -> open
+0 145544 67 ":- syscall <- open
+0 145544 149 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 282 ":- syscall <- ioctl
+0 145544 187 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 197 ":- syscall -> close
+0 145544 59 ":- syscall <- close
+0 145544 637 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 222 ":- syscall -> open
+0 145544 80 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 47 ":- syscall <- ioctl
+0 145544 172 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 199 ":- syscall -> close
+0 145544 19 ":- syscall <- close
+0 145544 144 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 205 ":- syscall -> open
+0 145544 62 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 211 ":- syscall -> ioctl
+0 145544 304 ":- syscall <- ioctl
+0 145544 190 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 197 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 211 ":- syscall -> open
+0 145544 70 ":- syscall <- open
+0 145544 149 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 211 ":- syscall -> ioctl
+0 145544 46 ":- syscall <- ioctl
+0 145544 172 ":- syscall -> lwp_exit
+0 145544 2 ":- syscall <- nosys
+0 145544 260 ":- syscall -> close
+0 145544 26 ":- syscall <- close
+0 145544 160 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 207 ":- syscall -> open
+0 145544 79 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 216 ":- syscall -> ioctl
+0 145544 274 ":- syscall <- ioctl
+0 145544 187 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 195 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 211 ":- syscall -> open
+0 145544 70 ":- syscall <- open
+0 145544 149 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 48 ":- syscall <- ioctl
+0 145544 173 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 201 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 211 ":- syscall -> open
+0 145544 65 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 324 ":- syscall <- ioctl
+0 145544 342 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 203 ":- syscall -> close
+0 145544 19 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 213 ":- syscall -> open
+0 145544 76 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 48 ":- syscall <- ioctl
+0 145544 174 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 198 ":- syscall -> close
+0 145544 18 ":- syscall <- close
+0 145544 146 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 206 ":- syscall -> open
+0 145544 63 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 272 ":- syscall <- ioctl
+0 145544 185 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 194 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 146 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 213 ":- syscall -> open
+0 145544 70 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 47 ":- syscall <- ioctl
+0 145544 173 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 236 ":- syscall -> close
+0 145544 23 ":- syscall <- close
+0 145544 156 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 210 ":- syscall -> open
+0 145544 76 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 276 ":- syscall <- ioctl
+0 145544 187 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 197 ":- syscall -> close
+0 145544 17 ":- syscall <- close
+0 145544 145 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 211 ":- syscall -> open
+0 145544 71 ":- syscall <- open
+0 145544 149 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 214 ":- syscall -> ioctl
+0 145544 47 ":- syscall <- ioctl
+0 145544 172 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 199 ":- syscall -> close
+0 145544 19 ":- syscall <- close
+0 145544 144 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 210 ":- syscall -> open
+0 145544 64 ":- syscall <- open
+0 145544 150 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 212 ":- syscall -> ioctl
+0 145544 297 ":- syscall <- ioctl
+0 145544 522 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 210 ":- syscall -> close
+0 145544 21 ":- syscall <- close
+0 145544 146 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 213 ":- syscall -> open
+0 145544 79 ":- syscall <- open
+0 145544 151 ":- syscall -> lwp_exit
+0 145544 0 ":- syscall <- nosys
+0 145544 213 ":- syscall -> ioctl
+0 145544 47 ":- syscall <- ioctl
+0 145544 173 ":- syscall -> lwp_exit
+0 145544 1 ":- syscall <- nosys
+0 145544 201 ":- syscall -> close
+0 145544 19 ":- syscall <- close
+0 145544 144 ":- syscall -> lwp_exit
+0 145544 91667 ":- syscall -> munmap
+0 145544 34 ":- syscall <- munmap
+0 145544 65 ":- syscall -> gtime
+0 145544 9 ":- syscall <- gtime
+0 145544 13 ":- syscall -> open
+0 145544 42 ":- syscall <- open
+0 145544 10 ":- syscall -> fstat64
+0 145544 9 ":- syscall <- fstat64
+0 145544 8 ":- syscall -> read
+0 145544 31 ":- syscall <- read
+0 145544 9 ":- syscall -> close
+0 145544 11 ":- syscall <- close
+0 145544 65 ":- syscall -> llseek
+0 145544 9 ":- syscall <- llseek
+0 145544 8 ":- syscall -> close
+0 145544 9 ":- syscall <- close
+0 145544 25 func_abc.py:14 func -> func_a
+0 145544 24 ":- syscall -> ioctl
+0 145544 9 ":- syscall <- ioctl
+0 145544 8 ":- syscall -> fstat64
+0 145544 8 ":- syscall <- fstat64
+0 145544 9 ":- syscall -> fstat64
+0 145544 7 ":- syscall <- fstat64
+0 145544 40 ":- syscall -> pollsys
+0 145544 1009424 ":- syscall <- pollsys
+0 145544 35 func_abc.py:9 func -> func_b
+0 145544 40 ":- syscall -> pollsys
+0 145544 1009681 ":- syscall <- pollsys
+0 145544 36 func_abc.py:5 func -> func_c
+0 145544 41 ":- syscall -> pollsys
+Function A
+Function B
+Function C
+0 145544 1000116 ":- syscall <- pollsys
+0 145544 34 func_abc.py:7 func <- func_c
+0 145544 28 func_abc.py:12 func <- func_b
+0 145544 14 func_abc.py:17 func <- func_a
+0 145544 14 func_abc.py:19 func <- ?
+0 145544 26 ":- syscall -> sigaction
+0 145544 15 ":- syscall <- sigaction
+0 145544 1150 ":- syscall -> write
+0 145544 21 ":- syscall <- write
+0 145544 212 ":- syscall -> open64
+0 145544 116 ":- syscall <- open64
+0 145544 11 ":- syscall -> ioctl
+0 145544 24 ":- syscall <- ioctl
+0 145544 10 ":- syscall -> close
+0 145544 16 ":- syscall <- close
+0 145544 8 ":- syscall -> open64
+0 145544 32 ":- syscall <- open64
+0 145544 9 ":- syscall -> ioctl
+0 145544 169 ":- syscall <- ioctl
+0 145544 10 ":- syscall -> close
+0 145544 12 ":- syscall <- close
+0 145544 62 ":- syscall -> rexit
+
+Here you can see the output showing the path the script follows as it is
+executed.
+
+0 145544 35 func_abc.py:9 func -> func_b
+0 145544 40 ":- syscall -> pollsys
+0 145544 1009681 ":- syscall <- pollsys
+0 145544 36 func_abc.py:5 func -> func_c
+
+This excerpt shows line 9 of the script executing. It makes a pollsys syscall
+in order to fulfill the request to sleep for one second, returns and then goes
+to line 5. Checking the logic flow of the example program, this makes sense.
diff --git a/cddl/contrib/dtracetoolkit/Examples/py_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/py_who_example.txt
new file mode 100644
index 0000000..7d1c3f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/py_who_example.txt
@@ -0,0 +1,34 @@
+These are examples of the results after running the py_who.d script.
+
+This script shows which UIDs and PIDs are running Python programs with Python
+provider support, and how active they are. It lists the name of the program,
+along with the number of lines executed per program as recorded by the line
+provider.
+
+Here it runs as the Code/Python/func_abc.py program is executed.
+
+# py_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ PID UID FUNCS FILE
+ 145442 0 1 /usr/lib/python2.4/encodings/aliases.py
+ 145442 0 1 /usr/lib/python2.4/linecache.py
+ 145442 0 2 /usr/lib/python2.4/types.py
+ 145442 0 4 /usr/lib/python2.4/encodings/__init__.py
+ 145442 0 4 func_abc.py
+ 145442 0 5 /usr/lib/python2.4/UserDict.py
+ 145442 0 5 /usr/lib/python2.4/warnings.py
+ 145442 0 6 /usr/lib/python2.4/codecs.py
+ 145442 0 6 /usr/lib/python2.4/encodings/ascii.py
+ 145442 0 7 /usr/lib/python2.4/copy_reg.py
+ 145442 0 11 <string>
+ 145442 0 13 /usr/lib/python2.4/stat.py
+ 145442 0 14 /usr/lib/python2.4/os.py
+ 145442 0 36 /usr/lib/python2.4/site.py
+ 145442 0 115 /usr/lib/python2.4/posixpath.py
+
+You can see that the program itself had four lines executed attributed to it,
+and the other lines in the program were associated with their particular
+Python library calls.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_calldist_example.txt
new file mode 100644
index 0000000..088497c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_calldist_example.txt
@@ -0,0 +1,153 @@
+The following is an example of running rb_calldist.d and tracing the elapsed
+times for functions.
+
+We run rb_calldist.d while running the program Code/Ruby/func_abc.rb. We can
+see that there are three sections in the DTrace output
+
+# rb_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Elapsed times (us),
+ ., obj-new, NoMemoryError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ., obj-new, SystemStackError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ., obj-new, ThreadGroup
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ ., obj-new, fatal
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ ., obj-new, Object
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 | 0
+
+
+Exclusive function elapsed times (us),
+ func_abc.rb, func, Module::method_added
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ func_abc.rb, func, Object::print
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 |@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ func_abc.rb, func, IO::write
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_abc.rb, func, Object::func_a
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.rb, func, Object::func_b
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.rb, func, Object::func_c
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ func_abc.rb, func, Object::sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+
+Inclusive function elapsed times (us),
+ func_abc.rb, func, Module::method_added
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ func_abc.rb, func, IO::write
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_abc.rb, func, Object::print
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ func_abc.rb, func, Object::func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.rb, func, Object::func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_abc.rb, func, Object::sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+ func_abc.rb, func, Object::func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+The elapsed times show us that the script spent some small amount of time
+processing various events that were not functions. In this case they were all
+obj-new events, and you can see that the slowest of these was a new Object at
+between 16 microseconds and 31 microseconds.
+
+The exclusive subroutine elapsed times show that each of our user defined
+functions took between 256 and 511 microseconds. This time excludes the time
+spent in other subroutines.
+
+The inclusive subroutine elapsed times show that func_c() took between 0.5
+seconds and 1 second, func_b() took between 1 second and 2.1 seconds, and
+func_a() took between 2.1 seconds and 4.2 seconds to execute. This time
+includes the time spent in other subroutines called, and since func_a() called
+func_b() which called func_c(), these times make sense.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_calls_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_calls_example.txt
new file mode 100644
index 0000000..acc0d4d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_calls_example.txt
@@ -0,0 +1,29 @@
+The following are examples of the results of running the rb_calls.d script.
+
+This script traces activity from all Ruby programs on the system that are
+running with Ruby provider support. In this example we see it running while
+the Code/Ruby/func_abc.rb script is run.
+
+# rb_calls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE TYPE NAME CALLS
+ . obj-new NoMemoryError 1
+ . obj-new SystemStackError 1
+ . obj-new ThreadGroup 1
+ . obj-new fatal 1
+ func_abc.rb method Object::func_a 1
+ func_abc.rb method Object::func_b 1
+ func_abc.rb method Object::func_c 1
+ . obj-new Object 3
+ func_abc.rb method IO::write 3
+ func_abc.rb method Module::method_added 3
+ func_abc.rb method Object::print 3
+ func_abc.rb method Object::sleep 3
+
+We can see that the file func_abc.rb called each of the user-defined functions
+included in the script; func_a, func_b, and func_c. It also called the print
+object and sleep amongst other things. Interspersed in the output are calls
+to new objects that are not tied to the program func_abc.rb. They are called
+from the Ruby engine for some other reason.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_calltime_example.txt
new file mode 100644
index 0000000..7245fec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_calltime_example.txt
@@ -0,0 +1,77 @@
+The following is an example of running rb_calltime.d and tracing the elapsed
+times for functions.
+
+We run rb_calltime.d while running the program Code/Ruby/func_abc.rb. We can
+see that there are four sections in the DTrace output
+
+# rb_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ . obj-new NoMemoryError 1
+ . obj-new SystemStackError 1
+ . obj-new ThreadGroup 1
+ . obj-new fatal 1
+ func_abc.rb func Object::func_a 1
+ func_abc.rb func Object::func_b 1
+ func_abc.rb func Object::func_c 1
+ . obj-new Object 3
+ func_abc.rb func IO::write 3
+ func_abc.rb func Module::method_added 3
+ func_abc.rb func Object::print 3
+ func_abc.rb func Object::sleep 3
+ - total - 15
+
+Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ . obj-new SystemStackError 3
+ . obj-new NoMemoryError 3
+ . obj-new fatal 11
+ . obj-new ThreadGroup 13
+ . obj-new Object 26
+
+Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.rb func Module::method_added 9
+ func_abc.rb func Object::print 92
+ func_abc.rb func IO::write 185
+ func_abc.rb func Object::func_c 344
+ func_abc.rb func Object::func_a 379
+ func_abc.rb func Object::func_b 383
+ func_abc.rb func Object::sleep 3020597
+ - total - 3021992
+
+Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.rb func Module::method_added 9
+ func_abc.rb func IO::write 185
+ func_abc.rb func Object::print 277
+ func_abc.rb func Object::func_c 1009829
+ func_abc.rb func Object::func_b 2019781
+ func_abc.rb func Object::sleep 3020597
+ func_abc.rb func Object::func_a 3021983
+
+The first section, Count, shows us how many times each function associated
+with func_abc.rb was called. It also shows other functions called by the Ruby
+engine.
+
+The second section, elapsed times, shows how long each action that was not
+calling a function took.
+
+The third section, exclusive function elapsed times, shows us how many
+microseconds the program spends in each function. This does not include the
+time spent in any sub-functions called by that particular function. The last
+line gives us the total time in microseconds.
+
+The fourth section, inclusive function elapsed times, are the absolute time
+from when the function began to when it completed - which includes off-CPU time
+due to other system events such as I/O, scheduling, interrupts, etc. In
+particular, for this case it has included the time waiting for the sleep
+commands.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_cpudist_example.txt
new file mode 100644
index 0000000..718495e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_cpudist_example.txt
@@ -0,0 +1,199 @@
+The following are examples of rb_cpudist.d.
+
+This script traces the on-CPU time of Ruby functions and prints a report in
+the form of a histogram. Here it traces the example program,
+Code/Ruby/func_slow.rb
+
+# rb_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+On-CPU times (us),
+ ., obj-new, NoMemoryError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ., obj-new, SystemStackError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ ., obj-new, ThreadGroup
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ ., obj-new, fatal
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ ., obj-new, Object
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+ 8 |@@@@@@@@@@@@@ 1
+ 16 | 0
+
+
+Exclusive function on-CPU times (us),
+ func_slow.rb, func, Module::method_added
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ func_slow.rb, func, Object::print
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 8 |@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ func_slow.rb, func, IO::write
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_slow.rb, func, Object::func_a
+ value ------------- Distribution ------------- count
+ 131072 | 0
+ 262144 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 524288 | 0
+
+ func_slow.rb, func, Object::func_b
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_slow.rb, func, Fixnum::<
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 599556
+ 2 | 72
+ 4 | 35
+ 8 | 128
+ 16 | 158
+ 32 | 49
+ 64 | 3
+ 128 | 2
+ 256 | 0
+
+ func_slow.rb, func, Object::func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.rb, func, Fixnum::+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1199062
+ 2 | 138
+ 4 | 74
+ 8 | 279
+ 16 | 344
+ 32 | 91
+ 64 | 9
+ 128 | 0
+ 256 | 3
+ 512 | 0
+
+
+Inclusive function on-CPU times (us),
+ func_slow.rb, func, Module::method_added
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ func_slow.rb, func, IO::write
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_slow.rb, func, Object::print
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 |@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ func_slow.rb, func, Fixnum::<
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 599556
+ 2 | 72
+ 4 | 35
+ 8 | 128
+ 16 | 158
+ 32 | 49
+ 64 | 3
+ 128 | 2
+ 256 | 0
+
+ func_slow.rb, func, Fixnum::+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1199062
+ 2 | 138
+ 4 | 74
+ 8 | 279
+ 16 | 344
+ 32 | 91
+ 64 | 9
+ 128 | 0
+ 256 | 3
+ 512 | 0
+
+ func_slow.rb, func, Object::func_b
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ func_slow.rb, func, Object::func_c
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ func_slow.rb, func, Object::func_a
+ value ------------- Distribution ------------- count
+ 2097152 | 0
+ 4194304 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8388608 | 0
+
+You can see that the results are in three sections.
+
+The first section shows us the on-CPU time for actions that were not of the
+type 'func'.
+
+The second section, Exclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, not including time spent in subroutines. You can
+see here that Object::print had two instances of being on-CPU between 4
+microseconds and 7 microseconds, and once instance of being on-CPU between 8
+microseconds and 15 microseconds.
+
+The third section, Inclusive function on-CPU times, shows us the time spent
+on-CPU by various functions, including that time spent in subroutines called
+by those functions. You can see that here Object::print had two instances
+of being on-CPU between 32 microseconds and 63 microseconds, and one instance
+of being on-CPU between 64 microseconds and 127 microseconds.
+
+It is important to pay close attention to the third column, "count" as this
+will indicate if there were any instances in a particular timeframe, even if
+the number is too small to show up on the histogram clearly. See Inclusive
+function on-CPU time for Fixnum::+ for an example.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_cputime_example.txt
new file mode 100644
index 0000000..edfa5aa
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_cputime_example.txt
@@ -0,0 +1,81 @@
+The following are examples of rb_cputime.d.
+
+This script traces the on-CPU time of Ruby functions and prints a report.
+Here it traces the example program, Code/Ruby/func_slow.rb
+
+# rb_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Count,
+ FILE TYPE NAME COUNT
+ . obj-new NoMemoryError 1
+ . obj-new SystemStackError 1
+ . obj-new ThreadGroup 1
+ . obj-new fatal 1
+ func_slow.rb func Object::func_a 1
+ func_slow.rb func Object::func_b 1
+ func_slow.rb func Object::func_c 1
+ . obj-new Object 3
+ func_slow.rb func IO::write 3
+ func_slow.rb func Module::method_added 3
+ func_slow.rb func Object::print 3
+ func_slow.rb func Fixnum::< 600003
+ func_slow.rb func Fixnum::+ 1200000
+ - total - 1800015
+
+Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ . obj-new SystemStackError 2
+ . obj-new NoMemoryError 2
+ . obj-new fatal 11
+ . obj-new ThreadGroup 12
+ . obj-new Object 19
+
+Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.rb func Module::method_added 4
+ func_slow.rb func Object::print 57
+ func_slow.rb func IO::write 180
+ func_slow.rb func Object::func_a 405946
+ func_slow.rb func Fixnum::< 691125
+ func_slow.rb func Object::func_b 809970
+ func_slow.rb func Object::func_c 1225235
+ func_slow.rb func Fixnum::+ 1285200
+ - total - 4417721
+
+Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.rb func Module::method_added 4
+ func_slow.rb func IO::write 180
+ func_slow.rb func Object::print 238
+ func_slow.rb func Fixnum::< 691125
+ func_slow.rb func Fixnum::+ 1285200
+ func_slow.rb func Object::func_c 2212572
+ func_slow.rb func Object::func_b 3683688
+ func_slow.rb func Object::func_a 4417717
+
+You can see the results are printed in four sections.
+
+The first section reports how many times each subroutine was called, and it's
+type.
+
+The second section reports on the on-CPU time of anything that was not of type
+"func", in this case the only elements reported here are of type obj-new.
+
+The exclusive function on-CPU times shows, amongst other results, that func_a
+spent around 0.4 seconds on-CPU. This time excludes time spent in other
+subroutines.
+
+The inclusive function on-CPU times show that func_a spent around 4.4
+seconds on-CPU. This includes the time spent in other subroutines called.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_flow_example.txt
new file mode 100644
index 0000000..6cfa54f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_flow_example.txt
@@ -0,0 +1,54 @@
+The following are examples of rb_flow.d.
+
+This is a simple script to trace the flow of Ruby functions.
+Here it traces the example program, Code/Ruby/func_abc.rb
+
+# rb_flow.d
+ C TIME(us) FILE -- CLASS::METHOD
+ 0 3066417516583 func_abc.rb -> Module::method_added
+ 0 3066417516640 func_abc.rb <- Module::method_added
+ 0 3066417516658 func_abc.rb -> Module::method_added
+ 0 3066417516668 func_abc.rb <- Module::method_added
+ 0 3066417516680 func_abc.rb -> Module::method_added
+ 0 3066417516689 func_abc.rb <- Module::method_added
+ 0 3066417516701 func_abc.rb -> Object::func_a
+ 0 3066417516711 func_abc.rb -> Object::print
+ 0 3066417516730 func_abc.rb -> IO::write
+ 0 3066417516832 func_abc.rb <- IO::write
+ 0 3066417516841 func_abc.rb <- Object::print
+ 0 3066417516849 func_abc.rb -> Object::sleep
+ 0 3066418520705 func_abc.rb <- Object::sleep
+ 0 3066418520727 func_abc.rb -> Object::func_b
+ 0 3066418520744 func_abc.rb -> Object::print
+ 0 3066418520753 func_abc.rb -> IO::write
+ 0 3066418520796 func_abc.rb <- IO::write
+ 0 3066418520805 func_abc.rb <- Object::print
+ 0 3066418520813 func_abc.rb -> Object::sleep
+ 0 3066419530803 func_abc.rb <- Object::sleep
+ 0 3066419530825 func_abc.rb -> Object::func_c
+ 0 3066419530842 func_abc.rb -> Object::print
+ 0 3066419530852 func_abc.rb -> IO::write
+ 0 3066419530893 func_abc.rb <- IO::write
+ 0 3066419530902 func_abc.rb <- Object::print
+ 0 3066419530910 func_abc.rb -> Object::sleep
+ 0 3066420540804 func_abc.rb <- Object::sleep
+ 0 3066420540822 func_abc.rb <- Object::func_c
+ 0 3066420540831 func_abc.rb <- Object::func_b
+ 0 3066420540840 func_abc.rb <- Object::func_a
+^C
+
+The fourth column is indented by 2 spaces to show when a new function begins.
+This shows which function is calling which - the output above begins by adding
+new methods, then showing that func_a began; did some print IO; slept, and
+returned from sleep; and then called func_b.
+
+The TIME(us) column shows time from boot in microseconds.
+
+The FILE column shows the file that was being executed.
+
+If the output looks illogical, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_flowinfo_example.txt
new file mode 100644
index 0000000..14fd851
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_flowinfo_example.txt
@@ -0,0 +1,54 @@
+Following are examples of rb_flowinfo.d.
+
+This is a simple script to trace the flow of Ruby methods. Here it traces the
+example program, Code/Ruby/func_abc.rb.
+
+# rb_flowinfo.d
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 146395 2 func_abc.rb:3 method -> Module::method_added
+0 146395 26 func_abc.rb:3 method <- Module::method_added
+0 146395 25 func_abc.rb:8 method -> Module::method_added
+0 146395 11 func_abc.rb:8 method <- Module::method_added
+0 146395 16 func_abc.rb:14 method -> Module::method_added
+0 146395 10 func_abc.rb:14 method <- Module::method_added
+0 146395 15 func_abc.rb:20 method -> Object::func_a
+0 146395 12 func_abc.rb:15 method -> Object::print
+0 146395 20 func_abc.rb:15 method -> IO::write
+0 146395 110 func_abc.rb:15 method <- IO::write
+0 146395 11 func_abc.rb:15 method <- Object::print
+0 146395 11 func_abc.rb:16 method -> Object::sleep
+0 146395 1003728 func_abc.rb:16 method <- Object::sleep
+0 146395 35 func_abc.rb:17 method -> Object::func_b
+0 146395 20 func_abc.rb:9 method -> Object::print
+0 146395 12 func_abc.rb:9 method -> IO::write
+0 146395 42 func_abc.rb:9 method <- IO::write
+0 146395 11 func_abc.rb:9 method <- Object::print
+0 146395 11 func_abc.rb:10 method -> Object::sleep
+0 146395 1009976 func_abc.rb:10 method <- Object::sleep
+0 146395 35 func_abc.rb:11 method -> Object::func_c
+0 146395 20 func_abc.rb:4 method -> Object::print
+0 146395 12 func_abc.rb:4 method -> IO::write
+0 146395 38 func_abc.rb:4 method <- IO::write
+0 146395 11 func_abc.rb:4 method <- Object::print
+0 146395 11 func_abc.rb:5 method -> Object::sleep
+0 146395 1009883 func_abc.rb:5 method <- Object::sleep
+0 146395 29 func_abc.rb:5 method <- Object::func_c
+0 146395 12 func_abc.rb:11 method <- Object::func_b
+0 146395 11 func_abc.rb:17 method <- Object::func_a
+^C
+
+As each method is entered, the last column is indented by 2 spaces. This
+shows which method is calling which.
+
+The DELTA(us) column shows the change in time from the previous line to the
+current line.
+
+The LINE column shows the line in the file what was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_flowtime_example.txt
new file mode 100644
index 0000000..27102da
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_flowtime_example.txt
@@ -0,0 +1,56 @@
+The following are examples of rb_flowtime.d.
+
+This is a simple script to trace the flow of Ruby methods.
+Here it traces the example program, Code/Ruby/func_abc.rb
+
+# rb_flowtime.d
+ C TIME(us) FILE DELTA(us) -- CLASS::METHOD
+ 0 3066547402640 func_abc.rb 2 -> Module::method_added
+ 0 3066547402662 func_abc.rb 22 <- Module::method_added
+ 0 3066547402683 func_abc.rb 20 -> Module::method_added
+ 0 3066547402693 func_abc.rb 9 <- Module::method_added
+ 0 3066547402707 func_abc.rb 14 -> Module::method_added
+ 0 3066547402716 func_abc.rb 9 <- Module::method_added
+ 0 3066547402729 func_abc.rb 12 -> Object::func_a
+ 0 3066547402740 func_abc.rb 10 -> Object::print
+ 0 3066547402759 func_abc.rb 18 -> IO::write
+ 0 3066547402860 func_abc.rb 101 <- IO::write
+ 0 3066547402871 func_abc.rb 10 <- Object::print
+ 0 3066547402881 func_abc.rb 10 -> Object::sleep
+ 0 3066548410630 func_abc.rb 1007749 <- Object::sleep
+ 0 3066548410660 func_abc.rb 30 -> Object::func_b
+ 0 3066548410679 func_abc.rb 18 -> Object::print
+ 0 3066548410689 func_abc.rb 10 -> IO::write
+ 0 3066548410730 func_abc.rb 40 <- IO::write
+ 0 3066548410740 func_abc.rb 9 <- Object::print
+ 0 3066548410749 func_abc.rb 9 -> Object::sleep
+ 0 3066549420724 func_abc.rb 1009974 <- Object::sleep
+ 0 3066549420755 func_abc.rb 30 -> Object::func_c
+ 0 3066549420773 func_abc.rb 18 -> Object::print
+ 0 3066549420783 func_abc.rb 10 -> IO::write
+ 0 3066549420825 func_abc.rb 41 <- IO::write
+ 0 3066549420835 func_abc.rb 9 <- Object::print
+ 0 3066549420844 func_abc.rb 9 -> Object::sleep
+ 0 3066550430611 func_abc.rb 1009766 <- Object::sleep
+ 0 3066550430635 func_abc.rb 24 <- Object::func_c
+ 0 3066550430645 func_abc.rb 10 <- Object::func_b
+ 0 3066550430655 func_abc.rb 9 <- Object::func_a
+^C
+
+The fifth column is indented by 2 spaces to show when a new method begins.
+This shows which method is calling which.
+
+The TIME(us) column shows time since boot.
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the seventh line of data output
+(skipping the header) reads as "the time from func_a beginning to
+calling the print method was 10 microseconds".
+
+The FILE column shows file that was being executed.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_funccalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_funccalls_example.txt
new file mode 100644
index 0000000..27c9c0c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_funccalls_example.txt
@@ -0,0 +1,25 @@
+This is a list of examples of the usage of rb_funccalls.d.
+
+It reports method calls from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Here we run it while the program Code/Ruby/func_abc.rb is executing.
+
+# rb_funccalls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE CLASS METHOD CALLS
+ func_abc.rb Object func_a 1
+ func_abc.rb Object func_b 1
+ func_abc.rb Object func_c 1
+ func_abc.rb IO write 3
+ func_abc.rb Module method_added 3
+ func_abc.rb Object print 3
+ func_abc.rb Object sleep 3
+
+We can see that during that one Ruby program, Our 3 user-defined methods,
+func_a, func_b and func_c are called once each. Amongst other calls we can
+see that a method from class IO - write, was called three times; probably by
+the print method. If you look at the example program Code/Ruby/func_abc.rb,
+you can see that 'print' is used three times, but IO::write is never directly
+called.
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_lines_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_lines_example.txt
new file mode 100644
index 0000000..544b508
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_lines_example.txt
@@ -0,0 +1,30 @@
+This simple script uses the line probe to count how many times a line was
+executed in a Ruby program. In this example you can see it running on the
+Code/Ruby/func_slow.rb program.
+
+# rb_lines.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE:LINE COUNT
+ func_slow.rb:3 1
+ func_slow.rb:4 1
+ func_slow.rb:5 1
+ func_slow.rb:6 1
+ func_slow.rb:12 1
+ func_slow.rb:13 1
+ func_slow.rb:14 1
+ func_slow.rb:15 1
+ func_slow.rb:19 1
+ func_slow.rb:22 1
+ func_slow.rb:23 1
+ func_slow.rb:24 1
+ func_slow.rb:25 1
+ func_slow.rb:29 1
+ func_slow.rb:32 1
+ func_slow.rb:26 100000
+ func_slow.rb:27 100000
+ func_slow.rb:16 200000
+ func_slow.rb:17 200000
+ func_slow.rb:7 300000
+ func_slow.rb:8 300000
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_malloc_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_malloc_example.txt
new file mode 100644
index 0000000..e0917c9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_malloc_example.txt
@@ -0,0 +1,120 @@
+The following is an example of rb_malloc.d.
+
+WARNING: This script is not 100% accurate; This prints graphical
+representations of libc malloc() byte distributions by "recent" Ruby operation,
+which we hope will be usually correct. This is an experimental script that may
+be improved over time.
+
+Here we can see it running on Code/Ruby/func_abc.rb
+
+# rb_malloc.d -c ./func_abc.rb
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+Ruby malloc byte distributions by recent Ruby operation,
+ func_abc.rb, method, Object::print
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 1
+ 32 | 0
+
+ func_abc.rb, method, Module::method_added
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ ., objnew, fatal
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@ 1
+ 4 |@ 1
+ 8 |@@@ 2
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 22
+ 32 |@@@@@@ 5
+ 64 | 0
+
+ func_abc.rb, method, IO::write
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8192 | 0
+
+ ., objnew, SystemStackError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 | 3
+ 4 |@@@@ 32
+ 8 |@@ 15
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 279
+ 32 |@@@ 30
+ 64 | 2
+ 128 | 0
+
+ ., objnew, NoMemoryError
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@ 3
+ 4 |@@@ 17
+ 8 |@@@@@@ 37
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@ 146
+ 32 |@@ 13
+ 64 | 2
+ 128 |@@@ 20
+ 256 | 0
+ 512 | 0
+ 1024 | 1
+ 2048 | 0
+
+ ., objnew, ThreadGroup
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 | 8
+ 4 |@@@ 224
+ 8 |@ 93
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1806
+ 32 |@@@@@@@@ 496
+ 64 | 3
+ 128 | 2
+ 256 | 0
+ 512 | 1
+ 1024 | 0
+
+ ., objnew, Object
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 | 35
+ 4 |@@@ 291
+ 8 |@@@ 300
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2679
+ 32 |@@ 215
+ 64 | 7
+ 128 | 0
+
+ ruby, startup, -
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@ 10
+ 4 |@@@ 34
+ 8 |@@@ 38
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 409
+ 32 |@@ 30
+ 64 | 1
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 2
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 | 0
+ 65536 | 0
+ 131072 | 1
+ 262144 | 0
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_objcpu_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_objcpu_example.txt
new file mode 100644
index 0000000..48e8a78
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_objcpu_example.txt
@@ -0,0 +1,51 @@
+The following are examples of running rb_objcpu.d.
+
+The rb_objnew.d script reports the on-CPU time for new Object creation in Ruby
+while the script is tracing. Here we see it running while
+Code/Ruby/func_abc.rb is executed.
+
+# rb_objcpu.d
+Tracing... Hit Ctrl-C to end.
+^C
+Total object creation on-CPU time (ms): 0
+
+Object creation on-CPU time distributions (us),
+
+ NoMemoryError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ SystemStackError
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ fatal
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ ThreadGroup
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 16 | 0
+
+ Object
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 |@@@@@@@@@@@@@ 1
+ 16 | 0
+
+We can see that there were several different types of Objects created
+including three of type 'Object', one of which took 1 microsecond, one of
+which took 2 to 3 microseconds, and the last of which took between 8 and 15
+microseconds.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_objnew_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_objnew_example.txt
new file mode 100644
index 0000000..340ac9a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_objnew_example.txt
@@ -0,0 +1,21 @@
+The following are examples of running rb_objnew.d.
+
+The rb_objnew.d script reports the new Ruby objects created (by filename and
+class) while the script is tracing. Here we see it running while
+Code/Ruby/func_abc.rb is executed.
+
+# rb_objnew.d
+Tracing... Hit Ctrl-C to end.
+^C
+ FILE CLASS COUNT
+ . NoMemoryError 1
+ . SystemStackError 1
+ . ThreadGroup 1
+ . fatal 1
+ . Object 3
+
+Since this is a simple example, not many objects were allocated - a few
+for the ruby engine, and three of class Object. No file was associated
+with these allocations, as they may have been caused by Ruby engine startup,
+and not necessarily lines of code in the example program.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_stat_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_stat_example.txt
new file mode 100644
index 0000000..706bf95
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_stat_example.txt
@@ -0,0 +1,22 @@
+The following are examples of running rb_stat.d on Ruby programs.
+
+rb_stat.d shows you the number of events per second that have happened since
+the last line output. The default interval is 1 second, but you can specify
+other intervals as arguments to the script.
+
+This shows the rb_stat.d script reflecting the Code/Ruby/func_slow.rb script.
+
+# ./rb_stat.d
+TIME EXEC/s METHOD/s OBJNEW/s OBJFRE/s RAIS/s RESC/s GC/s
+2007 Sep 17 03:59:07 0 0 0 0 0 0 0
+2007 Sep 17 03:59:08 0 210426 7 0 0 0 0
+2007 Sep 17 03:59:09 0 724067 0 0 0 0 0
+2007 Sep 17 03:59:10 0 730877 0 0 0 0 0
+2007 Sep 17 03:59:11 0 134645 0 0 0 0 0
+2007 Sep 17 03:59:12 0 0 0 0 0 0 0
+2007 Sep 17 03:59:13 0 0 0 0 0 0 0
+^C
+
+We can see that at 2007 Sep 17 03:59:08 there were 0 new Ruby programs
+executed, 210426 methods called, 7 objects created, 0 objects freed, 0 raises,
+0 rescues and 0 garbage collects.
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_syscalls_example.txt
new file mode 100644
index 0000000..869884b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_syscalls_example.txt
@@ -0,0 +1,54 @@
+The following are examples of sh_syscalls.d.
+
+This is a simple script to count Ruby methods and system calls. Here we trace
+an example program - Code/Ruby/func_abc.rb
+
+# rb_syscalls.d -c ./func_abc.rb
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+
+Calls for PID 146493,
+
+ FILE TYPE NAME COUNT
+ func_abc.rb method Object::func_a 1
+ func_abc.rb method Object::func_b 1
+ func_abc.rb method Object::func_c 1
+ func_abc.rb syscall getpid 1
+ func_abc.rb syscall getrlimit 1
+ func_abc.rb syscall getrlimit64 1
+ func_abc.rb syscall mmap 1
+ func_abc.rb syscall munmap 1
+ func_abc.rb syscall rexit 1
+ func_abc.rb syscall schedctl 1
+ func_abc.rb syscall sigpending 1
+ func_abc.rb syscall sysconfig 1
+ func_abc.rb syscall sysi86 1
+ func_abc.rb syscall write 1
+ func_abc.rb syscall llseek 2
+ func_abc.rb syscall read 2
+ func_abc.rb syscall setcontext 2
+ func_abc.rb method IO::write 3
+ func_abc.rb method Module::method_added 3
+ func_abc.rb method Object::print 3
+ func_abc.rb method Object::sleep 3
+ func_abc.rb syscall fstat64 3
+ func_abc.rb syscall getgid 3
+ func_abc.rb syscall getuid 3
+ func_abc.rb syscall ioctl 3
+ func_abc.rb syscall pollsys 3
+ func_abc.rb syscall close 4
+ func_abc.rb syscall lwp_sigmask 4
+ func_abc.rb syscall open64 4
+ func_abc.rb syscall gtime 6
+ func_abc.rb syscall sigaction 12
+ func_abc.rb syscall brk 56
+
+While tracing, three user-defined functions were called - func_a, func_b and
+func_c. There were 3 instances of the IO::write method being called. There
+were also many system calls made, including 56 brk()'s, and 12 sigaction()'s.
+
+This script can provide an insight to how a Ruby program is interacting
+with the system, by providing methods and system calls in the same output.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_syscolors_example.txt
new file mode 100644
index 0000000..854016e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_syscolors_example.txt
@@ -0,0 +1,331 @@
+The following are examples of rb_syscolors.d.
+
+This is a simple script to trace the method flow of Ruby functions within a
+program, and the system calls made. It renders the output in color ("colour")
+using terminal escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Ruby/func_abc.rb.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# rb_syscolors.d -c ./func_abc.rb
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 146499 2 ":- syscall -> munmap
+0 146499 35 ":- syscall <- munmap
+0 146499 56 ":- syscall -> mmap
+0 146499 18 ":- syscall <- mmap
+0 146499 41 ":- syscall -> setcontext
+0 146499 10 ":- syscall <- setcontext
+0 146499 10 ":- syscall -> getrlimit
+0 146499 11 ":- syscall <- getrlimit
+0 146499 9 ":- syscall -> getpid
+0 146499 8 ":- syscall <- getpid
+0 146499 66 ":- syscall -> setcontext
+0 146499 8 ":- syscall <- setcontext
+0 146499 1125 ":- syscall -> sysi86
+0 146499 12 ":- syscall <- sysi86
+0 146499 86 ":- syscall -> open64
+0 146499 89 ":- syscall <- open64
+0 146499 13 ":- syscall -> ioctl
+0 146499 35 ":- syscall <- ioctl
+0 146499 15 ":- syscall -> close
+0 146499 16 ":- syscall <- close
+0 146499 141 ":- syscall -> getrlimit64
+0 146499 10 ":- syscall <- getrlimit64
+0 146499 37 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 17 ":- syscall <- brk
+0 146499 19 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 11 ":- syscall <- brk
+0 146499 495 ":- syscall -> brk
+0 146499 11 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 55 ":- syscall -> sysconfig
+0 146499 9 ":- syscall <- sysconfig
+0 146499 109 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 189 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 161 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 144 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 184 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 129 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 174 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 145 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 129 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 134 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 135 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 136 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 98 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 132 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 125 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 189 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 413 ":- syscall -> brk
+0 146499 11 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 171 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 137 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 188 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 135 ":- syscall -> sigaction
+0 146499 10 ":- syscall <- sigaction
+0 146499 10 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 8 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 9 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 12 ":- syscall -> sigpending
+0 146499 8 ":- syscall <- sigpending
+0 146499 15 ":- syscall -> schedctl
+0 146499 44 ":- syscall <- schedctl
+0 146499 17 ":- syscall -> lwp_sigmask
+0 146499 8 ":- syscall <- lwp_sigmask
+0 146499 9 ":- syscall -> sigaction
+0 146499 8 ":- syscall <- sigaction
+0 146499 11 ":- syscall -> lwp_sigmask
+0 146499 8 ":- syscall <- lwp_sigmask
+0 146499 9 ":- syscall -> lwp_sigmask
+0 146499 7 ":- syscall <- lwp_sigmask
+0 146499 8 ":- syscall -> sigaction
+0 146499 7 ":- syscall <- sigaction
+0 146499 8 ":- syscall -> lwp_sigmask
+0 146499 7 ":- syscall <- lwp_sigmask
+0 146499 65 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 11 ":- syscall <- brk
+0 146499 149 ":- syscall -> getuid
+0 146499 9 ":- syscall <- getuid
+0 146499 12 ":- syscall -> getgid
+0 146499 8 ":- syscall <- getgid
+0 146499 29 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 184 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 9 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 171 ":- syscall -> brk
+0 146499 9 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 10 ":- syscall <- brk
+0 146499 48 ":- syscall -> getuid
+0 146499 8 ":- syscall <- getuid
+0 146499 9 ":- syscall -> getuid
+0 146499 7 ":- syscall <- getuid
+0 146499 10 ":- syscall -> getgid
+0 146499 7 ":- syscall <- getgid
+0 146499 8 ":- syscall -> getgid
+0 146499 7 ":- syscall <- getgid
+0 146499 79 ":- syscall -> open64
+0 146499 31 ":- syscall <- open64
+0 146499 14 ":- syscall -> llseek
+0 146499 9 ":- syscall <- llseek
+0 146499 9 ":- syscall -> close
+0 146499 12 ":- syscall <- close
+0 146499 15 ":- syscall -> open64
+0 146499 13 ":- syscall <- open64
+0 146499 21 ":- syscall -> fstat64
+0 146499 11 ":- syscall <- fstat64
+0 146499 22 ":- syscall -> read
+0 146499 36 ":- syscall <- read
+0 146499 153 ":- syscall -> read
+0 146499 10 ":- syscall <- read
+0 146499 11 ":- syscall -> llseek
+0 146499 8 ":- syscall <- llseek
+0 146499 8 ":- syscall -> close
+0 146499 9 ":- syscall <- close
+0 146499 23 func_abc.rb:3 line -- 
+0 146499 64 func_abc.rb:3 method -> Module::method_added
+0 146499 24 func_abc.rb:3 method <- Module::method_added
+0 146499 20 func_abc.rb:8 line -- 
+0 146499 15 func_abc.rb:8 method -> Module::method_added
+0 146499 13 func_abc.rb:8 method <- Module::method_added
+0 146499 13 func_abc.rb:14 line -- 
+0 146499 14 func_abc.rb:14 method -> Module::method_added
+0 146499 13 func_abc.rb:14 method <- Module::method_added
+0 146499 12 func_abc.rb:20 line -- 
+0 146499 13 func_abc.rb:20 method -> Object::func_a
+0 146499 12 func_abc.rb:15 line -- 
+0 146499 10 func_abc.rb:15 method -> Object::print
+0 146499 22 func_abc.rb:15 method -> IO::write
+0 146499 38 ":- syscall -> ioctl
+0 146499 11 ":- syscall <- ioctl
+0 146499 20 ":- syscall -> fstat64
+0 146499 9 ":- syscall <- fstat64
+0 146499 9 ":- syscall -> brk
+0 146499 8 ":- syscall <- brk
+0 146499 8 ":- syscall -> brk
+0 146499 11 ":- syscall <- brk
+0 146499 25 ":- syscall -> fstat64
+0 146499 8 ":- syscall <- fstat64
+0 146499 10 func_abc.rb:15 method <- IO::write
+0 146499 13 func_abc.rb:15 method <- Object::print
+0 146499 12 func_abc.rb:16 line -- 
+0 146499 10 func_abc.rb:16 method -> Object::sleep
+0 146499 20 ":- syscall -> gtime
+0 146499 9 ":- syscall <- gtime
+0 146499 24 ":- syscall -> pollsys
+0 146499 1006964 ":- syscall <- pollsys
+0 146499 26 ":- syscall -> gtime
+0 146499 14 ":- syscall <- gtime
+0 146499 18 func_abc.rb:16 method <- Object::sleep
+0 146499 27 func_abc.rb:17 line -- 
+0 146499 21 func_abc.rb:17 method -> Object::func_b
+0 146499 19 func_abc.rb:9 line -- 
+0 146499 12 func_abc.rb:9 method -> Object::print
+0 146499 14 func_abc.rb:9 method -> IO::write
+0 146499 15 func_abc.rb:9 method <- IO::write
+0 146499 12 func_abc.rb:9 method <- Object::print
+0 146499 12 func_abc.rb:10 line -- 
+0 146499 9 func_abc.rb:10 method -> Object::sleep
+0 146499 12 ":- syscall -> gtime
+0 146499 8 ":- syscall <- gtime
+0 146499 11 ":- syscall -> pollsys
+0 146499 1009739 ":- syscall <- pollsys
+0 146499 26 ":- syscall -> gtime
+0 146499 14 ":- syscall <- gtime
+0 146499 18 func_abc.rb:10 method <- Object::sleep
+0 146499 27 func_abc.rb:11 line -- 
+0 146499 21 func_abc.rb:11 method -> Object::func_c
+0 146499 20 func_abc.rb:4 line -- 
+0 146499 12 func_abc.rb:4 method -> Object::print
+0 146499 14 func_abc.rb:4 method -> IO::write
+0 146499 15 func_abc.rb:4 method <- IO::write
+0 146499 12 func_abc.rb:4 method <- Object::print
+0 146499 12 func_abc.rb:5 line -- 
+0 146499 9 func_abc.rb:5 method -> Object::sleep
+0 146499 12 ":- syscall -> gtime
+0 146499 8 ":- syscall <- gtime
+0 146499 11 ":- syscall -> pollsys
+Function A
+Function B
+Function C
+0 146499 1009762 ":- syscall <- pollsys
+0 146499 25 ":- syscall -> gtime
+0 146499 14 ":- syscall <- gtime
+0 146499 19 func_abc.rb:5 method <- Object::sleep
+0 146499 26 func_abc.rb:5 method <- Object::func_c
+0 146499 13 func_abc.rb:11 method <- Object::func_b
+0 146499 13 func_abc.rb:17 method <- Object::func_a
+0 146499 33 ":- syscall -> sigaction
+0 146499 10 ":- syscall <- sigaction
+0 146499 100 ":- syscall -> open64
+0 146499 107 ":- syscall <- open64
+0 146499 10 ":- syscall -> ioctl
+0 146499 10 ":- syscall <- ioctl
+0 146499 11 ":- syscall -> close
+0 146499 17 ":- syscall <- close
+0 146499 28 ":- syscall -> write
+0 146499 20 ":- syscall <- write
+0 146499 11 ":- syscall -> rexit
+
+Here you can see the output showing the path the program follows in its
+execution.
+
+ie:
+0 146499 10 func_abc.rb:16 method -> Object::sleep
+0 146499 20 ":- syscall -> gtime
+0 146499 9 ":- syscall <- gtime
+0 146499 24 ":- syscall -> pollsys
+0 146499 1006964 ":- syscall <- pollsys
+0 146499 26 ":- syscall -> gtime
+0 146499 14 ":- syscall <- gtime
+0 146499 18 func_abc.rb:16 method <- Object::sleep
+0 146499 27 func_abc.rb:17 line -- 
+0 146499 21 func_abc.rb:17 method -> Object::func_b
+0 146499 19 func_abc.rb:9 line -- 
+0 146499 12 func_abc.rb:9 method -> Object::print
+0 146499 14 func_abc.rb:9 method -> IO::write
+0 146499 15 func_abc.rb:9 method <- IO::write
+0 146499 12 func_abc.rb:9 method <- Object::print
+0 146499 12 func_abc.rb:10 line -- 
+
+shows that on cpu 0 the program is running a sleep command at line 16 of the
+func_abc.rb program (the pollsys and gtime syscalls are used in the Ruby
+engine to implement sleep). Then func_b runs, and prints a line
+(using Object::print which uses IO::write). Notice that the 'write' syscall
+does not happen until later. It is probably being buffered by Ruby - you can
+confirm this through further DTracing. Notice also tht you can see the output
+of the program:
+
+Function A
+Function B
+Function C
+
+in the file happening before the write syscall is run. DTrace does not do its
+output in 'real time'. There is a slight delay due to buffering.
diff --git a/cddl/contrib/dtracetoolkit/Examples/rb_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/rb_who_example.txt
new file mode 100644
index 0000000..35c0bb7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rb_who_example.txt
@@ -0,0 +1,20 @@
+These are examples of the results after running the rb_who.d script.
+
+This script shows which UIDs and PIDs are running Ruby programs with Ruby
+provider support, and how active they are. It lists the name of the program,
+along with the number of lines executed per program as recorded by the line
+provider.
+
+Here it runs as three Ruby programs are executed. Code/Ruby/func_abc.rb runs
+twice and Code/Ruby/func_slow.rb once.
+
+# rb_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID LINES FILE
+ 146485 0 12 ./func_abc.rb
+ 146486 0 12 ./func_abc.rb
+ 146487 0 1200015 ./func_slow.rb
+
+You can see that func_abc.rb has twelve lines of executable Ruby code, and
+that func_slow.rb has 100,000x that.
diff --git a/cddl/contrib/dtracetoolkit/Examples/readbytes_example.txt b/cddl/contrib/dtracetoolkit/Examples/readbytes_example.txt
new file mode 100644
index 0000000..fa2923b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/readbytes_example.txt
@@ -0,0 +1,22 @@
+The following is a demonstration of the readbytes.d script,
+
+
+Here the readbytes.d script is run for a few seconds, then Ctrl-C is hit,
+
+ # readbytes.d
+ dtrace: description 'sysinfo:::readch ' matched 4 probes
+ ^C
+
+ mozilla-bin 16
+ gnome-smproxy 64
+ metacity 64
+ dsdm 64
+ wnck-applet 64
+ xscreensaver 96
+ gnome-terminal 900
+ ttymon 5952
+ Xorg 17544
+
+In this interval the Xorg command has successfully read 17.5 Kb, while
+ttymon has read 5952 bytes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/readdist_example.txt b/cddl/contrib/dtracetoolkit/Examples/readdist_example.txt
new file mode 100644
index 0000000..42811d8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/readdist_example.txt
@@ -0,0 +1,35 @@
+The following is an example of the readdist.d script,
+
+
+Here the readdist.d script is run for a few seconds, then Ctrl-C is hit,
+
+ # readdist.d
+ dtrace: description 'sysinfo:::readch ' matched 4 probes
+ ^C
+ [...]
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 64 |@@@ 1
+ 128 | 0
+
+ Xorg
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@ 26
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 |@@@@ 6
+ 16 |@ 2
+ 32 |@ 2
+ 64 | 0
+ 128 |@@@@@@@@ 11
+ 256 |@@@ 4
+ 512 | 0
+
+This allows us to understand the read behaviour of each process. The
+Xorg command has executed 26 reads that returned 0 bytes, through
+to 4 reads that were at least 256 bytes (up to 511).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rfileio_example.txt b/cddl/contrib/dtracetoolkit/Examples/rfileio_example.txt
new file mode 100644
index 0000000..dcce81e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rfileio_example.txt
@@ -0,0 +1,94 @@
+The following are demonstrations of the rfileio.d script.
+
+
+rfileio.d prints file system statistics by file,
+
+ # ./rfileio.d
+
+ Read IOPS, top 20 (count)
+ /lib/ld.so.1 logical 2
+ /devices/pseudo/clone@0:ptm logical 4
+ /usr/bin/grep logical 4
+ /devices/pseudo/pts@0:3 logical 4
+ /extra1/contents physical 1700
+ /extra1/contents logical 11582
+
+ Read Bandwidth, top 20 (bytes)
+ /devices/pseudo/pts@0:3 logical 3
+ /devices/pseudo/clone@0:ptm logical 92
+ /lib/ld.so.1 logical 212
+ /usr/bin/grep logical 269
+ /extra1/contents physical 48115712
+ /extra1/contents logical 94865162
+
+ Total File System miss-rate: 50%
+ ^C
+
+ $ ls -l /extra1/contents
+ -rw-r--r-- 1 root root 94865162 Nov 2 21:08 /extra1/contents
+
+The /extra1/contents file was read using the grep command. The output shows
+that half of the contents was returned from the cache, the other half from disk
+(50% miss-rate). It is 94,865,162 bytes in size, which can be seen both in
+the ls -l output and the logical read() bytes reported by rfileio.d. There
+were 11,582 logical read() calls, which the disk driver satisfied by using
+1,700 disk events (aggregation).
+
+
+
+The following demonstrates many files being read.
+
+ # ./rfileio.d
+
+ Read IOPS, top 20 (count)
+ /usr/bin/amd64/glib-mkenums logical 4
+ /usr/bin/amd64/glib-genmarshal physical 4
+ /usr/bin/amd64/gdk-pixbuf-query-loaders logical 4
+ /usr/bin/amd64/ls logical 5
+ /usr/bin/amd64/pargs logical 5
+ /usr/bin/amd64/ps logical 5
+ /usr/bin/amd64/gconf-merge-tree physical 6
+ /usr/bin/amd64/cputrack logical 6
+ /usr/bin/amd64/gconftool-2 physical 6
+ /usr/bin/amd64/prctl logical 6
+ /usr/bin/amd64/prstat logical 6
+ /usr/bin/amd64/glib-genmarshal logical 7
+ /usr/bin/amd64/truss physical 8
+ /usr/bin/amd64/sort logical 9
+ /usr/bin/amd64/prex logical 10
+ /usr/bin/amd64/gconf-merge-tree logical 13
+ /usr/bin/amd64/mdb physical 15
+ /usr/bin/amd64/gconftool-2 logical 15
+ /usr/bin/amd64/truss logical 26
+ /usr/bin/amd64/mdb logical 63
+
+ Read Bandwidth, top 20 (bytes)
+ /usr/bin/amd64/prctl logical 36784
+ /usr/bin/amd64/prctl physical 36864
+ /usr/bin/amd64/prstat logical 44760
+ /usr/bin/amd64/prstat physical 45056
+ /usr/bin/amd64/glib-genmarshal logical 46064
+ /usr/bin/amd64/glib-genmarshal physical 46080
+ /usr/bin/amd64/cputrack logical 46912
+ /usr/bin/amd64/cputrack physical 47104
+ /usr/bin/amd64/sort logical 65120
+ /usr/bin/amd64/sort physical 65536
+ /usr/bin/amd64/prex logical 80968
+ /usr/bin/amd64/prex physical 81920
+ /usr/bin/amd64/gconf-merge-tree logical 113592
+ /usr/bin/amd64/gconf-merge-tree physical 122880
+ /usr/bin/amd64/gconftool-2 logical 129208
+ /usr/bin/amd64/gconftool-2 physical 139264
+ /usr/bin/amd64/truss logical 246360
+ /usr/bin/amd64/truss physical 262144
+ /usr/bin/amd64/mdb logical 627456
+ /usr/bin/amd64/mdb physical 638976
+
+ Total File System miss-rate: 81%
+ ^C
+
+The miss-rate was 81%, meaning we are returning around 20% of the data from
+the cache. Details for the top 20 files read by-bytes and by-count are listed;
+this shows the /usr/bin/amd64/mdb file was read() 63 times, causing 15 disk
+reads, and while 627,456 bytes were requested, 638,976 bytes were read from
+disk (the extra bytes are due to read-ahead and file system metadata).
diff --git a/cddl/contrib/dtracetoolkit/Examples/rfsio_example.txt b/cddl/contrib/dtracetoolkit/Examples/rfsio_example.txt
new file mode 100644
index 0000000..858ddf8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rfsio_example.txt
@@ -0,0 +1,82 @@
+The following are demonstrations of the rfsio.d script.
+
+
+
+Here we trace file read() activity that has fully missed the cache and
+must be read from disk,
+
+ # ./rfsio.d
+
+ Read IOPS (count)
+ / logical 7
+ /extra1 physical 162
+ /boot logical 235
+ /boot physical 410
+ /extra1 logical 9514
+
+ Read Bandwidth (bytes)
+ / logical 533
+ /boot logical 1502386
+ /boot physical 1512960
+ /extra1 physical 97153024
+ /extra1 logical 97228668
+
+ Total File System miss-rate: 100%
+ ^C
+
+The miss rate of 100% means that all of the file system activity missed
+the cache, and had to read from disk.
+
+
+
+The following demonstrates file read() activity to the root filesystem
+that mostly returned from the file system cache.
+
+ # ./rfsio.d
+
+ Read IOPS (count)
+ / physical 1
+ /extra1 physical 9
+ /devices logical 9
+ / logical 15
+ /extra1 logical 4096
+
+ Read Bandwidth (bytes)
+ /devices logical 9
+ / logical 949
+ / physical 8192
+ /extra1 physical 917504
+ /extra1 logical 4194304
+
+ Total File System miss-rate: 22%
+ ^C
+
+The total miss-rate was 22%, which is based on the bytes transferred that
+missed the cache.
+
+
+
+
+Now for an unusual demonstration,
+
+ # ./rfsio.d
+
+ Read IOPS (count)
+ /devices logical 1
+ / logical 10
+ /extra1 physical 106
+ /extra1 logical 6337
+
+ Read Bandwidth (bytes)
+ /devices logical 2
+ / logical 961
+ /extra1 logical 64846450
+ /extra1 physical 66151424
+
+ Total File System miss-rate: 102%
+ ^C
+
+Here the miss-rate is 102%, which indicates that more data was read from
+disk than was requested; this can occur due to UFS read-ahead, which
+assists the performance of sequential disk activity at the small risk of
+reading too much data.
diff --git a/cddl/contrib/dtracetoolkit/Examples/runocc_example.txt b/cddl/contrib/dtracetoolkit/Examples/runocc_example.txt
new file mode 100644
index 0000000..53dcb5f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/runocc_example.txt
@@ -0,0 +1,53 @@
+The following are demonstrations of the runocc.d script.
+
+
+
+Here we run it on a single CPU server that is fairly busy,
+
+ # ./runocc.d
+
+ CPU %runocc
+ 0 86
+
+ CPU %runocc
+ 0 85
+
+ CPU %runocc
+ 0 82
+ ^C
+
+The run queue occupancy is around 85%, meaning most of the time there
+are runnable threads queued waiting for CPU.
+
+
+
+This script is more interesting on a multi-CPU server,
+
+ # ./runocc.d
+
+ CPU %runocc
+ 1 16
+ 3 27
+ 0 38
+ 2 75
+
+ CPU %runocc
+ 0 25
+ 2 41
+ 3 42
+ 1 50
+
+ CPU %runocc
+ 3 1
+ 0 17
+ 2 26
+ 1 27
+
+ CPU %runocc
+ 3 2
+ 2 5
+ 0 24
+ 1 25
+ ^C
+
+Here there was some degree of saturation, especially on CPU 2 to start with.
diff --git a/cddl/contrib/dtracetoolkit/Examples/rwbbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/rwbbypid_example.txt
new file mode 100644
index 0000000..9091adf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rwbbypid_example.txt
@@ -0,0 +1,26 @@
+The following is a demonstration of the rwbbypid.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # rwbbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD DIR BYTES
+ 20347 bash R 22
+ 11053 dtrace W 32
+ 1532 Xorg W 64
+ 20317 sshd R 86
+ 20347 bash W 87
+ 20317 sshd W 137
+ 1659 mozilla-bin R 213
+ 20334 sshd R 1232
+ 20334 sshd W 1282
+ 11054 cp W 18652
+ 11054 cp R 18652
+ 1532 Xorg R 51112
+ 1659 mozilla-bin W 51261
+
+In the above output, we can see that mozilla-bin with PID 1659 has written
+51261 bytes, while Xorg has read 51112 bytes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rwbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/rwbypid_example.txt
new file mode 100644
index 0000000..0c8559b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rwbypid_example.txt
@@ -0,0 +1,19 @@
+The following is a demonstration of the rwbypid.d script,
+
+
+Here we run it for a few seconds then hit Ctrl-C,
+
+ # rwbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD DIR COUNT
+ 11131 dtrace W 2
+ 20334 sshd W 17
+ 20334 sshd R 24
+ 1532 Xorg W 69
+ 1659 mozilla-bin R 852
+ 1659 mozilla-bin W 1128
+ 1532 Xorg R 1702
+
+In the above output, we can see that Xorg with PID 1532 has made 1702 reads.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rwbytype_example.txt b/cddl/contrib/dtracetoolkit/Examples/rwbytype_example.txt
new file mode 100644
index 0000000..118cf16
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rwbytype_example.txt
@@ -0,0 +1,37 @@
+The following is an example fo the rwbytype.d script.
+
+
+We run rwbytype.d for a few seconds then hit Ctrl-C,
+
+ # rwbytype.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD VTYPE DIR BYTES
+ 1545 sshd chr W 1
+ 10357 more chr R 30
+ 2357 sshd chr W 31
+ 10354 dtrace chr W 32
+ 1545 sshd chr R 34
+ 6778 bash chr W 44
+ 1545 sshd sock R 52
+ 405 poold reg W 68
+ 1545 sshd sock W 136
+ 10357 bash reg R 481
+ 10356 find reg R 481
+ 10355 bash reg R 481
+ 10357 more reg R 1652
+ 2357 sshd sock R 1664
+ 10357 more chr W 96925
+ 10357 more fifo R 97280
+ 2357 sshd chr R 98686
+ 10356 grep fifo W 117760
+ 2357 sshd sock W 118972
+ 10356 grep reg R 147645
+
+Here we can see that the grep process with PID 10356 read 147645 bytes
+from "regular" files. These are I/O bytes at the application level, so
+much of these read bytes would have been cached by the filesystem page cache.
+
+vnode file types are listed in /usr/include/sys/vnode.h, and give an idea of
+what the file descriptor refers to.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rwsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/rwsnoop_example.txt
new file mode 100644
index 0000000..2ef26ab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rwsnoop_example.txt
@@ -0,0 +1,98 @@
+The following is a demonstration of the rwsnoop program,
+
+
+Here we run it for about a second,
+
+ # rwsnoop
+ UID PID CMD D BYTES FILE
+ 100 20334 sshd R 52 <unknown>
+ 100 20334 sshd W 1 /devices/pseudo/clone@0:ptm
+ 0 20320 bash W 1 /devices/pseudo/pts@0:12
+ 100 20334 sshd R 2 /devices/pseudo/clone@0:ptm
+ 100 20334 sshd W 52 <unknown>
+ 0 2848 ls W 58 /devices/pseudo/pts@0:12
+ 0 2848 ls W 68 /devices/pseudo/pts@0:12
+ 0 2848 ls W 57 /devices/pseudo/pts@0:12
+ 0 2848 ls W 67 /devices/pseudo/pts@0:12
+ 0 2848 ls W 48 /devices/pseudo/pts@0:12
+ 0 2848 ls W 49 /devices/pseudo/pts@0:12
+ 0 2848 ls W 33 /devices/pseudo/pts@0:12
+ 0 2848 ls W 41 /devices/pseudo/pts@0:12
+ 100 20334 sshd R 429 /devices/pseudo/clone@0:ptm
+ 100 20334 sshd W 468 <unknown>
+ ^C
+
+The output scrolls rather fast. Above, we can see an ls command was run,
+and we can see as ls writes each line. The "<unknown>" read/writes are
+socket activity, which have no corresponding filename.
+
+
+For a summary style output, use the rwtop program.
+
+
+
+If a particular program is of interest, the "-n" option can be used
+to match on process name. Here we match on "bash" during a login where
+the user uses the bash shell as their default,
+
+ # rwsnoop -n bash
+ UID PID CMD D BYTES FILE
+ 100 2854 bash R 757 /etc/nsswitch.conf
+ 100 2854 bash R 0 /etc/nsswitch.conf
+ 100 2854 bash R 668 /etc/passwd
+ 100 2854 bash R 980 /etc/profile
+ 100 2854 bash W 15 /devices/pseudo/pts@0:14
+ 100 2854 bash R 10 /export/home/brendan/.bash_profile
+ 100 2854 bash R 867 /export/home/brendan/.bashrc
+ 100 2854 bash R 980 /etc/profile
+ 100 2854 bash W 15 /devices/pseudo/pts@0:14
+ 100 2854 bash R 8951 /export/home/brendan/.bash_history
+ 100 2854 bash R 8951 /export/home/brendan/.bash_history
+ 100 2854 bash R 1652 /usr/share/lib/terminfo/d/dtterm
+ 100 2854 bash W 41 /devices/pseudo/pts@0:14
+ 100 2854 bash R 1 /devices/pseudo/pts@0:14
+ 100 2854 bash W 1 /devices/pseudo/pts@0:14
+ 100 2854 bash W 41 /devices/pseudo/pts@0:14
+ 100 2854 bash R 1 /devices/pseudo/pts@0:14
+ 100 2854 bash W 7 /devices/pseudo/pts@0:14
+
+In the above, various bash related files such as ".bash_profile" and
+".bash_history" can be seen. The ".bashrc" is also read, as it was sourced
+from the .bash_profile.
+
+
+
+Extra options with rwsnoop allow us to print zone ID, project ID, timestamps,
+etc. Here we use "-v" to see the time printed, and match on "ps" processes,
+
+ # rwsnoop -vn ps
+ TIMESTR UID PID CMD D BYTES FILE
+ 2005 Jul 24 04:23:45 0 2804 ps R 168 /proc/2804/auxv
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/2804/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 1495 /etc/ttysrch
+ 2005 Jul 24 04:23:45 0 2804 ps W 28 /devices/pseudo/pts.
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/0/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/1/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/2/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/3/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/218/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/7/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/9/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/360/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/91/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/112/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/307/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/226/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/242/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/228/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/243/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/234/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/119/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/143/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/361/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/20314/psinfo
+ 2005 Jul 24 04:23:45 0 2804 ps R 336 /proc/116/psinfo
+ [...]
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/rwtop_example.txt b/cddl/contrib/dtracetoolkit/Examples/rwtop_example.txt
new file mode 100644
index 0000000..7284312
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/rwtop_example.txt
@@ -0,0 +1,59 @@
+The following is a demonstration of the rwtop program,
+
+
+By default it will refresh the screen every 5 seconds,
+
+ # rwtop
+ 2005 Jul 24 01:00:43, load: 1.02, app_r: 8 KB, app_w: 19 KB
+
+ UID PID PPID CMD D BYTES
+ 0 20320 20347 bash R 10
+ 0 20320 20347 bash W 95
+ 100 20317 20314 sshd R 650
+ 100 20317 20314 sshd W 733
+ 0 2365 20320 ls W 1300
+ 0 2364 20320 vi R 2323
+ 0 2365 20320 ls R 2485
+ 100 20334 20331 sshd R 3010
+ 100 20334 20331 sshd W 3729
+ 0 2364 20320 vi W 14128
+
+In the above output, we can see that a "vi" process wrote 14 Kbytes and
+read 2 Kbytes.
+
+
+
+In the following example, we print the top 5 processes in a scrolling
+output by using "-C" to not clear the screen,
+
+ # rwtop -C -t5
+ Tracing... Please wait.
+ 2005 Jul 24 01:03:27, load: 1.05, app_r: 261 KB, app_w: 348 KB
+
+ UID PID PPID CMD D BYTES
+ 0 2381 20320 svcs W 5801
+ 0 9 1 svc.configd R 115712
+ 0 2380 20320 find W 140003
+ 100 20334 20331 sshd R 150740
+ 100 20334 20331 sshd W 210773
+
+ 2005 Jul 24 01:03:32, load: 1.07, app_r: 110 KB, app_w: 233 KB
+
+ UID PID PPID CMD D BYTES
+ 100 20317 20314 sshd R 419
+ 100 20317 20314 sshd W 468
+ 0 2382 20320 find W 110720
+ 100 20334 20331 sshd R 112835
+ 100 20334 20331 sshd W 128175
+
+ 2005 Jul 24 01:03:37, load: 1.07, app_r: 6 KB, app_w: 7 KB
+
+ UID PID PPID CMD D BYTES
+ 0 2383 20320 df W 1154
+ 0 2385 20320 ls W 1300
+ 0 2385 20320 ls R 2485
+ 100 20334 20331 sshd R 3929
+ 100 20334 20331 sshd W 4339
+
+ ^C
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sampleproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/sampleproc_example.txt
new file mode 100644
index 0000000..d60d446
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sampleproc_example.txt
@@ -0,0 +1,62 @@
+The following is an example of the sampleproc program.
+
+
+Here we run sampleproc for a few seconds on a workstation,
+
+ # ./sampleproc
+ Sampling at 100 hertz... Hit Ctrl-C to end.
+ ^C
+ PID CMD COUNT
+ 1659 mozilla-bin 3
+ 109 nscd 4
+ 2197 prstat 23
+ 2190 setiathome 421
+
+ PID CMD PERCENT
+ 1659 mozilla-bin 0
+ 109 nscd 0
+ 2197 prstat 5
+ 2190 setiathome 93
+
+The first table shows a count of how many times each process was sampled
+on the CPU. The second table gives this as a percentage.
+
+setiathome was on the CPU 421 times, which is 93% of the samples.
+
+
+
+
+The following is sampleproc running on a server with 4 CPUs. A bash shell
+is running in an infinate loop,
+
+ # ./sampleproc
+ Sampling at 100 hertz... Hit Ctrl-C to end.
+ ^C
+ PID CMD COUNT
+ 10140 dtrace 1
+ 28286 java 1
+ 29345 esd 2
+ 29731 esd 3
+ 2 pageout 4
+ 29733 esd 6
+ 10098 bash 1015
+ 0 sched 3028
+
+ PID CMD PERCENT
+ 10140 dtrace 0
+ 28286 java 0
+ 29345 esd 0
+ 29731 esd 0
+ 2 pageout 0
+ 29733 esd 0
+ 10098 bash 24
+ 0 sched 74
+
+The bash shell was on the CPUs for 24% of the time, which is consistant
+with a CPU bound single threaded application on a 4 CPU server.
+
+The above sample was around 10 seconds long. During this time, there were
+around 4000 samples (checking the COUNT column), this is due to
+4000 = CPUs (4) * Hertz (100) * Seconds (10).
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sar-c_example.txt b/cddl/contrib/dtracetoolkit/Examples/sar-c_example.txt
new file mode 100644
index 0000000..7669eba
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sar-c_example.txt
@@ -0,0 +1,55 @@
+The following is a demonstration of the sar-c.d script.
+
+
+Here we run both sar-c.d and "sar -c 1 100" at the same time, to compare
+outputs.
+
+The DTrace script,
+
+ # ./sar-c.d
+ Time scall/s sread/s swrit/s fork/s exec/s rchar/s wchar/s
+ 2005 Jun 14 02:40:24 1556 82 71 0.00 0.00 10262 10508
+ 2005 Jun 14 02:40:25 1553 88 75 0.00 0.00 15095 15341
+ 2005 Jun 14 02:40:26 1596 89 76 0.00 0.00 14885 15131
+ 2005 Jun 14 02:40:27 5395 290 154 9.00 10.00 185991 77219
+ 2005 Jun 14 02:40:28 1755 91 98 1.00 1.00 15421 16788
+ 2005 Jun 14 02:40:29 1757 100 91 1.00 1.00 17127 17462
+ 2005 Jun 14 02:40:30 1603 95 80 0.00 0.00 16767 16634
+ 2005 Jun 14 02:40:31 14380 83 2420 1.00 1.00 14556 126461
+ 2005 Jun 14 02:40:32 10573 88 1586 0.00 0.00 14222 87888
+ 2005 Jun 14 02:40:33 1645 87 76 0.00 0.00 15320 15608
+ 2005 Jun 14 02:40:34 2099 167 130 0.00 0.00 126295 74281
+ 2005 Jun 14 02:40:35 1559 79 67 0.00 0.00 11663 11977
+ [...]
+
+The original command,
+
+ $ sar -c 1 100
+
+ SunOS jupiter 5.10 Generic i86pc 06/14/2005
+
+ 02:40:23 scall/s sread/s swrit/s fork/s exec/s rchar/s wchar/s
+ 02:40:24 1549 86 74 0.00 0.00 14799 15040
+ 02:40:25 1552 85 73 0.00 0.00 14475 14719
+ 02:40:26 5479 300 161 9.00 10.00 186755 77983
+ 02:40:27 1725 86 94 0.99 0.99 14819 16172
+ 02:40:28 1596 96 82 0.00 0.00 16521 16762
+ 02:40:29 1716 93 85 1.00 1.00 16395 16730
+ 02:40:30 1579 88 75 0.00 0.00 15324 15192
+ 02:40:32 23036 79 3887 0.99 0.99 10113 193520
+ 02:40:33 1756 94 83 0.00 0.00 14935 15300
+ 02:40:34 2099 165 130 0.00 0.00 125051 73552
+ 02:40:35 1560 82 69 0.00 0.00 15976 16287
+ [...]
+
+We can see that both tools are producing similar data.
+
+The DTrace output lacks the "summary since boot" line, as it is not using
+Kstat to fetch this data.
+
+
+The sar-c.d script is not intended itself as a useful program, rather it
+is intended as a starting point for other DTrace scripts; a starting point
+of familiar statistics to provide the programmer with a "common ground"
+of knowledge.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/seeksize_example.txt b/cddl/contrib/dtracetoolkit/Examples/seeksize_example.txt
new file mode 100644
index 0000000..ba41a87
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/seeksize_example.txt
@@ -0,0 +1,197 @@
+The following are examples of seeksize.d.
+
+seeksize.d records disk head seek size for each operation by process.
+This allows up to identify processes that are causing "random" disk
+access and those causing "sequential" disk access.
+
+It is desirable for processes to be accesing the disks in large
+sequential operations. By using seeksize.d and bitesize.d we can
+identify this behaviour.
+
+
+
+In this example we read through a large file by copying it to a
+remote server. Most of the seek sizes are zero, indicating sequential
+access - and we would expect good performance from the disks
+under these conditions,
+
+# ./seeksize.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ 22349 scp /dl/sol-10-b63-x86-v1.iso mars:\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 726
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 |@ 13
+ 16 | 4
+ 32 | 0
+ 64 | 0
+ 128 | 2
+ 256 | 3
+ 512 | 4
+ 1024 | 4
+ 2048 | 3
+ 4096 | 0
+ 8192 | 3
+ 16384 | 0
+ 32768 | 1
+ 65536 | 0
+
+
+
+In this example we run find. The disk operations are fairly scattered,
+as illustrated below by the volume of non sequential reads,
+
+# ./seeksize.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ 22399 find /var/sadm/pkg/\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@ 1475
+ 1 | 0
+ 2 | 44
+ 4 |@ 77
+ 8 |@@@ 286
+ 16 |@@ 191
+ 32 |@ 154
+ 64 |@@ 173
+ 128 |@@ 179
+ 256 |@@ 201
+ 512 |@@ 186
+ 1024 |@@ 236
+ 2048 |@@ 201
+ 4096 |@@ 274
+ 8192 |@@ 243
+ 16384 |@ 154
+ 32768 |@ 113
+ 65536 |@@ 182
+ 131072 |@ 81
+ 262144 | 0
+
+
+
+
+I found the following interesting. This time I gzipp'd the large file.
+While zipping, the process is reading from one location and writing
+to another. One might expect that as the program toggles between
+reading from one location and writing to another, that often the
+distance would be the same (depending on where UFS puts the new file),
+
+# ./seeksize.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ 22368 gzip sol-10-b63-x86-v1.iso\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@ 353
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 | 7
+ 16 | 4
+ 32 | 2
+ 64 | 4
+ 128 | 14
+ 256 | 3
+ 512 | 3
+ 1024 | 5
+ 2048 | 1
+ 4096 | 0
+ 8192 | 3
+ 16384 | 1
+ 32768 | 1
+ 65536 | 1
+ 131072 | 1
+ 262144 |@@@@@@@@ 249
+ 524288 | 1
+ 1048576 | 2
+ 2097152 | 1
+ 4194304 | 2
+ 8388608 |@@@@@@@@@@@@@@@@@@ 536
+ 16777216 | 0
+
+
+
+
+The following example compares the operation of "find" with "tar".
+Both are reading from the same location, and we would expect that
+both programs would generally need to do the same number of seeks
+to navigate the direttory tree (depending on caching); and tar
+causing extra operations as it reads the file contents as well,
+
+# ./seeksize.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+ PID CMD
+ 22278 find /etc\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@ 251
+ 1 | 0
+ 2 |@ 8
+ 4 | 5
+ 8 |@ 10
+ 16 |@ 10
+ 32 |@ 10
+ 64 |@ 9
+ 128 |@ 11
+ 256 |@ 14
+ 512 |@@ 20
+ 1024 |@ 10
+ 2048 | 6
+ 4096 |@ 7
+ 8192 |@ 10
+ 16384 |@ 16
+ 32768 |@@ 21
+ 65536 |@@ 28
+ 131072 |@ 7
+ 262144 |@ 14
+ 524288 | 6
+ 1048576 |@ 15
+ 2097152 |@ 7
+ 4194304 | 0
+
+
+ 22282 tar cf /dev/null /etc\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@ 397
+ 1 | 0
+ 2 | 8
+ 4 | 14
+ 8 | 16
+ 16 |@ 24
+ 32 |@ 29
+ 64 |@@ 99
+ 128 |@@ 73
+ 256 |@@ 78
+ 512 |@@@ 109
+ 1024 |@@ 62
+ 2048 |@@ 69
+ 4096 |@@ 73
+ 8192 |@@@ 113
+ 16384 |@@ 81
+ 32768 |@@@ 111
+ 65536 |@@@ 108
+ 131072 |@ 49
+ 262144 |@ 33
+ 524288 | 20
+ 1048576 | 13
+ 2097152 | 7
+ 4194304 | 5
+ 8388608 |@ 30
+ 16777216 | 0
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/setuids_example.txt b/cddl/contrib/dtracetoolkit/Examples/setuids_example.txt
new file mode 100644
index 0000000..be197bf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/setuids_example.txt
@@ -0,0 +1,28 @@
+The following is an example of setuids.d. Login events in particular can
+be seen, along with use of the "su" command.
+
+ # ./setuids.d
+ UID SUID PPID PID PCMD CMD
+ 0 100 3037 3040 in.telnetd login -p -h mars -d /dev/pts/12
+ 100 0 3040 3045 bash su -
+ 0 102 3045 3051 sh su - fred
+ 0 100 3055 3059 sshd /usr/lib/ssh/sshd
+ 0 100 3065 3067 in.rlogind login -d /dev/pts/12 -r mars
+ 0 100 3071 3073 in.rlogind login -d /dev/pts/12 -r mars
+ 0 102 3078 3081 in.telnetd login -p -h mars -d /dev/pts/12
+ ^C
+
+The first line is a telnet login to the user brendan, UID 100. The parent
+command is "in.telnetd", the telnet daemon spawned by inetd, and the
+command that in.telnetd runs is "login".
+
+The second line shows UID 100 using the "su" command to become root.
+
+The third line has the root user using "su" to become fred, UID 102.
+
+The fourth line is an example of an ssh login.
+
+The fifth and sixth lines are examples of rsh and rlogin.
+
+The last line is another example of a telnet login for fred, UID 102.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_calldist_example.txt
new file mode 100644
index 0000000..6c6a01f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_calldist_example.txt
@@ -0,0 +1,309 @@
+The following are examples of sh_calldist.d.
+
+This script traces the elapsed time of Bourne shell functions and
+prints a report containing distribution plots per function. Here it
+traces the example program, Code/Shell/func_abc.sh.
+
+ # sh_calldist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Elapsed times (us),
+
+ func_abc.sh, builtin, echo
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ func_abc.sh, cmd, sleep
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+ Exclusive function elapsed times (us),
+
+ func_abc.sh, func, func_a
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ func_abc.sh, func, func_b
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ func_abc.sh, func, func_c
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ Inclusive function elapsed times (us),
+
+ func_abc.sh, func, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_abc.sh, func, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_abc.sh, func, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+The elapsed times show that the echo builtin takes between 16 and 64 us
+to execute.
+
+The exclusive function elapsed times show that each function spent
+between 2 and 4 ms. This exclusive time excludes the time spent in
+other functions.
+
+The inclusive function elapsed times show that func_c() took between 0.5 and
+1.0 seconds, func_b() took between 1.0 and 2.1 seconds, and func_a() took
+between 2.1 and 4.2 seconds to execute. This inclusive time includes the
+time spent in other functions and commands called, and since func_a()
+calls func_b() which calls func_c(), and, each function is calling "sleep 1",
+these times make sense.
+
+These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
+
+
+The following traces the firefox startup script.
+
+# sh_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Elapsed times (us),
+
+ run-mozilla.sh, builtin, return
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ run-mozilla.sh, builtin, shift
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ run-mozilla.sh, builtin, break
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ firefox, builtin, break
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ run-mozilla.sh, builtin, export
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+
+ firefox, builtin, export
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+
+ firefox, builtin, :
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2 | 0
+ 4 |@@@@@@@ 1
+ 8 | 0
+
+ firefox, builtin, pwd
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ firefox, builtin, test
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ firefox, builtin, cd
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@ 1
+ 16 |@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ firefox, builtin, [
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@ 3
+ 2 |@@ 1
+ 4 |@@ 1
+ 8 |@@@@@@@ 3
+ 16 |@@@@@@@@@@@ 5
+ 32 |@@@@@@@ 3
+ 64 |@@@@ 2
+ 128 | 0
+
+ run-mozilla.sh, builtin, type
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ run-mozilla.sh, builtin, [
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@ 4
+ 2 |@@@@@@@@@@ 5
+ 4 |@@@@ 2
+ 8 |@@@@@@ 3
+ 16 |@@@@@@@@@@ 5
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@ 1
+ 4096 | 0
+
+ firefox, builtin, echo
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ firefox, cmd, /usr/lib/firefox/run-mozilla.sh
+ value ------------- Distribution ------------- count
+ 2097152 | 0
+ 4194304 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8388608 | 0
+
+ run-mozilla.sh, cmd, /usr/lib/firefox/firefox-bin
+ value ------------- Distribution ------------- count
+ 2097152 | 0
+ 4194304 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8388608 | 0
+
+Exclusive function elapsed times (us),
+
+ run-mozilla.sh, func, moz_test_binary
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 64 | 0
+
+ firefox, func, moz_spc_verbose_echo
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@ 2
+ 8 |@@@@@@@@@@@@@ 2
+ 16 |@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ firefox, func, moz_pis_startstop_scripts
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ run-mozilla.sh, func, moz_run_program
+ value ------------- Distribution ------------- count
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 262144 | 0
+
+Inclusive function elapsed times (us),
+
+ firefox, func, moz_spc_verbose_echo
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 16 |@@@@@@@@@@@@@ 2
+ 32 | 0
+
+ run-mozilla.sh, func, moz_test_binary
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ firefox, func, moz_pis_startstop_scripts
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 | 0
+ 32768 |@@@@@@@@@@@@@@@@@@@@ 1
+ 65536 | 0
+
+ run-mozilla.sh, func, moz_run_program
+ value ------------- Distribution ------------- count
+ 2097152 | 0
+ 4194304 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 8388608 | 0
+
+
+As an example of interpreting the output: the inclusive elapsed time for
+the "[" (test) builtin,
+
+ firefox, builtin, [
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@ 3
+ 2 |@@ 1
+ 4 |@@ 1
+ 8 |@@@@@@@ 3
+ 16 |@@@@@@@@@@@ 5
+ 32 |@@@@@@@ 3
+ 64 |@@@@ 2
+ 128 | 0
+
+shows that it was called 17 times (after adding up the counts), 5 of which
+took between 16 and 31 microseconds.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_calls_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_calls_example.txt
new file mode 100644
index 0000000..064cf97
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_calls_example.txt
@@ -0,0 +1,60 @@
+The following are examples of sh_calls.d.
+
+This is a simple script to count Bourne shell calls. Here it traces an
+example program, Code/Perl/func_abc.sh.
+
+ # sh_calls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE TYPE NAME COUNT
+ func_abc.sh func func_a 1
+ func_abc.sh func func_b 1
+ func_abc.sh func func_c 1
+ func_abc.sh builtin echo 3
+ func_abc.sh cmd sleep 3
+
+While tracing, function func_a() from the program "func_abc.sh" was executed
+once, along with func_b() and func_c(). The "echo" builtin was called 3
+times, as was the "sleep" command.
+
+
+The following traced the firefox start script,
+
+ # sh_calls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE TYPE NAME COUNT
+ firefox builtin . 1
+ firefox builtin break 1
+ firefox builtin exit 1
+ firefox builtin pwd 1
+ firefox builtin test 1
+ firefox cmd /usr/lib/firefox/run-mozilla.sh 1
+ run-mozilla.sh builtin break 1
+ run-mozilla.sh builtin exit 1
+ run-mozilla.sh builtin return 1
+ run-mozilla.sh builtin shift 1
+ run-mozilla.sh builtin type 1
+ run-mozilla.sh cmd /usr/lib/firefox/firefox-bin 1
+ run-mozilla.sh func moz_run_program 1
+ run-mozilla.sh func moz_test_binary 1
+ firefox builtin echo 2
+ firefox func moz_pis_startstop_scripts 2
+ firefox builtin cd 3
+ firefox builtin export 3
+ run-mozilla.sh builtin export 3
+ firefox builtin : 6
+ firefox func moz_spc_verbose_echo 6
+ run-mozilla.sh subsh - 9
+ firefox builtin [ 18
+ firefox subsh - 20
+ run-mozilla.sh builtin [ 20
+
+The firefox start script called run-mozilla.sh, which can be seen both
+as a "cmd" call in the above output from the "firefox" script, and as
+additionall calls from the "run-mozilla.sh" script.
+
+The builtin called "[" is the test builtin, and was called 20 times by
+"run-mozilla.sh" and 18 times by "firefox". The "firefox" script also called
+20 subshells.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_calltime_example.txt
new file mode 100644
index 0000000..5c39ae4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_calltime_example.txt
@@ -0,0 +1,144 @@
+The following are examples of sh_calltime.d.
+
+This script traces the elapsed time of Bourne shell functions and
+prints a report. Here it traces the example program, Code/Shell/func_abc.sh.
+
+ # sh_calltime.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Counts,
+ FILE TYPE NAME COUNT
+ func_abc.sh func func_a 1
+ func_abc.sh func func_b 1
+ func_abc.sh func func_c 1
+ func_abc.sh builtin echo 3
+ func_abc.sh cmd sleep 3
+ - total - 9
+
+ Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.sh builtin echo 108
+ func_abc.sh cmd sleep 3023760
+ - total - 3023868
+
+ Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.sh func func_b 2629
+ func_abc.sh func func_c 2822
+ func_abc.sh func func_a 3249
+ - total - 8702
+
+ Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ func_abc.sh func func_c 1009659
+ func_abc.sh func func_b 2020077
+ func_abc.sh func func_a 3032571
+
+In total, three functions were called, one builtin and one command.
+
+The elapsed times show that 3.0 seconds was spent in the sleep command,
+which is what would be expected based on the script.
+
+The exclusive function elapsed times show that each function spent around
+2.7 milliseconds of time processing code - while not in other functions.
+
+The inclusive function elapsed times show that func_a() took around 3.0
+seconds to execute, followed by func_b() at 2.0 seconds, and func_c() at 1.0.
+The inclusive time includes the time spent in other calls, and since
+func_a() called func_b() which called func_c(), and they all call "sleep 1",
+these times make sense.
+
+These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc. In particular, for this case it has
+included the time waiting for the sleep commands.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
+If you study the func_abc.sh program alongside the above output, the numbers
+should make sense.
+
+
+
+The following traces the firefox start script.
+
+# sh_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Counts,
+ FILE TYPE NAME COUNT
+ firefox builtin break 1
+ firefox builtin pwd 1
+ firefox builtin test 1
+ firefox cmd /usr/lib/firefox/run-mozilla.sh 1
+ run-mozilla.sh builtin break 1
+ run-mozilla.sh builtin return 1
+ run-mozilla.sh builtin shift 1
+ run-mozilla.sh builtin type 1
+ run-mozilla.sh cmd /usr/lib/firefox/firefox-bin 1
+ run-mozilla.sh func moz_run_program 1
+ run-mozilla.sh func moz_test_binary 1
+ firefox builtin echo 2
+ firefox func moz_pis_startstop_scripts 2
+ firefox builtin cd 3
+ firefox builtin export 3
+ run-mozilla.sh builtin export 3
+ firefox builtin : 6
+ firefox func moz_spc_verbose_echo 6
+ firefox builtin [ 18
+ run-mozilla.sh builtin [ 20
+ - total - 103
+
+Elapsed times (us),
+ FILE TYPE NAME TOTAL
+ run-mozilla.sh builtin return 1
+ run-mozilla.sh builtin shift 1
+ run-mozilla.sh builtin break 2
+ firefox builtin break 4
+ run-mozilla.sh builtin export 6
+ firefox builtin export 10
+ firefox builtin : 15
+ firefox builtin pwd 50
+ firefox builtin cd 72
+ run-mozilla.sh builtin [ 210
+ firefox builtin echo 323
+ firefox builtin [ 480
+ run-mozilla.sh builtin type 486
+ firefox builtin test 15330
+ run-mozilla.sh cmd /usr/lib/firefox/firefox-bin 8941269
+ firefox cmd /usr/lib/firefox/run-mozilla.sh 9384335
+ - total - 18342766
+
+Exclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ run-mozilla.sh func moz_test_binary 54
+ firefox func moz_spc_verbose_echo 136
+ firefox func moz_pis_startstop_scripts 230221
+ run-mozilla.sh func moz_run_program 402343
+ - total - 632756
+
+Inclusive function elapsed times (us),
+ FILE TYPE NAME TOTAL
+ run-mozilla.sh func moz_test_binary 91
+ firefox func moz_spc_verbose_echo 151
+ firefox func moz_pis_startstop_scripts 230587
+ run-mozilla.sh func moz_run_program 9343826
+
+
+
+The output showed that the most inclusive function elapsed time was in
+moz_run_program() at 9.3 seconds, which comes as little suprise since
+I let firefox run for several seconds before closing it. That same duration
+explains the large command times in the elapsed times report.
+
+Of more interest are the exclusive function elapsed times, where
+moz_pis_startstop_scripts() was the slowest at 230 ms. Other areas of the
+report are also useful to sanity check your software - should it be calling
+these things? Especially if there are any commands called that can be
+builtins instead.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_cpudist_example.txt
new file mode 100644
index 0000000..272e909
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_cpudist_example.txt
@@ -0,0 +1,92 @@
+The following are examples of sh_cpudist.d.
+
+This script traces the on-CPU time of Bourne shell functions and
+prints a report containing distribution plots per function. Here it
+traces the example program, Code/Shell/func_slow.sh.
+
+ # sh_cpudist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ On-CPU times (us),
+
+ func_slow.sh, builtin, echo
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@ 1
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+
+ func_slow.sh, builtin, [
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 | 1
+ 2 | 1
+ 4 |@ 22
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 575
+ 16 | 2
+ 32 | 0
+ 64 | 2
+ 128 | 0
+
+ Exclusive function on-CPU times (us),
+
+ func_slow.sh, func, func_a
+ value ------------- Distribution ------------- count
+ 65536 | 0
+ 131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 262144 | 0
+
+ func_slow.sh, func, func_b
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ func_slow.sh, func, func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ Inclusive function on-CPU times (us),
+
+ func_slow.sh, func, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.sh, func, func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ func_slow.sh, func, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+The on-CPU times should that the "[" builtin (test) usually took between
+8 and 15 microseconds to execute, and was called over 500 times.
+
+The exclusive function on-CPU times show that func_a() spent between
+131 ms and 262 ms on-CPU.
+
+The inclusive function on-CPU times show that both func_b() and func_c()
+spent between 1.0 and 2.1 seconds on-CPU, and func_a() spent between 2.1
+and 4.2 seconds on-CPU. This inclusive time includes the time spent in other
+functions called, and since func_a() called func_b() which called func_c(),
+these times make sense.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the function began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_cputime_example.txt
new file mode 100644
index 0000000..d3ae5bc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_cputime_example.txt
@@ -0,0 +1,131 @@
+The following are examples of sh_cputime.d.
+
+This script traces the on-CPU time of Bourne shell functions and
+prints a report. Here it traces the example program, Code/Shell/func_slow.sh.
+
+ # sh_cputime.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ Counts,
+ FILE TYPE NAME COUNT
+ func_slow.sh func func_a 1
+ func_slow.sh func func_b 1
+ func_slow.sh func func_c 1
+ func_slow.sh builtin echo 3
+ func_slow.sh builtin [ 603
+ - total - 609
+
+ On-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.sh builtin echo 162
+ func_slow.sh builtin [ 6279
+ - total - 6441
+
+ Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.sh func func_a 269465
+ func_slow.sh func func_b 670372
+ func_slow.sh func func_c 1259073
+ - total - 2198911
+
+ Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ func_slow.sh func func_c 1262209
+ func_slow.sh func func_b 1934839
+ func_slow.sh func func_a 2205352
+
+In total, three functions were called, one builtin and one command.
+
+The exclusive function on-CPU times show that func_a() spent around 268.4 ms
+on-CPU, func_b() spent 670.3 ms, and func_c() spent 1259 ms. This exclusive
+times excludes time spent in other functions.
+
+The inclusive function on-CPU times show that func_c() spent around 1.3
+seconds on-CPU, func_b() spent around 1.9 seconds, and func_a() spent around
+2.2 seconds. This inclusive time includes the time spent in other functions
+called, and since func_a() called func_b() which called func_c(), these
+times make sense.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the function began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
+If you study the func_slow.sh program alongside the above output, the numbers
+should make sense.
+
+
+
+The following traced the firefox start script.
+
+# sh_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Counts,
+ FILE TYPE NAME COUNT
+ firefox builtin break 1
+ firefox builtin pwd 1
+ firefox builtin test 1
+ firefox cmd run-mozilla.sh 1
+ run-mozilla.sh builtin break 1
+ run-mozilla.sh builtin return 1
+ run-mozilla.sh builtin shift 1
+ run-mozilla.sh builtin type 1
+ run-mozilla.sh cmd firefox-bin 1
+ run-mozilla.sh func moz_run_program 1
+ run-mozilla.sh func moz_test_binary 1
+ firefox builtin echo 2
+ firefox func moz_pis_startstop_scripts 2
+ firefox builtin cd 3
+ firefox builtin export 3
+ run-mozilla.sh builtin export 3
+ firefox builtin : 6
+ firefox func moz_spc_verbose_echo 6
+ firefox builtin [ 18
+ run-mozilla.sh builtin [ 20
+ - total - 103
+
+On-CPU times (us),
+ FILE TYPE NAME TOTAL
+ run-mozilla.sh builtin return 0
+ run-mozilla.sh builtin shift 0
+ run-mozilla.sh builtin break 1
+ firefox builtin break 2
+ run-mozilla.sh builtin export 4
+ firefox builtin export 7
+ firefox builtin : 9
+ firefox builtin test 35
+ firefox builtin pwd 49
+ firefox builtin cd 64
+ run-mozilla.sh builtin [ 176
+ firefox builtin echo 309
+ firefox builtin [ 357
+ run-mozilla.sh builtin type 475
+ firefox cmd run-mozilla.sh 17090
+ run-mozilla.sh cmd firefox-bin 1932333
+ - total - 1950979
+
+Exclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ run-mozilla.sh func moz_test_binary 21
+ firefox func moz_spc_verbose_echo 22
+ run-mozilla.sh func moz_run_program 9098
+ firefox func moz_pis_startstop_scripts 12960
+ - total - 22103
+
+Inclusive function on-CPU times (us),
+ FILE TYPE NAME TOTAL
+ firefox func moz_spc_verbose_echo 31
+ run-mozilla.sh func moz_test_binary 56
+ run-mozilla.sh func moz_run_program 9243
+ firefox func moz_pis_startstop_scripts 13133
+
+The output showed that the most CPU time was spent in the firefox-bin command,
+taking 1.9 seconds of on-CPU time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_flow_example.txt
new file mode 100644
index 0000000..de7f22b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_flow_example.txt
@@ -0,0 +1,129 @@
+The following are examples of sh_flow.d.
+
+This is a simple script to trace the flow of Bourne shell functions,
+builtins and external commands. Here it traces the example program,
+Code/Shell/func_abc.sh.
+
+ # sh_flow.d
+ C TIME(us) FILE -- NAME
+ 0 3060274370505 func_abc.sh -> func_a
+ 0 3060274370529 func_abc.sh > echo
+ 0 3060274372742 func_abc.sh | sleep
+ 0 3060275381634 func_abc.sh -> func_b
+ 0 3060275381660 func_abc.sh > echo
+ 0 3060275383852 func_abc.sh | sleep
+ 0 3060276391653 func_abc.sh -> func_c
+ 0 3060276391679 func_abc.sh > echo
+ 0 3060276393671 func_abc.sh | sleep
+ 0 3060277401753 func_abc.sh <- func_c
+ 0 3060277401767 func_abc.sh <- func_b
+ 0 3060277401775 func_abc.sh <- func_a
+ ^C
+
+As each function is entered, the third column is indented by 2 spaces. This
+shows which function is calling who - the output abovebegins by showing that
+func_a() began, and then called func_b().
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+
+The following traces the firefox startup script.
+
+# sh_flow.d
+ C TIME(us) FILE -- NAME
+ 0 3060321598138 firefox > test
+ 0 3060321603730 firefox > [
+ 0 3060321603796 firefox > cd
+ 0 3060321603878 firefox > [
+ 0 3060321603900 firefox > [
+ 0 3060321604099 firefox > [
+ 0 3060321609050 firefox > echo
+ 0 3060321620601 firefox > echo
+ 0 3060321626369 firefox > [
+ 0 3060321626432 firefox > export
+ 0 3060321626459 firefox -> moz_pis_startstop_scripts
+ 0 3060321626519 firefox > export
+ 0 3060321626966 firefox > [
+ 0 3060321627031 firefox > .
+ 0 3060321628446 firefox -> moz_spc_verbose_echo
+ 0 3060321628458 firefox > :
+ 0 3060321628467 firefox <- moz_spc_verbose_echo
+ 0 3060321636461 firefox > [
+ 0 3060321636738 firefox -> moz_spc_verbose_echo
+ 0 3060321636751 firefox > :
+ 0 3060321636760 firefox <- moz_spc_verbose_echo
+ 0 3060321636778 firefox > [
+ 0 3060321636793 firefox > [
+ 0 3060321636817 firefox > [
+ 0 3060321637126 firefox -> moz_spc_verbose_echo
+ 0 3060321637136 firefox > :
+ 0 3060321637143 firefox <- moz_spc_verbose_echo
+ 0 3060321666922 firefox -> moz_spc_verbose_echo
+ 0 3060321666952 firefox > :
+ 0 3060321666964 firefox <- moz_spc_verbose_echo
+ 0 3060321674929 firefox > [
+ 0 3060321680246 firefox > [
+ 0 3060321680312 firefox -> moz_spc_verbose_echo
+ 0 3060321680323 firefox > :
+ 0 3060321680331 firefox <- moz_spc_verbose_echo
+ 0 3060321680356 firefox -> moz_spc_verbose_echo
+ 0 3060321680363 firefox > :
+ 0 3060321680370 firefox <- moz_spc_verbose_echo
+ 0 3060321680396 firefox > [
+ 0 3060321680428 firefox <- moz_pis_startstop_scripts
+ 0 3060321680525 firefox > [
+ 0 3060321680580 firefox > [
+ 0 3060321685358 firefox | /usr/lib/firefox/run-mozilla.sh
+ 0 3060321700731 run-mozilla.sh > [
+ 0 3060321700950 run-mozilla.sh > break
+ 0 3060321703259 run-mozilla.sh > [
+ 0 3060321703292 run-mozilla.sh > shift
+ 0 3060321703382 run-mozilla.sh > [
+ 0 3060321703421 run-mozilla.sh > [
+ 0 3060321703493 run-mozilla.sh > [
+ 0 3060321703642 run-mozilla.sh > [
+ 0 3060321703669 run-mozilla.sh > export
+ 0 3060321703706 run-mozilla.sh > [
+ 0 3060321703725 run-mozilla.sh > [
+ 0 3060321703857 run-mozilla.sh > [
+ 0 3060321703880 run-mozilla.sh > export
+ 0 3060321703925 run-mozilla.sh > export
+ 0 3060321703954 run-mozilla.sh > [
+ 0 3060321703982 run-mozilla.sh -> moz_run_program
+ 0 3060321704013 run-mozilla.sh > [
+ 0 3060321704049 run-mozilla.sh -> moz_test_binary
+ 0 3060321704065 run-mozilla.sh > [
+ 0 3060321704097 run-mozilla.sh > [
+ 0 3060321704127 run-mozilla.sh > return
+ 0 3060321704137 run-mozilla.sh <- moz_test_binary
+ 0 3060321704151 run-mozilla.sh > [
+ 0 3060321709953 run-mozilla.sh > type
+ 0 3060321724260 run-mozilla.sh > [
+ 0 3060321724559 run-mozilla.sh > [
+ 0 3060321724574 run-mozilla.sh > [
+ 0 3060321727396 run-mozilla.sh | /usr/lib/firefox/firefox-bin
+ 0 3060325513871 run-mozilla.sh > [
+ 0 3060325513898 run-mozilla.sh > [
+ 0 3060325513929 run-mozilla.sh > [
+ 0 3060325513940 run-mozilla.sh <- moz_run_program
+ 0 3060325513967 run-mozilla.sh > exit
+ 0 3060325515113 firefox -> moz_pis_startstop_scripts
+ 0 3060325515189 firefox > export
+ 0 3060325515431 firefox > [
+ 0 3060325515466 firefox > [
+ 0 3060325515487 firefox <- moz_pis_startstop_scripts
+ 0 3060325515503 firefox > exit
+
+This shows the flow, incluing the handover between the "firefox" script
+and the "run-mozilla.sh" script.
+
+There is a point in the output where flow appears to reverse (at time
+3060321709953, with the entry "> type"). This is due to another instance
+of the run-mozilla.sh script running, which is indistinguishable from
+the other lines in the output. To confirm this for yourself, add a PID
+column to the flow script (or use sh_flowinfo.d).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_flowinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_flowinfo_example.txt
new file mode 100644
index 0000000..1fb27cf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_flowinfo_example.txt
@@ -0,0 +1,242 @@
+The following are examples of sh_flowinfo.d.
+
+This is a simple script to trace the flow of Bourne shell functions,
+builtins and external commands. Here it traces the example program,
+Code/Shell/func_abc.sh.
+
+ # sh_flowinfo.d
+ C PID DELTA(us) FILE:LINE TYPE -- NAME
+ 0 19634 2 func_abc.sh:23 func -> func_a
+ 0 19634 24 func_abc.sh:18 builtin -> echo
+ 0 19634 41 func_abc.sh:- builtin <- echo
+ 0 19634 5873 func_abc.sh:19 cmd -> sleep
+ 0 19634 999373 func_abc.sh:- cmd <- sleep
+ 0 19634 39 func_abc.sh:20 func -> func_b
+ 0 19634 22 func_abc.sh:11 builtin -> echo
+ 0 19634 40 func_abc.sh:- builtin <- echo
+ 0 19634 4661 func_abc.sh:12 cmd -> sleep
+ 0 19634 1005349 func_abc.sh:- cmd <- sleep
+ 0 19634 49 func_abc.sh:13 func -> func_c
+ 0 19634 22 func_abc.sh:5 builtin -> echo
+ 0 19634 38 func_abc.sh:- builtin <- echo
+ 0 19634 4949 func_abc.sh:6 cmd -> sleep
+ 0 19634 1004817 func_abc.sh:- cmd <- sleep
+ 0 19634 36 func_abc.sh:- func <- func_c
+ 0 19634 14 func_abc.sh:- func <- func_b
+ 0 19634 8 func_abc.sh:- func <- func_a
+
+As each function is entered, the third column is indented by 2 spaces. This
+shows which function is calling who - the output abovebegins by showing that
+func_a() began, and then called func_b().
+
+The DELTA(us) column shows time from that line to the previous line, and
+so can be a bit tricky to read. For example, the fifth line of data output
+(skipping the header) reads as "the time from the command sleep beginning
+to ending was 999373 us, or 1.0 seconds".
+
+The LINE column shows the line in the file what was being executed. Refer
+to the source program to see what this line refers to.
+
+If the output looks shuffled, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+The following traces the firefox startup script.
+
+# sh_flowinfo.d
+ C PID DELTA(us) FILE:LINE TYPE -- NAME
+ 0 156789 1 firefox:- subsh -> pid 156790
+ 0 156789 20 firefox:- subsh <- = 0
+ 0 156789 31651 firefox:- subsh -> pid 156791
+ 0 156789 20 firefox:- subsh <- = 0
+ 0 156789 10502 firefox:109 builtin -> test
+ 0 156789 59 firefox:- builtin <- test
+ 0 156789 3804 firefox:- subsh -> pid 156792
+ 0 156789 21 firefox:- subsh <- = 0
+ 0 156789 22029 firefox:114 builtin -> [
+ 0 156789 57 firefox:- builtin <- [
+ 0 156789 90910 firefox:- subsh -> pid 156793
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156789 159492 firefox:- subsh -> pid 156794
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156789 127 firefox:116 builtin -> cd
+ 0 156789 54 firefox:- builtin <- cd
+ 0 156789 209757 firefox:- subsh -> pid 156795
+ 0 156789 23 firefox:- subsh <- = 0
+ 0 156795 206160 firefox:- subsh -> pid 156796
+ 0 156795 9 firefox:- subsh <- = 0
+ 0 156789 12115 firefox:118 builtin -> [
+ 0 156789 61 firefox:- builtin <- [
+ 0 156789 200529 firefox:- subsh -> pid 156797
+ 0 156789 24 firefox:- subsh <- = 0
+ 0 156789 136 firefox:123 builtin -> [
+ 0 156789 58 firefox:- builtin <- [
+ 0 156789 21 firefox:124 builtin -> cd
+ 0 156789 19 firefox:- builtin <- cd
+ 0 156798 175 firefox:1 builtin -> pwd
+ 0 156798 65 firefox:- builtin <- pwd
+ 0 156789 108835 firefox:- subsh -> pid 156798
+ 0 156789 18 firefox:- subsh <- = 0
+ 0 156789 119 firefox:128 builtin -> break
+ 0 156789 15 firefox:- builtin <- break
+ 0 156789 21 firefox:131 builtin -> cd
+ 0 156789 26 firefox:- builtin <- cd
+ 0 156789 61 firefox:133 builtin -> [
+ 0 156789 9 firefox:- builtin <- [
+ 0 156789 73508 firefox:147 builtin -> [
+ 0 156789 25 firefox:- builtin <- [
+ 0 156800 184 firefox:1 builtin -> echo
+ 0 156800 175 firefox:- builtin <- echo
+ 0 156789 15966 firefox:- subsh -> pid 156799
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156799 12091 firefox:- subsh -> pid 156800
+ 0 156799 10 firefox:- subsh <- = 0
+ 0 156802 178 firefox:1 builtin -> echo
+ 0 156802 167 firefox:- builtin <- echo
+ 0 156789 13822 firefox:- subsh -> pid 156801
+ 0 156789 18 firefox:- subsh <- = 0
+ 0 156801 81683 firefox:- subsh -> pid 156802
+ 0 156801 21 firefox:- subsh <- = 0
+ 0 156789 78324 firefox:158 builtin -> [
+ 0 156789 37 firefox:- builtin <- [
+ 0 156789 54 firefox:194 builtin -> export
+ 0 156789 9 firefox:- builtin <- export
+ 0 156789 26 firefox:197 func -> moz_pis_startstop_scripts
+ 0 156789 61 firefox:62 builtin -> export
+ 0 156789 9 firefox:- builtin <- export
+ 0 156789 413 firefox:67 builtin -> [
+ 0 156789 34 firefox:- builtin <- [
+ 0 156789 40 firefox:69 builtin -> .
+ 0 156789 20833 firefox:18 func -> moz_spc_verbose_echo
+ 0 156789 26 firefox:15 builtin -> :
+ 0 156789 16 firefox:- builtin <- :
+ 0 156789 15 firefox:- func <- moz_spc_verbose_echo
+ 0 156789 105106 firefox:- subsh -> pid 156803
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156789 129 firefox:19 builtin -> [
+ 0 156789 17 firefox:- builtin <- [
+ 0 156789 33 firefox:20 func -> moz_spc_verbose_echo
+ 0 156789 14 firefox:15 builtin -> :
+ 0 156789 7 firefox:- builtin <- :
+ 0 156789 9 firefox:- func <- moz_spc_verbose_echo
+ 0 156789 21 firefox:23 builtin -> [
+ 0 156789 8 firefox:- builtin <- [
+ 0 156789 16 firefox:26 builtin -> [
+ 0 156789 8 firefox:- builtin <- [
+ 0 156789 24 firefox:29 builtin -> [
+ 0 156789 43 firefox:- builtin <- [
+ 0 156789 77 firefox:36 func -> moz_spc_verbose_echo
+ 0 156789 9 firefox:15 builtin -> :
+ 0 156789 8 firefox:- builtin <- :
+ 0 156789 8 firefox:- func <- moz_spc_verbose_echo
+ 0 156789 158947 firefox:- subsh -> pid 156804
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156789 210112 firefox:- subsh -> pid 156805
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156805 205500 firefox:- subsh -> pid 156806
+ 0 156805 10 firefox:- subsh <- = 0
+ 0 156805 200987 firefox:- subsh -> pid 156807
+ 0 156805 20 firefox:- subsh <- = 0
+ 0 156789 363564 firefox:40 func -> moz_spc_verbose_echo
+ 0 156789 26 firefox:15 builtin -> :
+ 0 156789 17 firefox:- builtin <- :
+ 0 156789 15 firefox:- func <- moz_spc_verbose_echo
+ 0 156809 234 firefox:1 builtin -> [
+ 0 156809 70 firefox:- builtin <- [
+ 0 156789 46950 firefox:- subsh -> pid 156808
+ 0 156789 22 firefox:- subsh <- = 0
+ 0 156808 42371 firefox:- subsh -> pid 156809
+ 0 156808 10 firefox:- subsh <- = 0
+ 0 156789 27278 firefox:43 builtin -> [
+ 0 156789 26 firefox:- builtin <- [
+ 0 156789 62 firefox:44 func -> moz_spc_verbose_echo
+ 0 156789 15 firefox:15 builtin -> :
+ 0 156789 8 firefox:- builtin <- :
+ 0 156789 10 firefox:- func <- moz_spc_verbose_echo
+ 0 156789 30 firefox:67 func -> moz_spc_verbose_echo
+ 0 156789 9 firefox:15 builtin -> :
+ 0 156789 8 firefox:- builtin <- :
+ 0 156789 7 firefox:- func <- moz_spc_verbose_echo
+ 0 156789 8 firefox:- builtin <- .
+ 0 156789 28 firefox:67 builtin -> [
+ 0 156789 31 firefox:- builtin <- [
+ 0 156789 8 firefox:- func <- moz_pis_startstop_scripts
+ 0 156789 97 firefox:199 builtin -> [
+ 0 156789 35 firefox:- builtin <- [
+ 0 156789 29 firefox:205 builtin -> [
+ 0 156789 9 firefox:- builtin <- [
+ 0 156789 72519 firefox:209 cmd -> /usr/lib/firefox/run-mozilla.sh
+ 0 156810 1 run-mozilla.sh:- subsh -> pid 156811
+ 0 156810 15 run-mozilla.sh:- subsh <- = 0
+ 0 156810 129474 run-mozilla.sh:- subsh -> pid 156812
+ 0 156810 24 run-mozilla.sh:- subsh <- = 0
+ 0 156810 743 run-mozilla.sh:258 builtin -> [
+ 0 156810 28 run-mozilla.sh:- builtin <- [
+ 0 156810 212 run-mozilla.sh:275 builtin -> break
+ 0 156810 10 run-mozilla.sh:- builtin <- break
+ 0 156810 31 run-mozilla.sh:283 builtin -> [
+ 0 156810 10 run-mozilla.sh:- builtin <- [
+ 0 156810 16 run-mozilla.sh:286 builtin -> shift
+ 0 156810 9 run-mozilla.sh:- builtin <- shift
+ 0 156810 55 run-mozilla.sh:291 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 36 run-mozilla.sh:317 builtin -> [
+ 0 156810 34 run-mozilla.sh:- builtin <- [
+ 0 156810 37 run-mozilla.sh:327 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 142 run-mozilla.sh:362 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 26 run-mozilla.sh:366 builtin -> export
+ 0 156810 9 run-mozilla.sh:- builtin <- export
+ 0 156810 37 run-mozilla.sh:369 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 18 run-mozilla.sh:371 builtin -> [
+ 0 156810 19 run-mozilla.sh:- builtin <- [
+ 0 156810 112 run-mozilla.sh:379 builtin -> [
+ 0 156810 10 run-mozilla.sh:- builtin <- [
+ 0 156810 23 run-mozilla.sh:418 builtin -> export
+ 0 156810 9 run-mozilla.sh:- builtin <- export
+ 0 156810 45 run-mozilla.sh:419 builtin -> export
+ 0 156810 10 run-mozilla.sh:- builtin <- export
+ 0 156810 27 run-mozilla.sh:421 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 29 run-mozilla.sh:425 func -> moz_run_program
+ 0 156810 32 run-mozilla.sh:137 builtin -> [
+ 0 156810 25 run-mozilla.sh:- builtin <- [
+ 0 156810 20 run-mozilla.sh:145 func -> moz_test_binary
+ 0 156810 17 run-mozilla.sh:97 builtin -> [
+ 0 156810 23 run-mozilla.sh:- builtin <- [
+ 0 156810 15 run-mozilla.sh:99 builtin -> [
+ 0 156810 26 run-mozilla.sh:- builtin <- [
+ 0 156810 13 run-mozilla.sh:101 builtin -> return
+ 0 156810 9 run-mozilla.sh:- builtin <- return
+ 0 156810 11 run-mozilla.sh:- func <- moz_test_binary
+ 0 156810 18 run-mozilla.sh:146 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156814 185 run-mozilla.sh:1 builtin -> type
+ 0 156814 118188 run-mozilla.sh:- builtin <- type
+ 0 156810 167284 run-mozilla.sh:- subsh -> pid 156813
+ 0 156810 23 run-mozilla.sh:- subsh <- = 0
+ 0 156813 162135 run-mozilla.sh:- subsh -> pid 156814
+ 0 156813 12 run-mozilla.sh:- subsh <- = 0
+ 0 156813 200125 run-mozilla.sh:- subsh -> pid 156815
+ 0 156813 22 run-mozilla.sh:- subsh <- = 0
+ 0 156810 203465 run-mozilla.sh:152 builtin -> [
+ 0 156810 51 run-mozilla.sh:- builtin <- [
+ 0 156810 21 run-mozilla.sh:156 builtin -> [
+ 0 156810 9 run-mozilla.sh:- builtin <- [
+ 0 156810 15 run-mozilla.sh:159 builtin -> [
+ 0 156810 14 run-mozilla.sh:- builtin <- [
+ 0 156810 65752 run-mozilla.sh:- subsh -> pid 156816
+ 0 156810 24 run-mozilla.sh:- subsh <- = 0
+ 0 156816 251788 run-mozilla.sh:- subsh -> pid 156817
+ 0 156816 22 run-mozilla.sh:- subsh <- = 0
+ 0 156810 299677 run-mozilla.sh:167 cmd -> /usr/lib/firefox/firefox-bin
+ 0 156810 5124906 run-mozilla.sh:- cmd <- /usr/lib/firefox/firefox-bin
+ 0 156789 5993798 firefox:- cmd <- /usr/lib/firefox/run-mozilla.sh
+
+Now latencies can investigated by line number.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_flowtime_example.txt
new file mode 100644
index 0000000..03848de
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_flowtime_example.txt
@@ -0,0 +1,131 @@
+The following are examples of sh_flowtime.d.
+
+This is a simple script to trace the flow of Bourne shell functions,
+builtins and external commands. Here it traces the example program,
+Code/Shell/func_abc.sh.
+
+ # sh_flowtime.d
+ C TIME(us) FILE DELTA(us) -- NAME
+ 0 3060817866026 func_abc.sh 2 -> func_a
+ 0 3060817866086 func_abc.sh 60 > echo
+ 0 3060818871601 func_abc.sh 1005514 | sleep
+ 0 3060818871639 func_abc.sh 38 -> func_b
+ 0 3060818871684 func_abc.sh 44 > echo
+ 0 3060819881597 func_abc.sh 1009912 | sleep
+ 0 3060819881657 func_abc.sh 60 -> func_c
+ 0 3060819881717 func_abc.sh 60 > echo
+ 0 3060820891613 func_abc.sh 1009896 | sleep
+ 0 3060820891661 func_abc.sh 47 <- func_c
+ 0 3060820891675 func_abc.sh 14 <- func_b
+ 0 3060820891683 func_abc.sh 7 <- func_a
+ ^C
+
+As each function is entered, the third column is indented by 2 spaces. This
+shows which function is calling who - the output above begins by showing that
+func_a() began, and then called func_b().
+
+The DELTA(us) column is interpreted as follows,
+
+ -> previous line to the start of this function
+ <- previous line to the end of this function
+ > previous line to the end of this builtin
+ | previous line to the end of this command
+
+And so the above output shows that each sleep command is taking around 1.0
+seconds to execute.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
+
+
+The following traces the firefox start script.
+
+# sh_flowtime.d
+ C TIME(us) FILE DELTA(us) -- NAME
+ 0 3060994282580 firefox 2 > test
+ 0 3060994286921 firefox 4341 > [
+ 0 3060994286955 firefox 34 > cd
+ 0 3060994287014 firefox 58 > [
+ 0 3060994287059 firefox 45 > [
+ 0 3060994287227 firefox 167 > [
+ 0 3060994293793 firefox 2 > echo
+ 0 3060994305759 firefox 2 > echo
+ 0 3060994309613 firefox 22385 > [
+ 0 3060994309665 firefox 52 > export
+ 0 3060994309691 firefox 25 -> moz_pis_startstop_scripts
+ 0 3060994309752 firefox 61 > export
+ 0 3060994310199 firefox 447 > [
+ 0 3060994314462 firefox 4262 -> moz_spc_verbose_echo
+ 0 3060994314484 firefox 22 > :
+ 0 3060994314497 firefox 12 <- moz_spc_verbose_echo
+ 0 3060994322101 firefox 7604 > [
+ 0 3060994322134 firefox 33 -> moz_spc_verbose_echo
+ 0 3060994322147 firefox 12 > :
+ 0 3060994322155 firefox 7 <- moz_spc_verbose_echo
+ 0 3060994322501 firefox 345 > [
+ 0 3060994322518 firefox 17 > [
+ 0 3060994322578 firefox 59 > [
+ 0 3060994322641 firefox 62 -> moz_spc_verbose_echo
+ 0 3060994322650 firefox 9 > :
+ 0 3060994322656 firefox 6 <- moz_spc_verbose_echo
+ 0 3060994653794 firefox 331137 -> moz_spc_verbose_echo
+ 0 3060994653826 firefox 32 > :
+ 0 3060994653839 firefox 12 <- moz_spc_verbose_echo
+ 0 3060994659534 firefox 2 > [
+ 0 3060994667539 firefox 13699 > [
+ 0 3060994667604 firefox 65 -> moz_spc_verbose_echo
+ 0 3060994667617 firefox 13 > :
+ 0 3060994667625 firefox 8 <- moz_spc_verbose_echo
+ 0 3060994667653 firefox 27 -> moz_spc_verbose_echo
+ 0 3060994667661 firefox 7 > :
+ 0 3060994667668 firefox 6 <- moz_spc_verbose_echo
+ 0 3060994667675 firefox 7 > .
+ 0 3060994667725 firefox 49 > [
+ 0 3060994667732 firefox 6 <- moz_pis_startstop_scripts
+ 0 3060994667853 firefox 121 > [
+ 0 3060994667881 firefox 27 > [
+ 0 3060994804329 run-mozilla.sh 2 > [
+ 0 3060994804524 run-mozilla.sh 194 > break
+ 0 3060994804560 run-mozilla.sh 36 > [
+ 0 3060994804580 run-mozilla.sh 20 > shift
+ 0 3060994804649 run-mozilla.sh 68 > [
+ 0 3060994804710 run-mozilla.sh 61 > [
+ 0 3060994804747 run-mozilla.sh 36 > [
+ 0 3060994804889 run-mozilla.sh 142 > [
+ 0 3060994804915 run-mozilla.sh 26 > export
+ 0 3060994804952 run-mozilla.sh 36 > [
+ 0 3060994804981 run-mozilla.sh 28 > [
+ 0 3060994805093 run-mozilla.sh 112 > [
+ 0 3060994805116 run-mozilla.sh 22 > export
+ 0 3060994805160 run-mozilla.sh 44 > export
+ 0 3060994805187 run-mozilla.sh 27 > [
+ 0 3060994805215 run-mozilla.sh 27 -> moz_run_program
+ 0 3060994805263 run-mozilla.sh 48 > [
+ 0 3060994805283 run-mozilla.sh 19 -> moz_test_binary
+ 0 3060994805314 run-mozilla.sh 31 > [
+ 0 3060994805346 run-mozilla.sh 31 > [
+ 0 3060994805358 run-mozilla.sh 12 > return
+ 0 3060994805367 run-mozilla.sh 9 <- moz_test_binary
+ 0 3060994805385 run-mozilla.sh 17 > [
+ 0 3060994964498 run-mozilla.sh 2 > type
+ 0 3060995520942 run-mozilla.sh 715556 > [
+ 0 3060995520967 run-mozilla.sh 24 > [
+ 0 3060995520987 run-mozilla.sh 20 > [
+ 0 3061000622172 run-mozilla.sh 5101184 | /usr/lib/firefox/firefox-bin
+ 0 3061000622221 run-mozilla.sh 49 > [
+ 0 3061000622252 run-mozilla.sh 30 > [
+ 0 3061000622266 run-mozilla.sh 14 > [
+ 0 3061000622275 run-mozilla.sh 9 <- moz_run_program
+ 0 3061000623686 firefox 5955805 | /usr/lib/firefox/run-mozilla.sh
+ 0 3061000623793 firefox 106 -> moz_pis_startstop_scripts
+ 0 3061000623864 firefox 71 > export
+ 0 3061000624108 firefox 244 > [
+ 0 3061000624138 firefox 30 > [
+ 0 3061000624147 firefox 8 <- moz_pis_startstop_scripts
+
+Points of latency during startup are visible in the output. For more details,
+see Examples/sh_flowinfo_example.txt.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_lines_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_lines_example.txt
new file mode 100644
index 0000000..f19487c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_lines_example.txt
@@ -0,0 +1,32 @@
+The following are examples of sh_lines.d.
+
+This is a simple script to count Bourne shell line execution. Here it traces an
+example program, Code/Shell/func_slow.sh.
+
+ # sh_lines.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+
+ FILE:LINE COUNT
+ func_slow.sh:5 1
+ func_slow.sh:6 1
+ func_slow.sh:15 1
+ func_slow.sh:16 1
+ func_slow.sh:21 1
+ func_slow.sh:26 1
+ func_slow.sh:27 1
+ func_slow.sh:32 1
+ func_slow.sh:35 1
+ func_slow.sh:30 100
+ func_slow.sh:28 101
+ func_slow.sh:19 200
+ func_slow.sh:17 201
+ func_slow.sh:9 300
+ func_slow.sh:7 301
+ func_slow.sh:1 600
+
+The most frequently executed line was line 1 of func_slow.sh - which is actually
+line 1 of func_slow.sh subshells (command substitution, ` `). Apart from
+this slight confusion, the rest of the output should make sense (and most
+scripts only call one line in command substitution anyway).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_pidcolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_pidcolors_example.txt
new file mode 100644
index 0000000..a6025e4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_pidcolors_example.txt
@@ -0,0 +1,574 @@
+The following are examples of sh_pidcolors.d.
+
+This is the same script as in sh_syscolors.d, except with additional tracing.
+As well as the functions, lines and system calls traced in sh_syscolors.d,
+this also adds some "pid" provider tracing as a starting point for deeper
+analysis. In this case it adds the probes:
+
+ pid$target:a.out:e*:entry,
+ pid$target:a.out:e*:return
+
+which means, all functions from the /usr/bin/sh binary that begin with
+the letter "e". This adds about 34 probes, but you can customize it to be as
+inclusive as you like. It renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Shell/func_abc.sh.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# sh_pidcolors.d -c ./func_abc.sh -o /tmp/out
+Function A
+Function B
+Function C
+
+# cat /tmp/out
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 12312 2 func_abc.sh:- syscall -> munmap
+0 12312 34 func_abc.sh:- syscall <- munmap
+0 12312 53 func_abc.sh:- syscall -> mmap
+0 12312 19 func_abc.sh:- syscall <- mmap
+0 12312 43 func_abc.sh:- syscall -> setcontext
+0 12312 11 func_abc.sh:- syscall <- setcontext
+0 12312 11 func_abc.sh:- syscall -> getrlimit
+0 12312 11 func_abc.sh:- syscall <- getrlimit
+0 12312 10 func_abc.sh:- syscall -> getpid
+0 12312 9 func_abc.sh:- syscall <- getpid
+0 12312 63 func_abc.sh:- syscall -> setcontext
+0 12312 9 func_abc.sh:- syscall <- setcontext
+0 12312 813 func_abc.sh:- syscall -> sysi86
+0 12312 13 func_abc.sh:- syscall <- sysi86
+0 12312 85 func_abc.sh:- syscall -> open64
+0 12312 88 func_abc.sh:- syscall <- open64
+0 12312 13 func_abc.sh:- syscall -> ioctl
+0 12312 35 func_abc.sh:- syscall <- ioctl
+0 12312 15 func_abc.sh:- syscall -> close
+0 12312 17 func_abc.sh:- syscall <- close
+0 12312 123 func_abc.sh:- syscall -> getpid
+0 12312 9 func_abc.sh:- syscall <- getpid
+0 12312 17 func_abc.sh:- syscall -> setpgrp
+0 12312 9 func_abc.sh:- syscall <- setpgrp
+0 12312 11 func_abc.sh:- syscall -> setpgrp
+0 12312 8 func_abc.sh:- syscall <- setpgrp
+0 12312 11 func_abc.sh:- syscall -> access
+0 12312 19 func_abc.sh:- syscall <- access
+0 12312 14 func_abc.sh:- syscall -> brk
+0 12312 11 func_abc.sh:- syscall <- brk
+0 12312 15 func_abc.sh:- syscall -> sysconfig
+0 12312 9 func_abc.sh:- syscall <- sysconfig
+0 12312 10 func_abc.sh:- syscall -> sysconfig
+0 12312 8 func_abc.sh:- syscall <- sysconfig
+0 12312 11 func_abc.sh:- syscall -> sigaltstack
+0 12312 9 func_abc.sh:- syscall <- sigaltstack
+0 12312 16 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 12 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 9 func_abc.sh:- syscall -> sigaction
+0 12312 9 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 10 func_abc.sh:- syscall -> sigaction
+0 12312 8 func_abc.sh:- syscall <- sigaction
+0 12312 18 func_abc.sh:- sh -> endstak
+0 12312 18 func_abc.sh:- sh <- endstak
+0 12312 60 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 13 func_abc.sh:- syscall -> getuid
+0 12312 9 func_abc.sh:- syscall <- getuid
+0 12312 10 func_abc.sh:- syscall -> getuid
+0 12312 9 func_abc.sh:- syscall <- getuid
+0 12312 11 func_abc.sh:- syscall -> getgid
+0 12312 9 func_abc.sh:- syscall <- getgid
+0 12312 11 func_abc.sh:- syscall -> getgid
+0 12312 8 func_abc.sh:- syscall <- getgid
+0 12312 16 func_abc.sh:- syscall -> open64
+0 12312 20 func_abc.sh:- syscall <- open64
+0 12312 11 func_abc.sh:- sh -> exfile
+0 12312 10 func_abc.sh:- syscall -> close
+0 12312 8 func_abc.sh:- syscall <- close
+0 12312 24 func_abc.sh:- syscall -> fcntl
+0 12312 23 func_abc.sh:- syscall <- fcntl
+0 12312 10 func_abc.sh:- syscall -> close
+0 12312 10 func_abc.sh:- syscall <- close
+0 12312 9 func_abc.sh:- syscall -> fcntl
+0 12312 8 func_abc.sh:- syscall <- fcntl
+0 12312 28 func_abc.sh:- syscall -> ioctl
+0 12312 42 func_abc.sh:- syscall <- ioctl
+0 12312 10 func_abc.sh:- syscall -> ioctl
+0 12312 9 func_abc.sh:- syscall <- ioctl
+0 12312 14 func_abc.sh:- syscall -> read
+0 12312 33 func_abc.sh:- syscall <- read
+0 12312 11 func_abc.sh:- syscall -> brk
+0 12312 20 func_abc.sh:- syscall <- brk
+0 12312 13 func_abc.sh:- sh -> execute
+0 12312 11 func_abc.sh:- sh <- execute
+0 12312 10 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 29 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> execute
+0 12312 10 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 10 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- syscall -> read
+0 12312 16 func_abc.sh:- syscall <- read
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 25 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> execute
+0 12312 10 func_abc.sh:- sh <- execute
+0 12312 10 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- syscall -> brk
+0 12312 9 func_abc.sh:- syscall <- brk
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:23 line -- 
+0 12312 14 func_abc.sh:- sh -> estabf
+0 12312 10 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 18 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 12 func_abc.sh:- sh -> expand
+0 12312 10 func_abc.sh:- sh <- expand
+0 12312 14 func_abc.sh:23 func -> func_a
+0 12312 14 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 8 func_abc.sh:18 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 8 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 8 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 13 func_abc.sh:18 builtin -> echo
+0 12312 15 func_abc.sh:- sh -> echo
+0 12312 14 func_abc.sh:- syscall -> write
+0 12312 35 func_abc.sh:- syscall <- write
+0 12312 321 func_abc.sh:- sh <- echo
+0 12312 13 func_abc.sh:0 builtin <- echo
+0 12312 17 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 8 func_abc.sh:19 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 11 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- syscall -> getuid
+0 12312 9 func_abc.sh:- syscall <- getuid
+0 12312 15 func_abc.sh:- syscall -> stat64
+0 12312 27 func_abc.sh:- syscall <- stat64
+0 12312 11 func_abc.sh:- syscall -> access
+0 12312 15 func_abc.sh:- syscall <- access
+0 12312 18 func_abc.sh:- syscall -> schedctl
+0 12312 47 func_abc.sh:- syscall <- schedctl
+0 12312 219 func_abc.sh:- syscall -> fork1
+0 12312 234375 func_abc.sh:- syscall <- fork1
+0 12312 277 func_abc.sh:- syscall -> lwp_sigmask
+0 12312 13 func_abc.sh:- syscall <- lwp_sigmask
+0 12312 33 func_abc.sh:19 cmd -> sleep
+0 12312 59 func_abc.sh:- syscall -> waitsys
+0 12312 870257 func_abc.sh:- syscall <- waitsys
+0 12312 36 func_abc.sh:- syscall -> ioctl
+0 12312 16 func_abc.sh:- syscall <- ioctl
+0 12312 13 func_abc.sh:- syscall -> setpgrp
+0 12312 9 func_abc.sh:- syscall <- setpgrp
+0 12312 9 func_abc.sh:- syscall -> ioctl
+0 12312 9 func_abc.sh:- syscall <- ioctl
+0 12312 11 func_abc.sh:- syscall -> ioctl
+0 12312 33 func_abc.sh:- syscall <- ioctl
+0 12312 12 func_abc.sh:- syscall -> waitsys
+0 12312 25 func_abc.sh:- syscall <- waitsys
+0 12312 15 func_abc.sh:0 cmd <- sleep
+0 12312 20 func_abc.sh:- sh <- execute
+0 12312 15 func_abc.sh:- sh -> execute
+0 12312 14 func_abc.sh:20 line -- 
+0 12312 13 func_abc.sh:- sh -> estabf
+0 12312 10 func_abc.sh:- sh <- estabf
+0 12312 11 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 12 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 11 func_abc.sh:- sh -> expand
+0 12312 10 func_abc.sh:- sh <- expand
+0 12312 17 func_abc.sh:20 func -> func_b
+0 12312 14 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 8 func_abc.sh:11 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 13 func_abc.sh:11 builtin -> echo
+0 12312 15 func_abc.sh:- sh -> echo
+0 12312 12 func_abc.sh:- syscall -> write
+0 12312 32 func_abc.sh:- syscall <- write
+0 12312 320 func_abc.sh:- sh <- echo
+0 12312 12 func_abc.sh:0 builtin <- echo
+0 12312 16 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 8 func_abc.sh:12 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 225 func_abc.sh:- syscall -> fork1
+0 12312 60940 func_abc.sh:- syscall <- fork1
+0 12312 243 func_abc.sh:- syscall -> lwp_sigmask
+0 12312 15 func_abc.sh:- syscall <- lwp_sigmask
+0 12312 31 func_abc.sh:12 cmd -> sleep
+0 12312 31 func_abc.sh:- syscall -> waitsys
+0 12312 1007422 func_abc.sh:- syscall <- waitsys
+0 12312 28 func_abc.sh:- syscall -> ioctl
+0 12312 17 func_abc.sh:- syscall <- ioctl
+0 12312 11 func_abc.sh:- syscall -> setpgrp
+0 12312 9 func_abc.sh:- syscall <- setpgrp
+0 12312 9 func_abc.sh:- syscall -> ioctl
+0 12312 9 func_abc.sh:- syscall <- ioctl
+0 12312 9 func_abc.sh:- syscall -> ioctl
+0 12312 38 func_abc.sh:- syscall <- ioctl
+0 12312 12 func_abc.sh:- syscall -> waitsys
+0 12312 26 func_abc.sh:- syscall <- waitsys
+0 12312 15 func_abc.sh:0 cmd <- sleep
+0 12312 32 func_abc.sh:- sh <- execute
+0 12312 15 func_abc.sh:- sh -> execute
+0 12312 14 func_abc.sh:13 line -- 
+0 12312 13 func_abc.sh:- sh -> estabf
+0 12312 10 func_abc.sh:- sh <- estabf
+0 12312 12 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 12 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> expand
+0 12312 10 func_abc.sh:- sh <- expand
+0 12312 17 func_abc.sh:13 func -> func_c
+0 12312 13 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 8 func_abc.sh:5 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 10 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 13 func_abc.sh:5 builtin -> echo
+0 12312 15 func_abc.sh:- sh -> echo
+0 12312 12 func_abc.sh:- syscall -> write
+0 12312 32 func_abc.sh:- syscall <- write
+0 12312 309 func_abc.sh:- sh <- echo
+0 12312 12 func_abc.sh:0 builtin <- echo
+0 12312 16 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:6 line -- 
+0 12312 8 func_abc.sh:- sh -> estabf
+0 12312 22 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 11 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 9 func_abc.sh:- sh -> estabf
+0 12312 9 func_abc.sh:- sh <- estabf
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 9 func_abc.sh:- sh -> expand
+0 12312 9 func_abc.sh:- sh <- expand
+0 12312 220 func_abc.sh:- syscall -> fork1
+0 12312 60982 func_abc.sh:- syscall <- fork1
+0 12312 239 func_abc.sh:- syscall -> lwp_sigmask
+0 12312 15 func_abc.sh:- syscall <- lwp_sigmask
+0 12312 30 func_abc.sh:6 cmd -> sleep
+0 12312 30 func_abc.sh:- syscall -> waitsys
+0 12312 1007259 func_abc.sh:- syscall <- waitsys
+0 12312 29 func_abc.sh:- syscall -> ioctl
+0 12312 17 func_abc.sh:- syscall <- ioctl
+0 12312 11 func_abc.sh:- syscall -> setpgrp
+0 12312 9 func_abc.sh:- syscall <- setpgrp
+0 12312 9 func_abc.sh:- syscall -> ioctl
+0 12312 9 func_abc.sh:- syscall <- ioctl
+0 12312 9 func_abc.sh:- syscall -> ioctl
+0 12312 35 func_abc.sh:- syscall <- ioctl
+0 12312 12 func_abc.sh:- syscall -> waitsys
+0 12312 25 func_abc.sh:- syscall <- waitsys
+0 12312 15 func_abc.sh:0 cmd <- sleep
+0 12312 31 func_abc.sh:- sh <- execute
+0 12312 13 func_abc.sh:- sh <- execute
+0 12312 11 func_abc.sh:- func <- func_c
+0 12312 14 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- func <- func_b
+0 12312 10 func_abc.sh:- sh <- execute
+0 12312 18 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 9 func_abc.sh:- func <- func_a
+0 12312 9 func_abc.sh:- sh <- execute
+0 12312 12 func_abc.sh:- syscall -> brk
+0 12312 11 func_abc.sh:- syscall <- brk
+0 12312 12 func_abc.sh:- syscall -> read
+0 12312 16 func_abc.sh:- syscall <- read
+0 12312 10 func_abc.sh:- syscall -> ioctl
+0 12312 9 func_abc.sh:- syscall <- ioctl
+0 12312 10 func_abc.sh:- syscall -> ioctl
+0 12312 8 func_abc.sh:- syscall <- ioctl
+0 12312 11 func_abc.sh:- syscall -> close
+0 12312 13 func_abc.sh:- syscall <- close
+0 12312 12 func_abc.sh:- sh -> endjobs
+0 12312 14 func_abc.sh:- sh <- endjobs
+0 12312 10 func_abc.sh:- sh <- exfile
+0 12312 11 func_abc.sh:- sh -> endjobs
+0 12312 9 func_abc.sh:- sh <- endjobs
+0 12312 37 func_abc.sh:- syscall -> open64
+0 12312 103 func_abc.sh:- syscall <- open64
+0 12312 11 func_abc.sh:- syscall -> ioctl
+0 12312 11 func_abc.sh:- syscall <- ioctl
+0 12312 11 func_abc.sh:- syscall -> close
+0 12312 15 func_abc.sh:- syscall <- close
+0 12312 32 func_abc.sh:- syscall -> rexit
+
+Here you can see the output showing the path the script follows as it is
+executed.
+
+At the end of the sh_syscolor_example.txt file, you can see the steps that the
+script goes through when it runs func_a. The output contains the two
+consecutive lines:
+
+0 12979 14 func_abc.sh:23 line -- 
+0 12979 32 func_abc.sh:23 func -> func_a
+
+Here we trace many more events that happen in between these two lines, as seen
+below:
+
+0 12312 9 func_abc.sh:23 line -- 
+0 12312 14 func_abc.sh:- sh -> estabf
+0 12312 10 func_abc.sh:- sh <- estabf
+0 12312 10 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 18 func_abc.sh:- sh -> endstak
+0 12312 9 func_abc.sh:- sh <- endstak
+0 12312 12 func_abc.sh:- sh -> expand
+0 12312 10 func_abc.sh:- sh <- expand
+0 12312 14 func_abc.sh:23 func -> func_a
+0 12312 14 func_abc.sh:- sh -> execute
+0 12312 9 func_abc.sh:- sh -> execute
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_stat_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_stat_example.txt
new file mode 100644
index 0000000..a44a563
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_stat_example.txt
@@ -0,0 +1,44 @@
+Following are examples of running sh_stat.d on Shell scripts.
+
+sh_stat.d shows you the number of events per second that have happened since
+the last line output. The default interval is 1 second, but you can specify
+other intervals as arguments to the script.
+
+This shows the sh_stat.d script reflecting the Code/Shell/func_slow.sh script.
+
+ # sh_stat.d
+ TIME EXEC/s FUNCS/s BLTINS/s SUB-SH/s CMD/s
+ 2007 Sep 17 03:29:02 1 1 50 96 0
+ 2007 Sep 17 03:29:03 0 1 151 300 0
+ 2007 Sep 17 03:29:04 0 1 142 280 0
+ 2007 Sep 17 03:29:05 0 0 132 262 0
+ 2007 Sep 17 03:29:06 0 0 122 245 0
+ 2007 Sep 17 03:29:07 0 0 9 17 0
+ 2007 Sep 17 03:29:08 0 0 0 0 0
+ 2007 Sep 17 03:29:09 0 0 0 0 0
+ ^C
+
+We can see that at 2007 Sep 17 03:29:04 there were 0 Bourne shells executed,
+one function called, 142 built-in commands called, 280 sub-shells created and
+0 external commands called.
+
+
+Here the script runs when Mozilla Firefox is started.
+
+ # sh_stat.d
+ TIME EXEC/s FUNCS/s BLTINS/s SUB-SH/s CMD/s
+ 2007 Sep 17 03:29:52 1 9 52 38 2
+ 2007 Sep 17 03:29:53 0 0 0 0 0
+ 2007 Sep 17 03:29:54 0 0 0 0 0
+ 2007 Sep 17 03:29:55 0 0 0 0 0
+ 2007 Sep 17 03:29:56 0 0 0 0 0
+ 2007 Sep 17 03:29:57 0 0 0 0 0
+ 2007 Sep 17 03:29:58 0 0 0 0 0
+ 2007 Sep 17 03:29:59 0 0 0 0 0
+ 2007 Sep 17 03:30:00 0 0 0 0 0
+ 2007 Sep 17 03:30:01 1 1 8 0 0
+ 2007 Sep 17 03:30:02 0 0 0 0 0
+ 2007 Sep 17 03:30:03 0 0 0 0 0
+ 2007 Sep 17 03:30:04 0 0 0 0 0
+ ^C
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_syscalls_example.txt
new file mode 100644
index 0000000..fbda095
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_syscalls_example.txt
@@ -0,0 +1,59 @@
+The following are examples of sh_syscalls.d.
+
+This is a simple script to count Shell functions, built-ins, external command
+executions and system calls. Here we trace an example program -
+Code/Shell/func_abc.sh.
+
+# sh_syscalls.d -c ./func_abc.sh -o /tmp/out
+Function A
+Function B
+Function C
+
+# cat /tmp/out
+Tracing... Hit Ctrl-C to end.
+
+Calls for PID 12966,
+
+ FILE TYPE NAME COUNT
+ func_abc.sh func func_a 1
+ func_abc.sh func func_b 1
+ func_abc.sh func func_c 1
+ func_abc.sh syscall getrlimit 1
+ func_abc.sh syscall mmap 1
+ func_abc.sh syscall munmap 1
+ func_abc.sh syscall rexit 1
+ func_abc.sh syscall schedctl 1
+ func_abc.sh syscall sigaltstack 1
+ func_abc.sh syscall stat64 1
+ func_abc.sh syscall sysi86 1
+ func_abc.sh syscall access 2
+ func_abc.sh syscall fcntl 2
+ func_abc.sh syscall getgid 2
+ func_abc.sh syscall getpid 2
+ func_abc.sh syscall setcontext 2
+ func_abc.sh syscall sysconfig 2
+ func_abc.sh builtin echo 3
+ func_abc.sh cmd sleep 3
+ func_abc.sh syscall fork1 3
+ func_abc.sh syscall getuid 3
+ func_abc.sh syscall lwp_sigmask 3
+ func_abc.sh syscall open64 3
+ func_abc.sh syscall read 3
+ func_abc.sh syscall write 3
+ func_abc.sh syscall close 5
+ func_abc.sh syscall setpgrp 5
+ func_abc.sh syscall waitsys 6
+ func_abc.sh syscall brk 9
+ func_abc.sh syscall ioctl 15
+ func_abc.sh syscall sigaction 53
+
+While tracing, three functions were called - func_a(), func_b() and
+func_c(). There were 3 instances of the shell built-in 'echo' being called,
+and 3 executions of the sleep command (which is probably /usr/bin/sleep - use
+the syscall provider to confirm). There were numerous system calls made,
+including 9 brk()'s, 15 ioctl()'s and 53 sigaction()'s.
+
+This script can provide an insight to how a script is interacting
+with the system, by providing function calls, commands, built-ins and system
+calls in the same output.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_syscolors_example.txt
new file mode 100644
index 0000000..ccc722a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_syscolors_example.txt
@@ -0,0 +1,328 @@
+The following are examples of sh_syscolors.d.
+
+This is a simple script to trace the flow of Shell functions, lines, and
+system calls made. It renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Shell/func_abc.sh.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# sh_syscolors.d -c ./func_abc.sh -o /tmp/out
+Function A
+Function B
+Function C
+
+# cat /tmp/out
+C PID DELTA(us) FILE:LINE TYPE -- NAME
+0 12979 2 func_abc.sh:- syscall -> munmap
+0 12979 35 func_abc.sh:- syscall <- munmap
+0 12979 56 func_abc.sh:- syscall -> mmap
+0 12979 18 func_abc.sh:- syscall <- mmap
+0 12979 40 func_abc.sh:- syscall -> setcontext
+0 12979 11 func_abc.sh:- syscall <- setcontext
+0 12979 11 func_abc.sh:- syscall -> getrlimit
+0 12979 11 func_abc.sh:- syscall <- getrlimit
+0 12979 10 func_abc.sh:- syscall -> getpid
+0 12979 9 func_abc.sh:- syscall <- getpid
+0 12979 61 func_abc.sh:- syscall -> setcontext
+0 12979 9 func_abc.sh:- syscall <- setcontext
+0 12979 865 func_abc.sh:- syscall -> sysi86
+0 12979 14 func_abc.sh:- syscall <- sysi86
+0 12979 84 func_abc.sh:- syscall -> open64
+0 12979 89 func_abc.sh:- syscall <- open64
+0 12979 14 func_abc.sh:- syscall -> ioctl
+0 12979 35 func_abc.sh:- syscall <- ioctl
+0 12979 15 func_abc.sh:- syscall -> close
+0 12979 16 func_abc.sh:- syscall <- close
+0 12979 119 func_abc.sh:- syscall -> getpid
+0 12979 10 func_abc.sh:- syscall <- getpid
+0 12979 17 func_abc.sh:- syscall -> setpgrp
+0 12979 10 func_abc.sh:- syscall <- setpgrp
+0 12979 11 func_abc.sh:- syscall -> setpgrp
+0 12979 8 func_abc.sh:- syscall <- setpgrp
+0 12979 12 func_abc.sh:- syscall -> access
+0 12979 20 func_abc.sh:- syscall <- access
+0 12979 15 func_abc.sh:- syscall -> brk
+0 12979 11 func_abc.sh:- syscall <- brk
+0 12979 15 func_abc.sh:- syscall -> sysconfig
+0 12979 9 func_abc.sh:- syscall <- sysconfig
+0 12979 9 func_abc.sh:- syscall -> sysconfig
+0 12979 9 func_abc.sh:- syscall <- sysconfig
+0 12979 11 func_abc.sh:- syscall -> sigaltstack
+0 12979 9 func_abc.sh:- syscall <- sigaltstack
+0 12979 16 func_abc.sh:- syscall -> sigaction
+0 12979 10 func_abc.sh:- syscall <- sigaction
+0 12979 12 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 10 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 10 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 10 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 9 func_abc.sh:- syscall -> sigaction
+0 12979 8 func_abc.sh:- syscall <- sigaction
+0 12979 10 func_abc.sh:- syscall -> sigaction
+0 12979 9 func_abc.sh:- syscall <- sigaction
+0 12979 61 func_abc.sh:- syscall -> brk
+0 12979 9 func_abc.sh:- syscall <- brk
+0 12979 13 func_abc.sh:- syscall -> getuid
+0 12979 9 func_abc.sh:- syscall <- getuid
+0 12979 10 func_abc.sh:- syscall -> getuid
+0 12979 8 func_abc.sh:- syscall <- getuid
+0 12979 11 func_abc.sh:- syscall -> getgid
+0 12979 9 func_abc.sh:- syscall <- getgid
+0 12979 10 func_abc.sh:- syscall -> getgid
+0 12979 9 func_abc.sh:- syscall <- getgid
+0 12979 15 func_abc.sh:- syscall -> open64
+0 12979 19 func_abc.sh:- syscall <- open64
+0 12979 11 func_abc.sh:- syscall -> close
+0 12979 9 func_abc.sh:- syscall <- close
+0 12979 24 func_abc.sh:- syscall -> fcntl
+0 12979 23 func_abc.sh:- syscall <- fcntl
+0 12979 10 func_abc.sh:- syscall -> close
+0 12979 10 func_abc.sh:- syscall <- close
+0 12979 9 func_abc.sh:- syscall -> fcntl
+0 12979 9 func_abc.sh:- syscall <- fcntl
+0 12979 28 func_abc.sh:- syscall -> ioctl
+0 12979 42 func_abc.sh:- syscall <- ioctl
+0 12979 10 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 14 func_abc.sh:- syscall -> read
+0 12979 33 func_abc.sh:- syscall <- read
+0 12979 11 func_abc.sh:- syscall -> brk
+0 12979 21 func_abc.sh:- syscall <- brk
+0 12979 12 func_abc.sh:- syscall -> brk
+0 12979 9 func_abc.sh:- syscall <- brk
+0 12979 19 func_abc.sh:- syscall -> brk
+0 12979 9 func_abc.sh:- syscall <- brk
+0 12979 11 func_abc.sh:- syscall -> brk
+0 12979 9 func_abc.sh:- syscall <- brk
+0 12979 11 func_abc.sh:- syscall -> read
+0 12979 15 func_abc.sh:- syscall <- read
+0 12979 28 func_abc.sh:- syscall -> brk
+0 12979 9 func_abc.sh:- syscall <- brk
+0 12979 10 func_abc.sh:- syscall -> brk
+0 12979 8 func_abc.sh:- syscall <- brk
+0 12979 14 func_abc.sh:23 line -- 
+0 12979 32 func_abc.sh:23 func -> func_a
+0 12979 16 func_abc.sh:18 line -- 
+0 12979 18 func_abc.sh:18 builtin -> echo
+0 12979 21 func_abc.sh:- syscall -> write
+0 12979 33 func_abc.sh:- syscall <- write
+0 12979 311 func_abc.sh:0 builtin <- echo
+0 12979 65 func_abc.sh:19 line -- 
+0 12979 17 func_abc.sh:- syscall -> getuid
+0 12979 10 func_abc.sh:- syscall <- getuid
+0 12979 15 func_abc.sh:- syscall -> stat64
+0 12979 25 func_abc.sh:- syscall <- stat64
+0 12979 11 func_abc.sh:- syscall -> access
+0 12979 15 func_abc.sh:- syscall <- access
+0 12979 18 func_abc.sh:- syscall -> schedctl
+0 12979 46 func_abc.sh:- syscall <- schedctl
+0 12979 220 func_abc.sh:- syscall -> fork1
+0 12979 258957 func_abc.sh:- syscall <- fork1
+0 12979 244 func_abc.sh:- syscall -> lwp_sigmask
+0 12979 16 func_abc.sh:- syscall <- lwp_sigmask
+0 12979 31 func_abc.sh:19 cmd -> sleep
+0 12979 53 func_abc.sh:- syscall -> waitsys
+0 12979 1008036 func_abc.sh:- syscall <- waitsys
+0 12979 38 func_abc.sh:- syscall -> ioctl
+0 12979 18 func_abc.sh:- syscall <- ioctl
+0 12979 12 func_abc.sh:- syscall -> setpgrp
+0 12979 10 func_abc.sh:- syscall <- setpgrp
+0 12979 9 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> ioctl
+0 12979 37 func_abc.sh:- syscall <- ioctl
+0 12979 12 func_abc.sh:- syscall -> waitsys
+0 12979 26 func_abc.sh:- syscall <- waitsys
+0 12979 14 func_abc.sh:0 cmd <- sleep
+0 12979 21 func_abc.sh:20 line -- 
+0 12979 28 func_abc.sh:20 func -> func_b
+0 12979 15 func_abc.sh:11 line -- 
+0 12979 17 func_abc.sh:11 builtin -> echo
+0 12979 19 func_abc.sh:- syscall -> write
+0 12979 33 func_abc.sh:- syscall <- write
+0 12979 310 func_abc.sh:0 builtin <- echo
+0 12979 16 func_abc.sh:12 line -- 
+0 12979 226 func_abc.sh:- syscall -> fork1
+0 12979 64931 func_abc.sh:- syscall <- fork1
+0 12979 262 func_abc.sh:- syscall -> lwp_sigmask
+0 12979 16 func_abc.sh:- syscall <- lwp_sigmask
+0 12979 31 func_abc.sh:12 cmd -> sleep
+0 12979 31 func_abc.sh:- syscall -> waitsys
+0 12979 1003941 func_abc.sh:- syscall <- waitsys
+0 12979 30 func_abc.sh:- syscall -> ioctl
+0 12979 19 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> setpgrp
+0 12979 9 func_abc.sh:- syscall <- setpgrp
+0 12979 9 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 9 func_abc.sh:- syscall -> ioctl
+0 12979 38 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> waitsys
+0 12979 26 func_abc.sh:- syscall <- waitsys
+0 12979 14 func_abc.sh:0 cmd <- sleep
+0 12979 33 func_abc.sh:13 line -- 
+0 12979 27 func_abc.sh:13 func -> func_c
+0 12979 15 func_abc.sh:5 line -- 
+0 12979 17 func_abc.sh:5 builtin -> echo
+0 12979 20 func_abc.sh:- syscall -> write
+0 12979 33 func_abc.sh:- syscall <- write
+0 12979 309 func_abc.sh:0 builtin <- echo
+0 12979 17 func_abc.sh:6 line -- 
+0 12979 267 func_abc.sh:- syscall -> fork1
+0 12979 64649 func_abc.sh:- syscall <- fork1
+0 12979 257 func_abc.sh:- syscall -> lwp_sigmask
+0 12979 16 func_abc.sh:- syscall <- lwp_sigmask
+0 12979 31 func_abc.sh:6 cmd -> sleep
+0 12979 31 func_abc.sh:- syscall -> waitsys
+0 12979 1004183 func_abc.sh:- syscall <- waitsys
+0 12979 31 func_abc.sh:- syscall -> ioctl
+0 12979 18 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> setpgrp
+0 12979 9 func_abc.sh:- syscall <- setpgrp
+0 12979 9 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 9 func_abc.sh:- syscall -> ioctl
+0 12979 38 func_abc.sh:- syscall <- ioctl
+0 12979 12 func_abc.sh:- syscall -> waitsys
+0 12979 27 func_abc.sh:- syscall <- waitsys
+0 12979 14 func_abc.sh:0 cmd <- sleep
+0 12979 32 func_abc.sh:- func <- func_c
+0 12979 16 func_abc.sh:- func <- func_b
+0 12979 10 func_abc.sh:- func <- func_a
+0 12979 13 func_abc.sh:- syscall -> brk
+0 12979 12 func_abc.sh:- syscall <- brk
+0 12979 12 func_abc.sh:- syscall -> read
+0 12979 16 func_abc.sh:- syscall <- read
+0 12979 10 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 10 func_abc.sh:- syscall -> ioctl
+0 12979 9 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> close
+0 12979 13 func_abc.sh:- syscall <- close
+0 12979 37 func_abc.sh:- syscall -> open64
+0 12979 105 func_abc.sh:- syscall <- open64
+0 12979 11 func_abc.sh:- syscall -> ioctl
+0 12979 11 func_abc.sh:- syscall <- ioctl
+0 12979 11 func_abc.sh:- syscall -> close
+0 12979 15 func_abc.sh:- syscall <- close
+0 12979 31 func_abc.sh:- syscall -> rexit
+
+Here you can see the output showing the path the script follows as it is
+executed.
+
+ie:
+0 12979 14 func_abc.sh:23 line -- 
+0 12979 32 func_abc.sh:23 func -> func_a
+0 12979 16 func_abc.sh:18 line -- 
+0 12979 18 func_abc.sh:18 builtin -> echo
+0 12979 21 func_abc.sh:- syscall -> write
+0 12979 33 func_abc.sh:- syscall <- write
+0 12979 311 func_abc.sh:0 builtin <- echo
+0 12979 65 func_abc.sh:19 line -- 
+
+shows that on CPU 0 we run func_a (which is line 23 of the example script),
+where it uses the shell built-in echo command (on line 18 of the example
+script) to write a line of text to the screen. You can see in column 3 (the
+delta time) it takes 311 microseconds from when the write syscall finishes to
+when the echo built-in completes its clean-up and finishes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_wasted_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_wasted_example.txt
new file mode 100644
index 0000000..b11f952
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_wasted_example.txt
@@ -0,0 +1,45 @@
+Many shell programmers are in the habit of using calls to external commands
+instead of using shell built-in commands (an example of this is a call to
+usr/bin/echo instead of using the echo command built into the shell.
+
+This script shows sh_wasted.d tracing a shell script that calls /usr/bin/echo
+instead of using the built-in.
+
+# sh_wasted.d -c ./func_waste.sh
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+Script duration: 3101631 us
+
+External command elapsed times,
+ FILE NAME TIME(us)
+ func_waste.sh sleep 3019573
+
+Wasted command elapsed times,
+ FILE NAME TIME(us)
+ func_waste.sh /usr/bin/echo 26510
+
+You can see that the calls to /usr/bin/echo took around 26 thousand
+microseconds; time wasted by the shell having to access an external command.
+
+
+Here we trace the same script, except it uses the shell built-in echo command.
+
+# sh_wasted.d -c ./func_abc.sh
+Function A
+Tracing... Hit Ctrl-C to end.
+Function B
+Function C
+Script duration: 3032616 us
+
+External command elapsed times,
+ FILE NAME TIME(us)
+ func_abc.sh sleep 3012920
+
+Wasted command elapsed times,
+ FILE NAME TIME(us)
+
+The total time here is less and there are no 'wasted' calls to external
+commands.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sh_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/sh_who_example.txt
new file mode 100644
index 0000000..b35e8e4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sh_who_example.txt
@@ -0,0 +1,45 @@
+These are examples of the results after running the sh_who.d script.
+
+This script shows which UIDs and PIDs are running shell scripts, and how
+active they are. It measures the number of lines executed according to
+the line probe - which is a useful, but rough measure of shell activity.
+
+Here it runs as a script executes three times.
+
+# sh_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID LINES FILE
+ 13663 0 9 ./func_abc.sh
+ 13667 0 9 ./func_abc.sh
+ 13671 0 9 ./func_abc.sh
+
+We see func_abc.sh ran three seperate times, each with nine lines of shell
+activity.
+
+
+Here we trace an instance of starting Mozilla Firefox.
+
+# sh_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID LINES FILE
+ 13678 100 1 firefox
+ 13679 100 1 firefox
+ 13680 100 1 firefox
+ 13681 100 1 firefox
+ 13683 100 1 firefox
+ 13685 100 1 firefox
+ 13686 100 1 firefox
+ 13687 100 1 firefox
+ 13690 100 1 firefox
+ 13693 100 1 /usr/lib/firefox/run-mozilla.sh
+ 13694 100 1 /usr/lib/firefox/run-mozilla.sh
+ 13695 100 1 /usr/lib/firefox/run-mozilla.sh
+ 13692 100 55 /usr/lib/firefox/run-mozilla.sh
+ 13677 100 75 firefox
+
+Firefox itself (PID 13677) ran 75 lines of code. There are also instances of
+firefox running a single line of code with a different PID each time. These
+are probably calls to subshells. Use the sh provider to confirm.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/shellsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/shellsnoop_example.txt
new file mode 100644
index 0000000..be307f8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/shellsnoop_example.txt
@@ -0,0 +1,112 @@
+shellsnoop captures the text input and output from shells running on the
+system. In the following example shellsnoop was run in one window, while
+in another several commands were run: date, cal, uname -a, uptime and find.
+shellsnoop has successfully captured the text that was displayed on the
+other window.
+
+
+# shellsnoop
+ PID PPID CMD DIR TEXT
+ 4724 3762 ksh R
+ 4724 3762 ksh W date
+
+ 4741 4724 date W Sun Mar 28 23:10:06 EST 2004
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W cal
+
+ 4742 4724 cal W March 2004
+ 4742 4724 cal W S M Tu W Th F S
+ 4742 4724 cal W 1 2 3 4 5 6
+ 4742 4724 cal W 7 8 9 10 11 12 13
+ 4742 4724 cal W 14 15 16 17 18 19 20
+ 4742 4724 cal W 21 22 23 24 25 26 27
+ 4742 4724 cal W 28 29 30 31
+ 4742 4724 cal W
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W uname -a
+
+ 4743 4724 uname W SunOS jupiter 5.10 s10_51 i86pc i386 i86pc
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W uptime
+
+ 4744 4724 uptime W 11:10pm up 4 day(s), 11:15, 4 users, load average: 0.05, 0.02, 0.02
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W ls -l d*
+
+ 4745 4724 ls W -rwxr--r-- 3 root sys 1292 Jan 14 16:24 devfsadm
+ 4745 4724 ls W -rwxr--r-- 1 root sys 904 Jan 14 16:24 devlinks
+ 4745 4724 ls W -rwxr--r-- 6 root sys 621 Jan 14 16:17 dhcp
+ 4745 4724 ls W -rwxr--r-- 2 root sys 494 Jan 14 16:17 dhcpagent
+ 4745 4724 ls W -rwxr--r-- 5 root sys 1050 Jan 16 2002 directory
+ 4745 4724 ls W -rwxr--r-- 2 root sys 779 Jan 14 16:17 domainname
+ 4745 4724 ls W -rwxr--r-- 1 root sys 469 Jan 14 16:24 drvconfig
+ 4745 4724 ls W -r-xr-xr-x 4 root other 2804 Mar 27 13:37 dtlogin
+ 4724 3762 ksh R
+ 4724 3762 ksh W jupiter:/etc/init.d>
+ 4724 3762 ksh R
+ 4724 3762 ksh R
+ 4724 3762 ksh W find /etc/default
+
+ 4746 4724 find W /etc/default
+ 4746 4724 find W /etc/default/cron
+ 4746 4724 find W /etc/default/devfsadm
+ 4746 4724 find W /etc/default/dhcpagent
+ 4746 4724 find W /etc/default/fs
+ 4746 4724 find W /etc/default/inetd
+ 4746 4724 find W /etc/default/inetinit
+ 4746 4724 find W /etc/default/kbd
+ 4746 4724 find W /etc/default/keyserv
+ 4746 4724 find W /etc/default/ipsec
+ 4746 4724 find W /etc/default/nss
+ 4746 4724 find W /etc/default/passwd
+ 4746 4724 find W /etc/default/syslogd
+ 4746 4724 find W /etc/default/tar
+ 4746 4724 find W /etc/default/utmpd
+ 4746 4724 find W /etc/default/init
+ 4746 4724 find W /etc/default/login
+ 4746 4724 find W /etc/default/su
+ 4746 4724 find W /etc/default/power
+ 4746 4724 find W /etc/default/sys-suspend
+ 4746 4724 find W /etc/default/rpc.nisd
+ 4746 4724 find W /etc/default/nfs
+[...]
+
+
+
+shellsnoop has a "-q" option for running in "quiet" mode - the previous
+columns are not printed, so only shell output is seen,
+
+ # shellsnoop -q
+ # date
+ Wed Nov 30 16:19:48 EST 2005
+ #
+ # cal
+ November 2005
+ S M Tu W Th F S
+ 1 2 3 4 5
+ 6 7 8 9 10 11 12
+ 13 14 15 16 17 18 19
+ 20 21 22 23 24 25 26
+ 27 28 29 30
+
+ #
+
+The output appears somewhat boring, this is something you need to see
+in realtime.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/shortlived_example.txt b/cddl/contrib/dtracetoolkit/Examples/shortlived_example.txt
new file mode 100644
index 0000000..ebe4692
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/shortlived_example.txt
@@ -0,0 +1,57 @@
+The following is an example of the shortlived.d program.
+It can measure time spent processing short lived processes,
+that may be responsible for heavy load on the system but
+are usually difficult to see with sampling tools like prstat.
+
+
+
+Here we run in for a few seconds on a server,
+
+ # shortlived.d
+ Tracing... Hit Ctrl-C to stop.
+ ^C
+ short lived processes: 0.456 secs
+ total sample duration: 9.352 secs
+
+ Total time by process name,
+ date 12 ms
+ df 20 ms
+ ls 40 ms
+ perl 380 ms
+
+ Total time by PPID,
+ 3279 452 ms
+
+In the above output, around 5% of the CPU was lost to short
+lived processes - mostly perl. This may be many perl processes,
+here we are aggregating on the process name not the instance.
+
+
+
+Now shortlived.d is run on a server with a performance problem,
+
+ # uptime
+ 10:58pm up 5 day(s), 1:28, 1 user, load average: 2.20, 1.81, 1.04
+ #
+ # shortlived.d
+ Tracing... Hit Ctrl-C to stop.
+ ^C
+ short lived processes: 4.546 secs
+ total sample duration: 9.858 secs
+
+ Total time by process name,
+ expr 4122 ms
+
+ Total time by PPID,
+ 3279 4122 ms
+ #
+ # ps -p 3279
+ PID TTY TIME CMD
+ 3279 pts/10 0:45 report.sh
+
+shortlived.d showed that 50% of the CPU was consumed by short lived
+processes, all of them the "expr" command, and all having the
+parent proccess-ID 3279. We finished by checking PID 3279 to find
+it is a Bourne shell script called "report.sh".
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sigdist_example.txt b/cddl/contrib/dtracetoolkit/Examples/sigdist_example.txt
new file mode 100644
index 0000000..88b9df4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sigdist_example.txt
@@ -0,0 +1,18 @@
+The following is a demonstration of the sigdist.d script.
+
+
+Here we run sigdist.d, and in another window we kill -9 a sleep process,
+
+ # ./sigdist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ SENDER RECIPIENT SIG COUNT
+ sched dtrace 2 1
+ sched bash 18 1
+ bash sleep 9 1
+ sched Xorg 14 55
+
+We can see the signal sent from bash to sleep. We can also see that Xorg
+has recieved 55 signal 14s. a "man -s3head signal" may help explain what
+signal 14 is (alarm clock).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/stacksize_example.txt b/cddl/contrib/dtracetoolkit/Examples/stacksize_example.txt
new file mode 100644
index 0000000..156f351
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/stacksize_example.txt
@@ -0,0 +1,87 @@
+The following is a domonstration of the stacksize.d script.
+
+
+Here it is run for a few seconds then Ctrl-C is hit. The output prints
+distrubition plots of the size of the user stack as the value, and the
+number of times sampled at that size as the count.
+
+ # ./stacksize.d
+ Sampling... Hit Ctrl-C to end
+
+
+ automountd
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ nscd
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 256 | 0
+
+ svc.startd
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 512 | 0
+
+ sshd
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4096 | 0
+
+ dtrace
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2048 | 0
+
+ nautilus
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4096 | 0
+
+ Xvnc
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 4096 | 0
+
+ gnome-vfs-daemon
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 8192 | 0
+
+ Xorg
+ value ------------- Distribution ------------- count
+ 2048 | 0
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 8192 | 0
+
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@ 7
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 8192 | 0
+
+ acroread
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 92
+ 4096 | 0
+
+ perl
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1945
+ 2048 | 0
+
+
+ Errors:
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/statsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/statsnoop_example.txt
new file mode 100644
index 0000000..842017e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/statsnoop_example.txt
@@ -0,0 +1,94 @@
+The following is an example of the statsnoop tool.
+
+
+statsnoop is a companion to opensnoop, which traces a variety of stat()
+calls rather than open() calls.
+
+Here I run statsnoop on my idle laptop for about 3 seconds,
+
+ # statsnoop
+ UID PID COMM FD PATH
+ 0 1485 dtrace 0 /devices/pseudo/pts@0:6
+ 100 791 dtwm -1 /usr/mail/brendan
+ 100 791 dtwm -1 /usr/mail/brendan
+ 100 791 dtwm -1 /usr/mail/brendan
+ 100 791 dtwm -1 /usr/mail/brendan
+ 100 795 sdtperfmeter 0 /devices/pseudo/mm@0:null
+ 0 803 rpc.rstatd 0 /devices/pseudo/udp@0:udp
+ 0 803 rpc.rstatd 0 /devices/pseudo/udp@0:udp
+ 100 795 sdtperfmeter 0 /devices/pseudo/mm@0:null
+ 100 791 dtwm 0 /export/home/brendan/.dt/Trash/.trashinfo
+ 100 791 dtwm 0 /export/home/brendan/.dt/Trash/.trashinfo
+ 100 791 dtwm 0 /devices/pseudo/mm@0:null
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ 100 791 dtwm 0 /devices/pseudo/mm@0:null
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ 100 791 dtwm 0 /devices/pseudo/mm@0:null
+ 100 791 dtwm 0 /devices/pseudo/mm@0:null
+ 100 792 dtfile 0 /devices/pseudo/mm@0:null
+ 100 783 ttsession 0 /devices/pseudo/pts@0:3
+ ^C
+
+It is interesting what turns up. In the above output, a "dtwm" process
+with process ID 791 called stat on /usr/mail/brendan and received -1 as
+a return value - as this file does not exist. (when were mailboxes ever
+stored in /usr/mail??).
+
+
+statsnoop has a variety of options, as opensnoop does. Here I trace stat()s
+from processes called "bash", while a new bash shell is executed,
+
+ # statsnoop -n bash
+ UID PID COMM FD PATH
+ 100 1493 bash 0 /usr/bin/bash
+ 100 1493 bash 0 /devices/pseudo/pts@0:8
+ 100 1493 bash 0 /lib/libcurses.so.1
+ 100 1493 bash 0 /lib/libsocket.so.1
+ 100 1493 bash 0 /lib/libnsl.so.1
+ 100 1493 bash 0 /lib/libdl.so.1
+ 100 1493 bash 0 /lib/libc.so.1
+ 100 1493 bash 0 /devices/pseudo/pts@0:8
+ 100 1493 bash 0 /devices/pseudo/pts@0:8
+ 100 1493 bash 0 /export/home/brendan
+ 100 1493 bash 0 .
+ 100 1493 bash 0 /export/home/brendan/.bashrc
+ 100 1493 bash -1 /usr/mail/brendan
+ 100 1493 bash 0 /export/home/brendan/.bash_history
+ 100 1493 bash 0 /export/home/brendan/.bash_history
+ 100 1493 bash 0 /export/home/brendan/.bash_history
+ 100 1493 bash -1 /export/home/brendan/.inputrc
+ 100 1493 bash 0 .
+ ^C
+
+bash also checked /usr/mail/brendan? hmm...
+
+ $ echo $MAIL
+ /usr/mail/brendan
+
+hmmmmm...
+
+ $ cat .profile
+ # This is the default standard profile provided to a user.
+ # They are expected to edit it to meet their own needs.
+
+ MAIL=/usr/mail/${LOGNAME:?}
+
+huh?
+
+ $ cat /etc/skel/.profile
+ # This is the default standard profile provided to a user.
+ # They are expected to edit it to meet their own needs.
+
+ MAIL=/usr/mail/${LOGNAME:?}
+
+ $ cat /var/sadm/pkg/SUNWcsr/save/pspool/SUNWcsr/reloc/etc/skel/.profile
+ # This is the default standard profile provided to a user.
+ # They are expected to edit it to meet their own needs.
+
+ MAIL=/usr/mail/${LOGNAME:?}
+
+oh.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/swapinfo_example.txt b/cddl/contrib/dtracetoolkit/Examples/swapinfo_example.txt
new file mode 100644
index 0000000..e869766
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/swapinfo_example.txt
@@ -0,0 +1,22 @@
+The following is a demonstration of the swapinfo.d script,
+
+ # ./swapinfo.d
+ RAM _______Total 511 MB
+ RAM Unusable 8 MB
+ RAM Kernel 128 MB
+ RAM Locked 0 MB
+ RAM Used 256 MB
+ RAM Free 118 MB
+
+ Disk _______Total 1023 MB
+ Disk Resv 626 MB
+ Disk Avail 397 MB
+
+ Swap _______Total 1335 MB
+ Swap Resv 626 MB
+ Swap Avail 709 MB
+ Swap (Minfree) 62 MB
+
+The output above gives a summary of the state of virtual memory (swap)
+on the system.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/sysbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/sysbypid_example.txt
new file mode 100644
index 0000000..2858c51
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/sysbypid_example.txt
@@ -0,0 +1,45 @@
+The following is a demonstration of the sysbypid.d command,
+
+ # sysbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ EXEC PID SYS VALUE
+ xterm 24030 rawch 1
+ sched 0 rcvint 1
+ fsflush 3 pswitch 1
+ dtrace 19235 inv_swtch 1
+ xterm 24030 syswrite 2
+ Xorg 3597 syswrite 2
+ xterm 24030 inv_swtch 2
+ dtrace 19235 pswitch 2
+ dtrace 19235 syswrite 2
+ soffice.bin 4019 pswitch 3
+ xterm 24030 pswitch 3
+ mozilla-bin 3730 inv_swtch 4
+ xterm 24030 sysread 4
+ mozilla-bin 3730 readch 9
+ mozilla-bin 3730 sysread 9
+ Xorg 3597 pswitch 10
+ Xorg 3597 sysread 11
+ mozilla-bin 3730 syswrite 13
+ java_vm 28209 pswitch 13
+ sched 0 pswitch 15
+ mozilla-bin 3730 pswitch 25
+ setiathome 3929 trap 26
+ setiathome 3929 pswitch 26
+ setiathome 3929 inv_swtch 26
+ dtrace 19235 writech 32
+ dtrace 19235 outch 34
+ dtrace 19235 trap 53
+ Xorg 3597 writech 64
+ xterm 24030 readch 96
+ xterm 24030 writech 133
+ mozilla-bin 3730 writech 905
+ Xorg 3597 readch 1044
+
+In the above output, the Xorg command with PID 3597 read 1044 bytes, as
+indicated by readch.
+
+mozilla-bin with PID 3730 wrote 905 bytes, as indicated by the writech.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/syscallbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/syscallbypid_example.txt
new file mode 100644
index 0000000..e51bb14
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/syscallbypid_example.txt
@@ -0,0 +1,50 @@
+The following is a demonstration of the syscallbypid.d script,
+
+
+Here we run syscallbypid.d for a few seconds then hit Ctrl-C,
+
+ # syscallbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD SYSCALL COUNT
+ 11039 dtrace setcontext 1
+ 11039 dtrace lwp_sigmask 1
+ 7 svc.startd portfs 1
+ 357 poold lwp_cond_wait 1
+ 27328 java_vm lwp_cond_wait 1
+ 1532 Xorg writev 1
+ 11039 dtrace lwp_park 1
+ 11039 dtrace schedctl 1
+ 11039 dtrace mmap 1
+ 361 sendmail pollsys 1
+ 11039 dtrace fstat64 1
+ 11039 dtrace sigaction 2
+ 11039 dtrace write 2
+ 361 sendmail lwp_sigmask 2
+ 1659 mozilla-bin yield 2
+ 11039 dtrace sysconfig 3
+ 361 sendmail pset 3
+ 20317 sshd read 4
+ 361 sendmail gtime 4
+ 20317 sshd write 4
+ 27328 java_vm ioctl 6
+ 11039 dtrace brk 8
+ 1532 Xorg setcontext 8
+ 1532 Xorg lwp_sigmask 8
+ 20317 sshd pollsys 8
+ 357 poold pollsys 13
+ 1659 mozilla-bin read 16
+ 20317 sshd lwp_sigmask 16
+ 1532 Xorg setitimer 17
+ 27328 java_vm pollsys 18
+ 1532 Xorg pollsys 19
+ 11039 dtrace p_online 21
+ 1532 Xorg read 22
+ 1659 mozilla-bin write 25
+ 1659 mozilla-bin lwp_park 26
+ 11039 dtrace ioctl 36
+ 1659 mozilla-bin pollsys 155
+ 1659 mozilla-bin ioctl 306
+
+In the above output, we can see that "mozilla-bin" with PID 1659 made the
+most system calls - 306 ioctl()s.
diff --git a/cddl/contrib/dtracetoolkit/Examples/syscallbyproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/syscallbyproc_example.txt
new file mode 100644
index 0000000..7469b79
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/syscallbyproc_example.txt
@@ -0,0 +1,17 @@
+The following is an example of the syscallbyproc.d script,
+
+ # syscallbyproc.d
+ dtrace: description 'syscall:::entry ' matched 228 probes
+ ^C
+ snmpd 1
+ utmpd 2
+ inetd 2
+ nscd 7
+ svc.startd 11
+ sendmail 31
+ poold 133
+ dtrace 1720
+
+The above output shows that dtrace made the most system calls in this sample,
+1720 syscalls.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/syscallbysysc_example.txt b/cddl/contrib/dtracetoolkit/Examples/syscallbysysc_example.txt
new file mode 100644
index 0000000..d131a17
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/syscallbysysc_example.txt
@@ -0,0 +1,24 @@
+The following is a demonstration of the syscallbysysc.d script,
+
+ # syscallbysysc.d
+ dtrace: description 'syscall:::entry ' matched 228 probes
+ ^C
+ fstat 1
+ setcontext 1
+ lwp_park 1
+ schedctl 1
+ mmap 1
+ sigaction 2
+ pset 2
+ lwp_sigmask 2
+ gtime 3
+ sysconfig 3
+ write 4
+ brk 6
+ pollsys 7
+ p_online 558
+ ioctl 579
+
+In the above output, the ioctl system call was the most common, occuring
+579 times.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_calldist_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_calldist_example.txt
new file mode 100644
index 0000000..3388963
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_calldist_example.txt
@@ -0,0 +1,166 @@
+The following are examples of tcl_calldist.d.
+
+This script traces the elapsed time of Tcl procedures and commands and
+prints a report containing distribution plots per function. Here it traces the
+example program, Code/Tcl/func_abc.tcl
+
+# tcl_calldist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 exclusive elapsed times (us),
+ PID=16033, cmd, namespace
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@@@@ 1
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ PID=16033, cmd, puts
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ PID=16033, cmd, tclInit
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ PID=16033, proc, func_a
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ PID=16033, proc, func_b
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ PID=16033, proc, func_c
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ PID=16033, cmd, file
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@ 2
+ 16 |@@@@@@@ 2
+ 32 |@@@ 1
+ 64 |@@@@@@@@@@ 3
+ 128 | 0
+
+ PID=16033, cmd, source
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ PID=16033, cmd, if
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@ 4
+ 32 |@@@@@@@@@@@@@@@ 3
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 |@@@@@ 1
+ 1024 | 0
+
+ PID=16033, cmd, after
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+
+Top 10 inclusive elapsed times (us),
+ PID=16033, cmd, uplevel
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=16033, cmd, tclInit
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ PID=16033, proc, tclInit
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ PID=16033, cmd, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ PID=16033, proc, func_c
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ PID=16033, cmd, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=16033, proc, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=16033, cmd, after
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1048576 | 0
+
+ PID=16033, cmd, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ PID=16033, proc, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+The exclusive function elapsed times show that each func_a took between 256
+and 511 microseconds. This time excludes the time spent in any other functions.
+
+The inclusive elapsed times section shows that each func_a spent
+took between 2.1 and 4.2 seconds. This time also includes the time spent in
+any other commands or procedures called by func_a.
+
+These elapsed times are the absolute time from when the function began to
+when it completed - which includes off-CPU time due to other system events
+such as I/O, scheduling, interrupts, etc.
+
+Elapsed times are useful for identifying where latencies are.
+See Notes/ALLelapsed_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_calls_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_calls_example.txt
new file mode 100644
index 0000000..5ffada4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_calls_example.txt
@@ -0,0 +1,41 @@
+The following are examples of the results of running the tcl_calls.d script.
+
+In this example we see it running while the Code/Tcl/func_abc.tcl script is run.
+
+# tcl_calls.d Tracing... Hit Ctrl-C to end.
+^C
+ PID TYPE NAME COUNT
+ 16021 cmd concat 1
+ 16021 cmd exit 1
+ 16021 cmd func_a 1
+ 16021 cmd func_b 1
+ 16021 cmd func_c 1
+ 16021 cmd list 1
+ 16021 cmd rename 1
+ 16021 cmd source 1
+ 16021 cmd tclInit 1
+ 16021 cmd unset 1
+ 16021 cmd uplevel 1
+ 16021 cmd variable 1
+ 16021 proc func_a 1
+ 16021 proc func_b 1
+ 16021 proc func_c 1
+ 16021 proc tclInit 1
+ 16021 cmd foreach 2
+ 16021 cmd global 2
+ 16021 cmd interp 2
+ 16021 cmd package 2
+ 16021 cmd set 2
+ 16021 cmd after 3
+ 16021 cmd namespace 3
+ 16021 cmd puts 3
+ 16021 cmd lappend 4
+ 16021 cmd lsearch 4
+ 16021 cmd if 8
+ 16021 cmd info 11
+ 16021 cmd file 12
+ 16021 cmd proc 12
+
+You can see that PID 16021 made quite a few different types of command and
+procedure calls during its execution.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_calltime_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_calltime_example.txt
new file mode 100644
index 0000000..56d100a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_calltime_example.txt
@@ -0,0 +1,61 @@
+The following are examples of tcl_calltime.d.
+
+This script traces the total elapsed time of different Tcl commands and
+procedures and prints a report. Here it traces the example program,
+Code/Tcl/func_abc.tcl
+
+# tcl_calltime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 counts,
+ PID TYPE NAME COUNT
+ 16028 cmd after 3
+ 16028 cmd namespace 3
+ 16028 cmd puts 3
+ 16028 cmd lappend 4
+ 16028 cmd lsearch 4
+ 16028 cmd if 8
+ 16028 cmd info 11
+ 16028 cmd file 12
+ 16028 cmd proc 12
+ 0 total - 85
+
+Top 10 exclusive elapsed times (us),
+ PID TYPE NAME TOTAL
+ 16028 cmd tclInit 253
+ 16028 cmd namespace 272
+ 16028 proc func_c 330
+ 16028 proc func_b 357
+ 16028 proc func_a 363
+ 16028 cmd file 416
+ 16028 cmd if 852
+ 16028 cmd source 929
+ 16028 cmd after 3025152
+ 0 total - 3030001
+
+Top 10 inclusive elapsed times (us),
+ PID TYPE NAME TOTAL
+ 16028 cmd uplevel 1849
+ 16028 proc tclInit 2519
+ 16028 cmd tclInit 2772
+ 16028 proc func_c 1010031
+ 16028 cmd func_c 1010088
+ 16028 proc func_b 2020059
+ 16028 cmd func_b 2020106
+ 16028 cmd after 3025152
+ 16028 proc func_a 3026545
+ 16028 cmd func_a 3026572
+
+The output is in three sections. The first shows the top ten most executed
+commands while the script is tracing.
+
+The second (Top 10 exclusive elapsed times) shows us the top ten slowest
+commands or procedures, this number excludes any subroutines called during
+command execution.
+
+The third (Top 10 inclusive elapsed times) shows us the top ten slowest
+commands or procedures including any time spent in subroutines. You can see
+that func_a took the most amount of time all up. This makes sense if you
+compare the code at Code/Tcl/func_abc.tcl with the results.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_cpudist_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_cpudist_example.txt
new file mode 100644
index 0000000..09126f6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_cpudist_example.txt
@@ -0,0 +1,164 @@
+The following are examples of tcl_cpudist.d.
+
+This script traces the on-CPU time of Tcl commands and procedures and
+prints a report containing distribution plots per subroutine. Here it
+traces the example program, Code/Tcl/func_slow.tcl.
+
+# tcl_cpudist.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 exclusive on-CPU times (us),
+ PID=16043, cmd, info
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@ 1
+ 2 |@@@@@@@@@@@@@@@ 4
+ 4 |@@@@ 1
+ 8 |@@@@ 1
+ 16 |@@@@@@@@@@@ 3
+ 32 |@@@@ 1
+ 64 | 0
+
+ PID=16043, cmd, namespace
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@ 1
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 | 0
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ PID=16043, cmd, puts
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 64 | 0
+ 128 |@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ PID=16043, cmd, if
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@ 2
+ 16 |@@@@@@@@@@@@@@@@@@@@ 4
+ 32 |@@@@@ 1
+ 64 | 0
+ 128 |@@@@@ 1
+ 256 | 0
+
+ PID=16043, cmd, tclInit
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ PID=16043, cmd, file
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@ 4
+ 8 |@@@@@@@@@@@@@ 4
+ 16 | 0
+ 32 |@@@ 1
+ 64 |@@@@@@@@@@ 3
+ 128 | 0
+
+ PID=16043, cmd, source
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ PID=16043, proc, func_a
+ value ------------- Distribution ------------- count
+ 262144 | 0
+ 524288 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1048576 | 0
+
+ PID=16043, proc, func_b
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=16043, proc, func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+
+Top 10 inclusive on-CPU times (us),
+ PID=16043, cmd, source
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=16043, cmd, uplevel
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=16043, proc, tclInit
+ value ------------- Distribution ------------- count
+ 512 | 0
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2048 | 0
+
+ PID=16043, cmd, tclInit
+ value ------------- Distribution ------------- count
+ 1024 | 0
+ 2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4096 | 0
+
+ PID=16043, cmd, func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=16043, proc, func_c
+ value ------------- Distribution ------------- count
+ 524288 | 0
+ 1048576 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2097152 | 0
+
+ PID=16043, cmd, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ PID=16043, cmd, func_b
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ PID=16043, proc, func_a
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+ PID=16043, proc, func_b
+ value ------------- Distribution ------------- count
+ 1048576 | 0
+ 2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 4194304 | 0
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the subroutine began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive subroutine time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_cputime_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_cputime_example.txt
new file mode 100644
index 0000000..c736201
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_cputime_example.txt
@@ -0,0 +1,67 @@
+Following are examples of running tcl_cputime.d.
+
+Here it runs while we execute Code/Tcl/func_slow.tcl
+
+# tcl_cputime.d
+Tracing... Hit Ctrl-C to end.
+^C
+
+Top 10 counts,
+ PID TYPE NAME COUNT
+ 16038 cmd set 2
+ 16038 cmd namespace 3
+ 16038 cmd puts 3
+ 16038 cmd lappend 4
+ 16038 cmd lsearch 4
+ 16038 cmd if 8
+ 16038 cmd info 11
+ 16038 cmd file 12
+ 16038 cmd proc 12
+ 0 total - 82
+
+Top 10 exclusive on-CPU times (us),
+ PID TYPE NAME TOTAL
+ 16038 cmd namespace 130
+ 16038 cmd puts 232
+ 16038 cmd if 310
+ 16038 cmd tclInit 315
+ 16038 cmd file 411
+ 16038 cmd source 760
+ 16038 proc func_a 535521
+ 16038 proc func_b 1071082
+ 16038 proc func_c 1619323
+ 0 total - 3228670
+
+Top 10 inclusive on-CPU times (us),
+ PID TYPE NAME TOTAL
+ 16038 cmd source 1359
+ 16038 cmd uplevel 1367
+ 16038 proc tclInit 1865
+ 16038 cmd tclInit 2180
+ 16038 proc func_c 1619360
+ 16038 cmd func_c 1619404
+ 16038 proc func_b 2690525
+ 16038 cmd func_b 2690568
+ 16038 proc func_a 3226247
+ 16038 cmd func_a 3226275
+
+We can see that the output is in three sections. The first section represents
+the ten most commonly executed commands while the script is tracing.
+
+The exclusive function on-CPU times show that func_a spent around 0.5 seconds
+on-CPU, func_b spent about 1.0 seconds, and func_c, 1.6 seconds. This excludes
+time spent in other procedures or commands.
+
+The inclusive function on-CPU times show the time spent by these procedures in
+total, including the time spent in other functions called, and since func_a
+called func_b which called func_c, these times make sense.
+
+These on-CPU times are the time the thread spent running on a CPU, from when
+the function began to when it completed. This does not include time
+spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy.
+See Notes/ALLoncpu_notes.txt for more details. Also see
+Notes/ALLexclusive_notes.txt and Notes/ALLinclusive_notes.txt for a
+detailed explanation of exclusive vs inclusive function time.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_flow_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_flow_example.txt
new file mode 100644
index 0000000..dd2dcd6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_flow_example.txt
@@ -0,0 +1,195 @@
+The following are examples of running tcl_flow.d.
+
+Here the script is tracing the execution of Code/Tcl/func_abc.tcl
+
+# tcl_flow.d
+ C PID TIME(us) -- CALL
+ 0 16068 3904942506169 > if
+ 0 16068 3904942506261 > info
+ 0 16068 3904942506286 < info
+ 0 16068 3904942506350 > proc
+ 0 16068 3904942506363 < proc
+ 0 16068 3904942506369 < if
+ 0 16068 3904942506383 > tclInit
+ 0 16068 3904942506605 -> tclInit
+ 0 16068 3904942506614 > global
+ 0 16068 3904942506626 < global
+ 0 16068 3904942506632 > global
+ 0 16068 3904942506638 < global
+ 0 16068 3904942506643 > rename
+ 0 16068 3904942506666 < rename
+ 0 16068 3904942506675 > info
+ 0 16068 3904942506685 < info
+ 0 16068 3904942506694 > info
+ 0 16068 3904942506721 < info
+ 0 16068 3904942506728 > unset
+ 0 16068 3904942506741 < unset
+ 0 16068 3904942506746 > concat
+ 0 16068 3904942506760 < concat
+ 0 16068 3904942506774 > file
+ 0 16068 3904942506792 < file
+ 0 16068 3904942506797 > file
+ 0 16068 3904942506880 < file
+ 0 16068 3904942506885 > file
+ 0 16068 3904942506895 < file
+ 0 16068 3904942506901 > file
+ 0 16068 3904942507009 < file
+ 0 16068 3904942507015 > file
+ 0 16068 3904942507025 < file
+ 0 16068 3904942507031 > file
+ 0 16068 3904942507118 < file
+ 0 16068 3904942507124 > file
+ 0 16068 3904942507133 < file
+ 0 16068 3904942507139 > file
+ 0 16068 3904942507193 < file
+ 0 16068 3904942507200 > uplevel
+ 0 16068 3904942507209 > source
+ 0 16068 3904942507649 > if
+ 0 16068 3904942507664 > info
+ 0 16068 3904942507673 < info
+ 0 16068 3904942507681 < if
+ 0 16068 3904942507691 > package
+ 0 16068 3904942507700 < package
+ 0 16068 3904942507712 > if
+ 0 16068 3904942507722 > info
+ 0 16068 3904942507728 < info
+ 0 16068 3904942507749 > info
+ 0 16068 3904942507773 < info
+ 0 16068 3904942507780 < if
+ 0 16068 3904942507797 > namespace
+ 0 16068 3904942507898 > variable
+ 0 16068 3904942507905 < variable
+ 0 16068 3904942507911 > info
+ 0 16068 3904942507923 < info
+ 0 16068 3904942507928 > info
+ 0 16068 3904942507934 < info
+ 0 16068 3904942507939 > info
+ 0 16068 3904942507947 < info
+ 0 16068 3904942507952 > file
+ 0 16068 3904942507971 < file
+ 0 16068 3904942507977 > list
+ 0 16068 3904942507991 < list
+ 0 16068 3904942507996 > foreach
+ 0 16068 3904942508020 > lsearch
+ 0 16068 3904942508028 < lsearch
+ 0 16068 3904942508034 > lappend
+ 0 16068 3904942508041 < lappend
+ 0 16068 3904942508051 > lsearch
+ 0 16068 3904942508056 < lsearch
+ 0 16068 3904942508061 > lappend
+ 0 16068 3904942508068 < lappend
+ 0 16068 3904942508073 < foreach
+ 0 16068 3904942508078 > info
+ 0 16068 3904942508086 < info
+ 0 16068 3904942508090 > file
+ 0 16068 3904942508108 < file
+ 0 16068 3904942508113 > file
+ 0 16068 3904942508129 < file
+ 0 16068 3904942508134 > file
+ 0 16068 3904942508142 < file
+ 0 16068 3904942508148 > lsearch
+ 0 16068 3904942508153 < lsearch
+ 0 16068 3904942508158 > lappend
+ 0 16068 3904942508166 < lappend
+ 0 16068 3904942508170 > info
+ 0 16068 3904942508176 < info
+ 0 16068 3904942508181 > foreach
+ 0 16068 3904942508190 > lsearch
+ 0 16068 3904942508195 < lsearch
+ 0 16068 3904942508200 > lappend
+ 0 16068 3904942508206 < lappend
+ 0 16068 3904942508211 < foreach
+ 0 16068 3904942508217 < namespace
+ 0 16068 3904942508243 > if
+ 0 16068 3904942508261 > interp
+ 0 16068 3904942508276 < interp
+ 0 16068 3904942508283 < if
+ 0 16068 3904942508296 > package
+ 0 16068 3904942508302 < package
+ 0 16068 3904942508312 > if
+ 0 16068 3904942508322 > interp
+ 0 16068 3904942508328 < interp
+ 0 16068 3904942508369 < if
+ 0 16068 3904942508387 > if
+ 0 16068 3904942508398 > namespace
+ 0 16068 3904942508406 < namespace
+ 0 16068 3904942508412 < if
+ 0 16068 3904942508424 > set
+ 0 16068 3904942508430 < set
+ 0 16068 3904942508437 > set
+ 0 16068 3904942508443 < set
+ 0 16068 3904942508451 > if
+ 0 16068 3904942508463 > namespace
+ 0 16068 3904942508469 < namespace
+ 0 16068 3904942508479 > proc
+ 0 16068 3904942508488 < proc
+ 0 16068 3904942508493 < if
+ 0 16068 3904942508573 > proc
+ 0 16068 3904942508582 < proc
+ 0 16068 3904942508599 > proc
+ 0 16068 3904942508609 < proc
+ 0 16068 3904942508638 > proc
+ 0 16068 3904942508645 < proc
+ 0 16068 3904942508664 > proc
+ 0 16068 3904942508673 < proc
+ 0 16068 3904942508686 > proc
+ 0 16068 3904942508693 < proc
+ 0 16068 3904942508737 > if
+ 0 16068 3904942508760 > proc
+ 0 16068 3904942508782 < proc
+ 0 16068 3904942508788 < if
+ 0 16068 3904942508826 > proc
+ 0 16068 3904942508837 < proc
+ 0 16068 3904942508843 < source
+ 0 16068 3904942508848 < uplevel
+ 0 16068 3904942508857 <- tclInit
+ 0 16068 3904942508871 < tclInit
+ 0 16068 3904942509050 > proc
+ 0 16068 3904942509059 < proc
+ 0 16068 3904942509067 > proc
+ 0 16068 3904942509074 < proc
+ 0 16068 3904942509081 > proc
+ 0 16068 3904942509088 < proc
+ 0 16068 3904942509094 > func_a
+ 0 16068 3904942509110 -> func_a
+ 0 16068 3904942509116 > puts
+ 0 16068 3904942509256 < puts
+ 0 16068 3904942509262 > after
+ 0 16068 3904943510998 < after
+ 0 16068 3904943511016 > func_b
+ 0 16068 3904943511050 -> func_b
+ 0 16068 3904943511058 > puts
+ 0 16068 3904943511090 < puts
+ 0 16068 3904943511094 > after
+ 0 16068 3904944520994 < after
+ 0 16068 3904944521013 > func_c
+ 0 16068 3904944521043 -> func_c
+ 0 16068 3904944521051 > puts
+ 0 16068 3904944521092 < puts
+ 0 16068 3904944521097 > after
+ 0 16068 3904945530993 < after
+ 0 16068 3904945531012 <- func_c
+ 0 16068 3904945531020 < func_c
+ 0 16068 3904945531025 <- func_b
+ 0 16068 3904945531029 < func_b
+ 0 16068 3904945531034 <- func_a
+ 0 16068 3904945531039 < func_a
+ 0 16068 3904945531064 > exit
+^C
+
+You can see the output is in five columns.
+
+The first column is CPU-id, the second is PID, third is the time since boot in
+microseconds since the previous action. The fourth and fifth columns
+represent the action happening. The Tcl command or procedure name is prefixed
+by an indicator reprenting what is happening. These may be -> (procedure
+entry), <- (procedure return), > (command entry), or < (command return).
+
+As each action is taken, the fourth and fifth columns are indented by 2 spaces.
+This shows which procedure or command is calling which.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_flowtime_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_flowtime_example.txt
new file mode 100644
index 0000000..8e07238
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_flowtime_example.txt
@@ -0,0 +1,197 @@
+Following are examples of running tcl_flowtime.d.
+
+Here the tcl_flowtime.d script is running on the program
+Code/Tcl/func_abc.tcl.
+
+
+# tcl_flowtime.d
+ C PID TIME(us) DELTA(us) -- CALL
+ 0 17901 4436098007906 2 > if
+ 0 17901 4436098007976 70 > info
+ 0 17901 4436098007998 21 < info
+ 0 17901 4436098008050 52 > proc
+ 0 17901 4436098008063 12 < proc
+ 0 17901 4436098008069 6 < if
+ 0 17901 4436098008085 15 > tclInit
+ 0 17901 4436098008286 201 -> tclInit
+ 0 17901 4436098008295 8 > global
+ 0 17901 4436098008305 10 < global
+ 0 17901 4436098008311 6 > global
+ 0 17901 4436098008318 6 < global
+ 0 17901 4436098008323 5 > rename
+ 0 17901 4436098008342 18 < rename
+ 0 17901 4436098008353 10 > info
+ 0 17901 4436098008362 9 < info
+ 0 17901 4436098008369 6 > info
+ 0 17901 4436098008395 25 < info
+ 0 17901 4436098008403 8 > unset
+ 0 17901 4436098008410 6 < unset
+ 0 17901 4436098008416 5 > concat
+ 0 17901 4436098008425 8 < concat
+ 0 17901 4436098008440 15 > file
+ 0 17901 4436098008459 18 < file
+ 0 17901 4436098008465 6 > file
+ 0 17901 4436098008543 78 < file
+ 0 17901 4436098008550 7 > file
+ 0 17901 4436098008560 9 < file
+ 0 17901 4436098008567 7 > file
+ 0 17901 4436098008671 104 < file
+ 0 17901 4436098008678 7 > file
+ 0 17901 4436098008688 9 < file
+ 0 17901 4436098008695 6 > file
+ 0 17901 4436098008780 84 < file
+ 0 17901 4436098008787 6 > file
+ 0 17901 4436098008796 9 < file
+ 0 17901 4436098008803 6 > file
+ 0 17901 4436098008854 51 < file
+ 0 17901 4436098008862 7 > uplevel
+ 0 17901 4436098008872 10 > source
+ 0 17901 4436098009290 417 > if
+ 0 17901 4436098009304 14 > info
+ 0 17901 4436098009311 7 < info
+ 0 17901 4436098009319 7 < if
+ 0 17901 4436098009331 11 > package
+ 0 17901 4436098009340 9 < package
+ 0 17901 4436098009353 12 > if
+ 0 17901 4436098009363 10 > info
+ 0 17901 4436098009369 6 < info
+ 0 17901 4436098009390 20 > info
+ 0 17901 4436098009413 22 < info
+ 0 17901 4436098009421 7 < if
+ 0 17901 4436098009439 18 > namespace
+ 0 17901 4436098009530 90 > variable
+ 0 17901 4436098009537 7 < variable
+ 0 17901 4436098009544 6 > info
+ 0 17901 4436098009554 10 < info
+ 0 17901 4436098009561 6 > info
+ 0 17901 4436098009567 6 < info
+ 0 17901 4436098009573 5 > info
+ 0 17901 4436098009579 6 < info
+ 0 17901 4436098009586 6 > file
+ 0 17901 4436098009605 19 < file
+ 0 17901 4436098009611 6 > list
+ 0 17901 4436098009627 15 < list
+ 0 17901 4436098009633 6 > foreach
+ 0 17901 4436098009658 24 > lsearch
+ 0 17901 4436098009665 7 < lsearch
+ 0 17901 4436098009673 7 > lappend
+ 0 17901 4436098009680 7 < lappend
+ 0 17901 4436098009689 9 > lsearch
+ 0 17901 4436098009694 5 < lsearch
+ 0 17901 4436098009700 6 > lappend
+ 0 17901 4436098009707 6 < lappend
+ 0 17901 4436098009712 5 < foreach
+ 0 17901 4436098009719 6 > info
+ 0 17901 4436098009726 7 < info
+ 0 17901 4436098009732 5 > file
+ 0 17901 4436098009749 17 < file
+ 0 17901 4436098009756 6 > file
+ 0 17901 4436098009772 16 < file
+ 0 17901 4436098009778 6 > file
+ 0 17901 4436098009787 9 < file
+ 0 17901 4436098009795 7 > lsearch
+ 0 17901 4436098009800 5 < lsearch
+ 0 17901 4436098009806 6 > lappend
+ 0 17901 4436098009812 5 < lappend
+ 0 17901 4436098009818 5 > info
+ 0 17901 4436098009823 5 < info
+ 0 17901 4436098009830 6 > foreach
+ 0 17901 4436098009840 9 > lsearch
+ 0 17901 4436098009845 5 < lsearch
+ 0 17901 4436098009851 6 > lappend
+ 0 17901 4436098009857 5 < lappend
+ 0 17901 4436098009862 5 < foreach
+ 0 17901 4436098009868 5 < namespace
+ 0 17901 4436098009896 27 > if
+ 0 17901 4436098009915 18 > interp
+ 0 17901 4436098009922 7 < interp
+ 0 17901 4436098009930 8 < if
+ 0 17901 4436098009943 12 > package
+ 0 17901 4436098009949 5 < package
+ 0 17901 4436098009960 10 > if
+ 0 17901 4436098009970 10 > interp
+ 0 17901 4436098009976 5 < interp
+ 0 17901 4436098010018 41 < if
+ 0 17901 4436098010036 18 > if
+ 0 17901 4436098010049 12 > namespace
+ 0 17901 4436098010057 7 < namespace
+ 0 17901 4436098010063 6 < if
+ 0 17901 4436098010074 11 > set
+ 0 17901 4436098010081 6 < set
+ 0 17901 4436098010089 8 > set
+ 0 17901 4436098010095 5 < set
+ 0 17901 4436098010104 9 > if
+ 0 17901 4436098010116 12 > namespace
+ 0 17901 4436098010122 6 < namespace
+ 0 17901 4436098010133 10 > proc
+ 0 17901 4436098010142 8 < proc
+ 0 17901 4436098010148 5 < if
+ 0 17901 4436098010228 79 > proc
+ 0 17901 4436098010237 8 < proc
+ 0 17901 4436098010255 18 > proc
+ 0 17901 4436098010264 9 < proc
+ 0 17901 4436098010293 29 > proc
+ 0 17901 4436098010301 7 < proc
+ 0 17901 4436098010320 18 > proc
+ 0 17901 4436098010329 9 < proc
+ 0 17901 4436098010342 13 > proc
+ 0 17901 4436098010350 7 < proc
+ 0 17901 4436098010394 44 > if
+ 0 17901 4436098010418 23 > proc
+ 0 17901 4436098010437 18 < proc
+ 0 17901 4436098010443 6 < if
+ 0 17901 4436098010563 120 > proc
+ 0 17901 4436098010575 12 < proc
+ 0 17901 4436098010582 7 < source
+ 0 17901 4436098010588 5 < uplevel
+ 0 17901 4436098010596 8 <- tclInit
+ 0 17901 4436098010610 13 < tclInit
+ 0 17901 4436098010800 190 > proc
+ 0 17901 4436098010809 8 < proc
+ 0 17901 4436098010818 9 > proc
+ 0 17901 4436098010825 6 < proc
+ 0 17901 4436098010833 8 > proc
+ 0 17901 4436098010840 6 < proc
+ 0 17901 4436098010847 7 > func_a
+ 0 17901 4436098010863 15 -> func_a
+ 0 17901 4436098010870 6 > puts
+ 0 17901 4436098011006 136 < puts
+ 0 17901 4436098011014 7 > after
+ 0 17901 4436099020588 1009573 < after
+ 0 17901 4436099020611 23 > func_b
+ 0 17901 4436099020646 34 -> func_b
+ 0 17901 4436099020655 8 > puts
+ 0 17901 4436099020697 41 < puts
+ 0 17901 4436099020703 6 > after
+ 0 17901 4436100030614 1009910 < after
+ 0 17901 4436100030638 24 > func_c
+ 0 17901 4436100030671 32 -> func_c
+ 0 17901 4436100030680 9 > puts
+ 0 17901 4436100030723 42 < puts
+ 0 17901 4436100030729 6 > after
+ 0 17901 4436101040600 1009870 < after
+ 0 17901 4436101040623 22 <- func_c
+ 0 17901 4436101040633 10 < func_c
+ 0 17901 4436101040639 6 <- func_b
+ 0 17901 4436101040645 5 < func_b
+ 0 17901 4436101040651 5 <- func_a
+ 0 17901 4436101040656 5 < func_a
+ 0 17901 4436101040682 25 > exit
+
+You can see the output is in six columns.
+
+The first column is CPU-id, the second is PID, third is the time since boot in
+microseconds, fourth is the elapsed time since the previous action. The fifth
+and sixth columns represent the action. The Tcl command or procedure name is
+prefixed by an indicator reprenting what is happening. These may be ->
+(procedure entry), <- (procedure return), > (command entry), or < (command
+return).
+
+As each action is taken, the fifth and sixth columns are indented by 2 spaces.
+This shows which procedure or command is calling which.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_ins_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_ins_example.txt
new file mode 100644
index 0000000..6f1ba9a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_ins_example.txt
@@ -0,0 +1,46 @@
+The following are examples of running the script tcl_ins.d
+
+Here it traces as Code/Tcl/func_slow.tcl executes.
+
+# tcl_ins.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID TYPE NAME COUNT
+ 16005 inst foreach_start4 1
+ 16005 inst jumpTrue1 1
+ 16005 inst lappendScalar1 1
+ 16005 inst list 1
+ 16005 inst strneq 1
+ 16005 inst beginCatch4 2
+ 16005 inst dup 2
+ 16005 inst endCatch 2
+ 16005 inst eq 2
+ 16005 inst land 2
+ 16005 inst storeScalarStk 2
+ 16005 inst foreach_step4 4
+ 16005 inst not 4
+ 16005 inst loadArrayStk 5
+ 16005 inst streq 7
+ 16005 inst tryCvtToNumeric 8
+ 16005 inst jumpFalse1 12
+ 16005 inst loadScalarStk 13
+ 16005 inst jump1 14
+ 16005 inst pop 18
+ 16005 inst invokeStk1 53
+ 16005 inst add 600000
+ 16005 inst concat1 600000
+ 16005 inst exprStk 600000
+ 16005 inst lt 600007
+ 16005 inst storeScalar1 600016
+ 16005 inst done 600021
+ 16005 inst loadScalar1 1200020
+ 16005 inst push1 4200193
+
+It is showing the instructions called by Tcl as the program executes. The
+larger counts toward the bottom of the display are from the looping construct
+used in Code/Tcl/func_slow.tcl.
+
+Tracing the instructions is quite low-level and slow the target application
+considerably and would probably be used only as a last resort if you have no
+other indication of why CPUs are busy.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_insflow_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_insflow_example.txt
new file mode 100644
index 0000000..2919f8e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_insflow_example.txt
@@ -0,0 +1,997 @@
+The following are examples of running tcl_insflow.d
+
+Here you can see the script running while tracing Code/Tcl/func_abc.tcl
+
+# tcl_insflow.d
+ C PID TIME(us) DELTA(us) TYPE -- CALL
+ 0 174829 4436207514685 3 cmd -> if
+ 0 174829 4436207514793 107 inst -> push1
+ 0 174829 4436207514805 11 inst <- push1
+ 0 174829 4436207514814 8 inst -> push1
+ 0 174829 4436207514820 5 inst <- push1
+ 0 174829 4436207514826 5 inst -> push1
+ 0 174829 4436207514832 5 inst <- push1
+ 0 174829 4436207514838 5 inst -> invokeStk1
+ 0 174829 4436207514845 6 cmd -> info
+ 0 174829 4436207514883 38 cmd <- info
+ 0 174829 4436207514895 11 inst <- invokeStk1
+ 0 174829 4436207514901 6 inst -> push1
+ 0 174829 4436207514907 5 inst <- push1
+ 0 174829 4436207514913 5 inst -> eq
+ 0 174829 4436207514927 14 inst <- eq
+ 0 174829 4436207514933 6 inst -> done
+ 0 174829 4436207514940 6 inst <- done
+ 0 174829 4436207514978 38 inst -> push1
+ 0 174829 4436207514985 6 inst <- push1
+ 0 174829 4436207514991 5 inst -> push1
+ 0 174829 4436207514996 5 inst <- push1
+ 0 174829 4436207515002 5 inst -> push1
+ 0 174829 4436207515007 5 inst <- push1
+ 0 174829 4436207515013 5 inst -> push1
+ 0 174829 4436207515019 5 inst <- push1
+ 0 174829 4436207515024 5 inst -> invokeStk1
+ 0 174829 4436207515031 6 cmd -> proc
+ 0 174829 4436207515045 13 cmd <- proc
+ 0 174829 4436207515051 6 inst <- invokeStk1
+ 0 174829 4436207515057 6 inst -> done
+ 0 174829 4436207515063 5 inst <- done
+ 0 174829 4436207515069 6 cmd <- if
+ 0 174829 4436207515086 16 cmd -> tclInit
+ 0 174829 4436207515295 208 proc -> tclInit
+ 0 174829 4436207515305 10 inst -> push1
+ 0 174829 4436207515311 5 inst <- push1
+ 0 174829 4436207515317 6 inst -> push1
+ 0 174829 4436207515323 5 inst <- push1
+ 0 174829 4436207515328 5 inst -> push1
+ 0 174829 4436207515334 5 inst <- push1
+ 0 174829 4436207515340 5 inst -> push1
+ 0 174829 4436207515345 5 inst <- push1
+ 0 174829 4436207515351 5 inst -> invokeStk1
+ 0 174829 4436207515357 6 cmd -> global
+ 0 174829 4436207515369 11 cmd <- global
+ 0 174829 4436207515375 6 inst <- invokeStk1
+ 0 174829 4436207515381 5 inst -> pop
+ 0 174829 4436207515387 5 inst <- pop
+ 0 174829 4436207515393 5 inst -> push1
+ 0 174829 4436207515398 5 inst <- push1
+ 0 174829 4436207515404 5 inst -> push1
+ 0 174829 4436207515410 5 inst <- push1
+ 0 174829 4436207515415 5 inst -> push1
+ 0 174829 4436207515421 5 inst <- push1
+ 0 174829 4436207515427 5 inst -> invokeStk1
+ 0 174829 4436207515433 6 cmd -> global
+ 0 174829 4436207515440 7 cmd <- global
+ 0 174829 4436207515446 6 inst <- invokeStk1
+ 0 174829 4436207515452 5 inst -> pop
+ 0 174829 4436207515458 5 inst <- pop
+ 0 174829 4436207515463 5 inst -> push1
+ 0 174829 4436207515469 5 inst <- push1
+ 0 174829 4436207515475 5 inst -> push1
+ 0 174829 4436207515480 5 inst <- push1
+ 0 174829 4436207515486 5 inst -> push1
+ 0 174829 4436207515492 5 inst <- push1
+ 0 174829 4436207515497 5 inst -> invokeStk1
+ 0 174829 4436207515504 6 cmd -> rename
+ 0 174829 4436207515553 49 cmd <- rename
+ 0 174829 4436207515560 6 inst <- invokeStk1
+ 0 174829 4436207515566 6 inst -> pop
+ 0 174829 4436207515571 5 inst <- pop
+ 0 174829 4436207515577 5 inst -> push1
+ 0 174829 4436207515583 5 inst <- push1
+ 0 174829 4436207515589 5 inst -> storeScalar1
+ 0 174829 4436207515598 9 inst <- storeScalar1
+ 0 174829 4436207515605 6 inst -> push1
+ 0 174829 4436207515610 5 inst <- push1
+ 0 174829 4436207515616 5 inst -> storeScalar1
+ 0 174829 4436207515622 5 inst <- storeScalar1
+ 0 174829 4436207515628 5 inst -> push1
+ 0 174829 4436207515633 5 inst <- push1
+ 0 174829 4436207515639 5 inst -> push1
+ 0 174829 4436207515645 5 inst <- push1
+ 0 174829 4436207515650 5 inst -> push1
+ 0 174829 4436207515656 5 inst <- push1
+ 0 174829 4436207515662 5 inst -> invokeStk1
+ 0 174829 4436207515668 6 cmd -> info
+ 0 174829 4436207515679 10 cmd <- info
+ 0 174829 4436207515685 6 inst <- invokeStk1
+ 0 174829 4436207515691 5 inst -> tryCvtToNumeric
+ 0 174829 4436207515701 10 inst <- tryCvtToNumeric
+ 0 174829 4436207515708 6 inst -> jumpFalse1
+ 0 174829 4436207515714 5 inst <- jumpFalse1
+ 0 174829 4436207515719 5 inst -> push1
+ 0 174829 4436207515725 5 inst <- push1
+ 0 174829 4436207515731 5 inst -> push1
+ 0 174829 4436207515736 5 inst <- push1
+ 0 174829 4436207515742 5 inst -> push1
+ 0 174829 4436207515747 5 inst <- push1
+ 0 174829 4436207515753 5 inst -> invokeStk1
+ 0 174829 4436207515760 6 cmd -> info
+ 0 174829 4436207515787 27 cmd <- info
+ 0 174829 4436207515793 6 inst <- invokeStk1
+ 0 174829 4436207515799 5 inst -> tryCvtToNumeric
+ 0 174829 4436207515805 5 inst <- tryCvtToNumeric
+ 0 174829 4436207515811 5 inst -> jumpFalse1
+ 0 174829 4436207515817 5 inst <- jumpFalse1
+ 0 174829 4436207515823 5 inst -> push1
+ 0 174829 4436207515828 5 inst <- push1
+ 0 174829 4436207515834 5 inst -> pop
+ 0 174829 4436207515839 5 inst <- pop
+ 0 174829 4436207515845 5 inst -> beginCatch4
+ 0 174829 4436207515851 5 inst <- beginCatch4
+ 0 174829 4436207515857 5 inst -> loadScalar1
+ 0 174829 4436207515863 5 inst <- loadScalar1
+ 0 174829 4436207515868 5 inst -> lappendScalar1
+ 0 174829 4436207515877 8 inst <- lappendScalar1
+ 0 174829 4436207515883 6 inst -> push1
+ 0 174829 4436207515889 5 inst <- push1
+ 0 174829 4436207515895 5 inst -> push1
+ 0 174829 4436207515900 5 inst <- push1
+ 0 174829 4436207515906 5 inst -> invokeStk1
+ 0 174829 4436207515912 6 cmd -> unset
+ 0 174829 4436207515920 7 cmd <- unset
+ 0 174829 4436207515926 6 inst <- invokeStk1
+ 0 174829 4436207515932 5 inst -> pop
+ 0 174829 4436207515938 5 inst <- pop
+ 0 174829 4436207515943 5 inst -> push1
+ 0 174829 4436207515949 5 inst <- push1
+ 0 174829 4436207515955 5 inst -> jump1
+ 0 174829 4436207515960 5 inst <- jump1
+ 0 174829 4436207515966 5 inst -> endCatch
+ 0 174829 4436207515972 5 inst <- endCatch
+ 0 174829 4436207515977 5 inst -> pop
+ 0 174829 4436207515983 5 inst <- pop
+ 0 174829 4436207515989 5 inst -> push1
+ 0 174829 4436207515994 5 inst <- push1
+ 0 174829 4436207516000 5 inst -> loadScalar1
+ 0 174829 4436207516006 5 inst <- loadScalar1
+ 0 174829 4436207516012 5 inst -> loadScalar1
+ 0 174829 4436207516017 5 inst <- loadScalar1
+ 0 174829 4436207516023 5 inst -> invokeStk1
+ 0 174829 4436207516029 6 cmd -> concat
+ 0 174829 4436207516049 19 cmd <- concat
+ 0 174829 4436207516055 6 inst <- invokeStk1
+ 0 174829 4436207516061 5 inst -> storeScalar1
+ 0 174829 4436207516068 6 inst <- storeScalar1
+ 0 174829 4436207516074 6 inst -> loadScalar1
+ 0 174829 4436207516080 5 inst <- loadScalar1
+ 0 174829 4436207516085 5 inst -> storeScalar1
+ 0 174829 4436207516091 5 inst <- storeScalar1
+ 0 174829 4436207516097 5 inst -> foreach_start4
+ 0 174829 4436207516104 6 inst <- foreach_start4
+ 0 174829 4436207516110 6 inst -> foreach_step4
+ 0 174829 4436207516125 14 inst <- foreach_step4
+ 0 174829 4436207516131 5 inst -> loadScalar1
+ 0 174829 4436207516137 5 inst <- loadScalar1
+ 0 174829 4436207516143 5 inst -> storeScalar1
+ 0 174829 4436207516148 5 inst <- storeScalar1
+ 0 174829 4436207516154 5 inst -> push1
+ 0 174829 4436207516160 5 inst <- push1
+ 0 174829 4436207516165 5 inst -> push1
+ 0 174829 4436207516171 5 inst <- push1
+ 0 174829 4436207516177 5 inst -> loadScalar1
+ 0 174829 4436207516182 5 inst <- loadScalar1
+ 0 174829 4436207516188 5 inst -> push1
+ 0 174829 4436207516194 5 inst <- push1
+ 0 174829 4436207516200 5 inst -> invokeStk1
+ 0 174829 4436207516206 6 cmd -> file
+ 0 174829 4436207516218 12 cmd <- file
+ 0 174829 4436207516224 6 inst <- invokeStk1
+ 0 174829 4436207516230 5 inst -> storeScalar1
+ 0 174829 4436207516236 5 inst <- storeScalar1
+ 0 174829 4436207516242 5 inst -> push1
+ 0 174829 4436207516247 5 inst <- push1
+ 0 174829 4436207516253 5 inst -> push1
+ 0 174829 4436207516258 5 inst <- push1
+ 0 174829 4436207516264 5 inst -> loadScalar1
+ 0 174829 4436207516270 5 inst <- loadScalar1
+ 0 174829 4436207516276 5 inst -> invokeStk1
+ 0 174829 4436207516282 6 cmd -> file
+ 0 174829 4436207516368 86 cmd <- file
+ 0 174829 4436207516375 6 inst <- invokeStk1
+ 0 174829 4436207516381 6 inst -> tryCvtToNumeric
+ 0 174829 4436207516387 5 inst <- tryCvtToNumeric
+ 0 174829 4436207516393 5 inst -> jumpFalse1
+ 0 174829 4436207516398 5 inst <- jumpFalse1
+ 0 174829 4436207516404 5 inst -> push1
+ 0 174829 4436207516410 5 inst <- push1
+ 0 174829 4436207516416 5 inst -> pop
+ 0 174829 4436207516421 5 inst <- pop
+ 0 174829 4436207516427 5 inst -> jump1
+ 0 174829 4436207516432 5 inst <- jump1
+ 0 174829 4436207516438 5 inst -> foreach_step4
+ 0 174829 4436207516444 5 inst <- foreach_step4
+ 0 174829 4436207516450 5 inst -> loadScalar1
+ 0 174829 4436207516456 5 inst <- loadScalar1
+ 0 174829 4436207516462 6 inst -> storeScalar1
+ 0 174829 4436207516468 5 inst <- storeScalar1
+ 0 174829 4436207516473 5 inst -> push1
+ 0 174829 4436207516479 5 inst <- push1
+ 0 174829 4436207516485 5 inst -> push1
+ 0 174829 4436207516490 5 inst <- push1
+ 0 174829 4436207516496 5 inst -> loadScalar1
+ 0 174829 4436207516502 5 inst <- loadScalar1
+ 0 174829 4436207516508 5 inst -> push1
+ 0 174829 4436207516513 5 inst <- push1
+ 0 174829 4436207516519 5 inst -> invokeStk1
+ 0 174829 4436207516525 6 cmd -> file
+ 0 174829 4436207516536 10 cmd <- file
+ 0 174829 4436207516542 6 inst <- invokeStk1
+ 0 174829 4436207516548 5 inst -> storeScalar1
+ 0 174829 4436207516555 6 inst <- storeScalar1
+ 0 174829 4436207516561 6 inst -> push1
+ 0 174829 4436207516566 5 inst <- push1
+ 0 174829 4436207516572 5 inst -> push1
+ 0 174829 4436207516578 5 inst <- push1
+ 0 174829 4436207516583 5 inst -> loadScalar1
+ 0 174829 4436207516589 5 inst <- loadScalar1
+ 0 174829 4436207516595 5 inst -> invokeStk1
+ 0 174829 4436207516601 6 cmd -> file
+ 0 174829 4436207516709 107 cmd <- file
+ 0 174829 4436207516716 6 inst <- invokeStk1
+ 0 174829 4436207516722 6 inst -> tryCvtToNumeric
+ 0 174829 4436207516728 5 inst <- tryCvtToNumeric
+ 0 174829 4436207516733 5 inst -> jumpFalse1
+ 0 174829 4436207516739 5 inst <- jumpFalse1
+ 0 174829 4436207516745 5 inst -> push1
+ 0 174829 4436207516751 5 inst <- push1
+ 0 174829 4436207516756 5 inst -> pop
+ 0 174829 4436207516762 5 inst <- pop
+ 0 174829 4436207516768 5 inst -> jump1
+ 0 174829 4436207516773 5 inst <- jump1
+ 0 174829 4436207516779 5 inst -> foreach_step4
+ 0 174829 4436207516785 5 inst <- foreach_step4
+ 0 174829 4436207516791 5 inst -> loadScalar1
+ 0 174829 4436207516796 5 inst <- loadScalar1
+ 0 174829 4436207516802 5 inst -> storeScalar1
+ 0 174829 4436207516808 5 inst <- storeScalar1
+ 0 174829 4436207516814 5 inst -> push1
+ 0 174829 4436207516820 5 inst <- push1
+ 0 174829 4436207516825 5 inst -> push1
+ 0 174829 4436207516831 5 inst <- push1
+ 0 174829 4436207516837 5 inst -> loadScalar1
+ 0 174829 4436207516842 5 inst <- loadScalar1
+ 0 174829 4436207516848 5 inst -> push1
+ 0 174829 4436207516854 5 inst <- push1
+ 0 174829 4436207516859 5 inst -> invokeStk1
+ 0 174829 4436207516866 6 cmd -> file
+ 0 174829 4436207516876 10 cmd <- file
+ 0 174829 4436207516882 6 inst <- invokeStk1
+ 0 174829 4436207516888 5 inst -> storeScalar1
+ 0 174829 4436207516895 6 inst <- storeScalar1
+ 0 174829 4436207516901 6 inst -> push1
+ 0 174829 4436207516906 5 inst <- push1
+ 0 174829 4436207516912 5 inst -> push1
+ 0 174829 4436207516918 5 inst <- push1
+ 0 174829 4436207516923 5 inst -> loadScalar1
+ 0 174829 4436207516929 5 inst <- loadScalar1
+ 0 174829 4436207516935 5 inst -> invokeStk1
+ 0 174829 4436207516941 6 cmd -> file
+ 0 174829 4436207517027 86 cmd <- file
+ 0 174829 4436207517034 6 inst <- invokeStk1
+ 0 174829 4436207517040 6 inst -> tryCvtToNumeric
+ 0 174829 4436207517046 5 inst <- tryCvtToNumeric
+ 0 174829 4436207517052 5 inst -> jumpFalse1
+ 0 174829 4436207517057 5 inst <- jumpFalse1
+ 0 174829 4436207517063 5 inst -> push1
+ 0 174829 4436207517069 5 inst <- push1
+ 0 174829 4436207517075 5 inst -> pop
+ 0 174829 4436207517080 5 inst <- pop
+ 0 174829 4436207517086 5 inst -> jump1
+ 0 174829 4436207517091 5 inst <- jump1
+ 0 174829 4436207517097 5 inst -> foreach_step4
+ 0 174829 4436207517103 5 inst <- foreach_step4
+ 0 174829 4436207517109 5 inst -> loadScalar1
+ 0 174829 4436207517115 5 inst <- loadScalar1
+ 0 174829 4436207517121 5 inst -> storeScalar1
+ 0 174829 4436207517127 5 inst <- storeScalar1
+ 0 174829 4436207517132 5 inst -> push1
+ 0 174829 4436207517138 5 inst <- push1
+ 0 174829 4436207517144 5 inst -> push1
+ 0 174829 4436207517149 5 inst <- push1
+ 0 174829 4436207517155 5 inst -> loadScalar1
+ 0 174829 4436207517161 5 inst <- loadScalar1
+ 0 174829 4436207517167 5 inst -> push1
+ 0 174829 4436207517172 5 inst <- push1
+ 0 174829 4436207517178 5 inst -> invokeStk1
+ 0 174829 4436207517184 6 cmd -> file
+ 0 174829 4436207517194 10 cmd <- file
+ 0 174829 4436207517201 6 inst <- invokeStk1
+ 0 174829 4436207517206 5 inst -> storeScalar1
+ 0 174829 4436207517213 6 inst <- storeScalar1
+ 0 174829 4436207517219 5 inst -> push1
+ 0 174829 4436207517225 5 inst <- push1
+ 0 174829 4436207517231 5 inst -> push1
+ 0 174829 4436207517236 5 inst <- push1
+ 0 174829 4436207517242 5 inst -> loadScalar1
+ 0 174829 4436207517247 5 inst <- loadScalar1
+ 0 174829 4436207517253 5 inst -> invokeStk1
+ 0 174829 4436207517260 6 cmd -> file
+ 0 174829 4436207517313 53 cmd <- file
+ 0 174829 4436207517319 6 inst <- invokeStk1
+ 0 174829 4436207517325 5 inst -> tryCvtToNumeric
+ 0 174829 4436207517331 6 inst <- tryCvtToNumeric
+ 0 174829 4436207517337 5 inst -> jumpFalse1
+ 0 174829 4436207517343 5 inst <- jumpFalse1
+ 0 174829 4436207517348 5 inst -> beginCatch4
+ 0 174829 4436207517354 5 inst <- beginCatch4
+ 0 174829 4436207517360 6 inst -> push1
+ 0 174829 4436207517366 5 inst <- push1
+ 0 174829 4436207517371 5 inst -> push1
+ 0 174829 4436207517377 5 inst <- push1
+ 0 174829 4436207517383 5 inst -> push1
+ 0 174829 4436207517388 5 inst <- push1
+ 0 174829 4436207517394 5 inst -> loadScalar1
+ 0 174829 4436207517400 5 inst <- loadScalar1
+ 0 174829 4436207517405 5 inst -> list
+ 0 174829 4436207517412 6 inst <- list
+ 0 174829 4436207517418 5 inst -> invokeStk1
+ 0 174829 4436207517424 6 cmd -> uplevel
+ 0 174829 4436207517436 11 cmd -> source
+ 0 174829 4436207517878 441 cmd -> if
+ 0 174829 4436207517897 18 inst -> push1
+ 0 174829 4436207517903 6 inst <- push1
+ 0 174829 4436207517910 6 inst -> push1
+ 0 174829 4436207517915 5 inst <- push1
+ 0 174829 4436207517921 5 inst -> push1
+ 0 174829 4436207517927 5 inst <- push1
+ 0 174829 4436207517932 5 inst -> invokeStk1
+ 0 174829 4436207517939 6 cmd -> info
+ 0 174829 4436207517947 8 cmd <- info
+ 0 174829 4436207517954 6 inst <- invokeStk1
+ 0 174829 4436207517960 5 inst -> push1
+ 0 174829 4436207517965 5 inst <- push1
+ 0 174829 4436207517971 5 inst -> eq
+ 0 174829 4436207517979 7 inst <- eq
+ 0 174829 4436207517985 5 inst -> done
+ 0 174829 4436207517991 5 inst <- done
+ 0 174829 4436207517997 6 cmd <- if
+ 0 174829 4436207518010 12 cmd -> package
+ 0 174829 4436207518021 10 cmd <- package
+ 0 174829 4436207518034 13 cmd -> if
+ 0 174829 4436207518046 11 inst -> push1
+ 0 174829 4436207518051 5 inst <- push1
+ 0 174829 4436207518057 5 inst -> push1
+ 0 174829 4436207518063 5 inst <- push1
+ 0 174829 4436207518068 5 inst -> push1
+ 0 174829 4436207518074 5 inst <- push1
+ 0 174829 4436207518080 5 inst -> invokeStk1
+ 0 174829 4436207518086 6 cmd -> info
+ 0 174829 4436207518094 7 cmd <- info
+ 0 174829 4436207518099 5 inst <- invokeStk1
+ 0 174829 4436207518105 5 inst -> not
+ 0 174829 4436207518111 6 inst <- not
+ 0 174829 4436207518117 5 inst -> done
+ 0 174829 4436207518123 5 inst <- done
+ 0 174829 4436207518147 24 inst -> push1
+ 0 174829 4436207518153 5 inst <- push1
+ 0 174829 4436207518159 5 inst -> push1
+ 0 174829 4436207518164 5 inst <- push1
+ 0 174829 4436207518170 5 inst -> push1
+ 0 174829 4436207518175 5 inst <- push1
+ 0 174829 4436207518181 5 inst -> invokeStk1
+ 0 174829 4436207518187 6 cmd -> info
+ 0 174829 4436207518212 25 cmd <- info
+ 0 174829 4436207518218 6 inst <- invokeStk1
+ 0 174829 4436207518224 5 inst -> tryCvtToNumeric
+ 0 174829 4436207518230 5 inst <- tryCvtToNumeric
+ 0 174829 4436207518236 5 inst -> jumpFalse1
+ 0 174829 4436207518242 5 inst <- jumpFalse1
+ 0 174829 4436207518248 5 inst -> push1
+ 0 174829 4436207518253 5 inst <- push1
+ 0 174829 4436207518259 5 inst -> push1
+ 0 174829 4436207518264 5 inst <- push1
+ 0 174829 4436207518270 5 inst -> storeScalarStk
+ 0 174829 4436207518278 7 inst <- storeScalarStk
+ 0 174829 4436207518284 5 inst -> done
+ 0 174829 4436207518289 5 inst <- done
+ 0 174829 4436207518295 6 cmd <- if
+ 0 174829 4436207518315 19 cmd -> namespace
+ 0 174829 4436207518421 106 inst -> push1
+ 0 174829 4436207518428 6 inst <- push1
+ 0 174829 4436207518434 5 inst -> push1
+ 0 174829 4436207518440 5 inst <- push1
+ 0 174829 4436207518445 5 inst -> invokeStk1
+ 0 174829 4436207518452 6 cmd -> variable
+ 0 174829 4436207518460 8 cmd <- variable
+ 0 174829 4436207518466 6 inst <- invokeStk1
+ 0 174829 4436207518472 5 inst -> pop
+ 0 174829 4436207518477 5 inst <- pop
+ 0 174829 4436207518483 5 inst -> push1
+ 0 174829 4436207518489 5 inst <- push1
+ 0 174829 4436207518494 5 inst -> push1
+ 0 174829 4436207518500 5 inst <- push1
+ 0 174829 4436207518506 5 inst -> invokeStk1
+ 0 174829 4436207518513 7 cmd -> info
+ 0 174829 4436207518526 13 cmd <- info
+ 0 174829 4436207518532 6 inst <- invokeStk1
+ 0 174829 4436207518538 5 inst -> push1
+ 0 174829 4436207518544 5 inst <- push1
+ 0 174829 4436207518549 5 inst -> strneq
+ 0 174829 4436207518555 6 inst <- strneq
+ 0 174829 4436207518561 5 inst -> push1
+ 0 174829 4436207518567 5 inst <- push1
+ 0 174829 4436207518573 5 inst -> push1
+ 0 174829 4436207518578 5 inst <- push1
+ 0 174829 4436207518584 5 inst -> push1
+ 0 174829 4436207518589 5 inst <- push1
+ 0 174829 4436207518595 5 inst -> push1
+ 0 174829 4436207518600 5 inst <- push1
+ 0 174829 4436207518606 5 inst -> push1
+ 0 174829 4436207518612 5 inst <- push1
+ 0 174829 4436207518617 5 inst -> invokeStk1
+ 0 174829 4436207518624 6 cmd -> info
+ 0 174829 4436207518631 7 cmd <- info
+ 0 174829 4436207518637 6 inst <- invokeStk1
+ 0 174829 4436207518643 5 inst -> push1
+ 0 174829 4436207518648 5 inst <- push1
+ 0 174829 4436207518654 5 inst -> push1
+ 0 174829 4436207518660 5 inst <- push1
+ 0 174829 4436207518665 5 inst -> push1
+ 0 174829 4436207518671 5 inst <- push1
+ 0 174829 4436207518677 5 inst -> push1
+ 0 174829 4436207518682 5 inst <- push1
+ 0 174829 4436207518688 5 inst -> invokeStk1
+ 0 174829 4436207518694 6 cmd -> info
+ 0 174829 4436207518701 7 cmd <- info
+ 0 174829 4436207518707 6 inst <- invokeStk1
+ 0 174829 4436207518713 5 inst -> invokeStk1
+ 0 174829 4436207518720 7 cmd -> file
+ 0 174829 4436207518741 20 cmd <- file
+ 0 174829 4436207518748 6 inst <- invokeStk1
+ 0 174829 4436207518753 5 inst -> invokeStk1
+ 0 174829 4436207518760 6 cmd -> list
+ 0 174829 4436207518768 8 cmd <- list
+ 0 174829 4436207518774 6 inst <- invokeStk1
+ 0 174829 4436207518780 5 inst -> push1
+ 0 174829 4436207518786 5 inst <- push1
+ 0 174829 4436207518791 5 inst -> invokeStk1
+ 0 174829 4436207518798 6 cmd -> foreach
+ 0 174829 4436207518821 23 inst -> push1
+ 0 174829 4436207518827 6 inst <- push1
+ 0 174829 4436207518833 5 inst -> push1
+ 0 174829 4436207518839 5 inst <- push1
+ 0 174829 4436207518844 5 inst -> push1
+ 0 174829 4436207518850 5 inst <- push1
+ 0 174829 4436207518856 5 inst -> loadScalarStk
+ 0 174829 4436207518862 6 inst <- loadScalarStk
+ 0 174829 4436207518868 5 inst -> push1
+ 0 174829 4436207518874 5 inst <- push1
+ 0 174829 4436207518879 5 inst -> loadScalarStk
+ 0 174829 4436207518886 6 inst <- loadScalarStk
+ 0 174829 4436207518892 5 inst -> invokeStk1
+ 0 174829 4436207518898 6 cmd -> lsearch
+ 0 174829 4436207518906 8 cmd <- lsearch
+ 0 174829 4436207518913 6 inst <- invokeStk1
+ 0 174829 4436207518918 5 inst -> push1
+ 0 174829 4436207518924 5 inst <- push1
+ 0 174829 4436207518930 5 inst -> lt
+ 0 174829 4436207518936 6 inst <- lt
+ 0 174829 4436207518942 5 inst -> push1
+ 0 174829 4436207518947 5 inst <- push1
+ 0 174829 4436207518953 5 inst -> push1
+ 0 174829 4436207518958 5 inst <- push1
+ 0 174829 4436207518964 5 inst -> push1
+ 0 174829 4436207518969 5 inst <- push1
+ 0 174829 4436207518975 5 inst -> loadScalarStk
+ 0 174829 4436207518981 6 inst <- loadScalarStk
+ 0 174829 4436207518987 5 inst -> invokeStk1
+ 0 174829 4436207518993 6 cmd -> lappend
+ 0 174829 4436207519002 8 cmd <- lappend
+ 0 174829 4436207519008 6 inst <- invokeStk1
+ 0 174829 4436207519013 5 inst -> jump1
+ 0 174829 4436207519019 5 inst <- jump1
+ 0 174829 4436207519025 5 inst -> done
+ 0 174829 4436207519030 5 inst <- done
+ 0 174829 4436207519038 8 inst -> push1
+ 0 174829 4436207519044 5 inst <- push1
+ 0 174829 4436207519050 5 inst -> push1
+ 0 174829 4436207519055 5 inst <- push1
+ 0 174829 4436207519061 5 inst -> push1
+ 0 174829 4436207519066 5 inst <- push1
+ 0 174829 4436207519072 5 inst -> loadScalarStk
+ 0 174829 4436207519078 5 inst <- loadScalarStk
+ 0 174829 4436207519084 5 inst -> push1
+ 0 174829 4436207519090 5 inst <- push1
+ 0 174829 4436207519095 5 inst -> loadScalarStk
+ 0 174829 4436207519102 6 inst <- loadScalarStk
+ 0 174829 4436207519108 5 inst -> invokeStk1
+ 0 174829 4436207519114 6 cmd -> lsearch
+ 0 174829 4436207519120 6 cmd <- lsearch
+ 0 174829 4436207519126 5 inst <- invokeStk1
+ 0 174829 4436207519132 5 inst -> push1
+ 0 174829 4436207519138 5 inst <- push1
+ 0 174829 4436207519143 5 inst -> lt
+ 0 174829 4436207519149 5 inst <- lt
+ 0 174829 4436207519155 5 inst -> push1
+ 0 174829 4436207519160 5 inst <- push1
+ 0 174829 4436207519166 5 inst -> push1
+ 0 174829 4436207519171 5 inst <- push1
+ 0 174829 4436207519177 5 inst -> push1
+ 0 174829 4436207519182 5 inst <- push1
+ 0 174829 4436207519188 5 inst -> loadScalarStk
+ 0 174829 4436207519194 5 inst <- loadScalarStk
+ 0 174829 4436207519200 5 inst -> invokeStk1
+ 0 174829 4436207519206 6 cmd -> lappend
+ 0 174829 4436207519213 7 cmd <- lappend
+ 0 174829 4436207519219 6 inst <- invokeStk1
+ 0 174829 4436207519225 5 inst -> jump1
+ 0 174829 4436207519231 5 inst <- jump1
+ 0 174829 4436207519236 5 inst -> done
+ 0 174829 4436207519242 5 inst <- done
+ 0 174829 4436207519248 6 cmd <- foreach
+ 0 174829 4436207519255 6 inst <- invokeStk1
+ 0 174829 4436207519260 5 inst -> jump1
+ 0 174829 4436207519266 5 inst <- jump1
+ 0 174829 4436207519272 5 inst -> pop
+ 0 174829 4436207519277 5 inst <- pop
+ 0 174829 4436207519283 5 inst -> push1
+ 0 174829 4436207519288 5 inst <- push1
+ 0 174829 4436207519294 5 inst -> push1
+ 0 174829 4436207519300 5 inst <- push1
+ 0 174829 4436207519305 5 inst -> push1
+ 0 174829 4436207519311 5 inst <- push1
+ 0 174829 4436207519316 5 inst -> push1
+ 0 174829 4436207519322 5 inst <- push1
+ 0 174829 4436207519328 5 inst -> push1
+ 0 174829 4436207519333 5 inst <- push1
+ 0 174829 4436207519339 5 inst -> push1
+ 0 174829 4436207519344 5 inst <- push1
+ 0 174829 4436207519350 5 inst -> push1
+ 0 174829 4436207519356 5 inst <- push1
+ 0 174829 4436207519362 5 inst -> push1
+ 0 174829 4436207519367 5 inst <- push1
+ 0 174829 4436207519373 5 inst -> push1
+ 0 174829 4436207519378 5 inst <- push1
+ 0 174829 4436207519384 5 inst -> invokeStk1
+ 0 174829 4436207519390 6 cmd -> info
+ 0 174829 4436207519399 8 cmd <- info
+ 0 174829 4436207519405 5 inst <- invokeStk1
+ 0 174829 4436207519411 5 inst -> invokeStk1
+ 0 174829 4436207519417 6 cmd -> file
+ 0 174829 4436207519435 18 cmd <- file
+ 0 174829 4436207519442 6 inst <- invokeStk1
+ 0 174829 4436207519448 5 inst -> invokeStk1
+ 0 174829 4436207519454 6 cmd -> file
+ 0 174829 4436207519471 17 cmd <- file
+ 0 174829 4436207519478 6 inst <- invokeStk1
+ 0 174829 4436207519484 5 inst -> push1
+ 0 174829 4436207519490 5 inst <- push1
+ 0 174829 4436207519495 5 inst -> invokeStk1
+ 0 174829 4436207519502 6 cmd -> file
+ 0 174829 4436207519512 9 cmd <- file
+ 0 174829 4436207519518 6 inst <- invokeStk1
+ 0 174829 4436207519524 5 inst -> storeScalarStk
+ 0 174829 4436207519530 6 inst <- storeScalarStk
+ 0 174829 4436207519536 6 inst -> push1
+ 0 174829 4436207519542 5 inst <- push1
+ 0 174829 4436207519547 5 inst -> push1
+ 0 174829 4436207519553 5 inst <- push1
+ 0 174829 4436207519559 5 inst -> push1
+ 0 174829 4436207519564 5 inst <- push1
+ 0 174829 4436207519570 5 inst -> loadScalarStk
+ 0 174829 4436207519576 6 inst <- loadScalarStk
+ 0 174829 4436207519582 5 inst -> push1
+ 0 174829 4436207519587 5 inst <- push1
+ 0 174829 4436207519593 5 inst -> loadScalarStk
+ 0 174829 4436207519599 5 inst <- loadScalarStk
+ 0 174829 4436207519605 5 inst -> invokeStk1
+ 0 174829 4436207519611 6 cmd -> lsearch
+ 0 174829 4436207519617 6 cmd <- lsearch
+ 0 174829 4436207519623 6 inst <- invokeStk1
+ 0 174829 4436207519629 5 inst -> push1
+ 0 174829 4436207519635 5 inst <- push1
+ 0 174829 4436207519640 5 inst -> lt
+ 0 174829 4436207519646 5 inst <- lt
+ 0 174829 4436207519652 5 inst -> push1
+ 0 174829 4436207519657 5 inst <- push1
+ 0 174829 4436207519663 5 inst -> push1
+ 0 174829 4436207519668 5 inst <- push1
+ 0 174829 4436207519674 5 inst -> push1
+ 0 174829 4436207519679 5 inst <- push1
+ 0 174829 4436207519685 5 inst -> loadScalarStk
+ 0 174829 4436207519691 5 inst <- loadScalarStk
+ 0 174829 4436207519697 5 inst -> invokeStk1
+ 0 174829 4436207519703 6 cmd -> lappend
+ 0 174829 4436207519710 6 cmd <- lappend
+ 0 174829 4436207519716 6 inst <- invokeStk1
+ 0 174829 4436207519722 5 inst -> jump1
+ 0 174829 4436207519727 5 inst <- jump1
+ 0 174829 4436207519733 5 inst -> pop
+ 0 174829 4436207519739 5 inst <- pop
+ 0 174829 4436207519744 5 inst -> push1
+ 0 174829 4436207519750 5 inst <- push1
+ 0 174829 4436207519756 5 inst -> push1
+ 0 174829 4436207519761 5 inst <- push1
+ 0 174829 4436207519767 5 inst -> push1
+ 0 174829 4436207519772 5 inst <- push1
+ 0 174829 4436207519778 5 inst -> invokeStk1
+ 0 174829 4436207519784 6 cmd -> info
+ 0 174829 4436207519791 6 cmd <- info
+ 0 174829 4436207519797 6 inst <- invokeStk1
+ 0 174829 4436207519803 5 inst -> tryCvtToNumeric
+ 0 174829 4436207519809 5 inst <- tryCvtToNumeric
+ 0 174829 4436207519815 5 inst -> jumpFalse1
+ 0 174829 4436207519820 5 inst <- jumpFalse1
+ 0 174829 4436207519826 5 inst -> push1
+ 0 174829 4436207519832 5 inst <- push1
+ 0 174829 4436207519837 5 inst -> push1
+ 0 174829 4436207519843 5 inst <- push1
+ 0 174829 4436207519849 5 inst -> push1
+ 0 174829 4436207519854 5 inst <- push1
+ 0 174829 4436207519860 5 inst -> loadScalarStk
+ 0 174829 4436207519866 6 inst <- loadScalarStk
+ 0 174829 4436207519872 5 inst -> push1
+ 0 174829 4436207519877 5 inst <- push1
+ 0 174829 4436207519883 5 inst -> invokeStk1
+ 0 174829 4436207519889 6 cmd -> foreach
+ 0 174829 4436207519899 9 inst -> push1
+ 0 174829 4436207519904 5 inst <- push1
+ 0 174829 4436207519910 5 inst -> push1
+ 0 174829 4436207519915 5 inst <- push1
+ 0 174829 4436207519921 5 inst -> push1
+ 0 174829 4436207519927 5 inst <- push1
+ 0 174829 4436207519932 5 inst -> loadScalarStk
+ 0 174829 4436207519938 6 inst <- loadScalarStk
+ 0 174829 4436207519944 5 inst -> push1
+ 0 174829 4436207519950 5 inst <- push1
+ 0 174829 4436207519955 5 inst -> loadScalarStk
+ 0 174829 4436207519962 6 inst <- loadScalarStk
+ 0 174829 4436207519968 5 inst -> invokeStk1
+ 0 174829 4436207519974 6 cmd -> lsearch
+ 0 174829 4436207519980 6 cmd <- lsearch
+ 0 174829 4436207519986 6 inst <- invokeStk1
+ 0 174829 4436207519992 5 inst -> push1
+ 0 174829 4436207519998 5 inst <- push1
+ 0 174829 4436207520003 5 inst -> lt
+ 0 174829 4436207520009 5 inst <- lt
+ 0 174829 4436207520015 5 inst -> push1
+ 0 174829 4436207520020 5 inst <- push1
+ 0 174829 4436207520026 5 inst -> push1
+ 0 174829 4436207520031 5 inst <- push1
+ 0 174829 4436207520037 5 inst -> push1
+ 0 174829 4436207520043 5 inst <- push1
+ 0 174829 4436207520048 5 inst -> loadScalarStk
+ 0 174829 4436207520054 5 inst <- loadScalarStk
+ 0 174829 4436207520060 5 inst -> invokeStk1
+ 0 174829 4436207520066 6 cmd -> lappend
+ 0 174829 4436207520073 6 cmd <- lappend
+ 0 174829 4436207520079 5 inst <- invokeStk1
+ 0 174829 4436207520085 5 inst -> jump1
+ 0 174829 4436207520090 5 inst <- jump1
+ 0 174829 4436207520096 5 inst -> done
+ 0 174829 4436207520102 5 inst <- done
+ 0 174829 4436207520108 6 cmd <- foreach
+ 0 174829 4436207520114 5 inst <- invokeStk1
+ 0 174829 4436207520119 5 inst -> jump1
+ 0 174829 4436207520125 5 inst <- jump1
+ 0 174829 4436207520131 5 inst -> done
+ 0 174829 4436207520136 5 inst <- done
+ 0 174829 4436207520143 6 cmd <- namespace
+ 0 174829 4436207520171 28 cmd -> if
+ 0 174829 4436207520192 20 inst -> push1
+ 0 174829 4436207520198 6 inst <- push1
+ 0 174829 4436207520203 5 inst -> push1
+ 0 174829 4436207520209 5 inst <- push1
+ 0 174829 4436207520215 5 inst -> invokeStk1
+ 0 174829 4436207520221 6 cmd -> interp
+ 0 174829 4436207520230 9 cmd <- interp
+ 0 174829 4436207520236 5 inst <- invokeStk1
+ 0 174829 4436207520242 5 inst -> not
+ 0 174829 4436207520247 5 inst <- not
+ 0 174829 4436207520253 5 inst -> jumpTrue1
+ 0 174829 4436207520259 5 inst <- jumpTrue1
+ 0 174829 4436207520265 5 inst -> push1
+ 0 174829 4436207520270 5 inst <- push1
+ 0 174829 4436207520276 5 inst -> dup
+ 0 174829 4436207520281 5 inst <- dup
+ 0 174829 4436207520287 5 inst -> jumpFalse1
+ 0 174829 4436207520293 5 inst <- jumpFalse1
+ 0 174829 4436207520298 5 inst -> push1
+ 0 174829 4436207520304 5 inst <- push1
+ 0 174829 4436207520310 5 inst -> push1
+ 0 174829 4436207520315 5 inst <- push1
+ 0 174829 4436207520321 5 inst -> loadArrayStk
+ 0 174829 4436207520328 6 inst <- loadArrayStk
+ 0 174829 4436207520334 5 inst -> push1
+ 0 174829 4436207520339 5 inst <- push1
+ 0 174829 4436207520345 5 inst -> streq
+ 0 174829 4436207520351 5 inst <- streq
+ 0 174829 4436207520357 5 inst -> land
+ 0 174829 4436207520363 6 inst <- land
+ 0 174829 4436207520368 5 inst -> done
+ 0 174829 4436207520374 5 inst <- done
+ 0 174829 4436207520381 6 cmd <- if
+ 0 174829 4436207520394 13 cmd -> package
+ 0 174829 4436207520401 6 cmd <- package
+ 0 174829 4436207520413 11 cmd -> if
+ 0 174829 4436207520424 11 inst -> push1
+ 0 174829 4436207520429 5 inst <- push1
+ 0 174829 4436207520435 5 inst -> push1
+ 0 174829 4436207520441 5 inst <- push1
+ 0 174829 4436207520446 5 inst -> invokeStk1
+ 0 174829 4436207520453 6 cmd -> interp
+ 0 174829 4436207520459 6 cmd <- interp
+ 0 174829 4436207520465 5 inst <- invokeStk1
+ 0 174829 4436207520471 5 inst -> not
+ 0 174829 4436207520476 5 inst <- not
+ 0 174829 4436207520482 5 inst -> done
+ 0 174829 4436207520488 5 inst <- done
+ 0 174829 4436207520527 39 inst -> push1
+ 0 174829 4436207520533 5 inst <- push1
+ 0 174829 4436207520539 5 inst -> push1
+ 0 174829 4436207520544 5 inst <- push1
+ 0 174829 4436207520550 5 inst -> loadArrayStk
+ 0 174829 4436207520557 6 inst <- loadArrayStk
+ 0 174829 4436207520563 5 inst -> push1
+ 0 174829 4436207520568 5 inst <- push1
+ 0 174829 4436207520574 5 inst -> streq
+ 0 174829 4436207520580 5 inst <- streq
+ 0 174829 4436207520586 5 inst -> push1
+ 0 174829 4436207520591 5 inst <- push1
+ 0 174829 4436207520597 5 inst -> dup
+ 0 174829 4436207520602 5 inst <- dup
+ 0 174829 4436207520608 5 inst -> jumpFalse1
+ 0 174829 4436207520614 5 inst <- jumpFalse1
+ 0 174829 4436207520619 5 inst -> push1
+ 0 174829 4436207520625 5 inst <- push1
+ 0 174829 4436207520631 5 inst -> push1
+ 0 174829 4436207520636 5 inst <- push1
+ 0 174829 4436207520642 5 inst -> loadArrayStk
+ 0 174829 4436207520648 6 inst <- loadArrayStk
+ 0 174829 4436207520654 5 inst -> push1
+ 0 174829 4436207520660 5 inst <- push1
+ 0 174829 4436207520665 5 inst -> streq
+ 0 174829 4436207520671 5 inst <- streq
+ 0 174829 4436207520677 5 inst -> land
+ 0 174829 4436207520682 5 inst <- land
+ 0 174829 4436207520688 5 inst -> jumpFalse1
+ 0 174829 4436207520694 5 inst <- jumpFalse1
+ 0 174829 4436207520700 5 inst -> push1
+ 0 174829 4436207520705 5 inst <- push1
+ 0 174829 4436207520711 5 inst -> pop
+ 0 174829 4436207520716 5 inst <- pop
+ 0 174829 4436207520722 5 inst -> push1
+ 0 174829 4436207520728 5 inst <- push1
+ 0 174829 4436207520733 5 inst -> push1
+ 0 174829 4436207520739 5 inst <- push1
+ 0 174829 4436207520744 5 inst -> loadArrayStk
+ 0 174829 4436207520751 6 inst <- loadArrayStk
+ 0 174829 4436207520757 5 inst -> push1
+ 0 174829 4436207520762 5 inst <- push1
+ 0 174829 4436207520768 5 inst -> streq
+ 0 174829 4436207520773 5 inst <- streq
+ 0 174829 4436207520779 5 inst -> push1
+ 0 174829 4436207520785 5 inst <- push1
+ 0 174829 4436207520791 5 inst -> done
+ 0 174829 4436207520796 5 inst <- done
+ 0 174829 4436207520802 6 cmd <- if
+ 0 174829 4436207520822 19 cmd -> if
+ 0 174829 4436207520835 13 inst -> push1
+ 0 174829 4436207520841 5 inst <- push1
+ 0 174829 4436207520847 5 inst -> push1
+ 0 174829 4436207520852 5 inst <- push1
+ 0 174829 4436207520858 5 inst -> push1
+ 0 174829 4436207520864 5 inst <- push1
+ 0 174829 4436207520869 5 inst -> push1
+ 0 174829 4436207520875 5 inst <- push1
+ 0 174829 4436207520881 5 inst -> invokeStk1
+ 0 174829 4436207520887 6 cmd -> namespace
+ 0 174829 4436207520896 8 cmd <- namespace
+ 0 174829 4436207520902 6 inst <- invokeStk1
+ 0 174829 4436207520908 5 inst -> push1
+ 0 174829 4436207520913 5 inst <- push1
+ 0 174829 4436207520919 5 inst -> streq
+ 0 174829 4436207520925 6 inst <- streq
+ 0 174829 4436207520931 5 inst -> done
+ 0 174829 4436207520936 5 inst <- done
+ 0 174829 4436207520942 6 cmd <- if
+ 0 174829 4436207521503 560 cmd -> set
+ 0 174829 4436207521515 11 cmd <- set
+ 0 174829 4436207521524 9 cmd -> set
+ 0 174829 4436207521531 6 cmd <- set
+ 0 174829 4436207521541 10 cmd -> if
+ 0 174829 4436207521559 17 inst -> push1
+ 0 174829 4436207521566 7 inst <- push1
+ 0 174829 4436207521573 6 inst -> push1
+ 0 174829 4436207521578 5 inst <- push1
+ 0 174829 4436207521584 5 inst -> push1
+ 0 174829 4436207521590 5 inst <- push1
+ 0 174829 4436207521596 5 inst -> push1
+ 0 174829 4436207521601 5 inst <- push1
+ 0 174829 4436207521607 5 inst -> invokeStk1
+ 0 174829 4436207521613 6 cmd -> namespace
+ 0 174829 4436207521621 7 cmd <- namespace
+ 0 174829 4436207521627 6 inst <- invokeStk1
+ 0 174829 4436207521633 5 inst -> push1
+ 0 174829 4436207521639 5 inst <- push1
+ 0 174829 4436207521644 5 inst -> streq
+ 0 174829 4436207521650 5 inst <- streq
+ 0 174829 4436207521656 5 inst -> done
+ 0 174829 4436207521662 5 inst <- done
+ 0 174829 4436207521674 11 inst -> push1
+ 0 174829 4436207521679 5 inst <- push1
+ 0 174829 4436207521685 5 inst -> push1
+ 0 174829 4436207521691 5 inst <- push1
+ 0 174829 4436207521697 5 inst -> push1
+ 0 174829 4436207521702 5 inst <- push1
+ 0 174829 4436207521708 5 inst -> push1
+ 0 174829 4436207521714 5 inst <- push1
+ 0 174829 4436207521720 5 inst -> invokeStk1
+ 0 174829 4436207521726 6 cmd -> proc
+ 0 174829 4436207521738 12 cmd <- proc
+ 0 174829 4436207521744 6 inst <- invokeStk1
+ 0 174829 4436207521750 5 inst -> done
+ 0 174829 4436207521756 5 inst <- done
+ 0 174829 4436207521762 6 cmd <- if
+ 0 174829 4436207521862 99 cmd -> proc
+ 0 174829 4436207521872 10 cmd <- proc
+ 0 174829 4436207521891 19 cmd -> proc
+ 0 174829 4436207521902 10 cmd <- proc
+ 0 174829 4436207521932 30 cmd -> proc
+ 0 174829 4436207521941 8 cmd <- proc
+ 0 174829 4436207521961 19 cmd -> proc
+ 0 174829 4436207521970 9 cmd <- proc
+ 0 174829 4436207521985 14 cmd -> proc
+ 0 174829 4436207521994 8 cmd <- proc
+ 0 174829 4436207522039 45 cmd -> if
+ 0 174829 4436207522053 14 inst -> push1
+ 0 174829 4436207522059 5 inst <- push1
+ 0 174829 4436207522065 6 inst -> push1
+ 0 174829 4436207522070 5 inst <- push1
+ 0 174829 4436207522076 5 inst -> loadArrayStk
+ 0 174829 4436207522083 7 inst <- loadArrayStk
+ 0 174829 4436207522089 5 inst -> push1
+ 0 174829 4436207522094 5 inst <- push1
+ 0 174829 4436207522100 5 inst -> streq
+ 0 174829 4436207522106 5 inst <- streq
+ 0 174829 4436207522112 5 inst -> done
+ 0 174829 4436207522117 5 inst <- done
+ 0 174829 4436207522134 16 inst -> push1
+ 0 174829 4436207522140 5 inst <- push1
+ 0 174829 4436207522146 5 inst -> push1
+ 0 174829 4436207522151 5 inst <- push1
+ 0 174829 4436207522157 5 inst -> push1
+ 0 174829 4436207522163 5 inst <- push1
+ 0 174829 4436207522168 5 inst -> push1
+ 0 174829 4436207522174 5 inst <- push1
+ 0 174829 4436207522180 5 inst -> invokeStk1
+ 0 174829 4436207522186 6 cmd -> proc
+ 0 174829 4436207522205 19 cmd <- proc
+ 0 174829 4436207522212 6 inst <- invokeStk1
+ 0 174829 4436207522218 5 inst -> done
+ 0 174829 4436207522223 5 inst <- done
+ 0 174829 4436207522230 6 cmd <- if
+ 0 174829 4436207522274 44 cmd -> proc
+ 0 174829 4436207522286 11 cmd <- proc
+ 0 174829 4436207522294 8 cmd <- source
+ 0 174829 4436207522301 6 cmd <- uplevel
+ 0 174829 4436207522307 6 inst <- invokeStk1
+ 0 174829 4436207522313 6 inst -> storeScalar1
+ 0 174829 4436207522319 5 inst <- storeScalar1
+ 0 174829 4436207522325 5 inst -> push1
+ 0 174829 4436207522331 5 inst <- push1
+ 0 174829 4436207522337 5 inst -> jump1
+ 0 174829 4436207522342 5 inst <- jump1
+ 0 174829 4436207522348 5 inst -> endCatch
+ 0 174829 4436207522354 5 inst <- endCatch
+ 0 174829 4436207522360 5 inst -> not
+ 0 174829 4436207522366 5 inst <- not
+ 0 174829 4436207522371 5 inst -> jumpFalse1
+ 0 174829 4436207522377 5 inst <- jumpFalse1
+ 0 174829 4436207522383 5 inst -> push1
+ 0 174829 4436207522389 5 inst <- push1
+ 0 174829 4436207522394 5 inst -> done
+ 0 174829 4436207522400 5 inst <- done
+ 0 174829 4436207522409 8 proc <- tclInit
+ 0 174829 4436207522426 17 cmd <- tclInit
+ 0 174829 4436207522671 245 cmd -> proc
+ 0 174829 4436207522681 9 cmd <- proc
+ 0 174829 4436207522691 9 cmd -> proc
+ 0 174829 4436207522698 7 cmd <- proc
+ 0 174829 4436207522708 9 cmd -> proc
+ 0 174829 4436207522715 7 cmd <- proc
+ 0 174829 4436207522723 8 cmd -> func_a
+ 0 174829 4436207522742 18 proc -> func_a
+ 0 174829 4436207522752 10 inst -> push1
+ 0 174829 4436207522757 5 inst <- push1
+ 0 174829 4436207522763 5 inst -> push1
+ 0 174829 4436207522769 5 inst <- push1
+ 0 174829 4436207522775 5 inst -> invokeStk1
+ 0 174829 4436207522781 6 cmd -> puts
+ 0 174829 4436207523212 430 cmd <- puts
+ 0 174829 4436207523266 54 inst <- invokeStk1
+ 0 174829 4436207523275 8 inst -> pop
+ 0 174829 4436207523281 6 inst <- pop
+ 0 174829 4436207523287 5 inst -> push1
+ 0 174829 4436207523292 5 inst <- push1
+ 0 174829 4436207523298 5 inst -> push1
+ 0 174829 4436207523304 5 inst <- push1
+ 0 174829 4436207523310 5 inst -> invokeStk1
+ 0 174829 4436207523318 7 cmd -> after
+ 0 174829 4436208530951 1007632 cmd <- after
+ 0 174829 4436208530972 21 inst <- invokeStk1
+ 0 174829 4436208530984 12 inst -> pop
+ 0 174829 4436208530993 9 inst <- pop
+ 0 174829 4436208530999 5 inst -> push1
+ 0 174829 4436208531005 5 inst <- push1
+ 0 174829 4436208531010 5 inst -> invokeStk1
+ 0 174829 4436208531021 10 cmd -> func_b
+ 0 174829 4436208531057 35 proc -> func_b
+ 0 174829 4436208531067 10 inst -> push1
+ 0 174829 4436208531073 5 inst <- push1
+ 0 174829 4436208531079 5 inst -> push1
+ 0 174829 4436208531084 5 inst <- push1
+ 0 174829 4436208531090 5 inst -> invokeStk1
+ 0 174829 4436208531096 6 cmd -> puts
+ 0 174829 4436208531137 40 cmd <- puts
+ 0 174829 4436208531144 6 inst <- invokeStk1
+ 0 174829 4436208531150 5 inst -> pop
+ 0 174829 4436208531155 5 inst <- pop
+ 0 174829 4436208531161 5 inst -> push1
+ 0 174829 4436208531166 5 inst <- push1
+ 0 174829 4436208531172 5 inst -> push1
+ 0 174829 4436208531178 5 inst <- push1
+ 0 174829 4436208531184 5 inst -> invokeStk1
+ 0 174829 4436208531190 6 cmd -> after
+ 0 174829 4436209540924 1009734 cmd <- after
+ 0 174829 4436209540946 21 inst <- invokeStk1
+ 0 174829 4436209540957 11 inst -> pop
+ 0 174829 4436209540967 9 inst <- pop
+ 0 174829 4436209540973 5 inst -> push1
+ 0 174829 4436209540978 5 inst <- push1
+ 0 174829 4436209540984 5 inst -> invokeStk1
+ 0 174829 4436209540995 10 cmd -> func_c
+ 0 174829 4436209541029 34 proc -> func_c
+ 0 174829 4436209541039 10 inst -> push1
+ 0 174829 4436209541045 5 inst <- push1
+ 0 174829 4436209541051 5 inst -> push1
+ 0 174829 4436209541056 5 inst <- push1
+ 0 174829 4436209541062 5 inst -> invokeStk1
+ 0 174829 4436209541068 6 cmd -> puts
+ 0 174829 4436209541111 42 cmd <- puts
+ 0 174829 4436209541118 7 inst <- invokeStk1
+ 0 174829 4436209541124 5 inst -> pop
+ 0 174829 4436209541129 5 inst <- pop
+ 0 174829 4436209541135 5 inst -> push1
+ 0 174829 4436209541141 5 inst <- push1
+ 0 174829 4436209541147 5 inst -> push1
+ 0 174829 4436209541153 5 inst <- push1
+ 0 174829 4436209541158 5 inst -> invokeStk1
+ 0 174829 4436209541165 6 cmd -> after
+ 0 174829 4436210550785 1009619 cmd <- after
+ 0 174829 4436210550807 22 inst <- invokeStk1
+ 0 174829 4436210550819 11 inst -> done
+ 0 174829 4436210550830 10 inst <- done
+ 0 174829 4436210550839 9 proc <- func_c
+ 0 174829 4436210550850 11 cmd <- func_c
+ 0 174829 4436210550856 6 inst <- invokeStk1
+ 0 174829 4436210550862 5 inst -> done
+ 0 174829 4436210550868 5 inst <- done
+ 0 174829 4436210550874 6 proc <- func_b
+ 0 174829 4436210550880 6 cmd <- func_b
+ 0 174829 4436210550887 6 inst <- invokeStk1
+ 0 174829 4436210550892 5 inst -> done
+ 0 174829 4436210550898 5 inst <- done
+ 0 174829 4436210550904 6 proc <- func_a
+ 0 174829 4436210550911 6 cmd <- func_a
+ 0 174829 4436210550938 27 cmd -> exit
+
+As you can see the output is quite long, and in seven columns. The first
+column is the CPU the action is on. The second is the PID. The third is the
+time since boot in microseconds.
+
+The fourth column is the number of microseconds that has elapsed between the
+previous line and the current one.
+
+The fifth column is the type of event that occurred (procedure, command or
+instruction).
+
+The sixth and seventh columns are indented by 2 spaces to show when a new
+event occurs. This shows us which command is calling which.
+
+If the output looks strange, check the CPU "C" column - if it changes,
+then the output is probably shuffled. See Notes/ALLsnoop_notes.txt for
+details and suggested workarounds.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_proccalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_proccalls_example.txt
new file mode 100644
index 0000000..ed6820d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_proccalls_example.txt
@@ -0,0 +1,17 @@
+Following are examples of running tcl_proccalls.d.
+
+The output shows what happens when the code from Code/Tcl/func_abc.tcl is
+traced.
+
+# tcl_proccalls.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID COUNT PROCEDURE
+ 16078 1 func_a
+ 16078 1 func_b
+ 16078 1 func_c
+ 16078 1 tclInit
+
+This simple output shows that PID 16078 was responsible for four procedures
+beginning, one each of func_a, func_b, func_c, and tclInit.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_procflow_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_procflow_example.txt
new file mode 100644
index 0000000..93b822e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_procflow_example.txt
@@ -0,0 +1,29 @@
+The following are examples of tcl_procflow.d.
+
+This is a simple script to trace the flow of Tcl procedures.
+
+Here it traces the example program, Code/Tcl/func_abc.tcl.
+
+# tcl_procflow.d
+ C PID TIME(us) -- PROCEDURE
+ 0 16073 3904971507502 -> tclInit
+ 0 16073 3904971509096 <- tclInit
+ 0 16073 3904971509305 -> func_a
+ 0 16073 3904972511039 -> func_b
+ 0 16073 3904973521023 -> func_c
+ 0 16073 3904974530998 <- func_c
+ 0 16073 3904974531008 <- func_b
+ 0 16073 3904974531014 <- func_a
+^C
+
+As each procedure starts, the third column is indented by 2 spaces. This
+shows which procedure is calling which - the output above begins with an init
+procedure and then shows that func_a began, and then called func_b.
+
+The columns are CPU, PID, Time since boot, indicator and procedure name.
+
+If the output looks shuffled, check the CPU "C" and "TIME" columns, and
+post sort based on TIME if necessary.
+
+See Notes/ALLflow_notes.txt for important notes about reading flow outputs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_stat_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_stat_example.txt
new file mode 100644
index 0000000..178fef1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_stat_example.txt
@@ -0,0 +1,24 @@
+Following are examples of running tcl_stat.d on Tcl programs.
+
+tcl_stat.d shows you the number of events per second that have happened since
+the last line output. The default interval is 1 second, but you can specify
+other intervals as arguments to the script.
+
+This shows the sh_stat.d script reflecting the Code/Tcl/func_abc.tcl program.
+
+# tcl_stat.d
+TIME EXEC/s PROC/s CMD/s OBJNEW/s OBJFRE/s OP/s
+2007 Sep 26 23:34:36 0 0 0 0 0 0
+2007 Sep 26 23:34:37 1 2 75 911 805 377
+2007 Sep 26 23:34:38 0 1 3 4 2 10
+2007 Sep 26 23:34:39 0 1 3 3 2 10
+2007 Sep 26 23:34:40 0 0 1 7 8 3
+2007 Sep 26 23:34:41 0 0 0 0 0 0
+2007 Sep 26 23:34:42 0 0 0 0 0 0
+^C
+
+ At 2007 Sep 26 23:34:37 we can see that there was one Tcl program executed
+(this number may include those programs without Tcl provider support), two
+procedures called, 75 new commands created, 911 objects created, 805 objects
+freed, and 377 bytecode operations.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_syscalls_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_syscalls_example.txt
new file mode 100644
index 0000000..5553b1c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_syscalls_example.txt
@@ -0,0 +1,66 @@
+The following are examples of sh_syscalls.d.
+
+This is a simple script to count Tcl commands, procedures and system calls.
+
+Here we trace an example program - Code/Tcl/func_abc.tcl.
+
+# tcl_syscalls.d -c './tclsh func_abc.tcl '
+Tracing... Hit Ctrl-C to end.
+Function A
+Function B
+Function C
+ PID TYPE NAME COUNT
+ 16580 cmd concat 1
+ 16580 cmd exit 1
+ 16580 cmd func_a 1
+ 16580 cmd func_b 1
+ 16580 cmd func_c 1
+ 16580 cmd list 1
+ 16580 cmd rename 1
+ 16580 cmd source 1
+ 16580 cmd tclInit 1
+ 16580 cmd unset 1
+ 16580 cmd uplevel 1
+ 16580 cmd variable 1
+ 16580 proc func_a 1
+ 16580 proc func_b 1
+ 16580 proc func_c 1
+ 16580 proc tclInit 1
+ 16580 syscall getpid 1
+ 16580 syscall getrlimit 1
+ 16580 syscall mmap 1
+ 16580 syscall munmap 1
+ 16580 syscall rexit 1
+ 16580 syscall sigaction 1
+ 16580 syscall sigpending 1
+ 16580 syscall sysi86 1
+ 16580 syscall uname 1
+ 16580 cmd foreach 2
+ 16580 cmd global 2
+ 16580 cmd interp 2
+ 16580 cmd package 2
+ 16580 cmd set 2
+ 16580 syscall setcontext 2
+ 16580 syscall stat64 2
+ 16580 syscall sysconfig 2
+ 16580 cmd after 3
+ 16580 cmd namespace 3
+ 16580 cmd puts 3
+ 16580 syscall pollsys 3
+ 16580 syscall write 3
+ 16580 cmd lappend 4
+ 16580 cmd lsearch 4
+ 16580 syscall close 5
+ 16580 syscall llseek 6
+ 16580 cmd if 8
+ 16580 cmd info 11
+ 16580 syscall read 11
+ 16580 cmd file 12
+ 16580 cmd proc 12
+ 16580 syscall fcntl 12
+ 16580 syscall ioctl 12
+ 16580 syscall open64 14
+ 16580 syscall resolvepath 25
+ 16580 syscall brk 27
+ 16580 syscall access 54
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_syscolors_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_syscolors_example.txt
new file mode 100644
index 0000000..b592986
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_syscolors_example.txt
@@ -0,0 +1,563 @@
+The following are examples of tcl_syscolors.d.
+
+This is a simple script to trace the flow of Tcl processes, Tcl commands and
+system calls made, and renders the output in color ("colour") using terminal
+escape sequences (which you can tweak by modifying the script).
+
+Here it traces the example program, Code/Tcl/func_abc.tcl.
+
+WARNING: This output is full of terminal escape sequences, so if you are
+trying to view this through an editor or web browser - it may look awful.
+Try viewing this using "more" (although, depending on your terminal, it
+still may look awful).
+
+# tcl_syscolors.d -c './tclsh func_abc.tcl
+Function A
+ C PID DELTA(us) TYPE -- NAME
+ 0 16624 2 syscall -> munmap
+ 0 16624 31 syscall <- munmap
+ 0 16624 52 syscall -> mmap
+ 0 16624 21 syscall <- mmap
+ 0 16624 38 syscall -> setcontext
+ 0 16624 8 syscall <- setcontext
+ 0 16624 8 syscall -> getrlimit
+ 0 16624 9 syscall <- getrlimit
+ 0 16624 8 syscall -> getpid
+ 0 16624 7 syscall <- getpid
+ 0 16624 68 syscall -> setcontext
+ 0 16624 7 syscall <- setcontext
+ 0 16624 177 syscall -> sigpending
+ 0 16624 8 syscall <- sigpending
+ 0 16624 88 syscall -> sysconfig
+ 0 16624 7 syscall <- sysconfig
+ 0 16624 107 syscall -> open64
+ 0 16624 115 syscall <- open64
+ 0 16624 13 syscall -> ioctl
+ 0 16624 64 syscall <- ioctl
+ 0 16624 16 syscall -> close
+ 0 16624 17 syscall <- close
+ 0 16624 1208 syscall -> sysi86
+ 0 16624 9 syscall <- sysi86
+ 0 16624 146 syscall -> llseek
+ 0 16624 10 syscall <- llseek
+ 0 16624 7 syscall -> llseek
+ 0 16624 7 syscall <- llseek
+ 0 16624 7 syscall -> llseek
+ 0 16624 6 syscall <- llseek
+ 0 16624 24 syscall -> sigaction
+ 0 16624 8 syscall <- sigaction
+ 0 16624 63 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 14 syscall <- brk
+ 0 16624 76 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 12 syscall <- brk
+ 0 16624 328 syscall -> resolvepath
+ 0 16624 35 syscall <- resolvepath
+ 0 16624 24 syscall -> access
+ 0 16624 10 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 10 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 16 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 17 syscall <- resolvepath
+ 0 16624 32 syscall -> open64
+ 0 16624 22 syscall <- open64
+ 0 16624 32 syscall -> resolvepath
+ 0 16624 18 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 15 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 16 syscall <- open64
+ 0 16624 30 syscall -> resolvepath
+ 0 16624 23 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 21 syscall <- open64
+ 0 16624 29 syscall -> resolvepath
+ 0 16624 17 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 15 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 15 syscall <- open64
+ 0 16624 30 syscall -> resolvepath
+ 0 16624 20 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 20 syscall <- open64
+ 0 16624 29 syscall -> resolvepath
+ 0 16624 16 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 10 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 14 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 14 syscall <- open64
+ 0 16624 28 syscall -> resolvepath
+ 0 16624 20 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 43 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 13 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 14 syscall <- open64
+ 0 16624 10 syscall -> sysconfig
+ 0 16624 7 syscall <- sysconfig
+ 0 16624 33 syscall -> resolvepath
+ 0 16624 19 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 15 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 17 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 18 syscall <- open64
+ 0 16624 30 syscall -> resolvepath
+ 0 16624 17 syscall <- resolvepath
+ 0 16624 7 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 15 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 16 syscall <- open64
+ 0 16624 30 syscall -> resolvepath
+ 0 16624 21 syscall <- resolvepath
+ 0 16624 11 syscall -> open64
+ 0 16624 25 syscall <- open64
+ 0 16624 15 syscall -> fcntl
+ 0 16624 7 syscall <- fcntl
+ 0 16624 31 syscall -> ioctl
+ 0 16624 8 syscall <- ioctl
+ 0 16624 49 syscall -> brk
+ 0 16624 8 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 11 syscall <- brk
+ 0 16624 30 syscall -> read
+ 0 16624 35 syscall <- read
+ 0 16624 54 syscall -> read
+ 0 16624 8 syscall <- read
+ 0 16624 21 syscall -> close
+ 0 16624 10 syscall <- close
+ 0 16624 51 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 111 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 8 syscall <- brk
+ 0 16624 94 syscall -> uname
+ 0 16624 8 syscall <- uname
+ 0 16624 47 syscall -> ioctl
+ 0 16624 35 syscall <- ioctl
+ 0 16624 73 cmd -> if
+ 0 16624 89 cmd -> info
+ 0 16624 25 cmd <- info
+ 0 16624 46 cmd -> proc
+ 0 16624 11 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 23 cmd <- proc
+ 0 16624 9 cmd <- if
+ 0 16624 18 cmd -> tclInit
+ 0 16624 223 proc -> tclInit
+ 0 16624 12 cmd -> global
+ 0 16624 12 cmd <- global
+ 0 16624 9 cmd -> global
+ 0 16624 9 cmd <- global
+ 0 16624 8 cmd -> rename
+ 0 16624 24 cmd <- rename
+ 0 16624 13 cmd -> info
+ 0 16624 12 cmd <- info
+ 0 16624 13 cmd -> info
+ 0 16624 19 cmd <- info
+ 0 16624 11 cmd -> unset
+ 0 16624 13 cmd <- unset
+ 0 16624 9 cmd -> concat
+ 0 16624 15 cmd <- concat
+ 0 16624 18 cmd -> file
+ 0 16624 20 cmd <- file
+ 0 16624 8 cmd -> file
+ 0 16624 25 syscall -> resolvepath
+ 0 16624 24 syscall <- resolvepath
+ 0 16624 9 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 12 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 14 syscall <- resolvepath
+ 0 16624 12 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 9 cmd <- file
+ 0 16624 10 cmd -> file
+ 0 16624 12 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 24 syscall -> resolvepath
+ 0 16624 23 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 8 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 16 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 17 syscall <- resolvepath
+ 0 16624 12 syscall -> access
+ 0 16624 16 syscall <- access
+ 0 16624 29 cmd <- file
+ 0 16624 10 cmd -> file
+ 0 16624 12 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 23 syscall -> resolvepath
+ 0 16624 20 syscall <- resolvepath
+ 0 16624 8 syscall -> access
+ 0 16624 9 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 10 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 11 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 13 syscall <- access
+ 0 16624 7 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 syscall -> resolvepath
+ 0 16624 15 syscall <- resolvepath
+ 0 16624 11 syscall -> access
+ 0 16624 14 syscall <- access
+ 0 16624 7 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 12 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 23 syscall -> resolvepath
+ 0 16624 20 syscall <- resolvepath
+ 0 16624 11 syscall -> access
+ 0 16624 19 syscall <- access
+ 0 16624 7 cmd <- file
+ 0 16624 10 cmd -> uplevel
+ 0 16624 13 cmd -> source
+ 0 16624 14 syscall -> stat64
+ 0 16624 23 syscall <- stat64
+ 0 16624 10 syscall -> open64
+ 0 16624 23 syscall <- open64
+ 0 16624 8 syscall -> fcntl
+ 0 16624 7 syscall <- fcntl
+ 0 16624 8 syscall -> ioctl
+ 0 16624 7 syscall <- ioctl
+ 0 16624 26 syscall -> read
+ 0 16624 29 syscall <- read
+ 0 16624 8 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 57 syscall -> read
+ 0 16624 15 syscall <- read
+ 0 16624 55 syscall -> read
+ 0 16624 14 syscall <- read
+ 0 16624 8 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 8 syscall <- brk
+ 0 16624 63 syscall -> read
+ 0 16624 14 syscall <- read
+ 0 16624 45 syscall -> read
+ 0 16624 13 syscall <- read
+ 0 16624 8 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 8 syscall <- brk
+ 0 16624 63 syscall -> read
+ 0 16624 14 syscall <- read
+ 0 16624 29 syscall -> read
+ 0 16624 7 syscall <- read
+ 0 16624 10 syscall -> close
+ 0 16624 10 syscall <- close
+ 0 16624 18 cmd -> if
+ 0 16624 19 cmd -> info
+ 0 16624 10 cmd <- info
+ 0 16624 12 cmd <- if
+ 0 16624 14 cmd -> package
+ 0 16624 12 cmd <- package
+ 0 16624 15 cmd -> if
+ 0 16624 12 cmd -> info
+ 0 16624 9 cmd <- info
+ 0 16624 26 cmd -> info
+ 0 16624 16 cmd <- info
+ 0 16624 10 cmd <- if
+ 0 16624 21 cmd -> namespace
+ 0 16624 87 cmd -> variable
+ 0 16624 10 cmd <- variable
+ 0 16624 9 cmd -> info
+ 0 16624 13 cmd <- info
+ 0 16624 9 cmd -> info
+ 0 16624 8 cmd <- info
+ 0 16624 8 cmd -> info
+ 0 16624 8 cmd <- info
+ 0 16624 9 cmd -> file
+ 0 16624 21 cmd <- file
+ 0 16624 9 cmd -> list
+ 0 16624 17 cmd <- list
+ 0 16624 8 cmd -> foreach
+ 0 16624 27 cmd -> lsearch
+ 0 16624 10 cmd <- lsearch
+ 0 16624 10 cmd -> lappend
+ 0 16624 9 cmd <- lappend
+ 0 16624 11 cmd -> lsearch
+ 0 16624 8 cmd <- lsearch
+ 0 16624 8 cmd -> lappend
+ 0 16624 8 cmd <- lappend
+ 0 16624 8 cmd <- foreach
+ 0 16624 8 cmd -> info
+ 0 16624 10 cmd <- info
+ 0 16624 8 cmd -> file
+ 0 16624 15 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 24 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 19 cmd <- file
+ 0 16624 9 cmd -> file
+ 0 16624 11 cmd <- file
+ 0 16624 10 cmd -> lsearch
+ 0 16624 8 cmd <- lsearch
+ 0 16624 9 cmd -> lappend
+ 0 16624 8 cmd <- lappend
+ 0 16624 8 cmd -> info
+ 0 16624 8 cmd <- info
+ 0 16624 9 cmd -> foreach
+ 0 16624 12 cmd -> lsearch
+ 0 16624 8 cmd <- lsearch
+ 0 16624 8 cmd -> lappend
+ 0 16624 8 cmd <- lappend
+ 0 16624 8 cmd <- foreach
+ 0 16624 8 cmd <- namespace
+ 0 16624 30 cmd -> if
+ 0 16624 22 cmd -> interp
+ 0 16624 17 cmd <- interp
+ 0 16624 11 cmd <- if
+ 0 16624 15 cmd -> package
+ 0 16624 8 cmd <- package
+ 0 16624 13 cmd -> if
+ 0 16624 12 cmd -> interp
+ 0 16624 8 cmd <- interp
+ 0 16624 44 cmd <- if
+ 0 16624 21 cmd -> if
+ 0 16624 15 cmd -> namespace
+ 0 16624 10 cmd <- namespace
+ 0 16624 9 cmd <- if
+ 0 16624 13 cmd -> set
+ 0 16624 9 cmd <- set
+ 0 16624 10 cmd -> set
+ 0 16624 8 cmd <- set
+ 0 16624 12 cmd -> if
+ 0 16624 14 cmd -> namespace
+ 0 16624 8 cmd <- namespace
+ 0 16624 13 cmd -> proc
+ 0 16624 12 cmd <- proc
+ 0 16624 8 cmd <- if
+ 0 16624 69 cmd -> proc
+ 0 16624 11 cmd <- proc
+ 0 16624 20 cmd -> proc
+ 0 16624 12 cmd <- proc
+ 0 16624 22 syscall -> brk
+ 0 16624 7 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 18 cmd -> proc
+ 0 16624 10 cmd <- proc
+ 0 16624 21 cmd -> proc
+ 0 16624 11 cmd <- proc
+ 0 16624 16 cmd -> proc
+ 0 16624 10 cmd <- proc
+ 0 16624 42 cmd -> if
+ 0 16624 25 cmd -> proc
+ 0 16624 9 syscall -> brk
+ 0 16624 6 syscall <- brk
+ 0 16624 7 syscall -> brk
+ 0 16624 9 syscall <- brk
+ 0 16624 21 cmd <- proc
+ 0 16624 9 cmd <- if
+ 0 16624 41 cmd -> proc
+ 0 16624 13 cmd <- proc
+ 0 16624 9 cmd <- source
+ 0 16624 8 cmd <- uplevel
+ 0 16624 10 proc <- tclInit
+ 0 16624 17 cmd <- tclInit
+ 0 16624 35 syscall -> resolvepath
+ 0 16624 31 syscall <- resolvepath
+ 0 16624 13 syscall -> stat64
+ 0 16624 24 syscall <- stat64
+ 0 16624 9 syscall -> open64
+ 0 16624 23 syscall <- open64
+ 0 16624 8 syscall -> fcntl
+ 0 16624 7 syscall <- fcntl
+ 0 16624 9 syscall -> ioctl
+ 0 16624 7 syscall <- ioctl
+ 0 16624 12 syscall -> read
+ 0 16624 21 syscall <- read
+ 0 16624 10 syscall -> read
+ 0 16624 7 syscall <- read
+ 0 16624 9 syscall -> close
+ 0 16624 8 syscall <- close
+ 0 16624 12 cmd -> proc
+ 0 16624 11 cmd <- proc
+ 0 16624 11 cmd -> proc
+ 0 16624 9 cmd <- proc
+ 0 16624 11 cmd -> proc
+ 0 16624 9 cmd <- proc
+ 0 16624 9 cmd -> func_a
+ 0 16624 17 proc -> func_a
+ 0 16624 10 cmd -> puts
+ 0 16624 25 syscall -> llseek
+ 0 16624 9 syscall <- llseek
+ 0 16624 9 syscall -> ioctl
+ 0 16624 6 syscall <- ioctl
+ 0 16624 13 syscall -> getsockname
+ 0 16624 8 syscall <- getsockname
+ 0 16624 18 syscall -> llseek
+ 0 16624 8 syscall <- llseek
+ 0 16624 7 syscall -> ioctl
+ 0 16624 86 syscall <- ioctl
+ 0 16624 184 syscall -> ioctl
+ 0 16624 17 syscall <- ioctl
+ 0 16624 14 syscall -> llseek
+ 0 16624 7 syscall <- llseek
+ 0 16624 7 syscall -> ioctl
+ 0 16624 13 syscall <- ioctl
+ 0 16624 8 syscall -> ioctl
+ 0 16624 12 syscall <- ioctl
+ 0 16624 24 syscall -> write
+ 0 16624 108 syscall <- write
+ 0 16624 10 cmd <- puts
+ 0 16624 11 cmd -> after
+ 0 16624 23 syscall -> pollsys
+Function B
+ 0 16624 1009593 syscall <- pollsys
+ 0 16624 24 cmd <- after
+ 0 16624 23 cmd -> func_b
+ 0 16624 37 proc -> func_b
+ 0 16624 12 cmd -> puts
+ 0 16624 17 syscall -> write
+ 0 16624 74 syscall <- write
+ 0 16624 8 cmd <- puts
+ 0 16624 9 cmd -> after
+ 0 16624 10 syscall -> pollsys
+Function C
+ 0 16624 1009748 syscall <- pollsys
+ 0 16624 24 cmd <- after
+ 0 16624 23 cmd -> func_c
+ 0 16624 35 proc -> func_c
+ 0 16624 12 cmd -> puts
+ 0 16624 17 syscall -> write
+ 0 16624 75 syscall <- write
+ 0 16624 8 cmd <- puts
+ 0 16624 9 cmd -> after
+ 0 16624 10 syscall -> pollsys
+ 0 16624 1009831 syscall <- pollsys
+ 0 16624 24 cmd <- after
+ 0 16624 23 proc <- func_c
+ 0 16624 13 cmd <- func_c
+ 0 16624 9 proc <- func_b
+ 0 16624 8 cmd <- func_b
+ 0 16624 8 proc <- func_a
+ 0 16624 8 cmd <- func_a
+ 0 16624 30 cmd -> exit
+ 0 16624 41 syscall -> fcntl
+ 0 16624 11 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 7 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 11 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 9 syscall -> fcntl
+ 0 16624 7 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 7 syscall -> fcntl
+ 0 16624 6 syscall <- fcntl
+ 0 16624 81 syscall -> open64
+ 0 16624 119 syscall <- open64
+ 0 16624 8 syscall -> ioctl
+ 0 16624 8 syscall <- ioctl
+ 0 16624 10 syscall -> close
+ 0 16624 16 syscall <- close
+ 0 16624 68 syscall -> rexit
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcl_who_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcl_who_example.txt
new file mode 100644
index 0000000..d1eefa3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcl_who_example.txt
@@ -0,0 +1,17 @@
+The following is an example of running tcl_who.d.
+
+The output produces four fields of interest in tracing tcl calls by process.
+
+Here we see it running while Code/Tcl/func_slow.tcl and Code/Tcl/func_abc.tcl
+are executed.
+# tcl_who.d
+Tracing... Hit Ctrl-C to end.
+^C
+ PID UID CALLS ARGS
+ 16063 100 83 ./tclsh scripts/func_slow.tcl
+ 16061 100 86 ./tclsh scripts/func_abc.tcl
+
+CALLS is a measure of activity, and is a count of the procedures and commands
+that Tcl called. The ARGS column shows the process name and arguments given
+for a particular PID in order to identify the particular Tcl code involved.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_d_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_d_example.txt
new file mode 100644
index 0000000..a0a8cc8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_d_example.txt
@@ -0,0 +1,41 @@
+The following is a demonstration of the tcpsnoop script.
+
+
+
+Here we run tcpsnoop and wait for new TCP connections to be established,
+
+ # tcpsnoop.d
+ UID PID LADDR LPORT DR RADDR RPORT SIZE CMD
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 66 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 56 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 606 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 -> 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 78 inetd
+ 0 242 192.168.1.5 23 -> 192.168.1.1 54224 54 inetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 57 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 78 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 57 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 63 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 72 in.telnetd
+ [...]
+
+As new connections are made, each of the TCP packets are traced along with
+the UID, PID and command name.
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_example.txt
new file mode 100644
index 0000000..1124175
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_example.txt
@@ -0,0 +1,61 @@
+The following is a demonstration of the tcpsnoop program.
+
+
+
+Here we run tcpsnoop and wait for new TCP connections to be established,
+
+ # tcpsnoop
+ UID PID LADDR LPORT DR RADDR RPORT SIZE CMD
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 66 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 56 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 606 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 -> 192.168.1.1 79 54 finger
+ 100 20892 192.168.1.5 36398 <- 192.168.1.1 79 54 finger
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 -> 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 54 inetd
+ 0 242 192.168.1.5 23 <- 192.168.1.1 54224 78 inetd
+ 0 242 192.168.1.5 23 -> 192.168.1.1 54224 54 inetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 57 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 78 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 57 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 63 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 54 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 <- 192.168.1.1 54224 60 in.telnetd
+ 0 20893 192.168.1.5 23 -> 192.168.1.1 54224 72 in.telnetd
+ [...]
+
+As new connections are made, each of the TCP packets are traced along with
+the UID, PID and command name.
+
+
+
+tcpsnoop has many options, for example here we use "-v" to print times,
+
+ # tcpsnoop -v
+ STRTIME UID PID LADDR LPORT DR RADDR RPORT SIZE CMD
+ 2005 Jul 11 21:21:19 0 242 192.168.1.5 79 <- 192.168.1.1 49001 54 inetd
+ 2005 Jul 11 21:21:19 0 242 192.168.1.5 79 -> 192.168.1.1 49001 54 inetd
+ 2005 Jul 11 21:21:19 0 242 192.168.1.5 79 <- 192.168.1.1 49001 54 inetd
+ 2005 Jul 11 21:21:19 0 242 192.168.1.5 79 <- 192.168.1.1 49001 56 inetd
+ 2005 Jul 11 21:21:19 0 242 192.168.1.5 79 -> 192.168.1.1 49001 54 inetd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 -> 192.168.1.1 49001 444 in.fingerd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 -> 192.168.1.1 49001 54 in.fingerd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 <- 192.168.1.1 49001 54 in.fingerd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 <- 192.168.1.1 49001 54 in.fingerd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 <- 192.168.1.1 49001 54 in.fingerd
+ 2005 Jul 11 21:21:19 0 23181 192.168.1.5 79 -> 192.168.1.1 49001 54 in.fingerd
+ [...]
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_d_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_d_example.txt
new file mode 120000
index 0000000..d53301a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_d_example.txt
@@ -0,0 +1 @@
+tcpsnoop_d_example.txt \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_example.txt
new file mode 120000
index 0000000..794263c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpsnoop_snv_example.txt
@@ -0,0 +1 @@
+tcpsnoop_example.txt \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpstat_example.txt
new file mode 100644
index 0000000..d7d8cb3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpstat_example.txt
@@ -0,0 +1,22 @@
+The following is a demonstration of the tcpstat.d script,
+
+
+Here we run tcpstat.d as a large file is downloaded,
+
+ # tcpstat.d
+ TCP_out TCP_outRe TCP_in TCP_inDup TCP_inUn
+ 0 0 0 0 0
+ 20 0 1540 0 0
+ 632 0 576 0 0
+ 560 0 115552 0 0
+ 1872 0 2900480 0 0
+ 1968 0 3032320 0 0
+ 1776 0 2752160 0 0
+ 752 0 999824 0 0
+ 0 0 0 0 0
+ 0 0 0 0 0
+ 0 0 0 0 0
+ ^C
+
+We can see the TCP_in value rise to around 3 Mb/sec as the download occurs.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcptop_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcptop_example.txt
new file mode 100644
index 0000000..c90fc75
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcptop_example.txt
@@ -0,0 +1,28 @@
+The following is a demonstration of the tcptop command,
+
+
+tcptop will display info on newly established TCP connections,
+
+ # tcptop -C 10
+ Tracing... Please wait.
+ 2005 Jul 5 04:55:25, load: 1.11, TCPin: 2 KB, TCPout: 110 KB
+
+ UID PID LADDR LPORT FADDR FPORT SIZE NAME
+ 100 20876 192.168.1.5 36396 192.168.1.1 79 1160 finger
+ 100 20875 192.168.1.5 36395 192.168.1.1 79 1160 finger
+ 100 20878 192.168.1.5 36397 192.168.1.1 23 1303 telnet
+ 100 20877 192.168.1.5 859 192.168.1.1 514 115712 rcp
+
+ 2005 Jul 5 04:55:35, load: 1.10, TCPin: 0 KB, TCPout: 0 KB
+
+ UID PID LADDR LPORT FADDR FPORT SIZE NAME
+ 0 242 192.168.1.5 79 192.168.1.1 54220 272 inetd
+ 0 20879 192.168.1.5 79 192.168.1.1 54220 714 in.fingerd
+
+ [...]
+
+
+In the above output, we run it with a 10 second interval and with -C so
+that the screen does not clear. Some traffic was captured, around 110 Kbytes
+by the rcp process (PID 20877), etc.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcptop_snv_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcptop_snv_example.txt
new file mode 120000
index 0000000..f2a169e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcptop_snv_example.txt
@@ -0,0 +1 @@
+tcptop_example.txt \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Examples/tcpwdist_example.txt b/cddl/contrib/dtracetoolkit/Examples/tcpwdist_example.txt
new file mode 100644
index 0000000..02a392c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/tcpwdist_example.txt
@@ -0,0 +1,70 @@
+The following is a demonstration of the tcpwdist.d script.
+
+
+Here the tcpwdist.d script is run for a few seconds then Ctrl-C is hit,
+
+ # tcpwdist.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID: 15300 CMD: finger @mars\0
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@@@@@@ 1
+ 4 | 0
+
+ PID: 4967 CMD: /usr/lib/ssh/sshd\0
+
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@ 1
+ 64 |@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ PID: 9172 CMD: /usr/lib/ssh/sshd\0
+
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@ 4
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14
+ 128 | 0
+ 256 | 0
+ 512 |@@ 1
+ 1024 | 0
+
+ PID: 15301 CMD: rcp 1Mb.gz mars:/tmp\0
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@ 2
+ 2 |@ 1
+ 4 | 0
+ 8 |@ 2
+ 16 |@ 2
+ 32 | 0
+ 64 | 0
+ 128 | 0
+ 256 | 0
+ 512 | 0
+ 1024 | 0
+ 2048 | 0
+ 4096 | 0
+ 8192 | 0
+ 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 64
+ 32768 | 0
+
+In the above output we can see the "rcp" command dominates, sending
+large writes (16 to 31 Kb) 64 times. The "sshd" ssh daemons each sent
+several smaller writes, from 32 to 127 bytes - which corresponds to
+command line activity (eg, screen width of 80 bytes). The finger command
+sent 2 bytes once, and zero data bytes once.
+
+These values are the TCP write payload sizes.
+
+The writes from the "rcp" command seem unusual at over 16 Kb each, when
+this is an Ethernet network with an MTU of 1500 bytes. The reason is that
+at this point the data has not yet been broken down into MTU sized packets,
+so we are looking at the applications behaviour as it writes to TCP.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/threaded_example.txt b/cddl/contrib/dtracetoolkit/Examples/threaded_example.txt
new file mode 100644
index 0000000..1e41a0e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/threaded_example.txt
@@ -0,0 +1,108 @@
+The following is a demonstration of the threaded.d script,
+
+
+Here we run a test program called "cputhread" that creates 4 busy threads
+that run at the same time. Here we run it on a server with only 1 CPU,
+
+ # threaded.d
+
+ 2005 Jul 26 02:56:37,
+
+ PID: 8516 CMD: cputhread
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@ 17
+ 3 |@@@@@@@@@@@ 28
+ 4 |@@@@@@@@@@@ 27
+ 5 |@@@@@@@@@@@ 28
+ 6 | 0
+ [...]
+
+In the above output, we can see that cputhread has four busy threads with
+thread IDs 2, 3, 4 and 5. We are sampling at 100 Hertz, and have caught
+each of these threads on the CPU between 17 and 28 times.
+
+Since the above counts add to 100, this is either a sign of a single CPU
+server (which it is), or a sign that a multithreaded application may be
+running "serialised" - only 1 thread at a time. Compare the above output
+to a multi CPU server,
+
+
+
+Here we run the same test program on a server with 4 CPUs,
+
+ # threaded.d
+
+ 2005 Jul 26 02:48:44,
+
+ PID: 5218 CMD: cputhread
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@ 80
+ 3 |@@@@@@@@@@ 72
+ 4 |@@@@@@@@@ 64
+ 5 |@@@@@@@@@@@ 78
+ 6 | 0
+ [...]
+
+This time the counts add to equal 294, so this program is definitely
+running on multiple CPUs at the same time, otherwise this total would
+not be beyond our sample rate of 100. The distribution of threads on CPU
+is fairly even, and the above serves as an example of a multithreaded
+application performing well.
+
+
+
+Now we run a test program called "cpuserial", which also create 4 busy
+threads, however due to a coding problem (poor use of mutex locks) they
+only run one at a time,
+
+ # threaded.d
+
+ 2005 Jul 26 03:07:21,
+
+ PID: 5238 CMD: cpuserial
+
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 3 |@@@@@@@@@@@@ 30
+ 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 70
+ 5 | 0
+ [...]
+
+The above looks like we are back on a single CPU server with 100 samples
+in total, however we are still on our 4 CPU server. Only two threads have
+run, and the above distribution is a good indication that they have
+run serialised.
+
+
+
+Now more of a fringe case. This version of cpuserial again creates 4 threads
+that are all busy and hungry for the CPU, and again we run it on a 4 CPU
+server,
+
+ # threaded.d
+
+ 2005 Jul 26 03:25:45,
+
+ PID: 5280 CMD: cpuserial
+
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@@@@@@ 42
+ 3 |@@@@@@@@@@@@@@@@@@ 50
+ 4 |@@@@@@ 15
+ 5 |@ 2
+ 6 | 0
+ [...]
+
+So all threads are running, good. And with a total of 109, at some point
+more than one thread was running at the same time (otherwise this would
+not have exceeded 100, bearing in mind a sample rate of 100 Hertz). However,
+what is not so good is that with 4 CPUs we have only scored 109 samples -
+since all threads are CPU hungry we'd hope that more often they could
+run across the CPUs simultaneously; however this wasn't the case. Again,
+this fault was created by poor use of mutex locks.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/topsyscall_example.txt b/cddl/contrib/dtracetoolkit/Examples/topsyscall_example.txt
new file mode 100644
index 0000000..dda1aa0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/topsyscall_example.txt
@@ -0,0 +1,65 @@
+The following is a demonstration of the topsyscall command,
+
+
+Here topsyscall is run with no arguments,
+
+ # topsyscall
+ 2005 Jun 13 22:13:21, load average: 1.24, 1.24, 1.22 syscalls: 1287
+
+ SYSCALL COUNT
+ getgid 4
+ getuid 5
+ waitsys 5
+ xstat 7
+ munmap 7
+ sysconfig 8
+ brk 8
+ setcontext 8
+ open 8
+ getpid 9
+ close 9
+ resolvepath 10
+ lwp_sigmask 22
+ mmap 26
+ lwp_park 43
+ read 59
+ write 72
+ sigaction 113
+ pollsys 294
+ ioctl 520
+
+The screen updates every second, and continues until Ctrl-C is hit to
+end the program.
+
+In the above output we can see that the ioctl() system call occured 520 times,
+pollsys() 294 times and sigaction() 113 times.
+
+
+
+Here the command is run with a 10 second interval,
+
+ # topsyscall 10
+ 2005 Jun 13 22:15:35, load average: 1.21, 1.22, 1.22 syscalls: 10189
+
+ SYSCALL COUNT
+ writev 6
+ close 7
+ lseek 7
+ open 7
+ brk 8
+ nanosleep 9
+ portfs 10
+ llseek 14
+ lwp_cond_wait 21
+ p_online 21
+ gtime 27
+ rusagesys 71
+ setcontext 92
+ lwp_sigmask 98
+ setitimer 183
+ lwp_park 375
+ write 438
+ read 551
+ pollsys 3071
+ ioctl 5144
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/topsysproc_example.txt b/cddl/contrib/dtracetoolkit/Examples/topsysproc_example.txt
new file mode 100644
index 0000000..368ea31
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/topsysproc_example.txt
@@ -0,0 +1,56 @@
+The following is a demonstration of the topsysproc program,
+
+
+Here we run topsysproc with no arguments,
+
+ # topsysproc
+ 2005 Jun 13 22:25:16, load average: 1.24, 1.23, 1.21 syscalls: 1347
+
+ PROCESS COUNT
+ svc.startd 1
+ nscd 1
+ setiathome 7
+ poold 18
+ sshd 21
+ java_vm 35
+ tput 49
+ dtrace 56
+ Xorg 108
+ sh 110
+ clear 122
+ mozilla-bin 819
+
+The screen refreshes every 1 second, which can be changed by specifying
+a different interval at the command line.
+
+In the above output we can see that processes with the name "mozilla-bin"
+made 819 system calls, while processes with the name "clear" made 122.
+
+
+
+Now topsysproc is run with a 15 second interval,
+
+ # topsysproc 15
+ 2005 Jun 13 22:29:43, load average: 1.19, 1.20, 1.20 syscalls: 15909
+
+ PROCESS COUNT
+ fmd 1
+ inetd 2
+ svc.configd 2
+ gconfd-2 3
+ miniserv.pl 3
+ sac 6
+ snmpd 6
+ sshd 8
+ automountd 8
+ ttymon 9
+ svc.startd 17
+ nscd 21
+ in.routed 37
+ sendmail 41
+ setiathome 205
+ poold 293
+ dtrace 413
+ java_vm 529
+ Xorg 1234
+ mozilla-bin 13071
diff --git a/cddl/contrib/dtracetoolkit/Examples/udpstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/udpstat_example.txt
new file mode 100644
index 0000000..4ffa3ba
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/udpstat_example.txt
@@ -0,0 +1,39 @@
+The following is an example of the udpstat.d script,
+
+
+
+Here we run udpstat for a few seconds. Firstly, we run a "spray" command
+outbound, followed by a spray inbound. Both can be identified in the
+output below,
+
+ # udpstat.d
+ UDP_out UDP_outErr UDP_in UDP_inErr UDP_noPort
+ 0 0 0 0 1
+ 0 0 0 0 2
+ 0 0 0 0 0
+ 1165 0 2 0 0
+ 0 0 0 0 0
+ 0 0 0 0 2
+ 3 0 1166 0 1
+ 0 0 0 0 0
+ 0 0 0 0 0
+ 0 0 0 0 0
+ ^C
+
+
+
+Here we run udpstat.d while an outbound DNS lookup is performed using
+"nslookup",
+
+ # udpstat.d
+ UDP_out UDP_outErr UDP_in UDP_inErr UDP_noPort
+ 0 0 0 0 1
+ 0 0 0 0 1
+ 1 0 1 0 0
+ 0 0 0 0 0
+ 0 0 0 0 3
+ ^C
+
+Little output is observed as this tracks datagrams not bytes. There is
+one outbound and one inbound datagram.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/uname-a_example.txt b/cddl/contrib/dtracetoolkit/Examples/uname-a_example.txt
new file mode 100644
index 0000000..281033d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/uname-a_example.txt
@@ -0,0 +1,15 @@
+The following is a demonstration of the uname.d script,
+
+
+Here we run the usual "uname -a" command and compare the output to that
+given by the uname.d script,
+
+ # uname -a
+ SunOS jupiter 5.10 Generic i86pc i386 i86pc
+
+ # ./uname-a.d
+ SunOS jupiter 5.10 Generic i86pc i386 i86pc
+
+The output is the same. uname-a.d is intended as a demonstration script,
+and as a starting point for other scripts.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/vmbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/vmbypid_example.txt
new file mode 100644
index 0000000..9e09b83
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/vmbypid_example.txt
@@ -0,0 +1,32 @@
+The following is a demonstration of the vmbypid.d command,
+
+ # vmbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ EXEC PID VM VALUE
+ find 19216 prot_fault 1
+ bash 19216 zfod 1
+ dtrace 19215 pgfrec 3
+ dtrace 19215 pgrec 3
+ bash 19216 pgfrec 5
+ bash 19216 pgrec 5
+ find 19216 cow_fault 6
+ find 19216 pgfrec 6
+ find 19216 pgrec 6
+ bash 19216 prot_fault 10
+ bash 19216 cow_fault 15
+ bash 19155 prot_fault 30
+ dtrace 19215 zfod 52
+ find 19216 zfod 54
+ dtrace 19215 as_fault 56
+ bash 19216 as_fault 74
+ find 19216 as_fault 91
+ find 19216 fspgin 315
+ find 19216 pgin 315
+ find 19216 pgpgin 315
+ find 19216 maj_fault 315
+
+In the above output, the find command at PID 19211 triggered 315 maj_faults -
+major faults, that would require disk activity to satisfy (as confirmed by the
+pgpgin value for pages paged in).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/vmstat-p_example.txt b/cddl/contrib/dtracetoolkit/Examples/vmstat-p_example.txt
new file mode 100644
index 0000000..1a0fe14
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/vmstat-p_example.txt
@@ -0,0 +1,51 @@
+The following is a demonstration of the vmstat-p.d script,
+
+
+We run both vmstat-p.d and the original vmstat(1M) command at the same time
+to compare outputs,
+
+ $ vmstat -p 1
+ memory page executable anonymous filesystem
+ swap free re mf fr de sr epi epo epf api apo apf fpi fpo fpf
+ 1144488 142456 2 8 1 0 0 0 0 0 0 0 0 2 1 1
+ 1063812 84472 18 92 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050404 75108 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050404 75108 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050404 75108 476 150 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050184 74772 73 0 0 0 0 0 0 0 0 0 0 788 0 0
+ 1050400 74988 2371 173 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050400 75100 1057 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050400 75100 2 0 0 0 0 0 0 0 0 0 0 4 0 0
+ 1050400 75100 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050400 75100 4529 172 0 0 0 0 0 0 0 0 0 192 0 0
+ 1050400 75104 0 0 0 0 0 0 0 0 0 0 0 467 0 0
+ 1050400 75104 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+
+ # ./vmstat-p.d
+ memory page executable anonymous filesystem
+ swap free re mf sr epi epo epf api apo apf fpi fpo fpf
+ 1050404 75108 8 80 0 0 0 0 0 0 0 0 0 0
+ 1050404 75108 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050404 75108 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050180 74768 2216 608 0 0 0 0 0 0 0 568 0 0
+ 1050400 74988 4 0 0 0 0 0 0 0 0 228 0 0
+ 1050400 75100 13852 700 0 0 0 0 0 0 0 0 0 0
+ 1050400 75100 8 0 0 0 0 0 0 0 0 4 0 0
+ 1050400 75100 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050400 75100 0 0 0 0 0 0 0 0 0 0 0 0
+ 1050400 75104 18480 700 0 0 0 0 0 0 0 668 0 0
+ 1050400 75104 0 0 0 0 0 0 0 0 0 0 0 0
+
+Above we can see the columns are corresponding well. "re" and "mf" in the
+DTrace output appear four times as large as they should be, because in the
+DTrace output we are printing Kbs not page counts (for consistancy).
+
+The DTrace output lacks the "summary since boot" line, as it is not using
+Kstat to fetch this data.
+
+
+The vmstat-p.d script is not intended itself as a useful program, rather it
+is intended as a starting point for other DTrace scripts; a starting point
+of familiar statistics to provide the programmer with a "common ground"
+of knowledge.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/vmstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/vmstat_example.txt
new file mode 100644
index 0000000..7d953fd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/vmstat_example.txt
@@ -0,0 +1,45 @@
+The following is an example of the vmstat.d script,
+
+
+We run both vmstat.d and the original vmstat(1M) command at the same time
+to compare outputs,
+
+ $ vmstat 1
+ kthr memory page disk faults cpu
+ r b w swap free re mf pi po fr de sr cd s0 -- -- in sy cs us sy id
+ 0 0 0 1147468 144324 2 8 2 1 1 0 0 1 0 0 0 294 990 355 18 2 80
+ 1 0 0 1065480 92276 13 73 0 0 0 0 0 0 0 0 0 359 1055 376 85 15 0
+ 0 0 0 1052088 82940 0 0 0 0 0 0 0 0 0 0 0 409 999 402 97 3 0
+ 0 0 0 1052088 82940 0 0 0 0 0 0 0 0 0 0 0 406 975 407 97 3 0
+ 0 0 0 1052088 82940 0 0 0 0 0 0 0 0 0 0 0 406 1037 429 97 3 0
+ 0 0 0 1052088 82940 247 1763 0 0 0 0 0 2 0 0 0 427 4828 680 81 19 0
+ 0 0 0 1051264 82300 0 0 0 0 0 0 0 0 0 0 0 414 1164 441 97 3 0
+ 0 0 0 1051264 82300 11 134 0 0 0 0 0 0 0 0 0 423 1218 461 95 5 0
+ 0 0 0 1051264 82300 0 0 0 0 0 0 0 0 0 0 0 416 1054 435 98 2 0
+ [...]
+
+ # ./vmstat.d
+ w swap free re mf pi po fr sr in sy cs
+ 0 1052088 82940 8 80 0 0 0 0 117 958 379
+ 0 1052088 82940 0 0 0 0 0 0 123 955 402
+ 0 1052088 82940 0 0 0 0 0 0 121 1025 420
+ 0 1052088 82940 0 0 0 0 0 0 121 1065 433
+ 0 1051264 82300 1008 7192 0 0 0 0 219 4886 684
+ 0 1051264 82300 0 0 0 0 0 0 193 1188 461
+ 0 1051264 82300 44 540 0 0 0 0 165 1226 450
+ 0 1051264 82300 0 0 0 0 0 0 123 1012 421
+ [...]
+
+Above we can see the columns are corresponding well. "re" and "mf" in the
+DTrace output appear four times as large as they should be, because in the
+DTrace output we are printing Kbs not page counts (for consistancy).
+
+The DTrace output lacks the "summary since boot" line, as it is not using
+Kstat to fetch this data.
+
+
+The vmstat.d script is not intended itself as a useful program, rather it
+is intended as a starting point for other DTrace scripts; a starting point
+of familiar statistics to provide the programmer with a "common ground"
+of knowledge.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/vopstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/vopstat_example.txt
new file mode 100644
index 0000000..646419e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/vopstat_example.txt
@@ -0,0 +1,89 @@
+The following are demonstrations of the vopstat script.
+
+
+By default, vopstat traces activity at the vnode interface and prints
+summaries every five seconds. It will either trace all filesystems or
+just the mountpoint specified.
+
+Here it was run on /extra1, while a tar command archived /extra1,
+
+ # ./vopstat /extra1
+ VOP Physical IO Count
+ fop_getpage 66
+
+ VOP Count Count
+ fop_readdir 1
+ fop_read 2
+ fop_cmp 2
+ fop_seek 3
+ fop_close 7
+ fop_open 10
+ fop_getattr 12
+ fop_access 13
+ fop_lookup 16
+ fop_rwunlock 3802
+ fop_rwlock 3802
+ fop_putpage 4701
+ fop_getpage 6648
+ fop_dispose 19109
+
+ VOP Wall Time mSeconds
+ fop_readdir 0
+ fop_cmp 0
+ fop_read 0
+ fop_seek 0
+ fop_close 0
+ fop_open 0
+ fop_access 0
+ fop_getattr 0
+ fop_lookup 0
+ fop_rwunlock 64
+ fop_putpage 86
+ fop_rwlock 93
+ fop_dispose 346
+ fop_getpage 402
+ ^C
+
+There were 66 calls for physical I/O operations, fop_getpage, as files
+were read from disk. The VOP Count show that there were many calls to
+fop_putpage and fop_getpage, as tar works its way through files; and
+many more to fop_dispose. The total elaspsed time for these calls
+are listed at the bottom, in milleseconds.
+
+This rate of events will put some pressure on the DTrace buffer,
+you may see dynamic variable drops.
+
+
+
+vopstat also has a -t option to trace activity. Here it is run on /extra1
+while an "ls" command listed files from that directory,
+
+# ./vopstat -t /extra1
+ Event Device Path RW Size Offset
+-> fop_getattr - /extra1 - 0 0
+<- fop_getattr - /extra1 - 0 0
+-> fop_access - /extra1 - 0 0
+<- fop_access - /extra1 - 0 0
+-> fop_open - /extra1 - 0 0
+<- fop_open - /extra1 - 0 0
+-> fop_getattr - /extra1 - 0 0
+<- fop_getattr - /extra1 - 0 0
+-> fop_rwlock - /extra1 - 0 0
+<- fop_rwlock - /extra1 - 0 0
+-> fop_readdir - /extra1 - 0 0
+-> fop_getpage - /extra1 - 0 0
+<- fop_getpage - /extra1 - 0 0
+-> fop_rwunlock - /extra1 - 0 0
+<- fop_rwunlock - /extra1 - 0 0
+-> fop_rwlock - /extra1 - 0 0
+<- fop_rwlock - /extra1 - 0 0
+-> fop_readdir - /extra1 - 0 0
+<- fop_readdir - /extra1 - 0 0
+-> fop_rwunlock - /extra1 - 0 0
+<- fop_rwunlock - /extra1 - 0 0
+-> fop_close - /extra1 - 0 512
+<- fop_close - /extra1 - 0 512
+^C
+
+Each call can be seen as it happened, including the entry and return of
+these calls.
diff --git a/cddl/contrib/dtracetoolkit/Examples/weblatency_example.txt b/cddl/contrib/dtracetoolkit/Examples/weblatency_example.txt
new file mode 100644
index 0000000..995b545
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/weblatency_example.txt
@@ -0,0 +1,127 @@
+The following is a demonstration of the weblatency.d script.
+
+Here we run weblatency.d while a mozilla browser loads the
+http://www.planetsolaris.org website. After the website was loaded, Ctrl-C
+was hit to print the following report,
+
+ # weblatency.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ HOST NUM
+ static.flickr.com 1
+ images.pegasosppc.com 1
+ www.planetsolaris.org 5
+ blogs.sun.com 7
+
+ HOST AVGTIME(ms)
+ static.flickr.com 65
+ blogs.sun.com 285
+ images.pegasosppc.com 491
+ www.planetsolaris.org 757
+
+ HOST MAXTIME(ms)
+ static.flickr.com 65
+ images.pegasosppc.com 491
+ blogs.sun.com 962
+ www.planetsolaris.org 3689
+
+This gives us an understanding on which hosts were responsible for the
+time endured while loading the website. It turns out that requests to
+www.planetsolaris.org were the slowest, with a maximum time of 3.7 seconds
+(probably the first request, which incurred a DNS lookup).
+
+
+
+The following shows the same google lookup performed on a number of sites,
+
+ # weblatency.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ HOST NUM
+ www.google.com.au 3
+ www.google.co.uk 3
+ www.google.com 3
+ www.google.co.nz 3
+
+ HOST AVGTIME(ms)
+ www.google.co.nz 450
+ www.google.com.au 502
+ www.google.com 567
+ www.google.co.uk 595
+
+ HOST MAXTIME(ms)
+ www.google.co.nz 544
+ www.google.com.au 559
+ www.google.com 744
+ www.google.co.uk 763
+
+From the average time you would guess that I was running this from
+New Zealand (the fastest), with times to the other hosts following suit
+(Australia, USA, UK). I was actually running this from Australia - it's
+interesting that the New Zealand server responded slightly faster.
+
+
+
+
+Now several websites are loaded as a larger demonstration,
+
+ # weblatency.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ HOST NUM
+ shop.abc.net.au 1
+ static.technorati.com 1
+ sunopensolaris.112.2o7.net 1
+ www.theage.com.au 1
+ ffxcam.smh.com.au 1
+ sunglobal.112.2o7.net 2
+ embed.technorati.com 2
+ technorati.com 2
+ fdimages.fairfax.com.au 4
+ blogs.sun.com 5
+ bugs.opensolaris.org 7
+ www.abc.net.au 34
+ www.smh.com.au 51
+
+ HOST AVGTIME(ms)
+ ffxcam.smh.com.au 0
+ sunglobal.112.2o7.net 0
+ www.abc.net.au 56
+ www.theage.com.au 64
+ shop.abc.net.au 65
+ www.smh.com.au 73
+ fdimages.fairfax.com.au 88
+ blogs.sun.com 130
+ bugs.opensolaris.org 162
+ static.technorati.com 350
+ technorati.com 352
+ embed.technorati.com 632
+ sunopensolaris.112.2o7.net 900
+
+ HOST MAXTIME(ms)
+ ffxcam.smh.com.au 0
+ sunglobal.112.2o7.net 0
+ www.theage.com.au 64
+ shop.abc.net.au 65
+ fdimages.fairfax.com.au 243
+ www.smh.com.au 244
+ blogs.sun.com 293
+ www.abc.net.au 315
+ static.technorati.com 350
+ technorati.com 356
+ bugs.opensolaris.org 560
+ sunopensolaris.112.2o7.net 900
+ embed.technorati.com 973
+
+It's interesting that the most common host (www.smh.com.au, NUM == 51),
+responded with a fast AVGTIME (73 ms). The reason for this may be due to
+cacheing by my proxy server. Less common hosts such as embed.technorati.com
+were quite slow.
+
+
+
+The results from weblatency.d are interesting, but they don't point the
+finger at one single cause for website latency. The value here is the response
+time experienced by the client - which is a combination of many response
+times (link speeds, proxy server, DNS server, web server).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/whatexec_example.txt b/cddl/contrib/dtracetoolkit/Examples/whatexec_example.txt
new file mode 100644
index 0000000..519909e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/whatexec_example.txt
@@ -0,0 +1,18 @@
+The following are demonstrations of the whatexec.d script.
+
+
+Here we run it while a few commands are also executed,
+
+ # ./whatexec.d
+ PEXEC EXEC OK TYPE
+ bash /usr/bin/clear Y #!/u\0
+ bash /sbin/sh Y \177ELF\0
+ clear /usr/bin/tput Y \177ELF\0
+ bash /export/home/brendan/DOOM.EXE N MZ\644\0
+ ^C
+
+whatexec.d has first found that "clear" was run, which has a type that
+begins with "#!" - a script. clear runs "sh" and "tput", both ELF files.
+
+We finish by attempting to run a MZ file, "DOOM.EXE", which is rejected
+(OK is "N").
diff --git a/cddl/contrib/dtracetoolkit/Examples/woof_example.txt b/cddl/contrib/dtracetoolkit/Examples/woof_example.txt
new file mode 100644
index 0000000..dc81527
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/woof_example.txt
@@ -0,0 +1,28 @@
+The following explains how to demonstrate the woof.d DTrace script.
+
+This script is only useful if you have an audio device, /dev/audio. To test
+audio, you can run:
+
+ $ audioplay /usr/share/audio/samples/au/sample.au
+
+The volume can be adjusted from a few tools, including,
+
+ $ /usr/dt/bin/sdtaudiocontrol
+
+...
+
+woof.d will bark whenever a new process is created. In order to demonstrate
+it, first run the following:
+
+ # ./woof.d &
+
+You have now installed the dog (if the dog becomes a nusience, you are
+allowed to kill it). Now compare the difference between these recursive
+grep commands:
+
+ $ find /etc -type f -exec grep localhost {} \;
+
+ $ find /etc -type f -exec grep localhost {} +
+
+The first find command is the "bad way", the second is the "good way". You
+will hear for yourself why this is the case.
diff --git a/cddl/contrib/dtracetoolkit/Examples/wpm_example.txt b/cddl/contrib/dtracetoolkit/Examples/wpm_example.txt
new file mode 100644
index 0000000..bfc74a9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/wpm_example.txt
@@ -0,0 +1,57 @@
+The following is an example of the wpm.d script.
+
+
+This script takes the name of a program to trace, and assumes that reads
+on file descriptor zero (STDIN) are keystrokes.
+
+When run, a 5 second count down begins before keystrokes are measured,
+
+ # wpm.d vim
+ Measuring will start in : 5 seconds
+
+While running, I retyped the first three sentences of this file a few times
+which clocked the following result,
+
+ # wpm.d vim
+ Measuring will start in : 0 seconds
+ Measuring will stop in : 0 seconds
+
+ Characters typed : 509
+ Words per minute : 84
+
+ Minimum keystroke latency : 12 ms
+ Average keystroke latency : 118 ms
+ Maximum keystroke latency : 493 ms
+
+ Word size distribution (letters),
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@ 6
+ 2 |@@@@@ 11
+ 3 |@@@@@ 11
+ 4 |@@@@@@ 13
+ 5 |@@@@ 8
+ 6 |@@@@@@ 12
+ 7 |@@@@@ 11
+ 8 | 0
+ 9 |@@ 4
+ 10 |@ 3
+ 11 |@ 2
+ 12 | 0
+ 13 | 0
+ 14 | 1
+ 15 | 0
+
+ Keystroke latency distribution (ms),
+
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 | 1
+ 16 | 5
+ 32 |@@@@@ 66
+ 64 |@@@@@@@@@@@@@@@@@@@@ 247
+ 128 |@@@@@@@@@@@@@ 167
+ 256 |@ 16
+ 512 | 0
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/writebytes_example.txt b/cddl/contrib/dtracetoolkit/Examples/writebytes_example.txt
new file mode 100644
index 0000000..baa83fc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/writebytes_example.txt
@@ -0,0 +1,26 @@
+The following is a demonstration of the writebytes.d script,
+
+
+Here the writebytes.d script is run for a few seconds, then Ctrl-C is hit,
+
+ # writebytes.d
+ dtrace: description 'sysinfo:::writech ' matched 4 probes
+ ^C
+ dtrace 1
+ gnome-settings-d 8
+ xscreensaver 8
+ gnome-panel 8
+ nautilus 8
+ date 29
+ wnck-applet 120
+ bash 210
+ mozilla-bin 1497
+ ls 1947
+ metacity 3172
+ Xorg 7424
+ gnome-terminal 51955
+
+
+In this interval the gnome-terminal command has successfully written 51.9 Kb,
+while Xorg has written 7424 bytes.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/writedist_example.txt b/cddl/contrib/dtracetoolkit/Examples/writedist_example.txt
new file mode 100644
index 0000000..f334843
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/writedist_example.txt
@@ -0,0 +1,38 @@
+The following is an example of the writedist.d script,
+
+
+Here the writedist.d script is run for a few seconds, then Ctrl-C is hit,
+
+ # writedist.d
+ dtrace: description 'sysinfo:::writech ' matched 4 probes
+ ^C
+ [...]
+ Xorg
+ value ------------- Distribution ------------- count
+ 16 | 0
+ 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 169
+ 64 |@@@ 16
+ 128 |@@ 10
+ 256 | 0
+
+ gnome-terminal
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@ 6
+ 2 | 0
+ 4 | 0
+ 8 | 1
+ 16 |@ 2
+ 32 |@@@ 7
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@ 63
+ 256 |@@@@ 10
+ 512 | 1
+ 1024 |@@@@@ 13
+ 2048 |@ 2
+ 4096 |@@@ 7
+
+This allows us to understand the write behaviour of each process. The
+gnome-terminal command has executed 6 writes that returned 0 bytes, through
+to 7 writes that were at least 4096 bytes (up to 8192).
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/xcallsbypid_example.txt b/cddl/contrib/dtracetoolkit/Examples/xcallsbypid_example.txt
new file mode 100644
index 0000000..1593b62
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/xcallsbypid_example.txt
@@ -0,0 +1,17 @@
+The following is a demonstration of the xcallsbypid.d script,
+
+ # xcallsbypid.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ PID CMD XCALLS
+ 215 utmpd 3
+ 6350 bash 3
+ 6351 bash 3
+ 6350 ls 24
+ 0 sched 48
+ 6349 dtrace 93
+ 6351 find 5718
+
+In the above output, we can see the find command with PID 6351 has caused
+5718 cross calls.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/xvmstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/xvmstat_example.txt
new file mode 100644
index 0000000..544bd98
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/xvmstat_example.txt
@@ -0,0 +1,44 @@
+The following is a demonstration of the xvmstat program.
+
+
+Here we run it with no arguments. It will default to 1 second samples, and
+will run forever,
+
+ # xvmstat
+ w swap free re maj mf cow pro sr epi epo epf api apo apf fpi fpo fpf
+ 0 1025 73 2 0 21 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 199 42 166 21 41 0 0 0 0 0 0 0 42 0 0
+ 0 1025 73 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 4404 47 175 26 30 0 0 0 0 0 0 0 48 0 0
+ 0 1025 73 433 0 0 0 14 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ^C
+
+Both "swap" and "free" are in units of megabytes, the rest are in units of
+pages. "maj" is major faults - a useful addition to the output.
+
+There is no summary since boot line, as this program in not using the
+Kstat data.
+
+
+
+The following runs xvmstat with a 5 second interval,
+
+ # xvmstat 5
+ w swap free re maj mf cow pro sr epi epo epf api apo apf fpi fpo fpf
+ 0 1025 72 1531 2 40 5 9 0 0 0 0 0 0 0 2 0 0
+ 0 1025 72 1534 0 36 5 9 0 0 0 0 0 0 0 0 0 0
+ 0 1025 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1025 72 5 1 82 16 25 0 0 0 0 0 0 0 1 0 0
+ 0 1025 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ^C
+
+The values from "re" to "fpf" are per second values.
+
diff --git a/cddl/contrib/dtracetoolkit/Examples/zvmstat_example.txt b/cddl/contrib/dtracetoolkit/Examples/zvmstat_example.txt
new file mode 100644
index 0000000..cb070c5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Examples/zvmstat_example.txt
@@ -0,0 +1,34 @@
+The following is a demonstration of the zvmstat command, which provides
+vmstat style info per zone using DTrace.
+
+Here we run zvmstat with an interval of 5 seconds. This is a server that
+only has two zones, "global" and "workzone1",
+
+ # zvmstat 5
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 62 340 0 0 0 0 0 0 0 0 0 0 0
+ workzone1 4 2 0 0 0 0 0 0 0 0 0 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 1132 484 0 0 2 0 0 0 0 0 832 0 0
+ workzone1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 50 319 2 0 2 0 0 0 0 0 579 2 2
+ workzone1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 54 317 0 0 0 0 0 0 0 0 0 0 0
+ workzone1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 54 316 1 0 0 0 0 0 0 0 0 1 1
+ workzone1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 157 659 1 0 10 0 0 0 0 0 3 2 1
+ workzone1 770 1085 0 0 48 0 0 0 0 0 928 0 0
+ ZONE re mf fr sr epi epo epf api apo apf fpi fpo fpf
+ global 56 317 0 0 6 0 0 0 0 0 2 0 0
+ workzone1 1478 21 0 0 0 0 0 0 0 0 1635 0 0
+
+During the first few samples, some filesystem activity can be observed in
+the global zone, created by a "find /" in the global. In the last few samples,
+filesystem activity can be seen in the non-global zone "workzone1" - this
+time created by running a "find /" within the non-global zone,
+
diff --git a/cddl/contrib/dtracetoolkit/FS/Readme b/cddl/contrib/dtracetoolkit/FS/Readme
new file mode 100644
index 0000000..30927a5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/Readme
@@ -0,0 +1,3 @@
+FS - File System based analysis
+
+ This would include VFS and UFS activity.
diff --git a/cddl/contrib/dtracetoolkit/FS/fspaging.d b/cddl/contrib/dtracetoolkit/FS/fspaging.d
new file mode 100755
index 0000000..4eaa718
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/fspaging.d
@@ -0,0 +1,154 @@
+#!/usr/sbin/dtrace -s
+/*
+ * fspaging.d - file system read/write and paging tracing.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This traces file related activity: system call reads and writes,
+ * vnode logical read and writes (fop), vnode putpage and getpage activity,
+ * and disk I/O. It can be used to examine the behaviour of each I/O
+ * layer, from the syscall interface to what the disk is doing. Behaviour
+ * such as read-ahead, and max I/O size breakup can be observed.
+ *
+ * This is a verbose version of fsrw.d, as this also traces paging activity.
+ *
+ * $Id: fspaging.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: fspaging.d
+ *
+ * FIELDS:
+ * Event Traced event (see EVENTS below)
+ * Device Device, for disk I/O
+ * RW Either Read or Write
+ * Size Size of I/O in bytes, if known
+ * Offset Offset of I/O in kilobytes, if known
+ * Path Path to file on disk
+ *
+ * EVENTS:
+ * sc-read System call read
+ * sc-write System call write
+ * fop_read Logical read
+ * fop_write Logical write
+ * fop_getpage Logical get page
+ * fop_putpage Logical put page
+ * disk_io Physical disk I/O
+ * disk_ra Physical disk I/O, read ahead
+ *
+ * The events are drawn with a level of indentation, which can sometimes
+ * help identify related events.
+ *
+ * SEE ALSO: fsrw.d
+ *
+ * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * ToDo: readv()
+ *
+ * 20-Mar-2006 Brendan Gregg Created this.
+ * 23-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf("%-13s %10s %2s %8s %6s %s\n",
+ "Event", "Device", "RW", "Size", "Offset", "Path");
+}
+
+syscall::*read:entry,
+syscall::*write*:entry
+{
+ /*
+ * starting with a file descriptior, dig out useful info
+ * from the corresponding file_t and vnode_t.
+ */
+ this->filistp = curthread->t_procp->p_user.u_finfo.fi_list;
+ this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp +
+ (uint64_t)arg0 * (uint64_t)sizeof (uf_entry_t));
+ this->filep = this->ufentryp->uf_file;
+ self->offset = this->filep->f_offset;
+ this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
+ self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+ self->sc_trace = this->vnodep ? this->vnodep->v_type == 1 ||
+ this->vnodep->v_type == 2 ? 1 : 0 : 0;
+}
+
+syscall::*read:entry
+/self->sc_trace/
+{
+ printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "R",
+ (int)arg2, self->offset / 1024, self->vpath);
+}
+
+syscall::*write*:entry
+/self->sc_trace/
+{
+ printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "W",
+ (int)arg2, self->offset / 1024, self->vpath);
+}
+
+syscall::*read:return,
+syscall::*write*:return
+{
+ self->vpath = 0;
+ self->offset = 0;
+ self->sc_trace = 0;
+}
+
+fbt::fop_putpage:entry,
+fbt::fop_getpage:entry
+/self->sc_trace && args[0]->v_path/
+{
+ printf(" %-11s %10s %2s %8d %6d %s\n", probefunc, ".",
+ probefunc == "fop_getpage" ? "R" : "W", (uint64_t)arg2,
+ args[1] / 1024, cleanpath(args[0]->v_path));
+}
+
+
+fbt::fop_read:entry,
+fbt::fop_write:entry
+/self->sc_trace && args[0]->v_path/
+{
+ printf(" %-11s %10s %2s %8d %6d %s\n", probefunc, ".",
+ probefunc == "fop_read" ? "R" : "W", args[1]->uio_resid,
+ args[1]->_uio_offset._f / 1024, cleanpath(args[0]->v_path));
+}
+
+fbt:ufs:ufs_getpage_ra:entry
+{
+ /* fetch the real offset (file_t is unaware of this) */
+ self->offset = ((inode_t *)args[0]->v_data)->i_nextrio;
+ self->read_ahead = 1;
+}
+
+fbt:ufs:ufs_getpage_ra:return
+{
+ self->read_ahead = 0;
+ self->offset = 0;
+}
+
+io::bdev_strategy:start
+{
+ this->offset = self->read_ahead ? self->offset : args[2]->fi_offset;
+ printf(" %-9s %10s %2s %8d %6d %s\n",
+ self->read_ahead ? "disk_ra" : "disk_io", args[1]->dev_statname,
+ args[0]->b_flags & B_READ ? "R" : "W", args[0]->b_bcount,
+ this->offset / 1024, args[2]->fi_pathname);
+}
diff --git a/cddl/contrib/dtracetoolkit/FS/fsrw.d b/cddl/contrib/dtracetoolkit/FS/fsrw.d
new file mode 100755
index 0000000..291f09aa
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/fsrw.d
@@ -0,0 +1,149 @@
+#!/usr/sbin/dtrace -s
+/*
+ * fsrw.d - file system read/write event tracing.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This traces file related activity: system call reads and writes,
+ * vnode logical read and writes (fop), and disk I/O. It can be used
+ * to examine the behaviour of each I/O layer, from the syscall
+ * interface to what the disk is doing. Behaviour such as read-ahead, and
+ * max I/O size breakup can be observed.
+ *
+ * $Id: fsrw.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: fsrw.d
+ *
+ * FIELDS:
+ * Event Traced event (see EVENTS below)
+ * Device Device, for disk I/O
+ * RW Either Read or Write
+ * Size Size of I/O in bytes
+ * Offset Offset of I/O in kilobytes
+ * Path Path to file on disk
+ *
+ * EVENTS:
+ * sc-read System call read
+ * sc-write System call write
+ * fop_read Logical read
+ * fop_write Logical write
+ * disk_io Physical disk I/O
+ * disk_ra Physical disk I/O, read ahead
+ *
+ * The events are drawn with a level of indentation, which can sometimes
+ * help identify related events.
+ *
+ * SEE ALSO: fspaging.d
+ *
+ * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * ToDo: readv()
+ *
+ * 20-Mar-2006 Brendan Gregg Created this.
+ * 23-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf("%-12s %10s %2s %8s %6s %s\n",
+ "Event", "Device", "RW", "Size", "Offset", "Path");
+}
+
+syscall::*read:entry,
+syscall::*write*:entry
+{
+ /*
+ * starting with a file descriptior, dig out useful info
+ * from the corresponding file_t and vnode_t.
+ */
+ this->filistp = curthread->t_procp->p_user.u_finfo.fi_list;
+ this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp +
+ (uint64_t)arg0 * (uint64_t)sizeof (uf_entry_t));
+ this->filep = this->ufentryp->uf_file;
+ self->offset = this->filep->f_offset;
+ this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
+ self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+
+ /* only trace activity to regular files and directories, as */
+ self->sc_trace = this->vnodep ? this->vnodep->v_type == VREG ||
+ this->vnodep->v_type == VDIR ? 1 : 0 : 0;
+}
+
+syscall::*read:entry
+/self->sc_trace/
+{
+ printf("sc-%-9s %10s %2s %8d %6d %s\n", probefunc, ".", "R",
+ (int)arg2, self->offset / 1024, self->vpath);
+}
+
+syscall::*write*:entry
+/self->sc_trace/
+{
+ printf("sc-%-9s %10s %2s %8d %6d %s\n", probefunc, ".", "W",
+ (int)arg2, self->offset / 1024, self->vpath);
+}
+
+syscall::*read:return,
+syscall::*write*:return
+{
+ self->vpath = 0;
+ self->offset = 0;
+ self->sc_trace = 0;
+}
+
+fbt::fop_read:entry,
+fbt::fop_write:entry
+/self->sc_trace && args[0]->v_path/
+{
+ printf(" %-10s %10s %2s %8d %6d %s\n", probefunc, ".",
+ probefunc == "fop_read" ? "R" : "W", args[1]->uio_resid,
+ args[1]->_uio_offset._f / 1024, cleanpath(args[0]->v_path));
+}
+
+fbt:ufs:ufs_getpage_ra:entry
+{
+ /* fetch the real offset (file_t is unaware of this) */
+ self->ra_offset = ((inode_t *)args[0]->v_data)->i_nextrio;
+ self->read_ahead = 1;
+}
+
+fbt:ufs:ufs_getpage_ra:return
+{
+ self->read_ahead = 0;
+ self->ra_offset = 0;
+}
+
+io::bdev_strategy:start
+{
+ this->offset = self->read_ahead ? self->ra_offset : args[2]->fi_offset;
+ printf(" %-8s %10s %2s %8d %6d %s\n",
+ self->read_ahead ? "disk_ra" : "disk_io", args[1]->dev_statname,
+ args[0]->b_flags & B_READ ? "R" : "W", args[0]->b_bcount,
+ this->offset / 1024, args[2]->fi_pathname);
+ /*
+ * it would seem to make sense to only trace disk events during
+ * an fop event, easily coded with a self->fop_trace flag. However
+ * writes are asynchronous to the fop_write calls (they are flushed
+ * at some later time), and so this approach will miss tracing
+ * most of the disk writes.
+ */
+}
diff --git a/cddl/contrib/dtracetoolkit/FS/rfileio.d b/cddl/contrib/dtracetoolkit/FS/rfileio.d
new file mode 100755
index 0000000..95a6caa
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/rfileio.d
@@ -0,0 +1,91 @@
+#!/usr/sbin/dtrace -s
+/*
+ * rfileio.d - read file I/O stats, with cache miss rate.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This script provides statistics on the number of reads and the bytes
+ * read from filesystems (logical), and the number of bytes read from
+ * disk (physical). A summary is printed every five seconds by file.
+ *
+ * A total miss-rate is also provided for the file system cache.
+ *
+ * $Id: rfileio.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: rfileio.d
+ *
+ * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 19-Mar-2006 Brendan Gregg Created this.
+ * 23-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+self int trace;
+uint64_t lbytes;
+uint64_t pbytes;
+
+dtrace:::BEGIN
+{
+ trace("Tracing...\n");
+}
+
+fbt::fop_read:entry
+/self->trace == 0 && args[0]->v_path/
+{
+ self->pathname = cleanpath(args[0]->v_path);
+ @rio[self->pathname, "logical"] = count();
+ lbytes += args[1]->uio_resid;
+ self->size = args[1]->uio_resid;
+ self->uiop = args[1];
+}
+
+fbt::fop_read:return
+/self->size/
+{
+ @rbytes[self->pathname, "logical"] =
+ sum(self->size - self->uiop->uio_resid);
+ self->size = 0;
+ self->uiop = 0;
+ self->pathname = 0;
+}
+
+io::bdev_strategy:start
+/self->size && args[0]->b_flags & B_READ/
+{
+ @rio[self->pathname, "physical"] = count();
+ @rbytes[self->pathname, "physical"] = sum(args[0]->b_bcount);
+ pbytes += args[0]->b_bcount;
+}
+
+profile:::tick-5s
+{
+ trunc(@rio, 20);
+ trunc(@rbytes, 20);
+ printf("\033[H\033[2J");
+ printf("\nRead IOPS, top 20 (count)\n");
+ printa("%-54s %10s %10@d\n", @rio);
+ printf("\nRead Bandwidth, top 20 (bytes)\n");
+ printa("%-54s %10s %10@d\n", @rbytes);
+ printf("\nTotal File System miss-rate: %d%%\n",
+ lbytes ? 100 * pbytes / lbytes : 0);
+ trunc(@rbytes);
+ trunc(@rio);
+ lbytes = pbytes = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/FS/rfsio.d b/cddl/contrib/dtracetoolkit/FS/rfsio.d
new file mode 100755
index 0000000..8477563
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/rfsio.d
@@ -0,0 +1,98 @@
+#!/usr/sbin/dtrace -s
+/*
+ * rfsio.d - read FS I/O stats, with cache miss rate.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This script provides statistics on the number of reads and the bytes
+ * read from filesystems (logical), and the number of bytes read from
+ * disk (physical). A summary is printed every five seconds by filesystem.
+ *
+ * A total miss-rate is also provided for the file system cache.
+ *
+ * $Id: rfsio.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: rfsio.d
+ *
+ * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 19-Mar-2006 Brendan Gregg Created this.
+ * 23-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+self int trace;
+uint64_t lbytes;
+uint64_t pbytes;
+
+dtrace:::BEGIN
+{
+ trace("Tracing...\n");
+}
+
+fbt::fop_read:entry
+/self->trace == 0/
+{
+ self->fs_mount = args[0]->v_vfsp == `rootvfs ? "/" :
+ args[0]->v_vfsp->vfs_vnodecovered ?
+ stringof(args[0]->v_vfsp->vfs_vnodecovered->v_path) : NULL;
+}
+
+fbt::fop_read:entry
+/self->fs_mount != NULL/
+{
+ @rio[self->fs_mount, "logical"] = count();
+ lbytes += args[1]->uio_resid;
+ self->size = args[1]->uio_resid;
+ self->uiop = args[1];
+}
+
+fbt::fop_read:return
+/self->size/
+{
+ @rbytes[self->fs_mount, "logical"] =
+ sum(self->size - self->uiop->uio_resid);
+ self->size = 0;
+ self->uiop = 0;
+ self->fs_mount = 0;
+}
+
+io::bdev_strategy:start
+/self->size && args[0]->b_flags & B_READ/
+{
+ @rio[self->fs_mount, "physical"] = count();
+ @rbytes[self->fs_mount, "physical"] = sum(args[0]->b_bcount);
+ pbytes += args[0]->b_bcount;
+}
+
+profile:::tick-5s
+{
+ trunc(@rio, 20);
+ trunc(@rbytes, 20);
+ printf("\033[H\033[2J");
+ printf("\nRead IOPS (count)\n");
+ printa("%-32s %10s %10@d\n", @rio);
+ printf("\nRead Bandwidth (bytes)\n");
+ printa("%-32s %10s %10@d\n", @rbytes);
+ printf("\nTotal File System miss-rate: %d%%\n",
+ lbytes ? 100 * pbytes / lbytes : 0);
+ trunc(@rbytes);
+ trunc(@rio);
+ lbytes = pbytes = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/FS/vopstat b/cddl/contrib/dtracetoolkit/FS/vopstat
new file mode 100755
index 0000000..a4c5af4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/FS/vopstat
@@ -0,0 +1,304 @@
+#!/usr/bin/sh
+#
+# vopstat - Trace the vnode interface.
+# Written using DTrace (Solaris 10 3/05)
+#
+# Author: Richard McDougall
+#
+# $Id: vopstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: vopstat [-t] [/mountname]
+#
+# vopstat # default output, summary each 5 secs
+# -t # trace activity as it occurs
+#
+# Example:
+#
+# ./vopstat
+#
+# VOP Physical IO Count
+# fop_fsync 236
+#
+# VOP Count Count
+# fop_create 1
+# fop_fid 1
+# fop_lookup 2
+# fop_access 3
+# fop_read 3
+# fop_poll 11
+# fop_fsync 31
+# fop_putpage 32
+# fop_ioctl 115
+# fop_write 517
+# fop_rwlock 520
+# fop_rwunlock 520
+# fop_inactive 529
+# fop_getattr 1057
+#
+# VOP Wall Time mSeconds
+# fop_fid 0
+# fop_access 0
+# fop_read 0
+# fop_poll 0
+# fop_lookup 0
+# fop_create 0
+# fop_ioctl 0
+# fop_putpage 1
+# fop_rwunlock 1
+# fop_rwlock 1
+# fop_inactive 1
+# fop_getattr 2
+# fop_write 22
+# fop_fsync 504
+#
+# COPYRIGHT: Copyright (c) 2006 Richard McDougall
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Shell Wrapper Concept by Brendan Gregg
+#
+# 08-Jan-2006 Richard McDougall Created this.
+# 23-Apr-2006 Brendan Gregg Minor style tweaks.
+# 23-Apr-2006 " " Last update.
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_trace=0; opt_fs=0; opt_stats=1; opt_all=0
+
+### process options
+while getopts t name
+do
+ case $name in
+ t) opt_trace=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: voptrace [-t] [/mountpoint]
+ voptrace # default output
+ -t # trace
+ eg,
+ voptrace -t # trace all file systems
+ voptrace -t /tmp # trace /tmp
+ voptrace /tmp # summary stats for /tmp
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+filesys="$1"
+
+### option logic
+if [ $opt_trace -eq 1 ]; then
+ opt_stats=0
+fi
+if [ -z "$filesys" ]; then
+ opt_all=1
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_fs = '$opt_fs';
+ inline int OPT_all = '$opt_all';
+ inline int OPT_trace = '$opt_trace';
+ inline int OPT_stats = '$opt_stats';
+ inline string FILESYS = "'$filesys'";
+
+ #pragma D option quiet
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ last_event[""] = 0;
+
+ /* print main headers */
+ OPT_stats == 1 ?
+ printf("\033[H\033[2J") : 1;
+
+ OPT_trace == 1 ?
+ printf("%2s %-15s %-10s %51s %2s %8s %8s\n",
+ "", "Event", "Device", "Path", "RW", "Size", "Offset") : 1;
+ self->path = "";
+ self->trace = 0;
+ }
+
+ dtrace:::BEGIN
+ /OPT_trace == 1/
+ {
+ /* make D compiler happy */
+ @vop_iocnt[""] = count();
+ @vop_cnt[""] = count();
+ @vop_time[""] = sum(0);
+ trunc(@vop_iocnt);
+ trunc(@vop_cnt);
+ trunc(@vop_time);
+ }
+
+ fbt::fop_*:entry
+ {
+ self->trace = 0;
+
+ /* Get vp: fop_open has a pointer to vp */
+ this->vpp = (vnode_t **)arg0;
+ self->vp = (vnode_t *)arg0;
+ self->vp = probefunc == "fop_open" ? (vnode_t *)*this->vpp : self->vp;
+
+ /* And the containing vfs */
+ this->vfsp = self->vp ? self->vp->v_vfsp : 0;
+
+ /* And the paths for the vp and containing vfs */
+ this->vfsvp = this->vfsp ?
+ (struct vnode *)((vfs_t *)this->vfsp)->vfs_vnodecovered : 0;
+ self->vfspath = this->vfsvp ? stringof(this->vfsvp->v_path) : "unknown";
+
+ /* Check if we should trace the root fs */
+ (OPT_all ||
+ (FILESYS == "/" && this->vfsp &&
+ (this->vfsp == `rootvfs))) ? self->trace = 1 : self->trace;
+
+ /* Check if we should trace the fs */
+ (OPT_all || (self->vfspath == FILESYS)) ? self->trace = 1 : self->trace;
+
+ self->vfspath = 0;
+ }
+
+ /*
+ * Trace the entry point to each fop
+ */
+ fbt::fop_*:entry
+ /self->trace/
+ {
+ self->path = (self->vp != NULL && self->vp->v_path) ?
+ stringof(self->vp->v_path) : "unknown";
+
+ /* Some fops has the len in arg2 */
+ (probefunc == "fop_getpage" ||
+ probefunc == "fop_putpage" ||
+ probefunc == "fop_none") ? self->len = arg2 : 1;
+
+ /* Some fops has the len in arg3 */
+ (probefunc == "fop_pageio" ||
+ probefunc == "fop_none") ? self->len = arg3 : 1;
+
+ /* Some fops has the len in arg4 */
+ (probefunc == "fop_addmap" ||
+ probefunc == "fop_map" ||
+ probefunc == "fop_delmap") ? self->len = arg4 : 1;
+
+ /* Some fops has the offset in arg1 */
+ (probefunc == "fop_addmap" ||
+ probefunc == "fop_map" ||
+ probefunc == "fop_getpage" ||
+ probefunc == "fop_putpage" ||
+ probefunc == "fop_seek" ||
+ probefunc == "fop_delmap") ? self->off = arg1 : 1;
+
+ /* Some fops has the offset in arg3 */
+ (probefunc == "fop_close" ||
+ probefunc == "fop_pageio") ? self->off = arg3 : 1;
+
+ /* Some fops has the offset in arg4 */
+ probefunc == "fop_frlock" ? self->off = arg4 : 1;
+
+ /* Some fops has the pathname in arg1 */
+ self->path = (probefunc == "fop_create" ||
+ probefunc == "fop_mkdir" ||
+ probefunc == "fop_rmdir" ||
+ probefunc == "fop_remove" ||
+ probefunc == "fop_lookup") ?
+ strjoin(self->path, strjoin("/", stringof(arg1))) : self->path;
+
+ OPT_trace ?
+ printf("%2s %-15s %-10s %51s %2s %8d %8d\n",
+ "->", probefunc, "-", self->path, "-",
+ self->len, self->off) : 1;
+
+ self->type = probefunc;
+ self->vop_entry[probefunc] = timestamp;
+ }
+
+ fbt::fop_*:return
+ /self->trace == 1/
+ {
+ OPT_trace ?
+ printf("%2s %-15s %-10s %51s %2s %8d %8d\n",
+ "<-", probefunc, "-", self->path, "-",
+ self->len, self->off) : 1;
+
+ OPT_stats == 1 ?
+ @vop_time[probefunc] =
+ sum(timestamp - self->vop_entry[probefunc]) : 1;
+ OPT_stats == 1 ?
+ @vop_cnt[probefunc] = count() : 1;
+
+ self->path = 0;
+ self->len = 0;
+ self->off = 0;
+ }
+
+ fbt::fop_*:return
+ {
+ self->trace = 0;
+ self->type = 0;
+ self->vp = 0;
+ }
+
+ /* Capture any I/O within this fop */
+ io:::start
+ /self->trace/
+ {
+ OPT_stats == 1 ?
+ @vop_iocnt[self->type] = count() : 1;
+
+ OPT_trace == 1?
+ printf("%2s %-15s %-10s %51s %2s %8d %8u\n",
+ "--", self->type, args[1]->dev_statname,
+ self->path, args[0]->b_flags & B_READ ? "R" : "W",
+ args[0]->b_bcount, args[0]->b_blkno) : 1;
+ }
+
+ profile:::tick-5s
+ /OPT_stats == 1/
+ {
+ /* Print top 20 only */
+ trunc(@vop_iocnt, 20);
+ trunc(@vop_time, 20);
+
+ /* Display microseconds */
+ normalize(@vop_time, 1000000);
+ printf("\033[H\033[2J");
+ printf("%-60s %10s\n", "VOP Physical IO", "Count");
+ printa("%-60s %10@d\n", @vop_iocnt);
+ printf("\n");
+ printf("%-60s %10s\n", "VOP Count", "Count");
+ printa("%-60s %10@d\n", @vop_cnt);
+ printf("\n");
+ printf("%-60s %10s\n", "VOP Wall Time", "mSeconds");
+ printa("%-60s %10@d\n", @vop_time);
+
+ /* Clear data */
+ trunc(@vop_iocnt);
+ trunc(@vop_cnt);
+ trunc(@vop_time);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Guide b/cddl/contrib/dtracetoolkit/Guide
new file mode 100644
index 0000000..739d367
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Guide
@@ -0,0 +1,91 @@
+Guide - Guide to the DTraceToolkit
+
+ How to get started, and a table of contents.
+
+QuickStart
+
+ 1. The top most useful scripts are in this directory.
+ 2. Try running them with "-h". Eg, "./execsnoop -h".
+ 3. Read Docs/Contents for a full list of scripts.
+
+QuickStart-by-Screenshot
+
+ 1. Look through the examples in the Examples directory until
+ you see an output you like
+ 2. Find the script and run it
+ 3. Look for its man page in Man
+
+Not-so-QuickStart
+
+ 1. Welcome!
+ 2. Check the Table of Contents below to become famaliar with the
+ directory structure of the DTraceToolkit.
+ 3. See Docs/Faq for any initial questions.
+ 4. Read Docs/Contents for a list of scripts.
+ 5. Read Docs/Readme to see where scripts are documented.
+ 6. Check Docs/Links for further DTrace.
+ 7. Once famaliar with the toolkit, the following may be useful to
+ add to your shell initialisation file,
+ PATH=$PATH:/opt/DTT/Bin
+ MANPATH=$MANPATH:/opt/DTT/Man
+ in this case assuming the toolkit was installed in /opt/DTT.
+
+Installation
+
+ 1. Run ./install
+ This will replace any existing version of the DTraceToolkit
+ with this one. It will prompt. Final install location is
+ printed by this install script.
+
+Table of Contents
+
+ DTraceToolkit-X.XX/
+ Bin/ Symlinks to all the scripts
+ Apps/ Application specific scripts
+ Cpu/ Scripts for CPU analysis
+ Code/ Example code to practise on
+ Disk/ Scripts for disk I/O analysis
+ Docs/ Documentation
+ Contents Command list for the Toolkit
+ Faq Frequently asked questions
+ Links Further DTrace links
+ Readme Readme for using the docs
+ Examples/ Examples of command usage
+ Guide This file!
+ Include/ DTrace include files
+ Java/ Scripts for tracing Java
+ JavaScript/ Scripts for tracing JavaScript
+ Kernel/ Scripts for kernel analysis
+ License The CDDL license
+ Locks/ Scripts for lock analysis
+ Man/ Man pages
+ man1m/ Man pages for the Toolkit commands
+ Mem/ Scripts for memory analysis
+ Misc/ Misc scripts
+ Net/ Scripts for network analysis
+ Notes/ Notes on Toolkit commands
+ Perl/ Scripts for tracing Perl
+ Php/ Scripts for tracing Php
+ Proc/ Scripts for process analysis
+ Python/ Scripts for tracing Python
+ Ruby/ Scripts for tracing Ruby
+ Shell/ Scripts for tracing Shell languages
+ Snippits/ Snippits of D scripting
+ System/ Scripts for system analysis
+ Tcl/ Scripts for tracing Tcl
+ User/ Scripts for user based activity analysis
+ Zones/ Scripts for analysis by zone
+ Version DTraceToolkit version
+ install Install script, use for installs only
+
+When you type ls in the DTraceToolkit, you will be looking at the top ten
+or so most useful scripts plus the top level directories. Other scripts have
+been placed in meaningful subdirectories, such as Disk, Kernel, Proc, etc.
+
+An optional Bin directory has been provided that links to all the scripts.
+
+The DTraceToolkit is released under the CDDL license. It's the same open
+source license that OpenSolaris has been released under.
+
+Thank you for using the DTraceToolkit!
+
diff --git a/cddl/contrib/dtracetoolkit/Include/Readme b/cddl/contrib/dtracetoolkit/Include/Readme
new file mode 100644
index 0000000..4aa4688
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Include/Readme
@@ -0,0 +1,18 @@
+Include - include scripts for D scripting
+
+ This directory contains files that can be included for use with D scripts.
+
+ There are two types of include files,
+
+ *.h
+ These can be included using,
+
+ #!/usr/sbin/dtrace -Cs
+ #include <filename.h>
+
+ *.d
+ These must be copyied to a translator directory (/usr/lib/dtrace),
+ and should be automatically pulled in.
+
+ This directory does not contain runnable DTrace scripts.
+
diff --git a/cddl/contrib/dtracetoolkit/Include/test.ksh b/cddl/contrib/dtracetoolkit/Include/test.ksh
new file mode 100755
index 0000000..a3e1036
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Include/test.ksh
@@ -0,0 +1,68 @@
+#!/usr/bin/ksh
+/*
+ * test.ksh - DTrace include file test script.
+ *
+ * $Id: test.ksh 36 2007-09-15 06:51:18Z brendan $
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 16-Sep-2007 Brendan Gregg Created this.
+ */
+
+dtrace -CI . -s /dev/stdin << END
+
+#include "tostr.h"
+#include "time.h"
+
+#pragma D option quiet
+#pragma D option destructive
+
+dtrace:::BEGIN
+{
+ i = 1;
+ printf("\nNUM_TO_STR %12d = %s\n", i, NUM_TO_STR(i));
+ i = 1100;
+ printf("NUM_TO_STR %12d = %s\n", i, NUM_TO_STR(i));
+ i = 1100000;
+ printf("NUM_TO_STR %12d = %s\n", i, NUM_TO_STR(i));
+ i = 999999999;
+ printf("NUM_TO_STR %12d = %s\n", i, NUM_TO_STR(i));
+
+ i = 1;
+ printf("\nBYTES_TO_STR %12d = %s\n", i, BYTES_TO_STR(i));
+ i = 1024;
+ printf("BYTES_TO_STR %12d = %s\n", i, BYTES_TO_STR(i));
+ i = 1000000;
+ printf("BYTES_TO_STR %12d = %s\n", i, BYTES_TO_STR(i));
+ i = 999999999;
+ printf("BYTES_TO_STR %12d = %s\n", i, BYTES_TO_STR(i));
+
+ i = 1;
+ printf("\nUS_TO_STR %12d = %s\n", i, US_TO_STR(i));
+ i = 1100;
+ printf("US_TO_STR %12d = %s\n", i, US_TO_STR(i));
+ i = 999999;
+ printf("US_TO_STR %12d = %s\n", i, US_TO_STR(i));
+
+ printf("\nwalltimestamp : %Y\n", walltimestamp);
+ printf("TZ=GMT date : ");
+ system("TZ=GMT date '+%%H:%%M:%%S'");
+ printf("TIME_HHMMSS : %s\n", TIME_HHMMSS);
+
+ exit(0);
+}
+END
diff --git a/cddl/contrib/dtracetoolkit/Include/time.h b/cddl/contrib/dtracetoolkit/Include/time.h
new file mode 100644
index 0000000..76caa2e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Include/time.h
@@ -0,0 +1,38 @@
+/*
+ * time.h - DTrace Time include file.
+ *
+ * $Id: time.h 36 2007-09-15 06:51:18Z brendan $
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 16-Sep-2007 Brendan Gregg Created this.
+ */
+
+/*
+ * TIME_HHMMSS - Returns GMT time as a "HH:MM:SS" string.
+ *
+ * eg, "21:53:07"
+ */
+#define TIME_HHMMSS \
+ strjoin(strjoin(strjoin(strjoin(strjoin( \
+ (((walltimestamp / 1000000000) % 86400) / 3600) < 10 ? "0" : "",\
+ lltostr(((walltimestamp / 1000000000) % 86400) / 3600)), ":"), \
+ strjoin((((walltimestamp / 1000000000) % 3600) / 60) < 10 ? \
+ "0" : "", lltostr(((walltimestamp / 1000000000) % 3600) / 60))),\
+ ":"), strjoin(((walltimestamp / 1000000000) % 60) < 10 ? \
+ "0" : "", lltostr((walltimestamp / 1000000000) % 60)))
+
diff --git a/cddl/contrib/dtracetoolkit/Include/tostr.h b/cddl/contrib/dtracetoolkit/Include/tostr.h
new file mode 100644
index 0000000..6032f6a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Include/tostr.h
@@ -0,0 +1,89 @@
+/*
+ * tostr.h - DTrace To-String include file.
+ *
+ * $Id: tostr.h 36 2007-09-15 06:51:18Z brendan $
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 16-Sep-2007 Brendan Gregg Created this.
+ */
+
+/*
+ * NUM_TO_STR(n) - takes a number and returns a string with a prefix,
+ * intended to fit withen 6 chars.
+ *
+ * Input Output
+ * 0 0
+ * 1 1
+ * 10 10
+ * 999 999
+ * 1000 1.0K
+ * 1100 1.1K
+ * 10000 10.0K
+ * 999999 999.0K
+ * 1000000 1.0M
+ * 10000000 10.0M
+ * 999999999 999.9M
+ */
+#define NUM_TO_STR(n) \
+ n >= 1000000 ? \
+ strjoin(strjoin(strjoin(lltostr(n / 1000000), "."), \
+ lltostr((n % 1000000) / 100000)), "M") : n >= 1000 ? \
+ strjoin(strjoin(strjoin(lltostr(n / 1000), "."), \
+ lltostr((n % 1000) / 100)), "K") : lltostr(n)
+
+/*
+ * BYTES_TO_STR(n) - takes a byte count and returns a string with a prefix,
+ * intended to fit withen 6 chars.
+ *
+ * Input Output
+ * 0 0
+ * 1 1
+ * 10 10
+ * 999 0.9K
+ * 1000 0.9K
+ * 1024 1.0K
+ * 10240 10.0K
+ * 1000000 976.5K
+ * 1048576 1.0M
+ * 1000000000 953.6M
+ */
+#define BYTES_TO_STR(n) \
+ n >= 1024000 ? \
+ strjoin(strjoin(strjoin(lltostr(n / 1048576), "."), \
+ lltostr((n % 1048576) / 104858)), "M") : n >= 1000 ? \
+ strjoin(strjoin(strjoin(lltostr(n / 1024), "."), \
+ lltostr((n % 1024) / 103)), "K") : lltostr(n)
+
+/*
+ * US_TO_STR(n) - takes microseconds and returns a string with a prefix,
+ * intended to fit withen 6 chars.
+ *
+ * Input Output
+ * 0 0
+ * 1 1u
+ * 10 10u
+ * 999 999u
+ * 1000 1.0m
+ * 1100 1.1m
+ * 10000 10.0m
+ * 999999 999.0m
+ */
+#define US_TO_STR(n) \
+ n == 0 ? "0" : n >= 1000 ? \
+ strjoin(lltostr(n / 1000), "m") : strjoin(lltostr(n), "u")
+
diff --git a/cddl/contrib/dtracetoolkit/Java/Readme b/cddl/contrib/dtracetoolkit/Java/Readme
new file mode 100644
index 0000000..ae455a5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/Readme
@@ -0,0 +1,17 @@
+Java - DTracing Java
+
+ These scripts trace the JVM, and require the Java hotspot provider which
+ was shipped with Java starting with version 1.6.0.
+
+ Some of these scripts measure method and object events, and require
+ the Java process to be run using the "+ExtendedDTraceProbes" flag.
+ For example,
+
+ java -XX:+ExtendedDTraceProbes classfile
+
+ The ExtendedDTraceProbes flag is not on by default to avoid the additional
+ overhead for maintaining these additional probes. When this flag is
+ enabled, the JVM may execute slightly slower than before; when the probes
+ are also enabled (especially method probes), the JVM may execute
+ significantly slower.
+
diff --git a/cddl/contrib/dtracetoolkit/Java/j_calldist.d b/cddl/contrib/dtracetoolkit/Java/j_calldist.d
new file mode 100755
index 0000000..f0cb087
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_calldist.d
@@ -0,0 +1,116 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * j_calldist.d - measure Java elapsed times for different types of operation.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_calldist.d 59 2007-10-03 08:21:58Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls are only visible when using the
+ * flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_calldist.d [top] # hit Ctrl-C to end
+ *
+ * The "top" optional argument will truncate the output for each report
+ * section to that many lines, with a default of 10.
+ *
+ * FIELDS:
+ * 1 Process ID
+ * 2 Type of call (method/gc)
+ * 3 Name of call
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+hotspot*:::method-entry
+{
+ self->depth[arg0]++;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+ self->method[arg0, self->depth[arg0]] = timestamp;
+}
+
+hotspot*:::method-return
+/self->method[arg0, self->depth[arg0]]/
+{
+ this->elapsed_incl = timestamp - self->method[arg0, self->depth[arg0]];
+ this->elapsed_excl = this->elapsed_incl -
+ self->exclude[arg0, self->depth[arg0]];
+ self->method[arg0, self->depth[arg0]] = 0;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+
+ @types_incl[pid, "method", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[pid, "method", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth[arg0]--;
+ self->exclude[arg0, self->depth[arg0]] += this->elapsed_incl;
+}
+
+hotspot*:::gc-begin
+{
+ self->gc = timestamp;
+ self->full = (boolean_t)arg0;
+}
+
+hotspot*:::gc-end
+/self->gc/
+{
+ this->elapsed = timestamp - self->gc;
+
+ @types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] =
+ quantize(this->elapsed / 1000);
+
+ self->gc = 0;
+ self->full = 0;
+}
+
+dtrace:::END
+{
+ trunc(@types, top);
+ printf("\nTop %d elapsed times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types);
+
+ trunc(@types_excl, top);
+ printf("\nTop %d exclusive method elapsed times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ printf("\nTop %d inclusive method elapsed times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_calls.d b/cddl/contrib/dtracetoolkit/Java/j_calls.d
new file mode 100755
index 0000000..087545d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_calls.d
@@ -0,0 +1,113 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_calls.d - count Java calls (method/...) using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_calls.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls and object allocation are only
+ * visible when using the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (see below)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * TYPEs:
+ * cload class load
+ * method method call
+ * mcompile method compile
+ * mload compiled method load
+ * oalloc object alloc
+ * thread thread start
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot*:::method-entry
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+ @calls[pid, "method", this->name] = count();
+}
+
+hotspot*:::object-alloc
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ @calls[pid, "oalloc", stringof(this->class)] = count();
+}
+
+hotspot*:::class-loaded
+{
+ this->class = (char *)copyin(arg0, arg1 + 1);
+ this->class[arg1] = '\0';
+ @calls[pid, "cload", stringof(this->class)] = count();
+}
+
+hotspot*:::thread-start
+{
+ this->thread = (char *)copyin(arg0, arg1 + 1);
+ this->thread[arg1] = '\0';
+ @calls[pid, "thread", stringof(this->thread)] = count();
+}
+
+hotspot*:::method-compile-begin
+{
+ this->class = (char *)copyin(arg0, arg1 + 1);
+ this->class[arg1] = '\0';
+ this->method = (char *)copyin(arg2, arg3 + 1);
+ this->method[arg3] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+ @calls[pid, "mcompile", this->name] = count();
+}
+
+hotspot*:::compiled-method-load
+{
+ this->class = (char *)copyin(arg0, arg1 + 1);
+ this->class[arg1] = '\0';
+ this->method = (char *)copyin(arg2, arg3 + 1);
+ this->method[arg3] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+ @calls[pid, "mload", this->name] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-8s %-52s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_calltime.d b/cddl/contrib/dtracetoolkit/Java/j_calltime.d
new file mode 100755
index 0000000..be4da51
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_calltime.d
@@ -0,0 +1,129 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * j_calltime.d - measure Java elapsed times for different types of operation.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_calltime.d 59 2007-10-03 08:21:58Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls are only visible when using the
+ * flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_calltime.d [top] # hit Ctrl-C to end
+ *
+ * The "top" optional argument will truncate the output for each report
+ * section to that many lines, with a default of 10.
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (method/gc/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+hotspot*:::method-entry
+{
+ self->depth[arg0]++;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+ self->method[arg0, self->depth[arg0]] = timestamp;
+}
+
+hotspot*:::method-return
+/self->method[arg0, self->depth[arg0]]/
+{
+ this->elapsed_incl = timestamp - self->method[arg0, self->depth[arg0]];
+ this->elapsed_excl = this->elapsed_incl -
+ self->exclude[arg0, self->depth[arg0]];
+ self->method[arg0, self->depth[arg0]] = 0;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+
+ @num[pid, "method", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "method", this->name] = sum(this->elapsed_incl);
+ @types_excl[pid, "method", this->name] = sum(this->elapsed_excl);
+ @types_excl[0, "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth[arg0]--;
+ self->exclude[arg0, self->depth[arg0]] += this->elapsed_incl;
+}
+
+hotspot*:::gc-begin
+{
+ self->gc = timestamp;
+ self->full = (boolean_t)arg0;
+}
+
+hotspot*:::gc-end
+/self->gc/
+{
+ this->elapsed = timestamp - self->gc;
+ self->gc = 0;
+
+ @num[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] = count();
+ @types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] =
+ sum(this->elapsed);
+ self->full = 0;
+}
+
+dtrace:::END
+{
+ trunc(@num, top);
+ printf("\nTop %d counts,\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-10s %-48s %@8d\n", @num);
+
+ trunc(@types, top);
+ normalize(@types, 1000);
+ printf("\nTop %d elapsed times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types);
+
+ trunc(@types_excl, top);
+ normalize(@types_excl, 1000);
+ printf("\nTop %d exclusive method elapsed times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ normalize(@types_incl, 1000);
+ printf("\nTop %d inclusive method elapsed times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_classflow.d b/cddl/contrib/dtracetoolkit/Java/j_classflow.d
new file mode 100755
index 0000000..162338a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_classflow.d
@@ -0,0 +1,100 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_classflow.d - trace a Java class method flow using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_classflow.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_classflow.d classname # hit Ctrl-C to end
+ *
+ * This watches Java method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * PID Process ID
+ * CLASS.METHOD Java class and method name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ * Changes in TID will appear to shuffle output, as we change from one thread
+ * depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+/* increasing bufsize can reduce drops */
+#pragma D option bufsize=16m
+#pragma D option quiet
+#pragma D option defaultargs
+#pragma D option switchrate=10
+
+self int depth[int];
+
+dtrace:::BEGIN
+/$$1 == ""/
+{
+ printf("USAGE: j_classflow.d classname\n");
+ exit(1);
+}
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "CLASS.METHOD");
+}
+
+hotspot*:::method-entry,
+hotspot*:::method-return
+{
+ this->class = stringof((char *)copyin(arg1, arg2 + 1));
+ this->class[arg2] = '\0';
+}
+
+hotspot*:::method-entry
+/this->class == $$1/
+{
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ printf("%3d %6d %-16d %*s-> %s.%s\n", cpu, pid, timestamp / 1000,
+ self->depth[arg0] * 2, "", stringof(this->class),
+ stringof(this->method));
+ self->depth[arg0]++;
+}
+
+hotspot*:::method-return
+/this->class == $$1/
+{
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ self->depth[arg0] -= self->depth[arg0] > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %*s<- %s.%s\n", cpu, pid, timestamp / 1000,
+ self->depth[arg0] * 2, "", stringof(this->class),
+ stringof(this->method));
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_cpudist.d b/cddl/contrib/dtracetoolkit/Java/j_cpudist.d
new file mode 100755
index 0000000..9a4626e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_cpudist.d
@@ -0,0 +1,116 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * j_cpudist.d - measure Java on-CPU times for different types of operation.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_cpudist.d 59 2007-10-03 08:21:58Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls are only visible when using the
+ * flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_cpudist.d [top] # hit Ctrl-C to end
+ *
+ * The "top" optional argument will truncate the output for each report
+ * section to that many lines, with a default of 10.
+ *
+ * FIELDS:
+ * 1 Process ID
+ * 2 Type of call (method/gc)
+ * 3 Name of call
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+hotspot*:::method-entry
+{
+ self->depth[arg0]++;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+ self->method[arg0, self->depth[arg0]] = vtimestamp;
+}
+
+hotspot*:::method-return
+/self->method[arg0, self->depth[arg0]]/
+{
+ this->oncpu_incl = vtimestamp - self->method[arg0, self->depth[arg0]];
+ this->oncpu_excl = this->oncpu_incl -
+ self->exclude[arg0, self->depth[arg0]];
+ self->method[arg0, self->depth[arg0]] = 0;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+
+ @types_incl[pid, "method", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[pid, "method", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth[arg0]--;
+ self->exclude[arg0, self->depth[arg0]] += this->oncpu_incl;
+}
+
+hotspot*:::gc-begin
+{
+ self->gc = vtimestamp;
+ self->full = (boolean_t)arg0;
+}
+
+hotspot*:::gc-end
+/self->gc/
+{
+ this->oncpu = vtimestamp - self->gc;
+
+ @types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] =
+ quantize(this->oncpu / 1000);
+
+ self->gc = 0;
+ self->full = 0;
+}
+
+dtrace:::END
+{
+ trunc(@types, top);
+ printf("\nTop %d on-CPU times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types);
+
+ trunc(@types_excl, top);
+ printf("\nTop %d exclusive method on-CPU times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ printf("\nTop %d inclusive method on-CPU times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_cputime.d b/cddl/contrib/dtracetoolkit/Java/j_cputime.d
new file mode 100755
index 0000000..a720cdb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_cputime.d
@@ -0,0 +1,129 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * j_cputime.d - measure Java on-CPU times for different types of operation.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_cputime.d 59 2007-10-03 08:21:58Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls are only visible when using the
+ * flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_cputime.d [top] # hit Ctrl-C to end
+ *
+ * The "top" optional argument will truncate the output for each report
+ * section to that many lines, with a default of 10.
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (method/gc/total)
+ * NAME Name of call
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+hotspot*:::method-entry
+{
+ self->depth[arg0]++;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+ self->method[arg0, self->depth[arg0]] = vtimestamp;
+}
+
+hotspot*:::method-return
+/self->method[arg0, self->depth[arg0]]/
+{
+ this->oncpu_incl = vtimestamp - self->method[arg0, self->depth[arg0]];
+ this->oncpu_excl = this->oncpu_incl -
+ self->exclude[arg0, self->depth[arg0]];
+ self->method[arg0, self->depth[arg0]] = 0;
+ self->exclude[arg0, self->depth[arg0]] = 0;
+
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+
+ @num[pid, "method", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "method", this->name] = sum(this->oncpu_incl);
+ @types_excl[pid, "method", this->name] = sum(this->oncpu_excl);
+ @types_excl[0, "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth[arg0]--;
+ self->exclude[arg0, self->depth[arg0]] += this->oncpu_incl;
+}
+
+hotspot*:::gc-begin
+{
+ self->gc = vtimestamp;
+ self->full = (boolean_t)arg0;
+}
+
+hotspot*:::gc-end
+/self->gc/
+{
+ this->oncpu = vtimestamp - self->gc;
+ self->gc = 0;
+
+ @num[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] = count();
+ @types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] =
+ sum(this->oncpu);
+ self->full = 0;
+}
+
+dtrace:::END
+{
+ trunc(@num, top);
+ printf("\nTop %d counts,\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-10s %-48s %@8d\n", @num);
+
+ trunc(@types, top);
+ normalize(@types, 1000);
+ printf("\nTop %d on-CPU times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types);
+
+ trunc(@types_excl, top);
+ normalize(@types_excl, 1000);
+ printf("\nTop %d exclusive method on-CPU times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ normalize(@types_incl, 1000);
+ printf("\nTop %d inclusive method on-CPU times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_events.d b/cddl/contrib/dtracetoolkit/Java/j_events.d
new file mode 100755
index 0000000..d8c938b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_events.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_events.d - count Java events using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_events.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Some events such as method calls are only
+ * visible when using the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_events.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * EVENT Event name (DTrace probe name)
+ * COUNT Number of calls during sample
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/* this matches both hotspot and hotspot_jni providers */
+hotspot*:::
+{
+ @calls[pid, probename] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %-36s %8s\n", "PID", "EVENT", "COUNT");
+ printa(" %6d %-36s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_flow.d b/cddl/contrib/dtracetoolkit/Java/j_flow.d
new file mode 100755
index 0000000..e98c067
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_flow.d
@@ -0,0 +1,87 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_flow.d - snoop Java execution showing method flow using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_flow.d 38 2007-09-16 08:17:41Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_flow.d # hit Ctrl-C to end
+ *
+ * This watches Java method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * PID Process ID
+ * CLASS.METHOD Java class and method name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ * Changes in TID will appear to shuffle output, as we change from one thread
+ * depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+/* increasing bufsize can reduce drops */
+#pragma D option bufsize=16m
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth[int];
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "CLASS.METHOD");
+}
+
+hotspot*:::method-entry
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ printf("%3d %6d %-16d %*s-> %s.%s\n", cpu, pid, timestamp / 1000,
+ self->depth[arg0] * 2, "", stringof(this->class),
+ stringof(this->method));
+ self->depth[arg0]++;
+}
+
+hotspot*:::method-return
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ self->depth[arg0] -= self->depth[arg0] > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %*s<- %s.%s\n", cpu, pid, timestamp / 1000,
+ self->depth[arg0] * 2, "", stringof(this->class),
+ stringof(this->method));
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_flowtime.d b/cddl/contrib/dtracetoolkit/Java/j_flowtime.d
new file mode 100755
index 0000000..53e75cd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_flowtime.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_flowtime.d - snoop Java execution with method flow and delta times.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_flowtime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches Java method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * TID Thread ID
+ * TIME(us) Time since boot (us)
+ * DELTA(us) Elapsed time from previous line to this line
+ * CLASS.METHOD Java class and method name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ * Changes in TID will appear to shuffle output, as we change from one thread
+ * depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+/* increasing bufsize can reduce drops */
+#pragma D option bufsize=16m
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth[int];
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s/%-5s %-16s %9s -- %s\n", "C", "PID", "TID", "TIME(us)",
+ "DELTA(us)", "CLASS.METHOD");
+}
+
+hotspot*:::method-entry,
+hotspot*:::method-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+hotspot*:::method-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ printf("%3d %6d/%-5d %-16d %9d %*s-> %s.%s\n", cpu, pid, tid,
+ timestamp / 1000, this->delta, self->depth[arg0] * 2, "",
+ stringof(this->class), stringof(this->method));
+ self->depth[arg0]++;
+ self->last = timestamp;
+}
+
+hotspot*:::method-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ self->depth[arg0] -= self->depth[arg0] > 0 ? 1 : 0;
+ printf("%3d %6d/%-5d %-16d %9d %*s<- %s.%s\n", cpu, pid, tid,
+ timestamp / 1000, this->delta, self->depth[arg0] * 2, "",
+ stringof(this->class), stringof(this->method));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_methodcalls.d b/cddl/contrib/dtracetoolkit/Java/j_methodcalls.d
new file mode 100755
index 0000000..606b820
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_methodcalls.d
@@ -0,0 +1,60 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_methodcalls.d - count Java method calls DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_methodcalls.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_methodcalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * COUNT Number of calls during sample
+ * CLASS.METHOD Java class and method name
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot*:::method-entry
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+ @calls[pid, this->name] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %8s %s\n", "PID", "COUNT", "CLASS.METHOD");
+ printa(" %6d %@8d %s\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_objnew.d b/cddl/contrib/dtracetoolkit/Java/j_objnew.d
new file mode 100755
index 0000000..8847005
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_objnew.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_objnew.d - report Java object allocation using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_objnew.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_objnew.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * OBJS Number of objects created
+ * CLASS.METHOD Java class and method name
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot*:::object-alloc
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ @objs[pid, stringof(this->class)] = count();
+ @dist[pid, stringof(this->class)] = quantize(arg3);
+}
+
+dtrace:::END
+{
+ printf("Java object allocation byte distributions by pid and class,\n");
+ printa(@dist);
+
+ printf("Java object allocation count by pid and class,\n\n");
+ printf(" %6s %8s %s\n", "PID", "OBJS", "CLASS");
+ printa(" %6d %8@d %s\n", @objs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_package.d b/cddl/contrib/dtracetoolkit/Java/j_package.d
new file mode 100755
index 0000000..cfeaf05
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_package.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_package.d - count Java class loads by package using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_package.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0).
+ *
+ * USAGE: j_package.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * LOADS Class loads during trace
+ * PACKAGE Package name from class
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot*:::class-loaded
+{
+ this->class = (char *)copyin(arg0, arg1 + 1);
+ this->class[arg1] = '\0';
+
+ @loads[pid, dirname(stringof(this->class))] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %8s %s\n", "PID", "LOADS", "PACKAGE");
+ printa(" %6d %@8d %s\n", @loads);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_profile.d b/cddl/contrib/dtracetoolkit/Java/j_profile.d
new file mode 100755
index 0000000..4ff009e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_profile.d
@@ -0,0 +1,78 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * j_profile.d - sample stack traces with Java translations using DTrace.
+ *
+ * USAGE: j_profile.d { -p PID | -c cmd } # hit Ctrl-C to end
+ * $Id: j_profile.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ *
+ * This samples stack traces for the process specified. This stack trace
+ * will cross the JVM and system libraries, and insert translations for Java
+ * stack frames where appropriate. This is best explained with an example
+ * stack frame output,
+ *
+ * Func_loop.func_c()V
+ * Func_loop.func_b()V
+ * Func_loop.func_a()V
+ * Func_loop.main([Ljava/lang/String;)V
+ * StubRoutines (1)
+ * libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHan
+ * libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmetho
+ * libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJ
+ * libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_j
+ * libjvm.so`jni_CallStaticVoidMethod+0x15d
+ * java`JavaMain+0xd30
+ * libc.so.1`_thr_setup+0x52
+ * libc.so.1`_lwp_start
+ * 101
+ *
+ * The lines at the top are Java frames, followed by the JVM (libjvm.so).
+ * The JVM symbols may be translated by passing the output through c++filt.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option jstackstrsize=1024
+
+/*
+ * Tunables
+ */
+#define DEPTH 10 /* stack depth, frames */
+#define RATE 101 /* sampling rate, Hertz */
+#define TOP 25 /* number of stacks to output */
+
+dtrace:::BEGIN
+{
+ printf("Sampling %d-level stacks at %d Hertz... Hit Ctrl-C to end.\n",
+ DEPTH, RATE);
+}
+
+profile-RATE
+/pid == $target/
+{
+ @stacks[jstack(DEPTH)] = count();
+}
+
+dtrace:::END
+{
+ trunc(@stacks, TOP);
+ printf("Top %d most frequently sampled stacks,\n", TOP);
+ printa(@stacks);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_stat.d b/cddl/contrib/dtracetoolkit/Java/j_stat.d
new file mode 100755
index 0000000..862fe31
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_stat.d
@@ -0,0 +1,148 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_stat.d - Java operation stats using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_stat.d 64 2007-10-04 08:35:29Z claire $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0). Method calls and object allocation are only
+ * visible when using the flag "+ExtendedDTraceProbes". eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_stat.d [interval [count]]
+ *
+ * FIELDS:
+ * EXEC/s Java programs executed per second, including
+ * those without Java provider support
+ * THREAD/s Threads created, per second
+ * METHOD/s Methods called, per second
+ * OBJNEW/s Objects created, per second
+ * CLOAD/s Class loads, per second
+ * EXCP/s Exceptions raised, per second
+ * GC/s Garbage collects, per second
+ *
+ * The numbers are per second counts for the interval specified. The default
+ * interval is 1 second.
+ *
+ * If you see a count in "EXECS" but not in the other columns, then your
+ * Java software is probably not running with the DTrace hotspot provider.
+ *
+ * If you see counts in "CLOAD" but not in "METHODS", then you Java
+ * software probably isn't running with "+ExtendedDTraceProbes".
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+dtrace:::BEGIN
+{
+ execs = threads = methods = objnew = cload = gc = exception = 0;
+ lines = SCREEN + 1;
+ interval = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ secs = interval;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %6s %8s %8s %8s %8s %6s %6s\n", "TIME", "EXEC/s",
+ "THREAD/s", "METHOD/s", "OBJNEW/s", "CLOAD/s", "EXCP/s", "GC/s");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Tally Data
+ */
+proc:::exec-success
+/execname == "java"/
+{
+ execs++;
+}
+
+hotspot*:::thread-start
+{
+ threads++;
+}
+
+hotspot*:::method-entry
+{
+ methods++;
+}
+
+hotspot*:::object-alloc
+{
+ oalloc++;
+}
+
+hotspot*:::class-loaded
+{
+ cload++;
+}
+
+hotspot*:::gc-begin
+{
+ gc++;
+}
+
+hotspot*:::ExceptionOccurred-entry
+{
+ exception++;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %6d %8d %8d %8d %8d %6d %6d\n", walltimestamp,
+ execs / interval, threads / interval, methods / interval,
+ oalloc / interval, cload / interval, exception / interval,
+ gc / interval);
+ execs = threads = methods = oalloc = cload = gc = exception = 0;
+ secs = interval;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_syscalls.d b/cddl/contrib/dtracetoolkit/Java/j_syscalls.d
new file mode 100755
index 0000000..4a24dea
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_syscalls.d
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_syscalls.d - count Java methods and syscalls using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_syscalls.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces Java methods if the hotspot provider exists (1.6.0) and
+ * the flag "+ExtendedDTraceProbes" is used. eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (method/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot$target:::method-entry
+{
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+ this->name = strjoin(strjoin(stringof(this->class), "."),
+ stringof(this->method));
+ @calls[pid, "method", this->name] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[pid, "syscall", probefunc] = count();
+}
+
+
+dtrace:::END
+{
+ printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-8s %-52s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_syscolors.d b/cddl/contrib/dtracetoolkit/Java/j_syscolors.d
new file mode 100755
index 0000000..691ae7e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_syscolors.d
@@ -0,0 +1,135 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_syscolors.d - trace Java method flow plus syscalls, in color.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_syscolors.d 58 2007-10-01 13:36:29Z brendan $
+ *
+ * This traces Java methods if the hotspot provider exists (1.6.0) and
+ * the flag "+ExtendedDTraceProbes" is used. eg,
+ * java -XX:+ExtendedDTraceProbes classfile
+ *
+ * USAGE: j_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches Java method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * TID Thread ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * TYPE Type of call (func/syscall)
+ * NAME Java method or syscall name
+ *
+ * If the flow appears to jump, check the TID column - the JVM may have
+ * switched to another thread.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ * Changes in TID will appear to shuffle output, as we change from one thread
+ * depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+/* increasing bufsize can reduce drops */
+#pragma D option bufsize=32m
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth[int];
+
+dtrace:::BEGIN
+{
+ color_java = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%3s %6s/%-5s %9s %-8s -- %s\n", "C", "PID", "TID", "DELTA(us)",
+ "TYPE", "NAME");
+}
+
+hotspot$target:::method-entry,
+hotspot$target:::method-return,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+hotspot$target:::method-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ printf("%s%3d %6d/%-5d %9d %-8s %*s-> %s.%s%s\n", color_java, cpu,
+ pid, tid, this->delta, "method", self->depth[arg0] * 2, "",
+ stringof(this->class), stringof(this->method), color_off);
+ self->depth[arg0]++;
+ self->depthlast = self->depth[arg0];
+ self->last = timestamp;
+}
+
+hotspot$target:::method-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->class = (char *)copyin(arg1, arg2 + 1);
+ this->class[arg2] = '\0';
+ this->method = (char *)copyin(arg3, arg4 + 1);
+ this->method[arg4] = '\0';
+
+ self->depth[arg0] -= self->depth[arg0] > 0 ? 1 : 0;
+ printf("%s%3d %6d/%-5d %9d %-8s %*s<- %s.%s%s\n", color_java, cpu,
+ pid, tid, this->delta, "method", self->depth[arg0] * 2, "",
+ stringof(this->class), stringof(this->method), color_off);
+ self->depthlast = self->depth[arg0];
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d/%-5d %9d %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, tid, this->delta, "syscall", self->depthlast * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d/%-5d %9d %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, tid, this->delta, "syscall", self->depthlast * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_thread.d b/cddl/contrib/dtracetoolkit/Java/j_thread.d
new file mode 100755
index 0000000..08d2de8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_thread.d
@@ -0,0 +1,64 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_thread.d - snoop Java thread execution using DTrace.
+ Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_thread.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0).
+ *
+ * USAGE: j_thread.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * TIME Time string
+ * PID Process ID
+ * TID Thread ID
+ * THREAD Thread name
+ *
+ * LEGEND:
+ * => thread start
+ * <= thread end
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+dtrace:::BEGIN
+{
+ printf("%-20s %6s/%-5s -- %s\n", "TIME", "PID", "TID", "THREAD");
+}
+
+hotspot*:::thread-start
+{
+ this->thread = (char *)copyin(arg0, arg1 + 1);
+ this->thread[arg1] = '\0';
+ printf("%-20Y %6d/%-5d => %s\n", walltimestamp, pid, tid,
+ stringof(this->thread));
+}
+
+hotspot*:::thread-stop
+{
+ this->thread = (char *)copyin(arg0, arg1 + 1);
+ this->thread[arg1] = '\0';
+ printf("%-20Y %6d/%-5d <= %s\n", walltimestamp, pid, tid,
+ stringof(this->thread));
+}
diff --git a/cddl/contrib/dtracetoolkit/Java/j_who.d b/cddl/contrib/dtracetoolkit/Java/j_who.d
new file mode 100755
index 0000000..8785cca
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Java/j_who.d
@@ -0,0 +1,58 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * j_who.d - trace Java calls by process using DTrace.
+ * Written for the Java hotspot DTrace provider.
+ *
+ * $Id: j_who.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This traces activity from all Java processes on the system with hotspot
+ * provider support (1.6.0).
+ *
+ * USAGE: j_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of Java
+ * UID User ID of the owner
+ * CALLS Number of calls made (a measure of activity)
+ * ARGS Process name and arguments
+ *
+ * The argument list is truncated at 55 characters (up to 80 is easily
+ * available). To easily read the full argument list, use other system tools;
+ * on Solaris use "pargs PID".
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+hotspot*:::Call*-entry
+{
+ @calls[pid, uid, curpsinfo->pr_psargs] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %-55s\n", "PID", "UID", "CALLS", "ARGS");
+ printa(" %6d %6d %@6d %-55.55s\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/Readme b/cddl/contrib/dtracetoolkit/JavaScript/Readme
new file mode 100644
index 0000000..a9bebf8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/Readme
@@ -0,0 +1,54 @@
+JavaScript - DTracing JavaScript
+
+ There scripts trace the JavaScript programming language, and require a
+ browser to be built with the DTrace JavaScript provider.
+
+ The DTrace JavaScript provider was originally written by Brendan Gregg,
+ and later developed as part of a Mozilla DTrace provider suite by
+ engineers from both Sun and Mozilla. It currently exists as patches
+ to the Mozilla source tree and requires building from source to get
+ working; it may be integrated into Solaris builds by default in the
+ future. To download the current patches and instructions, visit,
+
+ http://www.opensolaris.org/os/project/mozilla-dtrace/
+
+ A rough guide for the process is,
+
+ 1. Download the Mozilla source
+ http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS
+ 2. Download the Mozilla DTrace framework patch, and apply
+ https://bugzilla.mozilla.org/show_bug.cgi?id=370906
+ 3. Download the JavaScript DTrace provider patch, and apply
+ https://bugzilla.mozilla.org/show_bug.cgi?id=388564
+ 4. Create a .mozconfig file (needed for compilation).
+ 5. Setup various compilation environment vars (CC/CFLAGS/CXX/...)
+ 6. autoconf
+ 7. ./configure --enable-dtrace
+ 8. gmake
+
+ See John Rice's instructions linked from the OpenSolaris page above
+ for details on steps 4-8.
+
+ Since the DTrace JavaScript provider may be developed further, there is a
+ chance that it has changed slightly by the time you are reading this,
+ causing these scripts to either break or behave oddly. Firstly, check for
+ newer versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider javascript {
+ probe function-entry(file, class, func)
+ probe function-info(file, class, func, lineno, runfile, runlineno)
+ probe function-args(file, class, func, argc, argv, argv0, argv1,
+ argv2, argv3, argv4)
+ probe function-rval(file, class, func, lineno, rval, rval0)
+ probe function-return(file, class, func)
+ probe object-create-start(file, class)
+ probe object-create(file, class, *object, rlineno)
+ probe object-create-done(file, class)
+ probe object-finalize(NULL, class, *object)
+ probe execute-start(file, lineno)
+ probe execute-done(file, lineno)
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_calldist.d b/cddl/contrib/dtracetoolkit/JavaScript/js_calldist.d
new file mode 100755
index 0000000..2c4923a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_calldist.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_calldist.d - measure JavaScript elapsed times for types of operation.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_calldist.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system with
+ * JavaScript provider support.
+ *
+ * USAGE: js_calldist.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * 1 Filename of the JavaScript program
+ * 2 Type of call (func/obj-new)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+javascript*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg2);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+javascript*:::object-create-start
+{
+ self->object = timestamp;
+}
+
+javascript*:::object-create-done
+/self->object/
+{
+ this->elapsed = timestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types[this->file, "obj-new", this->name] =
+ quantize(this->elapsed / 1000);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("\nElapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("\nExclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_calls.d b/cddl/contrib/dtracetoolkit/JavaScript/js_calls.d
new file mode 100755
index 0000000..98f1a83
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_calls.d
@@ -0,0 +1,76 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_calls.d - count JavaScript calls using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_calls.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are
+ * running with JavaScript provider support.
+ *
+ * USAGE: js_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the JavaScript program
+ * TYPE Type of call (func/obj-new/...)
+ * NAME Descriptive name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ this->name = copyinstr(arg2);
+ @calls[basename(copyinstr(arg0)), "func", this->name] = count();
+}
+
+javascript*:::execute-start
+{
+ this->filename = basename(copyinstr(arg0));
+ @calls[this->filename, "exec", "."] = count();
+}
+
+javascript*:::object-create-start
+{
+ this->name = copyinstr(arg1);
+ this->filename = basename(copyinstr(arg0));
+ @calls[this->filename, "obj-new", this->name] = count();
+}
+
+javascript*:::object-finalize
+{
+ this->name = copyinstr(arg1);
+ @calls["<null>", "obj-free", this->name] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-24s %-10s %-30s %8s\n", "FILE", "TYPE", "NAME", "CALLS");
+ printa(" %-24s %-10s %-30s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_calltime.d b/cddl/contrib/dtracetoolkit/JavaScript/js_calltime.d
new file mode 100755
index 0000000..dce150e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_calltime.d
@@ -0,0 +1,115 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_calltime.d - measure JavaScript elapsed times for types of operation.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_calltime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system with
+ * JavaScript provider support.
+ *
+ * USAGE: js_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the JavaScript program
+ * TYPE Type of call (func/obj-new/gc/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+javascript*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg2);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+javascript*:::object-create-start
+{
+ self->object = timestamp;
+}
+
+javascript*:::object-create-done
+/self->object/
+{
+ this->elapsed = timestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "obj-new", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types[this->file, "obj-new", this->name] = sum(this->elapsed);
+ @types["-", "total", "-"] = sum(this->elapsed);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nElapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_cpudist.d b/cddl/contrib/dtracetoolkit/JavaScript/js_cpudist.d
new file mode 100755
index 0000000..cbe168d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_cpudist.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_cpudist.d - measure JavaScript on-CPU times for types of operation.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_cpudist.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system with
+ * JavaScript provider support.
+ *
+ * USAGE: js_cpudist.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * 1 Filename of the JavaScript program
+ * 2 Type of call (func/obj-new)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+javascript*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg2);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+javascript*:::object-create-start
+{
+ self->object = vtimestamp;
+}
+
+javascript*:::object-create-done
+/self->object/
+{
+ this->oncpu = vtimestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types[this->file, "obj-new", this->name] =
+ quantize(this->oncpu / 1000);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+dtrace:::END
+{
+ printf("\nElapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("\nExclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_cputime.d b/cddl/contrib/dtracetoolkit/JavaScript/js_cputime.d
new file mode 100755
index 0000000..bee77ab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_cputime.d
@@ -0,0 +1,115 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_cputime.d - measure JavaScript on-CPU times for types of operation.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_cputime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system with
+ * JavaScript provider support.
+ *
+ * USAGE: js_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the JavaScript program
+ * TYPE Type of call (func/obj-new/gc/total)
+ * NAME Name of call
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+javascript*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg2);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+javascript*:::object-create-start
+{
+ self->object = vtimestamp;
+}
+
+javascript*:::object-create-done
+/self->object/
+{
+ this->oncpu = vtimestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "obj-new", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types[this->file, "obj-new", this->name] = sum(this->oncpu);
+ @types["-", "total", "-"] = sum(this->oncpu);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nElapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20.20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_execs.d b/cddl/contrib/dtracetoolkit/JavaScript/js_execs.d
new file mode 100755
index 0000000..fb0ca91
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_execs.d
@@ -0,0 +1,51 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_execs.d - JavaScript execute snoop using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_execs.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are
+ * running with JavaScript provider support.
+ *
+ * USAGE: js_execs.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * TIME Time of event
+ * FILE Filename of the JavaScript program
+ * LINENO Line number in filename
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+dtrace:::BEGIN
+{
+ printf("%-20s %32s:%s\n", "TIME", "FILE", "LINENO");
+}
+
+javascript*:::execute-start
+{
+ printf("%-20Y %32s:%d\n", walltimestamp, basename(copyinstr(arg0)),
+ arg1);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_flow.d b/cddl/contrib/dtracetoolkit/JavaScript/js_flow.d
new file mode 100755
index 0000000..450cc69
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_flow.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_flow.d - snoop JavaScript execution showing function flow using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_flow.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are running
+ * with JavaScript provider support.
+ *
+ * USAGE: js_flow.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * FUNC Function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-22s -- %s\n", "C", "TIME(us)", "FILE", "FUNC");
+}
+
+javascript*:::function-entry
+{
+ printf("%3d %-16d %-22s %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg2));
+ self->depth++;
+}
+
+javascript*:::function-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-22s %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg2));
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_flowinfo.d b/cddl/contrib/dtracetoolkit/JavaScript/js_flowinfo.d
new file mode 100755
index 0000000..b4b7d5c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_flowinfo.d
@@ -0,0 +1,86 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_flowinfo.d - JavaScript function flow with info using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_flowinfo.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are running
+ * with JavaScript provider support.
+ *
+ * USAGE: js_flowinfo.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the JavScript program
+ * LINE Line number of filename
+ * TYPE Type of call (func)
+ * FUNC Function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "FUNC");
+}
+
+javascript*:::function-info,
+javascript*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+javascript*:::function-info
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg4)), arg5, "func",
+ self->depth * 2, "", copyinstr(arg2));
+ self->depth++;
+ self->last = timestamp;
+}
+
+javascript*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "func", self->depth * 2,
+ "", copyinstr(arg2));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_flowtime.d b/cddl/contrib/dtracetoolkit/JavaScript/js_flowtime.d
new file mode 100755
index 0000000..9545274
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_flowtime.d
@@ -0,0 +1,84 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_flowtime.d - JavaScript function flow with delta times using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_flowtime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are running
+ * with JavaScript provider support.
+ *
+ * USAGE: js_flowtime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * DELTA(us) Elapsed time from previous line to this line
+ * FUNC Function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-18s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "FUNC");
+}
+
+javascript*:::function-entry,
+javascript*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+javascript*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-18s %9d %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->delta, self->depth * 2, "",
+ copyinstr(arg2));
+ self->depth++;
+ self->last = timestamp;
+}
+
+javascript*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-18s %9d %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->delta, self->depth * 2, "",
+ copyinstr(arg2));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_objcpu.d b/cddl/contrib/dtracetoolkit/JavaScript/js_objcpu.d
new file mode 100755
index 0000000..6611f59
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_objcpu.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_objcpu.d - measure JavaScript object creation on-CPU time using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_objcpu.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system
+ * with JavaScript provider support.
+ *
+ * USAGE: js_objcpu.d # hit Ctrl-C to end
+ *
+ * Class names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::object-create-start
+{
+ self->vstart = vtimestamp;
+}
+
+javascript*:::object-create-done
+/self->vstart/
+{
+ this->oncpu = vtimestamp - self->vstart;
+ @total = sum(this->oncpu);
+ @dist[copyinstr(arg1)] = quantize(this->oncpu / 1000);
+ self->vstart = 0;
+}
+
+dtrace:::END
+{
+ normalize(@total, 1000000);
+ printa("Total object creation on-CPU time (ms): %@d\n\n", @total);
+ printf("Object creation on-CPU time distributions (us),\n");
+ printa(@dist);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_objgc.d b/cddl/contrib/dtracetoolkit/JavaScript/js_objgc.d
new file mode 100755
index 0000000..575b295
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_objgc.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_objgc.d - trace JavaScript Object GC using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_objgc.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all running browers on the system
+ * which support the JavaScript DTrace provider.
+ *
+ * USAGE: js_objgc.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename that contained the function
+ * CLASS Class to which this new object belongs
+ * TOTAL Object entropy (positive == uncollected)
+ *
+ * This script provides information on which objects are not being garbage
+ * collected, an issue which causes the browser to steadily leak memory.
+ * We trace object creation (+1) and destruction (-1), and provide a
+ * summary each second of the running tally of the object class and
+ * originating filename. If over the period of several minutes an object
+ * type is still steadily increasing, then that would be of interest.
+ * Be patient, depending on the rate of object creation it can take over
+ * ten minutes for garbage collect to kick in.
+ *
+ * NOTES:
+ * - it is possible that you will see negative entropy. That happens
+ * when you begin tracing after some objects have already been created,
+ * and then trace their destruction.
+ * - there are other Things that GC handles, other than Objects; extra
+ * probes can be added to trace them, should the need arise.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+/* if you get dynvardrops, increase this, */
+#pragma D option dynvarsize=32m
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::object-create
+/arg2/
+{
+ this->file = basename(copyinstr(arg0));
+ @objs[this->file, copyinstr(arg1)] = sum(1);
+ filename[arg2] = this->file;
+}
+
+javascript*:::object-finalize
+/filename[arg2] == NULL/
+{
+ @objs["<missed>", copyinstr(arg1)] = sum(-1);
+}
+
+javascript*:::object-finalize
+/filename[arg2] != NULL/
+{
+ @objs[filename[arg2], copyinstr(arg1)] = sum(-1);
+ filename[arg2] = 0;
+}
+
+profile:::tick-1sec,
+dtrace:::END
+{
+ printf("\n %-24s %8s %-20s %23Y\n", "FILE", "TOTAL", "CLASS",
+ walltimestamp);
+ printa(" %-24.24s %@8d %s\n", @objs);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_objnew.d b/cddl/contrib/dtracetoolkit/JavaScript/js_objnew.d
new file mode 100755
index 0000000..f57c7b5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_objnew.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_objnew.d - count JavaScript object creation using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_objnew.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers running on the system
+ * with JavaScript provider support.
+ *
+ * USAGE: js_objnew.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the JavaScript program
+ * CLASS Class of new object
+ * COUNT Number of object creations during tracing
+ *
+ * Filename and class names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::object-create-done
+{
+ @objs[basename(copyinstr(arg0)), copyinstr(arg1)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-24s %-36s %8s\n", "FILE", "CLASS", "COUNT");
+ printa(" %-24.24s %-36s %@8d\n", @objs);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_stat.d b/cddl/contrib/dtracetoolkit/JavaScript/js_stat.d
new file mode 100755
index 0000000..3237762
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_stat.d
@@ -0,0 +1,120 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_stat.d - JavaScript operation stats using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_stat.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all browsers on the system that are
+ * running with JavaScript provider support.
+ *
+ * USAGE: js_stat.d [interval [count]]
+ *
+ * FIELDS:
+ * EXEC/s JavaScript programs executed per second
+ * FUNCS/s Functions called, per second
+ * OBJNEW/s Objects created, per second
+ * OBJFRE/s Objects freed (finalize), per second
+ *
+ * The numbers are counts for the interval specified. The default interval
+ * is 1 second.
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+dtrace:::BEGIN
+{
+ execs = funcs = objnew = objfree = 0;
+ lines = SCREEN + 1;
+ interval = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ secs = interval;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %8s %8s %8s %8s\n", "TIME", "EXEC/s", "FUNC/s",
+ "OBJNEW/s", "OBJFRE/s");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Tally Data
+ */
+javascript*:::execute-start
+{
+ execs++;
+}
+
+javascript*:::function-entry
+{
+ funcs++;
+}
+
+javascript*:::object-create-start
+{
+ objnew++;
+}
+
+javascript*:::object-finalize
+{
+ objfree++;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %8d %8d %8d %8d\n", walltimestamp, execs / interval,
+ funcs / interval, objnew / interval, objfree / interval);
+ execs = funcs = objnew = objfree = 0;
+ secs = interval;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/JavaScript/js_who.d b/cddl/contrib/dtracetoolkit/JavaScript/js_who.d
new file mode 100755
index 0000000..f320b48
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/JavaScript/js_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * js_who.d - trace JavaScript function execution by process using DTrace.
+ * Written for the JavaScript DTrace provider.
+ *
+ * $Id: js_who.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces JavaScript activity from all browsers on the system that are
+ * running with JavaScript provider support.
+ *
+ * USAGE: js_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of JavaScript
+ * UID User ID of the owner
+ * FUNCS Number of function calls
+ * FILE Pathname of the JavaScript program
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+javascript*:::function-entry
+{
+ @funcs[pid, uid, copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %s\n", "PID", "UID", "FUNCS", "FILE");
+ printa(" %6d %6d %@6d %s\n", @funcs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/Readme b/cddl/contrib/dtracetoolkit/Kernel/Readme
new file mode 100644
index 0000000..3c5d6b3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/Readme
@@ -0,0 +1,3 @@
+Kernel - Kernel based analysis
+
+ These are scripts to monitor kernel activity.
diff --git a/cddl/contrib/dtracetoolkit/Kernel/cpudists b/cddl/contrib/dtracetoolkit/Kernel/cpudists
new file mode 100755
index 0000000..b708216
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/cpudists
@@ -0,0 +1,184 @@
+#!/usr/bin/sh
+#
+# cpudists - print CPU time distributions by Kernel/Idle/Processes.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: cpudists 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: cpudists [-ahV] [-t top] [interval [count]]
+#
+# -a # print all processes
+# -V # don't print timestamps
+# -t num # print top num only
+# eg,
+# cpudists 1 # print every 1 second
+# cpudists -a 10 # print all processes every 10 secs
+#
+#
+# FIELDS:
+# value The following or the process name,
+# IDLE Idle time - CPU running idle thread
+# KERNEL Kernel time - Kernel servicing interrupts, ...
+# PROCESS Process time - PIDs running on the system
+# count Number of occurances at least this duration (ns)
+#
+# NOTES:
+# * This takes into account multiple CPU servers, the total
+# seconds consumed will be a multiple of the CPU count and interval.
+#
+# SEE ALSO: cputimes
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 27-Apr-2005 Brendan Gregg Created this.
+# 22-Sep-2005 " " Fixed key corruption bug.
+# 22-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+opt_all=0; opt_time=1; opt_top=0; top=0; interval=1; count=1
+
+while getopts aht:V name
+do
+ case $name in
+ a) opt_all=1 ;;
+ V) opt_time=0 ;;
+ t) opt_top=1; top=$OPTARG ;;
+ h|?) cat <<-END >&2
+ USAGE: cpudists [-ahV] [-t top] [interval [count]]
+ cpudists # default output
+ -a # print all processes
+ -V # don't print times
+ -t num # print top num only
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+if [ "$1" -gt 0 ]; then
+ interval=$1; count=-1; shift
+fi
+if [ "$1" -gt 0 ]; then
+ count=$1; shift
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_all = '$opt_all';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_top = '$opt_top';
+ inline int TOP = '$top';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+
+ /* Initialise variables */
+ dtrace:::BEGIN
+ {
+ cpustart[cpu] = 0;
+ counts = COUNTER;
+ secs = INTERVAL;
+ }
+
+ /* Flag this thread as idle */
+ sysinfo:unix:idle_enter:idlethread
+ {
+ idle[cpu] = 1;
+ }
+
+ /* Save kernel time between running threads */
+ sched:::on-cpu
+ /cpustart[cpu]/
+ {
+ this->elapsed = timestamp - cpustart[cpu];
+ @Procs["KERNEL"] = quantize(this->elapsed);
+ }
+
+ /* Save the elapsed time of a thread */
+ sched:::off-cpu,
+ sched:::remain-cpu,
+ profile:::profile-1sec
+ /cpustart[cpu]/
+ {
+ /* determine the name for this thread */
+ program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" :
+ OPT_all ? execname : "PROCESS";
+
+ /* save elapsed */
+ this->elapsed = timestamp - cpustart[cpu];
+ @Procs[program[cpu]] = quantize(this->elapsed);
+ cpustart[cpu] = timestamp;
+ }
+
+ /* Record the start time of a thread */
+ sched:::on-cpu,
+ sched:::remain-cpu
+ {
+ idle[cpu] = 0;
+ cpustart[cpu] = timestamp;
+ }
+
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /* Print time */
+ profile:::tick-1sec
+ /secs == 0 && OPT_time/
+ {
+ printf("%Y,\n", walltimestamp);
+ }
+
+ /* Print report */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ OPT_top ? trunc(@Procs, TOP) : 1;
+ printa("%16s %@16d\n", @Procs);
+ trunc(@Procs);
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /* End of program */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /* cleanup for Ctrl-C */
+ dtrace:::END
+ {
+ trunc(@Procs);
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/Kernel/cputimes b/cddl/contrib/dtracetoolkit/Kernel/cputimes
new file mode 100755
index 0000000..881bf90
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/cputimes
@@ -0,0 +1,203 @@
+#!/usr/bin/sh
+#
+# cputimes - print CPU time consumed by Kernel/Idle/Processes.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: cputimes 3 2007-08-01 10:50:08Z brendan $
+#
+# This program accurately measures time consumed by the kernel, but in
+# doing so creates extra kernel load of it's own. The extra kernel
+# activity can be measured by running one cputimes and then another, and
+# comparing the difference in kernel consumed time. This method can be
+# used to estimate the load created by other DTrace scripts.
+#
+# USAGE: cputimes [-ahTV] [-t top] [interval [count]]
+#
+# -a # print all processes
+# -T # print totals
+# -V # don't print timestamps
+# -t num # print top num lines only
+# eg,
+# cputimes 1 # print every 1 second
+# cputimes -a 10 # print all processes every 10 secs
+# cputimes -at 8 5 # print top 8 lines every 5 secs
+#
+#
+# FIELDS:
+# THREADS The following or the process name,
+# IDLE Idle time - CPU running idle thread
+# KERNEL Kernel time - Kernel servicing interrupts, ...
+# PROCESS Process time - PIDs running on the system
+# TIME (ns) Sum of the CPU time, ns (nanoseconds)
+#
+# NOTES:
+# * This takes into account multiple CPU servers, the total
+# seconds consumed will be a multiple of the CPU count and interval.
+#
+# SEE ALSO: cpudists
+# Heisenberg's uncertainty principle.
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 27-Apr-2005 Brendan Gregg Created this.
+# 22-Sep-2005 " " Fixed a key corruption bug.
+# 22-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+opt_all=0; opt_time=1; opt_top=0; opt_totals=0
+top=0; interval=1; count=1
+
+while getopts aht:TV name
+do
+ case $name in
+ a) opt_all=1 ;;
+ T) opt_totals=1 ;;
+ V) opt_time=0 ;;
+ t) opt_top=1; top=$OPTARG ;;
+ h|?) cat <<-END >&2
+ USAGE: cputimes [-ahTV] [-t top] [interval [count]]
+ cputimes # default output
+ -a # print all processes
+ -T # print totals
+ -V # don't print times
+ -t num # print top num lines only
+ eg,
+ cputimes 1 # print every 1 second
+ cputimes -a 10 # all processes per 10 sec
+ cputimes -at 8 5 # top 8 lines every 5 secs
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+if [ "$1" -gt 0 ]; then
+ interval=$1; count=-1; shift
+fi
+if [ "$1" -gt 0 ]; then
+ count=$1; shift
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_all = '$opt_all';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_totals = '$opt_totals';
+ inline int OPT_top = '$opt_top';
+ inline int TOP = '$top';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+
+ /* Initialise variables */
+ dtrace:::BEGIN
+ {
+ cpustart[cpu] = 0;
+ counts = COUNTER;
+ secs = INTERVAL;
+ }
+
+ /* Flag this thread as idle */
+ sysinfo:unix:idle_enter:idlethread
+ {
+ idle[cpu] = 1;
+ }
+
+ /* Save kernel time between running threads */
+ sched:::on-cpu
+ /cpustart[cpu]/
+ {
+ this->elapsed = timestamp - cpustart[cpu];
+ @Procs["KERNEL"] = sum(this->elapsed);
+ }
+
+ /* Save the elapsed time of a thread */
+ sched:::off-cpu,
+ sched:::remain-cpu,
+ profile:::profile-1sec
+ /cpustart[cpu]/
+ {
+ /* determine the name for this thread */
+ program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" :
+ OPT_all ? execname : "PROCESS";
+
+ /* save elapsed */
+ this->elapsed = timestamp - cpustart[cpu];
+ @Procs[program[cpu]] = sum(this->elapsed);
+ cpustart[cpu] = timestamp;
+ }
+
+ /* Record the start time of a thread */
+ sched:::on-cpu,
+ sched:::remain-cpu
+ {
+ idle[cpu] = 0;
+ cpustart[cpu] = timestamp;
+ }
+
+
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /* Print time */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ OPT_time ? printf("%Y,\n", walltimestamp) : 1;
+ printf("%16s %16s\n", "THREADS", "TIME (ns)");
+ }
+
+ /* Print report */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ OPT_top ? trunc(@Procs, TOP) : 1;
+ printa("%16s %@16d\n", @Procs);
+ trunc(@Procs);
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /* End of program */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /* cleanup for Ctrl-C */
+ dtrace:::END
+ {
+ trunc(@Procs);
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/Kernel/cswstat.d b/cddl/contrib/dtracetoolkit/Kernel/cswstat.d
new file mode 100755
index 0000000..98ca83c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/cswstat.d
@@ -0,0 +1,74 @@
+#!/usr/sbin/dtrace -s
+/*
+ * cswstat.d - context switch time stat.
+ * Uses DTrace (Solaris 10 03/05)
+ *
+ * This prints a context switch count and consumed time for context
+ * switching every second.
+ *
+ * $Id: cswstat.d 15 2007-09-11 09:09:25Z brendan $
+ *
+ * USAGE: cswstat.d
+ *
+ * FIELDS:
+ * TIME Current time
+ * NUM Number of context switches
+ * CSWTIME(us) Time consumed context switching, us
+ * AVGTIME(us) Average context switch time, us
+ *
+ * THANKS: Toomas Soome
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 17-May-2005 Brendan Gregg Created this.
+ * 03-Nov-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ /* print header */
+ printf("%-20s %8s %12s %12s\n", "TIME", "NUM", "CSWTIME(us)",
+ "AVGTIME(us)");
+ times = 0;
+ num = 0;
+}
+
+sched:::off-cpu
+{
+ /* csw start */
+ num++;
+ start[cpu] = timestamp;
+}
+
+sched:::on-cpu
+/start[cpu]/
+{
+ /* csw end */
+ times += timestamp - start[cpu];
+ start[cpu] = 0;
+}
+
+profile:::tick-1sec
+{
+ /* print output */
+ printf("%20Y %8d %12d %12d\n", walltimestamp, num, times/1000,
+ num == 0 ? 0 : times/(1000 * num));
+ times = 0;
+ num = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/dnlcps.d b/cddl/contrib/dtracetoolkit/Kernel/dnlcps.d
new file mode 100755
index 0000000..d3c3e58
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/dnlcps.d
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -s
+/*
+ * dnlcps.d - DNLC stats by process.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * The DNLC is the Directory Name Lookup Cache. Filename lookups often
+ * return a hit from here, before needing to traverse the regular file
+ * system cache or go to disk.
+ *
+ * dnlcps.d prints DNLC statistics by process.
+ *
+ * $Id: dnlcps.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: dnlcps.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID Process ID
+ * CMD Command name
+ * value 0 == miss, 1 == hit
+ * count number of occurrences
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 27-Mar-2004 Brendan Gregg Created this.
+ * 14-Jun-2005 " " Rewrote this a lot.
+ * 18-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/*
+ * DNLC return
+ */
+fbt:genunix:dnlc_lookup:return
+{
+ this->code = arg1 == 0 ? 0 : 1;
+ @Result[execname, pid] = lquantize(this->code, 0, 1, 1);
+}
+
+/*
+ * Print report
+ */
+dtrace:::END
+{
+ printa(" CMD: %-16s PID: %d\n%@d\n", @Result);
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/dnlcsnoop.d b/cddl/contrib/dtracetoolkit/Kernel/dnlcsnoop.d
new file mode 100755
index 0000000..1150f45
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/dnlcsnoop.d
@@ -0,0 +1,92 @@
+#!/usr/sbin/dtrace -s
+/*
+ * dnlcsnoop.d - snoop DNLC activity.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * The DNLC is the Directory Name Lookup Cache. Filename lookups often
+ * return a hit from here, before needing to traverse the regular file
+ * system cache or go to disk.
+ *
+ * $Id: dnlcsnoop.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: dnlcsnoop.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID Process ID
+ * CMD Command name
+ * TIME Elapsed time for lookup, us
+ * HIT DNLC hit Y/N
+ * PATH Path for DNLC lookup
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 27-Mar-2004 Brendan Gregg Created this.
+ * 14-Jun-2005 " " Rewrote this a lot.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("%6s %-12s %5s %3s %s\n",
+ "PID", "CMD", "TIME", "HIT", "PATH");
+}
+
+/*
+ * DNLC lookup
+ */
+fbt:genunix:dnlc_lookup:entry
+{
+ /* store path */
+ self->path = stringof(args[0]->v_path);
+
+ /* check for trailing "/" */
+ this->len = strlen(self->path);
+ self->join = *(char *)(args[0]->v_path + this->len - 1) == '/' ?
+ "" : "/";
+
+ /* store lookup name */
+ self->name = stringof(arg1);
+
+ /* store start time */
+ self->start = timestamp;
+}
+
+/*
+ * DNLC return
+ */
+fbt:genunix:dnlc_lookup:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = (timestamp - self->start) / 1000;
+
+ /* print output */
+ printf("%6d %-12.12s %5d %3s %s%s%s\n",
+ pid, execname, this->elapsed, arg1 == 0 ? "N" : "Y",
+ self->path, self->join, self->name);
+
+ /* clear variables */
+ self->path = 0;
+ self->join = 0;
+ self->name = 0;
+ self->start = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/dnlcstat b/cddl/contrib/dtracetoolkit/Kernel/dnlcstat
new file mode 100755
index 0000000..b29e8c2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/dnlcstat
@@ -0,0 +1,162 @@
+#!/usr/bin/sh
+#
+# dnlcstat - DNLC statistics.
+# Written in DTrace (Solaris 10 3/05).
+#
+# The DNLC is the Directory Name Lookup Cache. Filename lookups often
+# return a hit from here, before needing to traverse the regular file
+# system cache or go to disk.
+#
+# $Id: dnlcstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: dnlcstat [interval [count]]
+#
+# FIELDS:
+#
+# %hit hit percentage for this sample
+# hit number of DNLC hits in this sample
+# miss number of DNLC misses in this sample
+#
+# SEE ALSO: CacheKit, http://www.brendangregg.com/cachekit.html
+# (contains a dnlcstat written in Perl, which uses less CPU)
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 27-Mar-2004 Brendan Gregg Created this.
+# 14-Jun-2005 " " Updated style.
+# 14-Jun-2005 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default values
+interval=1; count=-1
+
+### check arguments
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+ cat <<-END >&2
+ USAGE: dnlcstat [interval [count]]
+ dnlcstat # 1 second samples, infinite
+ eg,
+ dnlcstat 1 # print every 1 second
+ dnlcstat 5 6 # print every 5 seconds, 6 times
+ END
+ exit 1
+fi
+
+### argument logic
+if [ "$1" -gt 0 ]; then
+ interval=$1; count=-1; shift
+fi
+if [ "$1" -gt 0 ]; then
+ count=$1; shift
+fi
+if [ $interval -eq 0 ]; then
+ interval=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int SCREEN = 21;
+
+ int hits; /* hits */
+ int misses; /* misses */
+
+ /*
+ * Initialise variables
+ */
+ dtrace:::BEGIN
+ {
+ lines = SCREEN + 1;
+ counts = COUNTER;
+ secs = INTERVAL;
+ first = 1;
+ }
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN,
+ tick-1sec
+ /first || (secs == 0 && lines > SCREEN)/
+ {
+ printf("%10s %8s %8s\n","dnlc %hit","hit","miss");
+ lines = 0;
+ first = 0;
+ }
+
+ /*
+ * Probe DNLC lookups
+ */
+ fbt:genunix:dnlc_lookup:return
+ {
+ hits += arg1 == 0 ? 0 : 1;
+ misses += arg1 == 0 ? 1 : 0;
+ }
+
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+
+ /*
+ * Print output line
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* calculate hit percent */
+ this->divide = misses + hits == 0 ? 1 : misses + hits;
+ ratio = hits * 100 / this->divide;
+
+ /* print output */
+ printf("%10d %8d %8d\n",ratio,hits,misses);
+
+ /* clear counters */
+ hits = 0;
+ misses = 0;
+
+ /* process counts */
+ secs = INTERVAL;
+ counts--;
+ lines++;
+
+ }
+
+ /*
+ * End
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/Kernel/kstat_types.d b/cddl/contrib/dtracetoolkit/Kernel/kstat_types.d
new file mode 100755
index 0000000..119bc77
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/kstat_types.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -Cs
+/*
+ * kstat_types.d - Trace kstat reads with type info.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * kstat is the Kernel Statistics framework, which is used by tools
+ * such as vmstat, iostat, mpstat and sar. Try running vmstat while
+ * kstat_types.d is tracing - you should see details of the kstat
+ * reads performed.
+ *
+ * $Id: kstat_types.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: kstat_types.d (early release, check for updates)
+ *
+ * FIELDS:
+ * CMD command name
+ * CLASS kstat class (ks_class)
+ * TYPE kstat type as a string (ks_type)
+ * MOD:INS:NAME kstat module:instance:name
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 11-Feb-2006 Brendan Gregg Created this.
+ * 11-Feb-2006 " " Last update.
+ */
+
+#include <sys/isa_defs.h>
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("%-16s %-16s %-6s %s\n",
+ "CMD", "CLASS", "TYPE", "MOD:INS:NAME");
+}
+
+fbt::read_kstat_data:entry
+{
+#ifdef _MULTI_DATAMODEL
+ self->uk = (kstat32_t *)copyin((uintptr_t)arg1, sizeof (kstat32_t));
+#else
+ self->uk = (kstat_t *)copyin((uintptr_t)arg1, sizeof (kstat_t));
+#endif
+ printf("%-16s %-16s %-6s %s:%d:%s\n", execname,
+ self->uk->ks_class == "" ? "." : self->uk->ks_class,
+ self->uk->ks_type == 0 ? "raw"
+ : self->uk->ks_type == 1 ? "named"
+ : self->uk->ks_type == 2 ? "intr"
+ : self->uk->ks_type == 3 ? "io"
+ : self->uk->ks_type == 4 ? "timer" : "?",
+ self->uk->ks_module, self->uk->ks_instance, self->uk->ks_name);
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/modcalls.d b/cddl/contrib/dtracetoolkit/Kernel/modcalls.d
new file mode 100755
index 0000000..0386a7a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/modcalls.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * modcalls.d - kernel function calls by module. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: modcalls.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+fbt:::entry { @calls[probemod] = count(); }
diff --git a/cddl/contrib/dtracetoolkit/Kernel/priclass.d b/cddl/contrib/dtracetoolkit/Kernel/priclass.d
new file mode 100755
index 0000000..92275dc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/priclass.d
@@ -0,0 +1,67 @@
+#!/usr/sbin/dtrace -s
+/*
+ * priclass.d - priority distribution by scheduling class.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This is a simple DTrace script that samples at 1000 Hz the current
+ * thread's scheduling class and priority. A distribution plot is printed.
+ *
+ * With priorities, the higher the priority the better chance the thread
+ * has of being scheduled.
+ *
+ * This idea came from the script /usr/demo/dtrace/pri.d, which
+ * produces similar output for priority changes, not samples.
+ *
+ * $Id: priclass.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: priclass.d # hit Ctrl-C to end sampling
+ *
+ * FIELDS:
+ * value process priority
+ * count number of samples of at least this priority
+ *
+ * Also printed is the scheduling class,
+ *
+ * TS time sharing
+ * IA interactive
+ * RT real time
+ * SYS system
+ * FSS fair share schedular
+ *
+ * BASED ON: /usr/demo/dtrace/pri.d
+ *
+ * SEE ALSO: DTrace Guide "profile Provider" chapter (docs.sun.com)
+ * dispadmin(1M)
+ *
+ * PORTIONS: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 12-Feb-2006 Brendan Gregg Created this.
+ * 22-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Sampling... Hit Ctrl-C to end.\n");
+}
+
+profile:::profile-1000hz
+{
+ @count[stringof(curlwpsinfo->pr_clname)]
+ = lquantize(curlwpsinfo->pr_pri, 0, 170, 10);
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/pridist.d b/cddl/contrib/dtracetoolkit/Kernel/pridist.d
new file mode 100755
index 0000000..1b6d3eb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/pridist.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -s
+/*
+ * pridist.d - process priority distribution.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This is a simple DTrace script that samples at 1000 Hz which process
+ * is on the CPUs, and what the priority is. A distribution plot is printed.
+ *
+ * With priorities, the higher the priority the better chance the process
+ * (actually, thread) has of being scheduled.
+ *
+ * This idea came from the script /usr/demo/dtrace/profpri.d, which
+ * produces similar output for one particular PID.
+ *
+ * $Id: pridist.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: pridist.d # hit Ctrl-C to end sampling
+ *
+ * FIELDS:
+ * CMD process name
+ * PID process ID
+ * value process priority
+ * count number of samples of at least this priority
+ *
+ * BASED ON: /usr/demo/dtrace/profpri.d
+ *
+ * SEE ALSO:
+ * DTrace Guide "profile Provider" chapter (docs.sun.com)
+ * dispadmin(1M)
+ *
+ * PORTIONS: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 13-Jun-2005 Brendan Gregg Created this.
+ * 22-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Sampling... Hit Ctrl-C to end.\n");
+}
+
+profile:::profile-1000hz
+{
+ @Count[execname, pid] = lquantize(curlwpsinfo->pr_pri, 0, 170, 5);
+}
+
+dtrace:::END
+{
+ printa(" CMD: %-16s PID: %d\n%@d\n", @Count);
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/putnexts.d b/cddl/contrib/dtracetoolkit/Kernel/putnexts.d
new file mode 100755
index 0000000..cb99a72
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/putnexts.d
@@ -0,0 +1,38 @@
+#!/usr/sbin/dtrace -s
+/*
+ * putnexts.d - stream putnext() tracing with stacks. Solaris, DTrace.
+ *
+ * This shows who is calling putnext() to who, by listing the destination
+ * queue and the calling stack, by frequency count. This is especially useful
+ * for understanding streams based frameworks, such as areas of the Solaris
+ * TCP/IP stack.
+ *
+ * $Id: putnexts.d 14 2007-09-11 08:03:35Z brendan $
+ *
+ * USAGE: putnext.d
+ *
+ * BASED ON: /usr/demo/dtrace/putnext.d
+ *
+ * PORTIONS: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 12-Jun-2005 Brendan Gregg Created this.
+ */
+
+fbt::putnext:entry
+{
+ @[stringof(args[0]->q_qinfo->qi_minfo->mi_idname), stack(5)] = count();
+}
diff --git a/cddl/contrib/dtracetoolkit/Kernel/whatexec.d b/cddl/contrib/dtracetoolkit/Kernel/whatexec.d
new file mode 100755
index 0000000..e70173b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Kernel/whatexec.d
@@ -0,0 +1,79 @@
+#!/usr/sbin/dtrace -s
+/*
+ * whatexec.d - Examine the type of files exec'd.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This prints the first four chacacters of files that are executed.
+ * This traces the kernel function findexec_by_hdr(), which checks for
+ * a known magic number in the file's header.
+ *
+ * The idea came from a demo I heard about from the UK, where a
+ * "blue screen of death" was displayed for "MZ" files (although I
+ * haven't seen the script or the demo).
+ *
+ * $Id: whatexec.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: whatexec.d (early release, check for updates)
+ *
+ * FIELDS:
+ * PEXEC parent command name
+ * EXEC pathname to file exec'd
+ * OK is type runnable, Y/N
+ * TYPE first four characters from file
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 11-Feb-2006 Brendan Gregg Created this.
+ * 25-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+this char *buf;
+
+dtrace:::BEGIN
+{
+ printf("%-16s %-38s %2s %s\n", "PEXEC", "EXEC", "OK", "TYPE");
+}
+
+fbt::gexec:entry
+{
+ self->file = cleanpath((*(struct vnode **)arg0)->v_path);
+ self->ok = 1;
+}
+
+fbt::findexec_by_hdr:entry
+/self->ok/
+{
+ bcopy(args[0], this->buf = alloca(5), 4);
+ this->buf[4] = '\0';
+ self->hdr = stringof(this->buf);
+}
+
+fbt::findexec_by_hdr:return
+/self->ok/
+{
+ printf("%-16s %-38s %2s %S\n", execname, self->file,
+ arg1 == NULL ? "N" : "Y", self->hdr);
+ self->hdr = 0;
+}
+
+fbt::gexec:return
+{
+ self->file = 0;
+ self->ok = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/License b/cddl/contrib/dtracetoolkit/License
new file mode 120000
index 0000000..2095b96
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/License
@@ -0,0 +1 @@
+Docs/cddl1.txt \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Locks/lockbydist.d b/cddl/contrib/dtracetoolkit/Locks/lockbydist.d
new file mode 100755
index 0000000..9bfc224
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Locks/lockbydist.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * lockbydist.d - lock distrib. by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: lockbydist.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+lockstat:::adaptive-block { @time[execname] = quantize(arg1); }
diff --git a/cddl/contrib/dtracetoolkit/Locks/lockbyproc.d b/cddl/contrib/dtracetoolkit/Locks/lockbyproc.d
new file mode 100755
index 0000000..d7b9219
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Locks/lockbyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * lockbyproc.d - lock time by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: lockbyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+lockstat:::adaptive-block { @time[execname] = sum(arg1); }
diff --git a/cddl/contrib/dtracetoolkit/Man/Readme b/cddl/contrib/dtracetoolkit/Man/Readme
new file mode 100644
index 0000000..3164123
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/Readme
@@ -0,0 +1,40 @@
+Man - Man pages
+
+ There are a number of ways you can read these man pages. Either,
+
+ 1. Add this directory to your MANPATH,
+
+ cd Man
+ MANPATH=$MANPATH:$PWD
+ man iosnoop
+
+ 2. If the DTraceToolkit has been installed, and that dir to your MANPATH,
+
+ MANPATH=$MANPATH:/opt/DTT/Man
+ man iosnoop
+
+ 3. Set MANPATH to "." every time you read a script,
+
+ cd Man
+ MANPATH=. man iosnoop
+
+ 4. Use the -M option to "man", if your OS has it,
+
+ man -M Man iosnoop
+
+ 5. Prentend that you are /usr/bin/man, if your OS has nroff,
+
+ nroff -man Man/man1m/iosnoop.1m | more
+
+ 6. Pretend that you are /usr/bin/nroff,
+
+ more Man/man1m/iosnoop.1m
+
+ 7. Pretend that you have no pagers installed,
+
+ while read line; do echo $line; done < Man/man1m/iosnoop.1m
+
+ 8. Pretend that you can read hex,
+
+ od -x Man/man1m/iosnoop.1m
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/anonpgpid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/anonpgpid.d.1m
new file mode 100644
index 0000000..9cafd48
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/anonpgpid.d.1m
@@ -0,0 +1,54 @@
+.TH anonpgpid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+anonpgpid.d \- anonymous memory paging info by PID on CPU. Uses DTrace.
+.SH SYNOPSIS
+.B anonpgpid.d
+.SH DESCRIPTION
+This scripts may help identify which processes are affected by a system
+with low memory, which is paging to the physical swap device. A report
+of the process on the CPU when paging occured is printed.
+
+This program is currently an approximation - often the process when writing
+pages to swap will be "pageout" the pageout scanner, or "rcapd" the
+resource capping daemon.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Print report after Ctrl-C is hit,
+#
+.B anonpgpid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command name for the process
+.TP
+D
+direction, Read or Write
+.TP
+BYTES
+total bytes during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+anonpgpid.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/bitesize.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/bitesize.d.1m
new file mode 100644
index 0000000..4ef13be
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/bitesize.d.1m
@@ -0,0 +1,57 @@
+.TH bitesize.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+bitesize.d \- analyse disk I/O size by process. Uses DTrace.
+.SH SYNOPSIS
+.B bitesize.d
+.SH DESCRIPTION
+This produces a report for the size of disk events caused by
+processes. These are the disk events sent by the block I/O driver.
+
+If applications must use the disks, we generally prefer they do so
+sequentially with large I/O sizes, or larger "bites".
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B bitesize.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command and argument list
+.TP
+value
+size in bytes
+.TP
+count
+number of I/O operations
+.PP
+.SH NOTES
+The application may be requesting smaller sized operations, which
+are being rounded up to the nearest sector size or UFS block size.
+
+To analyse what the application is requesting, DTraceToolkit programs
+such as Proc/fddist may help.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+bitesize.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1M), seeksize(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/connections.1m b/cddl/contrib/dtracetoolkit/Man/man1m/connections.1m
new file mode 100644
index 0000000..ea0285c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/connections.1m
@@ -0,0 +1,77 @@
+.TH connections 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+connections \- print inbound TCP connections by process. Uses DTrace.
+.SH SYNOPSIS
+.B connections
+[\-htvZ]
+.SH DESCRIPTION
+This displays the PID and command name of the processes accepting
+connections, along with the source IP address and destination port number
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-t
+print timestamps, us
+.TP
+\-v
+print timestamps, string
+.TP
+\-Z
+print zonename
+.PP
+.SH EXAMPLES
+.TP
+snoop inbound connections
+#
+.B connections
+.TP
+snoop connections with time
+#
+.B connections
+\-v
+.PP
+.SH FIELDS
+.TP
+UID
+user ID of the server
+.TP
+PID
+process ID of the server
+.TP
+CMD
+server command name
+.TP
+TIME
+timestamp, us
+.TP
+TIMESTR
+timestamp, string
+.TP
+PORT
+server port
+.TP
+IP_SOURCE
+source IP of the client, written in IPv4 style
+.TP
+ZONE
+zonename
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+connections will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), snoop(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/cpudists.1m b/cddl/contrib/dtracetoolkit/Man/man1m/cpudists.1m
new file mode 100644
index 0000000..aeb29ca
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/cpudists.1m
@@ -0,0 +1,86 @@
+.TH cpudists 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+cpudists \- CPU distrib. by Kernel/Idle/Process. Uses DTrace.
+.SH SYNOPSIS
+.B cpudists
+[\-ahV] [\-t top] [interval [count]]
+.SH DESCRIPTION
+cpudists prints the CPU time distributions consumed by the Kernel,
+Idle threads and by Processes.
+
+This program is a variant on cputimes, and creates extra kernel load as
+described in cputimes(1M). cpudists prints out a distribution report
+(a quantize aggregation), such that the number of occurrences and
+duration of each thread using the CPUs can be identified.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo and sched providers.
+.SH OPTIONS
+.TP
+\-a
+print all processes
+.TP
+\-T
+print totals
+.TP
+\-V
+don't print timestamps
+.TP
+\-t num
+print top num lines only
+.SH EXAMPLES
+.TP
+Default, print Kernel/Idle/Process time, 1 x 1 second sample,
+#
+.B cpudists
+.PP
+.TP
+Print every 1 second,
+#
+.B cpudists
+1
+.PP
+.TP
+Print all processes every 10 seconds,
+#
+.B cpudists
+\-a 10
+.PP
+.TP
+Print top 8 lines every 5 seconds,
+#
+.B cpudists
+\-at 8 5
+.PP
+.SH FIELDS
+.TP
+IDLE
+Idle time - CPU running idle thread
+.TP
+KERNEL
+Kernel time - Kernel servicing interrupts, ...
+.TP
+PROCESS
+Process time - PIDs running on the system
+.TP
+value
+Time in nanoseconds
+.TP
+count
+Number of occurrences that were at least this duration (ns)
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+cpudists will run once, unless a count is specified.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), vmstat(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/cputimes.1m b/cddl/contrib/dtracetoolkit/Man/man1m/cputimes.1m
new file mode 100644
index 0000000..bcafbb1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/cputimes.1m
@@ -0,0 +1,87 @@
+.TH cputimes 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+cputimes \- print time by Kernel/Idle/Process. Uses DTrace.
+.SH SYNOPSIS
+.B cputimes
+[\-ahTV] [\-t top] [interval [count]]
+.SH DESCRIPTION
+cputimes prints the CPU time consumed by the Kernel, Idle threads and
+by Processes.
+
+This program accurately measures time consumed by the kernel, but in
+doing so creates extra kernel load of it's own. This extra kernel
+activity can be measured by running one cputimes and then another, and
+comparing the difference in kernel consumed time. This method can be
+used to estimate the load caused by other DTrace scripts.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo and sched providers.
+.SH OPTIONS
+.TP
+\-a
+print all processes
+.TP
+\-T
+print totals
+.TP
+\-V
+don't print timestamps
+.TP
+\-t num
+print top num lines only
+.SH EXAMPLES
+.TP
+Default, print Kernel/Idle/Process time, 1 x 1 second sample,
+#
+.B cputimes
+.PP
+.TP
+Print every 1 second,
+#
+.B cputimes
+1
+.PP
+.TP
+Print all processes every 10 seconds,
+#
+.B cputimes
+\-a 10
+.PP
+.TP
+Print top 8 lines every 5 seconds,
+#
+.B cputimes
+\-at 8 5
+.PP
+.SH FIELDS
+.TP
+THREADS
+Either KERNEL, IDLE, PROCESS or process name.
+.TP
+IDLE
+Idle time - CPU running idle thread
+.TP
+KERNEL
+Kernel time - Kernel servicing interrupts, ...
+.TP
+PROCESS
+Process time - PIDs running on the system
+.TP
+TIME (ns)
+Sum of the CPU time, ns (nanoseconds)
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+cputimes will run once, unless a count is specified.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), vmstat(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/cputypes.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/cputypes.d.1m
new file mode 100644
index 0000000..82b6fec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/cputypes.d.1m
@@ -0,0 +1,54 @@
+.TH cputypes.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+cputypes.d \- list CPU types. Uses DTrace.
+.SH SYNOPSIS
+.B cputypes.d
+.SH DESCRIPTION
+This program lists CPU type information for the online CPUs
+in the system.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+List CPU types,
+#
+.B cputypes.d
+.PP
+.SH FIELDS
+.TP
+CPU
+CPU ID
+.TP
+CHIP
+chip ID
+.TP
+PSET
+processor set ID
+.TP
+LGRP
+latency group ID
+.TP
+CLOCK
+clock speed, MHz
+.TP
+TYPE
+CPU type
+.TP
+FPU
+floating point identifier type
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+psrinfo(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/cpuwalk.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/cpuwalk.d.1m
new file mode 100644
index 0000000..16874d9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/cpuwalk.d.1m
@@ -0,0 +1,53 @@
+.TH cpuwalk.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+cpuwalk.d \- Measure which CPUs a process runs on. Uses DTrace.
+.SH SYNOPSIS
+.B cpuwalk.d [duration]
+.SH DESCRIPTION
+This program is for multi-CPU servers, and can help identify if a process
+is running on multiple CPUs concurrently or not.
+
+A duration may be specified in seconds.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Any
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+this runs until Ctrl\-C is hit,
+#
+.B cpuwalk.d
+.PP
+.TP
+run for 5 seconds,
+#
+.B cpuwalk.d
+5
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+value
+CPU id
+.TP
+count
+number of samples (sample at 100 hz)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+cpuwalk.d will run until Ctrl\-C is hit, or the duration specified
+is reached.
+.SH SEE ALSO
+threaded.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/crash.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/crash.d.1m
new file mode 100644
index 0000000..368229b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/crash.d.1m
@@ -0,0 +1,81 @@
+.TH crash.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+crash.d \- Crashed Application info. Uses DTrace.
+.SH SYNOPSIS
+.B crash.d
+.SH DESCRIPTION
+crash.d monitors for applications that crash.
+When a crash via a SIGSEGV or SIGBUS is detected, a report of the
+process state is printed out.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the proc provider, and uses /usr/bin/prun.
+.SH FIELDS
+.TP
+Type
+signal type
+.TP
+Program
+execname of process
+.TP
+Args
+argument listing of process
+.TP
+PID
+process ID
+.TP
+TID
+thread ID
+.TP
+LWPs
+number of Light Weight Processes
+.TP
+PPID
+parent process ID
+.TP
+UID
+user ID
+.TP
+TaskID
+task ID
+.TP
+ProjID
+project ID
+.TP
+PoolID
+pool ID
+.TP
+ZoneID
+zone ID
+.TP
+zone
+zone name
+.TP
+CWD
+current working directory
+.TP
+errno
+error number of last syscall
+.PP
+.SH EXAMPLES
+.TP
+Monitor for crashing applications.
+#
+.B crash.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+crash.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/creatbyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/creatbyproc.d.1m
new file mode 100644
index 0000000..fe4f123
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/creatbyproc.d.1m
@@ -0,0 +1,55 @@
+.TH creatbyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+creatbyproc.d \- snoop creat()s by process name. Uses DTrace.
+.SH SYNOPSIS
+.B creatbyproc.d
+.SH DESCRIPTION
+creatbyproc.d is a DTrace OneLiner to print file creations as it
+occurs, including the name of the process calling the open.
+
+This matches file creates from the creat() system call; not all
+file creation occurs in this way, sometimes it is through open()
+with a O_CREAT flag, this script will not monitor that activity.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This prints process names and new pathnames until Ctrl\-C is hit.
+#
+.B creatbyproc.d
+.PP
+.SH FIELDS
+.TP
+CPU
+The CPU that recieved the event
+.TP
+ID
+A DTrace probe ID for the event
+.TP
+FUNCTION:NAME
+The DTrace probe name for the event
+.TP
+remaining fields
+The first is the name of the process, the second is the file pathname.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+creatbyproc.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/cswstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/cswstat.d.1m
new file mode 100644
index 0000000..7256d5f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/cswstat.d.1m
@@ -0,0 +1,51 @@
+.TH cswstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+cswstat.d \- context switch time stats. Uses DTrace.
+.SH SYNOPSIS
+.B cswstat.d
+.SH DESCRIPTION
+cswstat.d is a DTrace program to print context switch time
+statistics.
+
+This program measures the time consumed during context switching,
+and prints it with the number of context switches and the average
+time.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sched provider.
+.SH EXAMPLES
+.TP
+Print statistics every second,
+#
+.B cswstat.d
+.PP
+.SH FIELDS
+.TP
+TIME
+The current time
+.TP
+NUM
+Number of context switches in this sample
+.TP
+CSWTIME
+Total time consumed context switching, us
+.TP
+AVGTIME
+Average time for each context switch, us
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+cswstat.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+mpstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dappprof.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dappprof.1m
new file mode 100644
index 0000000..de1b52a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dappprof.1m
@@ -0,0 +1,98 @@
+.TH dappprof 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dappprof \- profile user and lib function usage. Uses DTrace.
+.SH SYNOPSIS
+.B dappprof
+[\-acehoTU] [\-u lib] { \-p PID | command }
+.SH DESCRIPTION
+dappprof prints details on user and library call times for processes
+as a summary style aggragation. By default the user fuctions are
+traced, options can be used to trace library activity. Output can
+include function counts, elapsed times and on cpu times.
+
+The elapsed times are interesting, to help identify functions
+that take some time to complete (during which the process may
+have slept). CPU time helps us identify syscalls that
+are consuming CPU cycles to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the pid provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-c
+print function counts
+.TP
+\-e
+print elapsed times, ns
+.TP
+\-o
+print CPU times, ns
+.TP
+\-T
+print totals
+.TP
+\-p PID
+examine this PID
+.TP
+\-u lib
+trace this library instead
+.TP
+\-U
+trace all library and user functions
+.PP
+.SH EXAMPLES
+.TP
+run and examine the "df \-h" command,
+#
+.B dappprof
+df \-h
+.PP
+.TP
+print elapsed times, on-cpu times and counts for "df \-h",
+#
+.B dappprof
+-ceo df \-h
+.TP
+print elapsed times for PID 1871,
+#
+.B dappprof
+\-p 1871
+.PP
+.TP
+print all data for PID 1871,
+#
+.B dappprof
+\-ap 1871
+.PP
+.SH FIELDS
+.TP
+CALL
+Function call name
+.TP
+ELAPSED
+Total elapsed time, nanoseconds
+.TP
+CPU
+Total on-cpu time, nanoseconds
+.TP
+COUNT
+Number of occurrences
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dappprof will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dapptrace(1M), dtrace(1M), apptrace(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dapptrace.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dapptrace.1m
new file mode 100644
index 0000000..c439f05
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dapptrace.1m
@@ -0,0 +1,112 @@
+.TH dapptrace 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dapptrace \- trace user and library function usage. Uses DTrace.
+.SH SYNOPSIS
+.B dapptrace
+[\-acdeFlhoU] [\-u lib] { \-p PID | command }
+.SH DESCRIPTION
+dapptrace prints details on user and library function calls. By
+default it traces user functions only, options can be used to
+trace library activity.
+
+Of particular interest is the elapsed times and on cpu times, which
+can identify both function calls that are slow to complete, and those
+which are consuming CPU cycles.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the pid provider.
+.SH OPTIONS
+.TP
+\-a
+print all details
+.TP
+\-b bufsize
+dynamic variable buffer size. Increase this if you notice dynamic
+variable drop errors. The default is "4m" for 4 megabytes per CPU.
+.TP
+\-c
+print function call counts
+.TP
+\-d
+print relative timestamps, us
+.TP
+\-e
+print elapsed times, us
+.TP
+\-F
+print flow indentation
+.TP
+\-l
+force printing of pid/lwpid per line
+.TP
+\-o
+print on-cpu times, us
+.TP
+\-p PID
+examine this PID
+.TP
+\-u lib
+trace this library instead
+.TP
+\-U
+trace all library and user functions
+.PP
+.SH EXAMPLES
+.TP
+run and examine the "df -h" command,
+#
+.B dapptrace
+df -h
+.PP
+.TP
+examine PID 1871,
+#
+.B dapptrace
+\-p 1871
+.PP
+.TP
+print using flow indents,
+#
+.B dapptrace
+\-Fp 1871
+.PP
+.TP
+print elapsed and CPU times,
+#
+.B dapptrace
+\-eop 1871
+.PP
+.SH FIELDS
+.TP
+PID/LWPID
+Process ID / Lightweight Process ID
+.TP
+RELATIVE
+relative timestamps to the start of the thread, us (microseconds)
+.TP
+ELAPSD
+elapsed time for this system call, us
+.TP
+CPU
+on-cpu time for this system call, us
+.TP
+CALL(args)
+function call name, with some arguments in hexadecimal
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dapptrace will run forever until Ctrl\-C is hit, or if a command was
+executed dapptrace will finish when the command ends.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dappprof(1M), dtrace(1M), apptrace(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dexplorer.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dexplorer.1m
new file mode 100644
index 0000000..10683a9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dexplorer.1m
@@ -0,0 +1,64 @@
+.TH dexplorer 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dexplorer \- run a series of scripts and archive output. Uses DTrace.
+.SH SYNOPSIS
+.B dexplorer
+.SH DESCRIPTION
+This program automatically runs a collection of DTrace scripts to examine
+many areas of the system, and places the output in a meaningful directory
+structure that is tar'd and gzip'd.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-q
+quiet mode
+.TP
+\-y
+"yes", don't prompt for confirmation
+.TP
+\-D
+don't delete output dir
+.TP
+\-T
+don't create output tar.gz
+.TP
+\-d outputdir
+output directory
+.TP
+\-i interval
+interval for each sample
+.PP
+.SH EXAMPLES
+.TP
+Create output file in current directory,
+#
+.B dexplorer
+.TP
+Don't prompt
+#
+.B dexplorer
+\-y
+.TP
+Leave expanded directories, don't archive and compress,
+#
+.B dexplorer
+\-DT
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/diskhits.1m b/cddl/contrib/dtracetoolkit/Man/man1m/diskhits.1m
new file mode 100644
index 0000000..e8b9c57
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/diskhits.1m
@@ -0,0 +1,46 @@
+.TH diskhits 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+diskhits \- disk access by file offset. Uses DTrace.
+.SH SYNOPSIS
+.B diskhits pathname
+.SH DESCRIPTION
+This prints how a file was accessed, the locations on a distribution plot.
+This is for the cache misses only - the file activity that resulted in
+disk events.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample /var/adm/messages disk activity,
+#
+.B diskhits /var/adm/messages
+.PP
+.SH FIELDS
+.TP
+Location (KB)
+the file offset of the disk activity, Kbytes
+.TP
+Size (KB)
+size of the disk activity, Kbytes
+.TP
+Total RW
+Total disk activity, reads + writes
+.PP
+.SH BASED ON
+/usr/demo/dtrace/applicat.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "io Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+diskhits will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dispqlen.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dispqlen.d.1m
new file mode 100644
index 0000000..dcc0820
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dispqlen.d.1m
@@ -0,0 +1,36 @@
+.TH dispqlen.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dispqlen.d \- dispatcher queue length by CPU. Uses DTrace.
+.SH SYNOPSIS
+.B dispqlen.d
+.SH DESCRIPTION
+The dispatcher queue length is an indication of CPU saturation.
+It is not an indicatior of utilisation - the CPUs may or may not be
+utilised when the dispatcher queue reports a length of zero.
+
+This script measures this activity by sampling at 1000 Hertz per CPU.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - walks private kernel structs.
+.SH EXAMPLES
+.TP
+Print dispatcher queue length by CPU.
+#
+.B dispqlen.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dispqlen.d will sample until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+uptime(1), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dnlcps.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcps.d.1m
new file mode 100644
index 0000000..482fd07
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcps.d.1m
@@ -0,0 +1,51 @@
+.TH dnlcps.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dnlcps.d \- DNLC stats by process. Uses DTrace.
+.SH SYNOPSIS
+.B dnlcps.d
+.SH DESCRIPTION
+The DNLC is the Directory Name Lookup Cache. Filename lookups often
+return a hit from here, before needing to traverse the regular file
+system cache or go to disk.
+
+dnlcps.d prints DNLC statistics by process.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B dnlcps.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+value
+0 == miss, 1 == hit
+.TP
+count
+number of occurrences
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dnlcps.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dnlcsnoop.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcsnoop.d.1m
new file mode 100644
index 0000000..cd9ac7b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcsnoop.d.1m
@@ -0,0 +1,52 @@
+.TH dnlcsnoop.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dnlcsnoop.d \- snoop DNLC activity. Uses DTrace.
+.SH SYNOPSIS
+.B dnlcsnoop.d
+.SH DESCRIPTION
+The DNLC is the Directory Name Lookup Cache. Filename lookups often
+return a hit from here, before needing to traverse the regular file
+system cache or go to disk.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B dnlcsnoop.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+TIME
+Elapsed time for lookup, us
+.TP
+HIT
+DNLC hit Y/N
+.TP
+PATH
+Path for DNLC lookup
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dnlcsnoop.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dnlcstat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcstat.1m
new file mode 100644
index 0000000..146c39d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dnlcstat.1m
@@ -0,0 +1,57 @@
+.TH dnlcstat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dnlcstat \- DNLC statistics. Uses DTrace.
+.SH SYNOPSIS
+.B dnlcstat
+[interval [count]]
+.SH DESCRIPTION
+The DNLC is the Directory Name Lookup Cache. Filename lookups often
+return a hit from here, before needing to traverse the regular file
+system cache or go to disk.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Print DNLC statistics every second,
+#
+.B dnlcstat
+.TP
+Print every 5 seconds, 6 times,
+#
+.B dnlcstat
+5 6
+.PP
+.SH FIELDS
+.TP
+%hit
+hit percentage for this sample
+.TP
+hit
+number of DNLC hits in this sample
+.TP
+miss
+number of DNLC misses in this sample
+.PP
+.SH NOTES
+See the CacheKit, http://www.brendangregg.com/cachekit.html for a version
+of dnlcstat written in Perl (Kstat) that uses much less CPU.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dnlcstat will run until Ctrl\-C is hit, or until the count argument
+has been satisfied.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dtruss.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dtruss.1m
new file mode 100644
index 0000000..7837f0e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dtruss.1m
@@ -0,0 +1,123 @@
+.TH dtruss 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dtruss \- process syscall details. Uses DTrace.
+.SH SYNOPSIS
+.B dtruss
+[\-acdeflhoLs] [\-t syscall] { \-p PID | \-n name | command }
+.SH DESCRIPTION
+dtruss prints details on process system calls. It is like a DTrace
+version of truss, and has been designed to be less intrusive than
+truss.
+
+Of particular interest is the elapsed times and on cpu times, which
+can identify both system calls that are slow to complete, and those
+which are consuming CPU cycles.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-a
+print all details
+.TP
+\-b bufsize
+dynamic variable buffer size. Increase this if you notice dynamic
+variable drop errors. The default is "4m" for 4 megabytes per CPU.
+.TP
+\-c
+print system call counts
+.TP
+\-d
+print relative timestamps, us
+.TP
+\-e
+print elapsed times, us
+.TP
+\-f
+follow children as they are forked
+.TP
+\-l
+force printing of pid/lwpid per line
+.TP
+\-L
+don't print pid/lwpid per line
+.TP
+\-n name
+examine processes with this name
+.TP
+\-o
+print on-cpu times, us
+.TP
+\-s
+print stack backtraces
+.TP
+\-p PID
+examine this PID
+.TP
+\-t syscall
+examine this syscall only
+.PP
+.SH EXAMPLES
+.TP
+run and examine the "df -h" command
+#
+.B dtruss
+df -h
+.PP
+.TP
+examine PID 1871
+#
+.B dtruss
+\-p 1871
+.PP
+.TP
+examine all processes called "tar"
+#
+.B dtruss
+\-n tar
+.PP
+.TP
+run test.sh and follow children
+#
+.B dtruss
+\-f test.sh
+.TP
+run the "date" command and print elapsed and on cpu times,
+#
+.B dtruss
+\-eo date
+.PP
+.SH FIELDS
+.TP
+PID/LWPID
+Process ID / Lightweight Process ID
+.TP
+RELATIVE
+relative timestamps to the start of the thread, us (microseconds)
+.TP
+ELAPSD
+elapsed time for this system call, us
+.TP
+CPU
+on-cpu time for this system call, us
+.TP
+SYSCALL(args)
+system call name, with arguments (some may be evaluated)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dtruss will run forever until Ctrl\-C is hit, or if a command was
+executed dtruss will finish when the command ends.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+procsystime(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/dvmstat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/dvmstat.1m
new file mode 100644
index 0000000..20fa955
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/dvmstat.1m
@@ -0,0 +1,93 @@
+.TH dvmstat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+dvmstat \- vmstat by PID/name/command. Uses DTrace.
+.SH SYNOPSIS
+.B dvmstat
+{ \-p PID | \-n name | command }
+.SH DESCRIPTION
+This program provides vmstat like data for one particular PID, a
+process name, or when running a command. It prints statistics
+every second.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH OPTIONS
+.TP
+\-p PID
+examine this Process ID
+.TP
+\-n name
+examine processes with this name
+.PP
+.SH EXAMPLES
+.TP
+examine PID 1871,
+#
+.B dvmstat
+\-p 1871
+.TP
+examine processes called "tar",
+#
+.B dvmstat
+\-n tar
+.TP
+run and examine "df -h",
+#
+.B dvmstat
+df -h
+.PP
+.SH FIELDS
+.TP
+re
+page reclaims, Kbytes
+.TP
+maj
+major faults, Kbytes
+.TP
+mf
+minor faults, Kbytes
+.TP
+fr
+page frees, Kbytes
+.TP
+epi
+executable page ins, Kbytes
+.TP
+epo
+executable page outs, Kbytes
+.TP
+api
+anonymous page ins, Kbytes
+.TP
+apo
+anonymous page outs, Kbytes
+.TP
+fpi
+filesystem page ins, Kbytes
+.TP
+fpo
+filesystem page outs, Kbytes
+.TP
+sy
+system calls, number
+.PP
+.SH NOTES
+Most of the statistics are in units of kilobytes, unlike the
+original vmstat command which sometimes uses pages.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+dvmstat will run until Ctrl\-C is hit, or the command it is
+examining ends.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), vmstat(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/errinfo.1m b/cddl/contrib/dtracetoolkit/Man/man1m/errinfo.1m
new file mode 100644
index 0000000..6b63e52
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/errinfo.1m
@@ -0,0 +1,85 @@
+.TH errinfo 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+errinfo \- print errno for syscall fails. Uses DTrace.
+.SH SYNOPSIS
+.B errinfo
+[\-a|\-A|\-hsvZ] [\-c command]
+.SH DESCRIPTION
+errinfo snoops syscall failures and prints the errno value and
+description of the error number.
+
+This program can help determine if applications are silently
+failing, providing some details on the cause.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-c
+counts - print an aggregate style report containing a
+frequency count of errors
+.TP
+\-p PID
+examine this PID only
+.TP
+\-n name
+examine processes with ths name only (eg, "ls")
+.SH EXAMPLES
+.TP
+Default output, print errors as they occur,
+#
+.B errinfo
+.PP
+.TP
+Print a frequency count report,
+#
+.B errinfo
+\-c
+.PP
+.TP
+Snoop errors as they occur for "ssh" processes,
+#
+.B errinfo
+\-n ssh
+PP
+.TP
+Snoop errors for PID 81 only,
+#
+.B errinfo
+\-p 81
+.PP
+.SH FIELDS
+.TP
+EXEC
+Program name (truncated)
+.TP
+SYSCALL
+System call name
+.TP
+ERR
+Value of errno
+.TP
+DESC
+Description of errno message
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+errinfo will run forever until Ctrl\-C is hit.
+.SH FILES
+.TP
+/usr/include/sys/errno.h
+Contains the full descriptions for the error numbers.
+.PP
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/execsnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/execsnoop.1m
new file mode 100644
index 0000000..a7114ce
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/execsnoop.1m
@@ -0,0 +1,108 @@
+.TH execsnoop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+execsnoop \- snoop new process execution. Uses DTrace.
+.SH SYNOPSIS
+.B execsnoop
+[\-a|\-A|\-ejhsvZ] [\-c command]
+.SH DESCRIPTION
+execsnoop prints details of new processes as they are executed.
+Details such as UID, PID and argument listing are printed out.
+
+This program is very useful to examine short lived processes that would
+not normally appear in a prstat or "ps -ef" listing. Sometimes
+applications will run hundreds of short lived processes in their
+normal startup cycle, a behaviour that is easily monitored with execsnoop.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-A
+dump all data, space delimited
+.TP
+\-e
+safe output, parseable. This prevents the ARGS field containing "\\n"s,
+to assist postprocessing.
+.TP
+\-j
+print project ID
+.TP
+\-s
+print start time, us
+.TP
+\-v
+print start time, string
+.TP
+\-Z
+print zonename
+.TP
+\-c command
+command name to snoop
+.SH EXAMPLES
+.TP
+Default output, print processes as they are executed,
+#
+.B execsnoop
+.TP
+Print human readable timestamps,
+#
+.B execsnoop
+\-v
+.TP
+Print zonename,
+#
+.B execsnoop
+\-Z
+.TP
+Snoop this command only,
+#
+.B execsnoop
+\-f ls
+.PP
+.SH FIELDS
+.TP
+UID
+User ID
+.TP
+PID
+Process ID
+.TP
+PPID
+Parent Process ID
+.TP
+COMM
+command name for the process
+.TP
+ARGS
+argument listing for the process
+.TP
+ZONE
+zonename
+.TP
+PROJ
+project ID
+.TP
+TIME
+timestamp for the exec event, us
+.TP
+STRTIME
+timestamp for the exec event, string
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+execsnoop will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/fddist.1m b/cddl/contrib/dtracetoolkit/Man/man1m/fddist.1m
new file mode 100644
index 0000000..990d761
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/fddist.1m
@@ -0,0 +1,63 @@
+.TH fddist 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+fddist \- file descriptor usage distributions. Uses DTrace.
+.SH SYNOPSIS
+.B fddist [\-r|\-w]
+.SH DESCRIPTION
+This prints distributions for read and write events by file descriptor,
+by process. This can be used to determine which file descriptor a
+process is doing the most I/O with.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-r
+reads only
+.TP
+\-w
+writes only
+.PP
+.SH EXAMPLES
+.TP
+Sample both read and write activity,
+#
+.B fddist
+.TP
+Sample reads only,
+#
+.B fddist
+\-r
+.PP
+.SH FIELDS
+.TP
+EXEC
+process name
+.TP
+PID
+process ID
+.TP
+value
+file descriptor
+.TP
+count
+number of events
+.PP
+.SH BASED ON
+/usr/demo/dtrace/lquantize.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "Aggregations" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+fddist will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/filebyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/filebyproc.d.1m
new file mode 100644
index 0000000..23b5648
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/filebyproc.d.1m
@@ -0,0 +1,56 @@
+.TH filebyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+filebyproc.d \- snoop opens by process name. Uses DTrace.
+.SH SYNOPSIS
+.B filebyproc.d
+.SH DESCRIPTION
+filebyproc.d is a DTrace OneLiner to print file pathnames as they are
+opened, including the name of the process calling the open.
+A line will be printed regardless of whether the open is actually
+successful or not.
+
+This is useful to learn which files applications are attempting to
+open, such as config files, database files, log files, etc.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This prints new process name and pathnames until Ctrl\-C is hit.
+#
+.B filebyproc.d
+.PP
+.SH FIELDS
+.TP
+CPU
+The CPU that recieved the event
+.TP
+ID
+A DTrace probe ID for the event
+.TP
+FUNCTION:NAME
+The DTrace probe name for the event
+.TP
+remaining fields
+The first is the name of the process, the second is the file pathname.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+filebyproc.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+opensnoop(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/fspaging.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/fspaging.d.1m
new file mode 100644
index 0000000..6911ac5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/fspaging.d.1m
@@ -0,0 +1,88 @@
+.TH fspaging.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+fspaging.d \- file system read/write and paging tracing. Uses DTrace.
+.SH SYNOPSIS
+.B fspaging.d
+.SH DESCRIPTION
+This traces file related activity: system call reads and writes,
+vnode logical read and writes (fop), vnode putpage and getpage activity,
+and disk I/O. It can be used to examine the behaviour of each I/O
+layer, from the syscall interface to what the disk is doing. Behaviour
+such as read-ahead, and max I/O size breakup can be observed.
+
+This is a verbose version of fsrw.d, as this also traces paging activity.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Trace file system read/write/paging events,
+#
+.B fspaging.d
+.PP
+.SH FIELDS
+.TP
+Event
+traced event (see EVENTS below)
+.TP
+Device
+device, for disk I/O
+.TP
+RW
+either Read or Write
+.TP
+Size
+size of I/O in bytes
+.TP
+Offset
+offset of I/O in kilobytes
+.TP
+Path
+path to file on disk
+.PP
+.SH EVENTS
+.TP
+sc-read
+system call read
+.TP
+sc-write
+system call write
+.TP
+fop_read
+logical read
+.TP
+fop_write
+logical write
+.TP
+fop_getpage
+logical get page
+.TP
+fop_putpage
+logical put page
+.TP
+disk_io
+physical disk I/O
+.TP
+disk_ra
+physical disk I/O, read ahead
+.PP
+.SH IDEA
+Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+fspaging.d will trace until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+fsrw.d(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/fsrw.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/fsrw.d.1m
new file mode 100644
index 0000000..4389c21
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/fsrw.d.1m
@@ -0,0 +1,80 @@
+.TH fsrw.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+fsrw.d \- file system read/write event tracing. Uses DTrace.
+.SH SYNOPSIS
+.B fsrw.d
+.SH DESCRIPTION
+This traces file related activity: system call reads and writes,
+vnode logical read and writes (fop), and disk I/O. It can be used
+to examine the behaviour of each I/O layer, from the syscall
+interface to what the disk is doing. Behaviour such as read-ahead, and
+max I/O size breakup can be observed.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Trace file system read/write events,
+#
+.B fsrw.d
+.PP
+.SH FIELDS
+.TP
+Event
+traced event (see EVENTS below)
+.TP
+Device
+device, for disk I/O
+.TP
+RW
+either Read or Write
+.TP
+Size
+size of I/O in bytes
+.TP
+Offset
+offset of I/O in kilobytes
+.TP
+Path
+path to file on disk
+.PP
+.SH EVENTS
+.TP
+sc-read
+system call read
+.TP
+sc-write
+system call write
+.TP
+fop_read
+logical read
+.TP
+fop_write
+logical write
+.TP
+disk_io
+physical disk I/O
+.TP
+disk_ra
+physical disk I/O, read ahead
+.PP
+.SH IDEA
+Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+fsrw.d will trace until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+fspaging.d(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/guess.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/guess.d.1m
new file mode 100644
index 0000000..4c6d2e2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/guess.d.1m
@@ -0,0 +1,37 @@
+.TH guess.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+guess.d \- guessing game. Uses DTrace.
+.SH SYNOPSIS
+.B guess.d
+.SH DESCRIPTION
+This is written to demonstrate this language versus the same program
+written in other languages.
+
+See http://www.brendangregg.com/guessinggame.html
+
+It exists in the DTraceToolkit as a curiosity, rather than something
+actually useful.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+Play the game,
+#
+.B guess.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+guess.d will only exit when you win the game.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/hotkernel.1m b/cddl/contrib/dtracetoolkit/Man/man1m/hotkernel.1m
new file mode 100644
index 0000000..49772b6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/hotkernel.1m
@@ -0,0 +1,39 @@
+.TH hotkernel 1m "$Date:: 2007-09-24 #$" "USER COMMANDS"
+.SH NAME
+hotkernel - sample on-CPU kernel-level functions and modules.
+.SH SYNOPSIS
+.B hotkernel
+[\-hm]
+.SH DESCRIPTION
+This samples the on-CPU function at 1001 Hertz, for a simple yet
+effective kernel-level profiling tool for sampling exclusive function time.
+The output will identify which function is on the CPU the most - which is
+the hottest. See Notes/ALLexclusive_notes.txt for an explanation of
+exclusive time.
+.SH OS
+Solaris
+.SH STABILITY
+stable - Written using Perl and DTrace (Solaris 10 03/05)
+.SH EXAMPLES
+.TP
+Sample kernel functions,
+#
+.B hotkernel
+.PP
+.TP
+Sample kernel modules,
+#
+.B hotkernel
+\-m
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+hotkernel will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M), hotuser(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/hotspot.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/hotspot.d.1m
new file mode 100644
index 0000000..a99a589
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/hotspot.d.1m
@@ -0,0 +1,51 @@
+.TH hotspot.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+hotspot.d \- print disk event by location. Uses DTrace.
+.SH SYNOPSIS
+.B hotspot.d
+.SH DESCRIPTION
+hotspot.d is a simple DTrace script to determine if disk activity is
+occuring in the one place - a "hotspot". This helps us understand the
+system's usage of a disk, it does not imply that the existance or not
+of a hotspot is good or bad (often may be good, less seeking).
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B hotspot.d
+.PP
+.SH FIELDS
+.TP
+Disk
+disk instance name
+.TP
+Major
+driver major number
+.TP
+Minor
+driver minor number
+.TP
+value
+location of disk event, megabytes
+.TP
+count
+number of events
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+hotspot.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/hotuser.1m b/cddl/contrib/dtracetoolkit/Man/man1m/hotuser.1m
new file mode 100644
index 0000000..ab26523
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/hotuser.1m
@@ -0,0 +1,44 @@
+.TH hotuser 1m "$Date:: 2007-09-24 #$" "USER COMMANDS"
+.SH NAME
+hotuser - sample on-CPU user-level functions and libraries.
+.SH SYNOPSIS
+.B hotuser
+[\-hl] { \-c command | \-p PID }
+.SH DESCRIPTION
+This samples the on-CPU function at 1001 Hertz, for a simple yet
+effective user-level profiling tool for sampling exclusive function time.
+The output will identify which function is on the CPU the most - which
+is the hottest. See Notes/ALLexclusive_notes.txt for an explanation of
+exclusive time.
+.SH OS
+Solaris
+.SH STABILITY
+stable - Written using Perl and DTrace (Solaris 10 03/05)
+.SH EXAMPLES
+.TP
+Sample user functions from PID 81,
+#
+.B hotuser
+\-p 81
+.TP
+Sample user libraries from PID 81,
+#
+.B hotuser
+\-lp 81
+.TP
+Sample Xorg,
+#
+.B hotuser
+`pgrep \-n Xorg`
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+hotuser will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M), hotkernel(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/httpdstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/httpdstat.d.1m
new file mode 100644
index 0000000..5dd0a3f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/httpdstat.d.1m
@@ -0,0 +1,67 @@
+.TH httpdstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+httpdstat.d \- realtime httpd statistics. Uses DTrace.
+.SH SYNOPSIS
+.B httpdstat.d
+[interval [count]]
+.SH DESCRIPTION
+This prints connection statistics for "httpd" processes, such as those
+from an Apache web server.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+Print statistics every second,
+#
+.B httpdstat.d
+.TP
+Print every 5 seconds, 6 times,
+#
+.B httpdstat.d
+5 6
+.PP
+.SH FIELDS
+.TP
+TIME
+time, string
+.TP
+NUM
+number of connections
+.TP
+GET
+number of GETs
+.TP
+POST
+number of POSTs
+.TP
+HEAD
+number of HEADs
+.TP
+TRACE
+number of TRACEs
+.PP
+.SH NOTES
+All statistics are printed as a value per interval.
+
+This version does not process subsequent operations on keepalives.
+.PP
+.SH IDEA
+Ryan Matteson
+(who first wrote a solution to this).
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+httpdstat.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/icmpstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/icmpstat.d.1m
new file mode 100644
index 0000000..be4b87a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/icmpstat.d.1m
@@ -0,0 +1,47 @@
+.TH icmpstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+icmpstat.d \- print ICMP statistics. Uses DTrace.
+.SH SYNOPSIS
+.B icmpstat.d
+.SH DESCRIPTION
+icmpstat.d is a DTrace program to print ICMP statistics every second,
+retrieved from the MIB provider. This is a simple script to demonstrate the
+ability to trace ICMP events.
+
+The ICMP statistics are documented in the mib2_icmp struct
+in /usr/include/inet/mib2.h; and also in the mib provider
+chapter of the DTrace Guide, found at
+http://docs.sun.com/db/doc/817-6223.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the mib provider.
+.SH EXAMPLES
+.TP
+Print statistics every second,
+#
+.B icmpstat.d
+.PP
+.SH FIELDS
+.TP
+STATISTIC
+ICMP statistic name
+.TP
+VALUE
+total of statistic during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+icmpstat.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/intbycpu.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/intbycpu.d.1m
new file mode 100644
index 0000000..79314dc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/intbycpu.d.1m
@@ -0,0 +1,48 @@
+.TH intbycpu.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+intbycpu.d \- interrupts by CPU. Uses DTrace.
+.SH SYNOPSIS
+.B intbycpu.d
+.SH DESCRIPTION
+intbycpu.d is based on a DTrace OneLiner to a report of the number of
+interrupts by CPU.
+
+The intrstat(1M) command can be used for further analysis
+of interrputs.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sdt provider interrupt probes.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B intbycpu.d
+.PP
+.SH FIELDS
+.TP
+CPU
+This is the CPU id.
+.TP
+INTERRUPTS
+This is the number of interrputs received in the sample.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+intbycpu.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+intrstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/intoncpu.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/intoncpu.d.1m
new file mode 100644
index 0000000..ec52b81
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/intoncpu.d.1m
@@ -0,0 +1,42 @@
+.TH intoncpu.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+intoncpu.d \- print interrput on-cpu usage. Uses DTrace.
+.SH SYNOPSIS
+.B intoncpu.d
+.SH DESCRIPTION
+This prints a distribution of the on-cpu time for interrput threads.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sdt provider interrupt probes.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B intoncpu.d
+.PP
+.SH FIELDS
+.TP
+value
+Time interrupt thread was on-cpu, ns
+.TP
+count
+Number of occurrences of at least this time
+.PP
+.SH BASED ON
+/usr/demo/dtrace/intr.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "sdt Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+intoncpu.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+intrstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/inttimes.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/inttimes.d.1m
new file mode 100644
index 0000000..bc6d989
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/inttimes.d.1m
@@ -0,0 +1,43 @@
+.TH inttimes.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+inttimes.d \- print interrput on-cpu time total. Uses DTrace.
+.SH SYNOPSIS
+.B inttimes.d
+.SH DESCRIPTION
+This prints the total time each driver instance has spent servicing
+interrupts.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sdt provider interrupt probes.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B inttimes.d
+.PP
+.SH FIELDS
+.TP
+DEVICE
+instance name of the device driver
+.TP
+TIME (ns)
+sum of time spent servicing interrupt (nanoseconds)
+.PP
+.SH BASED ON
+/usr/demo/dtrace/intr.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "sdt Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+inttimes.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+intrstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iofile.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iofile.d.1m
new file mode 100644
index 0000000..fd3016d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iofile.d.1m
@@ -0,0 +1,49 @@
+.TH iofile.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iofile.d \- I/O wait time by file and process. Uses DTrace.
+.SH SYNOPSIS
+.B iofile.d
+.SH DESCRIPTION
+This prints the total I/O wait times for each filename by process.
+This can help determine why an application is performing poorly by
+identifying which file they are waiting on, and the total times.
+Both disk and NFS I/O are measured.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B iofile.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+TIME
+total wait time for disk events, us
+.TP
+FILE
+file pathname
+.PP
+.SH BASED ON
+/usr/demo/dtrace/iocpu.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iofile.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+iosnoop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iofileb.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iofileb.d.1m
new file mode 100644
index 0000000..56ca3ac
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iofileb.d.1m
@@ -0,0 +1,46 @@
+.TH iofileb.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iofileb.d \- I/O bytes by file and process. Uses DTrace.
+.SH SYNOPSIS
+.B iofileb.d
+.SH DESCRIPTION
+This prints a summary of requested disk activity by pathname,
+providing totals of the I/O events in bytes. It is a companion to the
+iofile.d script - which prints in terms of I/O wait time, not bytes.
+I/O wait time is a better metric for understanding performance issues.
+Both disk and NFS I/O are measured.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B iofileb.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+KB
+kilobytes of disk I/O
+.TP
+FILE
+file pathname
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iofileb.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+iofile.d(1M), iosnoop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iopattern.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iopattern.1m
new file mode 100644
index 0000000..6898f82
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iopattern.1m
@@ -0,0 +1,112 @@
+.TH iopattern 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iopattern \- print disk I/O pattern. Uses DTrace.
+.SH SYNOPSIS
+.B iopattern
+[\-v] [\-d device] [\-f filename] [\-m mount_point] [interval [count]]
+.SH DESCRIPTION
+This prints details on the I/O access pattern for the disks, such as
+percentage of events that were of a random or sequential nature.
+By default totals for all disks are printed.
+
+An event is considered random when the heads seek. This program prints
+the percentage of events that are random. The size of the seek is not
+measured - it's either random or not.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH OPTIONS
+.TP
+\-v
+print timestamp, string
+.TP
+\-d device
+instance name to snoop (eg, dad0)
+.TP
+\-f filename
+full pathname of file to snoop
+.TP
+\-m mount_point
+mountpoint for filesystem to snoop
+.SH EXAMPLES
+.TP
+Default output, print I/O summary every 1 second,
+#
+.B iopattern
+.PP
+.TP
+Print 10 second samples,
+#
+.B iopattern
+10
+.PP
+.TP
+Print 12 x 5 second samples,
+#
+.B iopattern
+5 12
+.PP
+.TP
+Snoop events on the root filesystem only,
+#
+.B iopattern
+\-m /
+.PP
+.SH FIELDS
+.TP
+%RAN
+percentage of events of a random nature
+.TP
+%SEQ
+percentage of events of a sequential nature
+.TP
+COUNT
+number of I/O events
+.TP
+MIN
+minimum I/O event size
+.TP
+MAX
+maximum I/O event size
+.TP
+AVG
+average I/O event size
+.TP
+KR
+total kilobytes read during sample
+.TP
+KW
+total kilobytes written during sample
+.TP
+DEVICE
+device name
+.TP
+MOUNT
+mount point
+.TP
+FILE
+filename (basename) for I/O operation
+.TP
+TIME
+timestamp, string
+.PP
+.SH IDEA
+Ryan Matteson
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iopattern will run forever until Ctrl\-C is hit, or the
+specified count is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1M), iotop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iopending.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iopending.1m
new file mode 100644
index 0000000..c31d967
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iopending.1m
@@ -0,0 +1,89 @@
+.TH iopending 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iopending \- plot number of pending disk events. Uses DTrace.
+.SH SYNOPSIS
+.B iopending
+[\-c] [\-d device] [\-f filename] [\-m mount_point] [interval [count]]
+.SH DESCRIPTION
+This samples the number of disk events that are pending and plots a
+distribution graph. By doing this the
+"serialness" or "parallelness" of disk behaviour can be distinguished.
+A high occurance of a pending value of more than 1 is an indication of
+saturation.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH OPTIONS
+.TP
+\-c
+clear screen
+.TP
+\-d device
+instance name to snoop (eg, dad0)
+.TP
+\-f filename
+full pathname of file to snoop
+.TP
+\-m mount_point
+mountpoint for filesystem to snoop
+.SH EXAMPLES
+.TP
+Default output, print I/O summary every 1 second,
+#
+.B iopending
+.PP
+.TP
+Print 10 second samples,
+#
+.B iopending
+10
+.PP
+.TP
+Print 12 x 5 second samples,
+#
+.B iopending
+5 12
+.PP
+.TP
+Snoop events on the root filesystem only,
+#
+.B iopending
+\-m /
+.PP
+.SH FIELDS
+.TP
+value
+number of pending events, 0 == idle
+.TP
+count
+number of samples @ 1000 Hz
+.TP
+load
+1 min load average
+.TP
+disk_r
+total disk read Kb for sample
+.TP
+disk_w
+total disk write Kb for sample
+.PP
+.SH IDEA
+Dr Rex di Bona
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iopending will run forever until Ctrl\-C is hit, or the
+specified count is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1M), iotop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iosnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iosnoop.1m
new file mode 100644
index 0000000..6e9058d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iosnoop.1m
@@ -0,0 +1,167 @@
+.TH iosnoop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iosnoop \- snoop I/O events as they occur. Uses DTrace.
+.SH SYNOPSIS
+.B iosnoop
+[\-a|\-A|\-Deghinostv] [\-d device] [\-f filename] [\-m mount_point]
+[\-n name] [\-p PID]
+.SH DESCRIPTION
+iosnoop prints I/O events as they happen, with useful details such
+as UID, PID, block number, size, filename, etc.
+
+This is useful to determine the process responsible for
+using the disks, as well as details on what activity the process
+is requesting. Behaviour such as random or sequential I/O can
+be observed by reading the block numbers.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-A
+dump all data, space delimited
+.TP
+\-D
+print time delta, us (elapsed)
+.TP
+\-e
+print device name
+.TP
+\-i
+print device instance
+.TP
+\-n
+print major and minor numbers
+.TP
+\-o
+print disk delta time, us
+.TP
+\-s
+print start time, us
+.TP
+\-t
+print completion time, us
+.TP
+\-v
+print completion time, string
+.TP
+\-d device
+instance name to snoop (eg, dad0)
+.TP
+\-f filename
+full pathname of file to snoop
+.TP
+\-m mount_point
+mountpoint for filesystem to snoop
+.TP
+\-n name
+process name
+.TP
+\-p PID
+process ID
+.PP
+.SH EXAMPLES
+.TP
+Default output, print I/O activity as it occurs,
+#
+.B iosnoop
+.PP
+.TP
+Print human readable timestamps,
+#
+.B iosnoop
+\-v
+.PP
+.TP
+Print major and minor numbers,
+#
+.B iosnoop
+\-n
+.PP
+.TP
+Snoop events on the root filesystem only,
+#
+.B iosnoop
+\-m /
+.PP
+.SH FIELDS
+.TP
+UID
+User ID
+.TP
+PID
+Process ID
+.TP
+PPID
+Parent Process ID
+.TP
+COMM
+command name for the process
+.TP
+ARGS
+argument listing for the process
+.TP
+SIZE
+size of the operation, bytes
+.TP
+BLOCK
+disk block for the operation (location. relative to this filesystem.
+more useful with the -n option to print major and minor numbers)
+.TP
+STIME
+timestamp for the disk request, us
+.TP
+TIME
+timestamp for the disk completion, us
+.TP
+DELTA
+elapsed time from request to completion, us (this is the elapsed
+time from the disk request (strategy) to the disk completion (iodone))
+.TP
+DTIME
+time for disk to complete request, us (this is the time for the
+disk to complete that event since it's last event (time between iodones),
+or, the time to the strategy if the disk had been idle)
+.TP
+STRTIME
+timestamp for the disk completion, string
+.TP
+DEVICE
+device name
+.TP
+INS
+device instance number
+.TP
+D
+direction, Read or Write
+.TP
+MOUNT
+mount point
+.TP
+FILE
+filename (basename) for I/O operation
+.PP
+.SH NOTES
+When filtering on PID or process name, be aware that poor disk event
+times may be due to events that have been filtered away, for example
+another process that may be seeking the disk heads elsewhere.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iosnoop will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iotop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/iotop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/iotop.1m
new file mode 100644
index 0000000..8052243
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/iotop.1m
@@ -0,0 +1,154 @@
+.TH iotop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+iotop \- display top disk I/O events by process. Uses DTrace.
+.SH SYNOPSIS
+.B iotop
+[\-C] [\-D|\-o|\-P] [\-j|\-Z] [\-d device] [\-f filename]
+[\-m mount_point] [\-t top] [interval [count]]
+.SH DESCRIPTION
+iotop tracks disk I/O by process, and prints a summary report that
+is refreshed every interval.
+
+This is measuring disk events that have made it past system caches.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-D
+print delta times - elapsed, us
+.TP
+\-j
+print project ID
+.TP
+\-o
+print disk delta times, us
+.TP
+\-P
+print %I/O (disk delta times)
+.TP
+\-Z
+print zone ID
+.TP
+\-d device
+instance name to snoop (eg, dad0)
+.TP
+\-f filename
+full pathname of file to snoop
+.TP
+\-m mount_point
+mountpoint for filesystem to snoop
+.TP
+\-t top
+print top number only
+.PP
+.SH EXAMPLES
+.TP
+Default output, print summary every 5 seconds
+#
+.B iotop
+.PP
+.TP
+One second samples,
+#
+.B iotop
+1
+.PP
+.TP
+print %I/O (time based),
+#
+.B iotop
+\-P
+.PP
+.TP
+Snoop events on the root filesystem only,
+#
+.B iotop
+\-m /
+.TP
+Print top 20 lines only,
+#
+.B iotop
+\-t 20
+.TP
+Print 12 x 5 second samples, scrolling,
+#
+.B iotop
+\-C 5 12
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+PPID
+parent process ID
+.TP
+PROJ
+project ID
+.TP
+ZONE
+zone ID
+.TP
+CMD
+command name for the process
+.TP
+DEVICE
+device name
+.TP
+MAJ
+device major number
+.TP
+MIN
+device minor number
+.TP
+D
+direction, Read or Write
+.TP
+BYTES
+total size of operations, bytes
+.TP
+ELAPSED
+total elapsed times from request to completion, us (this is the elapsed
+time from the disk request (strategy) to the disk completion (iodone))
+.TP
+DISKTIME
+total times for disk to complete request, us (this is the time for the
+disk to complete that event since it's last event (time between iodones),
+or, the time to the strategy if the disk had been idle)
+.TP
+%I/O
+percent disk I/O, based on time (DISKTIME)
+.TP
+load
+1 minute load average
+.TP
+disk_r
+total disk read Kb for sample
+.TP
+disk_w
+total disk write Kb for sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+iotop will run forever until Ctrl\-C is hit, or the specified
+interval is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_calldist.d.1m
new file mode 100644
index 0000000..d78ce85
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_calldist.d.1m
@@ -0,0 +1,48 @@
+.TH j_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_calldist.d - measure Java elapsed times for different types of operation.
+.SH SYNOPSIS
+.B j_calldist.d
+[top]
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls are only visible when using the
+flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+The "top" optional argument will truncate the output for each report
+section to that many lines, with a default of 10.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Process ID
+.TP
+2
+Type of call (method/gc)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_calls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_calls.d.1m
new file mode 100644
index 0000000..e89fb8e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_calls.d.1m
@@ -0,0 +1,57 @@
+.TH j_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_calls.d - count Java calls (method/...) using DTrace.
+.SH SYNOPSIS
+.B j_calls.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls and object allocation are only
+visible when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+TYPEs:
+cload class load
+method method call
+mcompile method compile
+mload compiled method load
+oalloc object alloc
+thread thread start
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_calls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (see below)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_calltime.d.1m
new file mode 100644
index 0000000..479dc5b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_calltime.d.1m
@@ -0,0 +1,51 @@
+.TH j_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_calltime.d - measure Java elapsed times for different types of operation.
+.SH SYNOPSIS
+.B j_calltime.d
+[top]
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls are only visible when using the
+flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+The "top" optional argument will truncate the output for each report
+section to that many lines, with a default of 10.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_calltime.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (method/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_classflow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_classflow.d.1m
new file mode 100644
index 0000000..af9d06c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_classflow.d.1m
@@ -0,0 +1,63 @@
+.TH j_classflow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_classflow.d - trace a Java class method flow using DTrace.
+.SH SYNOPSIS
+.B j_classflow.d
+classname
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+This watches Java method entries and returns, and indents child
+method calls.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_classflow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+PID
+Process ID
+.TP
+CLASS.METHOD
+Java class and method name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+Changes in TID will appear to shuffle output, as we change from one thread
+depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_classflow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_cpudist.d.1m
new file mode 100644
index 0000000..37fe5f0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_cpudist.d.1m
@@ -0,0 +1,48 @@
+.TH j_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_cpudist.d - measure Java on-CPU times for different types of operation.
+.SH SYNOPSIS
+.B j_cpudist.d
+[top]
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls are only visible when using the
+flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+The "top" optional argument will truncate the output for each report
+section to that many lines, with a default of 10.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Process ID
+.TP
+2
+Type of call (method/gc)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_cputime.d.1m
new file mode 100644
index 0000000..a0e767a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_cputime.d.1m
@@ -0,0 +1,51 @@
+.TH j_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_cputime.d - measure Java on-CPU times for different types of operation.
+.SH SYNOPSIS
+.B j_cputime.d
+[top]
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls are only visible when using the
+flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
+
+The "top" optional argument will truncate the output for each report
+section to that many lines, with a default of 10.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_cputime.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (method/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_events.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_events.d.1m
new file mode 100644
index 0000000..6df009b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_events.d.1m
@@ -0,0 +1,46 @@
+.TH j_events.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_events.d - count Java events using DTrace.
+.SH SYNOPSIS
+.B j_events.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Some events such as method calls are only
+visible when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_events.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+EVENT
+Event name (DTrace probe name)
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_events.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_flow.d.1m
new file mode 100644
index 0000000..579e681
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_flow.d.1m
@@ -0,0 +1,63 @@
+.TH j_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_flow.d - snoop Java execution showing method flow using DTrace.
+.SH SYNOPSIS
+.B j_flow.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+This watches Java method entries and returns, and indents child
+method calls.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+PID
+Process ID
+.TP
+CLASS.METHOD
+Java class and method name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+Changes in TID will appear to shuffle output, as we change from one thread
+depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_flowtime.d.1m
new file mode 100644
index 0000000..e4334b2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_flowtime.d.1m
@@ -0,0 +1,69 @@
+.TH j_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_flowtime.d - snoop Java execution with method flow and delta times.
+.SH SYNOPSIS
+.B j_flowtime.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+This watches Java method entries and returns, and indents child
+method calls.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+TID
+Thread ID
+.TP
+TIME(us)
+Time since boot (us)
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+CLASS.METHOD
+Java class and method name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+Changes in TID will appear to shuffle output, as we change from one thread
+depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_methodcalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_methodcalls.d.1m
new file mode 100644
index 0000000..a44aea7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_methodcalls.d.1m
@@ -0,0 +1,45 @@
+.TH j_methodcalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_methodcalls.d - count Java method calls DTrace.
+.SH SYNOPSIS
+.B j_methodcalls.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_methodcalls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+COUNT
+Number of calls during sample
+.TP
+CLASS.METHOD
+Java class and method name
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_methodcalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_objnew.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_objnew.d.1m
new file mode 100644
index 0000000..14a6b21
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_objnew.d.1m
@@ -0,0 +1,45 @@
+.TH j_objnew.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_objnew.d - report Java object allocation using DTrace.
+.SH SYNOPSIS
+.B j_objnew.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0) and the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_objnew.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+OBJS
+Number of objects created
+.TP
+CLASS.METHOD
+Java class and method name
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_objnew.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_package.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_package.d.1m
new file mode 100644
index 0000000..43f5b9b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_package.d.1m
@@ -0,0 +1,44 @@
+.TH j_package.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_package.d - count Java class loads by package using DTrace.
+.SH SYNOPSIS
+.B j_package.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0).
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_package.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+LOADS
+Class loads during trace
+.TP
+PACKAGE
+Package name from class
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_package.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_profile.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_profile.d.1m
new file mode 100644
index 0000000..7c1ca28
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_profile.d.1m
@@ -0,0 +1,52 @@
+.TH j_profile.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_profile.d - sample stack traces with Java translations using DTrace.
+.SH SYNOPSIS
+.SH DESCRIPTION
+This samples stack traces for the process specified. This stack trace
+will cross the JVM and system libraries, and insert translations for Java
+stack frames where appropriate. This is best explained with an example
+stack frame output,
+
+Func_loop.func_c()V
+Func_loop.func_b()V
+Func_loop.func_a()V
+Func_loop.main([Ljava/lang/String;)V
+StubRoutines (1)
+libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHan
+libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmetho
+libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJ
+libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_j
+libjvm.so`jni_CallStaticVoidMethod+0x15d
+java`JavaMain+0xd30
+libc.so.1`_thr_setup+0x52
+libc.so.1`_lwp_start
+101
+
+The lines at the top are Java frames, followed by the JVM (libjvm.so).
+The JVM symbols may be translated by passing the output through c++filt.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_profile.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_profile.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_stat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_stat.d.1m
new file mode 100644
index 0000000..ab1495e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_stat.d.1m
@@ -0,0 +1,68 @@
+.TH j_stat.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_stat.d - Java operation stats using DTrace.
+.SH SYNOPSIS
+.B j_stat.d
+[interval [count]]
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0). Method calls and object allocation are only
+visible when using the flag "+ExtendedDTraceProbes". eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+The numbers are counts for the interval specified. The default interval
+is 1 second.
+
+If you see a count in "EXECS" but not in the other columns, then your
+Java software is probably not running with the DTrace hotspot provider.
+
+If you see counts in "CLOAD" but not in "METHODS", then you Java
+software probably isn't running with "+ExtendedDTraceProbes".
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_stat.d
+.PP
+.SH FIELDS
+.TP
+EXEC/s
+Java programs executed per second, including
+those without Java provider support
+.TP
+METHOD/s
+Methods called, per second
+.TP
+OBJNEW/s
+Objects created, per second
+.TP
+CLOAD/s
+Class loads, per second
+.TP
+EXCP/s
+Exceptions raised, per second
+.TP
+RESC/s
+Rescues, per second
+.TP
+GC/s
+Garbage collects, per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_stat.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_syscalls.d.1m
new file mode 100644
index 0000000..854c901
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_syscalls.d.1m
@@ -0,0 +1,48 @@
+.TH j_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_syscalls.d - count Java methods and syscalls using DTrace.
+.SH SYNOPSIS
+.B j_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This traces Java methods if the hotspot provider exists (1.6.0) and
+the flag "+ExtendedDTraceProbes" is used. eg,
+java -XX:+ExtendedDTraceProbes classfile
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_syscalls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (method/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_syscolors.d.1m
new file mode 100644
index 0000000..e6bdebe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_syscolors.d.1m
@@ -0,0 +1,65 @@
+.TH j_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_syscolors.d - trace Java method flow plus syscalls, in color.
+.SH SYNOPSIS
+.B j_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This traces Java methods if the hotspot provider exists (1.6.0) and
+the flag "+ExtendedDTraceProbes" is used. eg,
+java -XX:+ExtendedDTraceProbes classfile
+
+This watches Java method entries and returns, and indents child
+method calls.
+
+If the flow appears to jump, check the TID column - the JVM may have
+switched to another thread.
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+TID
+Thread ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+TYPE
+Type of call (func/syscall)
+.TP
+NAME
+Java method or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+Changes in TID will appear to shuffle output, as we change from one thread
+depth to the next. See Docs/Notes/ALLjavaflow.txt for additional notes.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_thread.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_thread.d.1m
new file mode 100644
index 0000000..97caf9f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_thread.d.1m
@@ -0,0 +1,54 @@
+.TH j_thread.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_thread.d - snoop Java thread execution using DTrace.
+.SH SYNOPSIS
+.B j_thread.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0).
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_thread.d
+.PP
+.SH FIELDS
+.TP
+TIME
+Time string
+.TP
+PID
+Process ID
+.TP
+TID
+Thread ID
+.TP
+THREAD
+Thread name
+.SH LEGEND
+.TP
+=>
+thread start
+.TP
+<=
+thread end
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_thread.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/j_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/j_who.d.1m
new file mode 100644
index 0000000..97d68e8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/j_who.d.1m
@@ -0,0 +1,51 @@
+.TH j_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+j_who.d - trace Java calls by process using DTrace.
+.SH SYNOPSIS
+.B j_who.d
+
+.SH DESCRIPTION
+This traces activity from all Java processes on the system with hotspot
+provider support (1.6.0).
+
+The argument list is truncated at 55 characters (up to 80 is easily
+available). To easily read the full argument list, use other system tools;
+on Solaris use "pargs PID".
+.SH OS
+Solaris
+.SH STABILITY
+Evolving - uses the DTrace hotspot provider, which may change
+as additional features are introduced. Check Java/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B j_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of Java
+.TP
+UID
+User ID of the owner
+.TP
+CALLS
+Number of calls made (a measure of activity)
+.TP
+ARGS
+Process name and arguments
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+j_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_calldist.d.1m
new file mode 100644
index 0000000..fbd20fc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_calldist.d.1m
@@ -0,0 +1,46 @@
+.TH js_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_calldist.d - measure JavaScript elapsed times for types of operation.
+.SH SYNOPSIS
+.B js_calldist.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system with
+JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the JavaScript program
+.TP
+2
+Type of call (func/obj-new)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_calls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_calls.d.1m
new file mode 100644
index 0000000..c997293
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_calls.d.1m
@@ -0,0 +1,49 @@
+.TH js_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_calls.d - count JavaScript calls using DTrace.
+.SH SYNOPSIS
+.B js_calls.d
+
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are
+running with JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_calls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the JavaScript program
+.TP
+TYPE
+Type of call (func/obj-new/...)
+.TP
+NAME
+Descriptive name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_calltime.d.1m
new file mode 100644
index 0000000..785587b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH js_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_calltime.d - measure JavaScript elapsed times for types of operation.
+.SH SYNOPSIS
+.B js_calltime.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system with
+JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the JavaScript program
+.TP
+TYPE
+Type of call (func/obj-new/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_cpudist.d.1m
new file mode 100644
index 0000000..64a9aec
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_cpudist.d.1m
@@ -0,0 +1,46 @@
+.TH js_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_cpudist.d - measure JavaScript on-CPU times for types of operation.
+.SH SYNOPSIS
+.B js_cpudist.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system with
+JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the JavaScript program
+.TP
+2
+Type of call (func/obj-new)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_cputime.d.1m
new file mode 100644
index 0000000..2aaefc1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH js_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_cputime.d - measure JavaScript on-CPU times for types of operation.
+.SH SYNOPSIS
+.B js_cputime.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system with
+JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the JavaScript program
+.TP
+TYPE
+Type of call (func/obj-new/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_execs.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_execs.d.1m
new file mode 100644
index 0000000..61613c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_execs.d.1m
@@ -0,0 +1,46 @@
+.TH js_execs.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_execs.d - JavaScript execute snoop using DTrace.
+.SH SYNOPSIS
+.B js_execs.d
+
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are
+running with JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_execs.d
+.PP
+.SH FIELDS
+.TP
+TIME
+Time of event
+.TP
+FILE
+Filename of the JavaScript program
+.TP
+LINENO
+Line number in filename
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_execs.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_flow.d.1m
new file mode 100644
index 0000000..5d4ba0d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_flow.d.1m
@@ -0,0 +1,59 @@
+.TH js_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_flow.d - snoop JavaScript execution showing function flow using DTrace.
+.SH SYNOPSIS
+.B js_flow.d
+
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are running
+with JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+FUNC
+Function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_flowinfo.d.1m
new file mode 100644
index 0000000..1531ce5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_flowinfo.d.1m
@@ -0,0 +1,68 @@
+.TH js_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_flowinfo.d - JavaScript function flow with info using DTrace.
+.SH SYNOPSIS
+.B js_flowinfo.d
+
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are running
+with JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the JavScript program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func)
+.TP
+FUNC
+Function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_flowtime.d.1m
new file mode 100644
index 0000000..f90c999
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_flowtime.d.1m
@@ -0,0 +1,62 @@
+.TH js_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_flowtime.d - JavaScript function flow with delta times using DTrace.
+.SH SYNOPSIS
+.B js_flowtime.d
+
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are running
+with JavaScript provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FUNC
+Function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_objcpu.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_objcpu.d.1m
new file mode 100644
index 0000000..088fa06
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_objcpu.d.1m
@@ -0,0 +1,36 @@
+.TH js_objcpu.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_objcpu.d - measure JavaScript object creation on-CPU time using DTrace.
+.SH SYNOPSIS
+.B js_objcpu.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system
+with JavaScript provider support.
+
+Class names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_objcpu.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_objcpu.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_objgc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_objgc.d.1m
new file mode 100644
index 0000000..691883e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_objgc.d.1m
@@ -0,0 +1,60 @@
+.TH js_objgc.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_objgc.d - trace JavaScript Object GC using DTrace.
+.SH SYNOPSIS
+.B js_objgc.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all running browers on the system
+which support the JavaScript DTrace provider.
+
+This script provides information on which objects are not being garbage
+collected, an issue which causes the browser to steadily leak memory.
+We trace object creation (+1) and destruction (-1), and provide a
+summary each second of the running tally of the object class and
+originating filename. If over the period of several minutes an object
+type is still steadily increasing, then that would be of interest.
+Be patient, depending on the rate of object creation it can take over
+ten minutes for garbage collect to kick in.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_objgc.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename that contained the function
+.TP
+CLASS
+Class to which this new object belongs
+.TP
+TOTAL
+Object entropy (positive == uncollected)
+.SH NOTES
+
+\- it is possible that you will see negative entropy. That happens
+when you begin tracing after some objects have already been created,
+and then trace their destruction.
+\- there are other Things that GC handles, other than Objects; extra
+probes can be added to trace them, should the need arise.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_objgc.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_objnew.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_objnew.d.1m
new file mode 100644
index 0000000..83897b5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_objnew.d.1m
@@ -0,0 +1,46 @@
+.TH js_objnew.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_objnew.d - count JavaScript object creation using DTrace.
+.SH SYNOPSIS
+.B js_objnew.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers running on the system
+with JavaScript provider support.
+
+Filename and class names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_objnew.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the JavaScript program
+.TP
+CLASS
+Class of new object
+.TP
+COUNT
+Number of object creations during tracing
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_objnew.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_stat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_stat.d.1m
new file mode 100644
index 0000000..3234630
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_stat.d.1m
@@ -0,0 +1,52 @@
+.TH js_stat.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_stat.d - JavaScript operation stats using DTrace.
+.SH SYNOPSIS
+.B js_stat.d
+[interval [count]]
+.SH DESCRIPTION
+This traces activity from all browsers on the system that are
+running with JavaScript provider support.
+
+The numbers are counts for the interval specified. The default interval
+is 1 second.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_stat.d
+.PP
+.SH FIELDS
+.TP
+EXEC/s
+JavaScript programs executed per second
+.TP
+FUNCS/s
+Functions called, per second
+.TP
+OBJNEW/s
+Objects created, per second
+.TP
+OBJFRE/s
+Objects freed (finalize), per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_stat.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/js_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/js_who.d.1m
new file mode 100644
index 0000000..119ea26
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/js_who.d.1m
@@ -0,0 +1,49 @@
+.TH js_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+js_who.d - trace JavaScript function execution by process using DTrace.
+.SH SYNOPSIS
+.B js_who.d
+
+.SH DESCRIPTION
+This traces JavaScript activity from all browsers on the system that are
+running with JavaScript provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace JavaScript provider, which may change
+as additional features are introduced. Check JavaScript/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B js_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of JavaScript
+.TP
+UID
+User ID of the owner
+.TP
+FUNCS
+Number of function calls
+.TP
+FILE
+Pathname of the JavaScript program
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+js_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/kill.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/kill.d.1m
new file mode 100644
index 0000000..e9e966a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/kill.d.1m
@@ -0,0 +1,53 @@
+.TH kill.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+kill.d \- snoop process signals as they occur. Uses DTrace.
+.SH SYNOPSIS
+.B kill.d
+.SH DESCRIPTION
+kill.d is a simple DTrace program to print details of process
+signals as they are sent, such as the PID source and destination,
+signal number and result.
+
+This program can be used to determine which process is sending
+signals to which other process.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+Default output, print process signals as they are sent.
+#
+.B kill.d
+.PP
+.SH FIELDS
+.TP
+FROM
+source PID
+.TP
+COMMAND
+source command name
+.TP
+TO
+destination PID
+.TP
+SIG
+destination signal ("9" for a kill -9)
+.TP
+RESULT
+result of signal (-1 is for failure)
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+kill.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/kstat_types.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/kstat_types.d.1m
new file mode 100644
index 0000000..8a2d119
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/kstat_types.d.1m
@@ -0,0 +1,50 @@
+.TH kstat_types.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+kstat_types.d \- Trace kstat reads with type info. Uses DTrace.
+.SH SYNOPSIS
+.B kstat_types.d
+.SH DESCRIPTION
+kstat is the Kernel Statistics framework, which is used by tools
+such as vmstat, iostat, mpstat and sar. Try running vmstat while
+kstat_types.d is tracing - you should see details of the kstat
+reads performed.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Trace kstat reads as they occur,
+#
+.B kstat_types.d
+.PP
+.SH FIELDS
+.TP
+CMD
+command name
+.TP
+CLASS
+kstat class (ks_class)
+.TP
+TYPE
+kstat type as a string (ks_type)
+.TP
+MOD:INS:NAME
+kstat module:instance:name
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+kstat_types.d will trace until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), kstat(1M), kstat(3KSTAT)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/lastwords.1m b/cddl/contrib/dtracetoolkit/Man/man1m/lastwords.1m
new file mode 100644
index 0000000..024234b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/lastwords.1m
@@ -0,0 +1,56 @@
+.TH lastwords 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+lastwords \- print syscalls before exit. Uses DTrace.
+.SH SYNOPSIS
+.B lastwords command
+.SH DESCRIPTION
+This prints the last few system calls for processes matching
+the given name, when they exit. This makes use of a ring buffer
+so that the impact on the system is minimised.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall and proc providers.
+.SH EXAMPLES
+.TP
+Catch last few syscalls for dying netscape processes,
+#
+.B lastwords netscape
+.PP
+.SH FIELDS
+.TP
+TIME
+time of syscall return, ns
+.TP
+PID
+process ID
+.TP
+EXEC
+process name (execname)
+.TP
+SYSCALL
+system call
+.TP
+RETURN
+return value for the system call
+.TP
+ERR
+errno for the system call
+.PP
+.SH BASED ON
+/usr/demo/dtrace/ring.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "Buffers and Buffering" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+lastwords will sample until a command with that name exits.
+.SH SEE ALSO
+dtruss(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/loads.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/loads.d.1m
new file mode 100644
index 0000000..f18d3b1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/loads.d.1m
@@ -0,0 +1,38 @@
+.TH loads.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+loads.d \- print load averages. Uses DTrace.
+.SH SYNOPSIS
+.B loads.d
+.SH DESCRIPTION
+These are the same load averages that the "uptime" command prints.
+The purpose of this script is to demonstrate fetching these values
+from the DTrace language.
+
+The first field is the 1 minute average, the second is the 5 minute,
+and the third is the 15 minute average. The value represents the average
+number of runnable threads in the system, a value higher than your
+CPU (core/hwthread) count may be a sign of CPU saturation.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses kernel symbols, which may change for a future version
+of this OS.
+.SH EXAMPLES
+.TP
+Print load averages,
+#
+.B loads.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+uptime(1), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/lockbydist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/lockbydist.d.1m
new file mode 100644
index 0000000..188c5a4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/lockbydist.d.1m
@@ -0,0 +1,54 @@
+.TH lockbydist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+lockbydist.d \- lock distrib. by process name. Uses DTrace.
+.SH SYNOPSIS
+.B lockbydist.d
+.SH DESCRIPTION
+lockbydist.d is a DTrace OneLiner to a report the time threads have
+spent blocked on adaptive mutexes, by process name.
+
+A distribution is printed to illustrate the number of blocks at
+different lengths in time. This helps us identify if there are many
+short blocks, or fewer large blocks.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the lockstat provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B lockbydist.d
+.PP
+.SH FIELDS
+.TP
+process name
+The process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+value
+The blocked time in nanoseconds
+.TP
+count
+The number of occurrences that were at least this size
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+lockbydist.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+lockstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/lockbyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/lockbyproc.d.1m
new file mode 100644
index 0000000..af6c911
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/lockbyproc.d.1m
@@ -0,0 +1,47 @@
+.TH lockbyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+lockbyproc.d \- lock time by process name. Uses DTrace.
+.SH SYNOPSIS
+.B lockbyproc.d
+.SH DESCRIPTION
+lockbyproc.d is a DTrace OneLiner to a report the total time threads
+have spent blocked on adaptive mutexes, by process name.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the lockstat provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B lockbyproc.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+This is the total length of time blocked, in nanoseconds.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+lockbyproc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+lockstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/minfbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/minfbypid.d.1m
new file mode 100644
index 0000000..45574f4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/minfbypid.d.1m
@@ -0,0 +1,46 @@
+.TH minfbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+minfbypid.d \- minor faults by process name. Uses DTrace.
+.SH SYNOPSIS
+.B minfbypid.d
+.SH DESCRIPTION
+minfbypid.d is a DTrace OneLiner to a report the number of minor
+faults by process name.
+
+This is based on a script from DExplorer.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B minfbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+MINFAULTS
+number of minor faults in this sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+minfbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/minfbyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/minfbyproc.d.1m
new file mode 100644
index 0000000..9045e48
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/minfbyproc.d.1m
@@ -0,0 +1,47 @@
+.TH minfbyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+minfbyproc.d \- minor faults by process name. Uses DTrace.
+.SH SYNOPSIS
+.B minfbyproc.d
+.SH DESCRIPTION
+minfbyproc.d is a DTrace OneLiner to a report the number of minor
+faults by process name.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B minfbyproc.d
+.PP
+.SH FIELDS
+.TP
+first field
+The process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+The number minor faults
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+minfbyproc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/mmapfiles.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/mmapfiles.d.1m
new file mode 100644
index 0000000..e4bb2c8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/mmapfiles.d.1m
@@ -0,0 +1,42 @@
+.TH mmapfiles.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+mmapfiles.d \- mmap'd files by process. Uses DTrace.
+.SH SYNOPSIS
+.B mmapfiles.d
+.SH DESCRIPTION
+This prints statistics on the pathnames that were mmap'd by processes.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B mmapfiles.d
+.PP
+.SH FIELDS
+.TP
+MMAPS
+number of mmaps
+.TP
+CMD
+process name
+.TP
+PATHNAME
+pathname of mmap'd file
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+mmapfiles.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/modcalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/modcalls.d.1m
new file mode 100644
index 0000000..af7722b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/modcalls.d.1m
@@ -0,0 +1,50 @@
+.TH modcalls.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+modcalls.d \- kernel function calls by module. Uses DTrace.
+.SH SYNOPSIS
+.B modcalls.d
+.SH DESCRIPTION
+modcalls.d is a DTrace OneLiner to a report of the number of
+kernel function calls by module.
+
+This script may be useful to determine whether drivers are "thinking" when
+troubleshooting driver issues.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Any
+.SH STABILITY
+stable - while this script uses the unstable fbt provider, it does so
+in a stable way.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B modcalls.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the module name, or kernel driver name. if a name is
+unfamiliar to you there may be a man page to explain what it is.
+.TP
+second field
+This is the number of function calls by this module.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+modcalls.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/newproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/newproc.d.1m
new file mode 100644
index 0000000..b3b979b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/newproc.d.1m
@@ -0,0 +1,54 @@
+.TH newproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+newproc.d \- snoop new processes. Uses DTrace.
+.SH SYNOPSIS
+.B newproc.d
+.SH DESCRIPTION
+newproc.d is a DTrace OneLiner to snoop new processes as they are run.
+The argument listing is printed.
+
+This is useful to identify short lived processes that are usually
+difficult to spot using traditional tools.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the proc provider.
+.SH EXAMPLES
+.TP
+This prints new processes until Ctrl\-C is hit.
+#
+.B newproc.d
+.PP
+.SH FIELDS
+.TP
+CPU
+The CPU that recieved the event
+.TP
+ID
+A DTrace probe ID for the event
+.TP
+FUNCTION:NAME
+The DTrace probe name for the event
+.TP
+remaining fields
+These contains the argument listing for the new process
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+newproc.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+execsnoop(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/nfswizard.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/nfswizard.d.1m
new file mode 100644
index 0000000..64d8e41
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/nfswizard.d.1m
@@ -0,0 +1,36 @@
+.TH nfswizard.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+nfswizard.d \- nfs client activity wizard. Uses DTrace.
+.SH SYNOPSIS
+.B nfswizard.d
+.SH DESCRIPTION
+This examines activity caused by NFS client processes on the same server
+that you are running this script on. A detailed report is generated
+to explain various details of NFS client activity, including response
+times and file access.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.PP
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample NFS client activity, then print a report after Ctrl\-C,
+#
+.B nfswizard.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+nfswizard.d will sample activity until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/opensnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/opensnoop.1m
new file mode 100644
index 0000000..bc449c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/opensnoop.1m
@@ -0,0 +1,139 @@
+.TH opensnoop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+opensnoop \- snoop file opens as they occur. Uses DTrace.
+.SH SYNOPSIS
+.B opensnoop
+[\-a|\-A|\-ceghsvxZ] [\-f pathname] [\-n name] [\-p PID]
+.SH DESCRIPTION
+opensnoop tracks file opens. As a process issues a file open, details
+such as UID, PID and pathname are printed out.
+
+The returned file descriptor is printed,
+a value of -1 indicates an error. This can be useful
+for troubleshooting to determine if appliacions are attempting to
+open files that do not exist.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-A
+dump all data, space delimited
+.TP
+\-c
+print current working directory of process
+.TP
+\-e
+print errno value
+.TP
+\-g
+print full command arguments
+.TP
+\-s
+print start time, us
+.TP
+\-v
+print start time, string
+.TP
+\-x
+only print failed opens
+.TP
+\-Z
+print zonename
+.TP
+\-f pathname
+file pathname to snoop
+.TP
+\-n name
+process name to snoop
+.TP
+\-p PID
+process ID to snoop
+.PP
+.SH EXAMPLES
+.TP
+Default output, print file opens by process as they occur,
+#
+.B opensnoop
+.PP
+.TP
+Print human readable timestamps,
+#
+.B opensnoop
+\-v
+.PP
+.TP
+See error codes,
+#
+.B opensnoop
+\-e
+.PP
+.TP
+Snoop this file only,
+#
+.B opensnoop
+\-f /etc/passwd
+.PP
+.SH FIELDS
+.TP
+ZONE
+Zone name
+.TP
+UID
+User ID
+.TP
+PID
+Process ID
+.TP
+PPID
+Parent Process ID
+.TP
+FD
+File Descriptor (-1 is error)
+.TP
+ERR
+errno value (see /usr/include/sys/errno.h)
+.TP
+CWD
+current working directory of process
+.TP
+PATH
+pathname for file open
+.TP
+COMM
+command name for the process
+.TP
+ARGS
+argument listing for the process
+.TP
+TIME
+timestamp for the open event, us
+.TP
+STRTIME
+timestamp for the open event, string
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+opensnoop will run forever until Ctrl\-C is hit.
+.SH BUGS
+occasionally the pathname for the file open cannot be read
+and the following error will be seen,
+
+dtrace: error on enabled probe ID 6 (...): invalid address
+
+this is normal behaviour.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pathopens.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pathopens.d.1m
new file mode 100644
index 0000000..cf043bd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pathopens.d.1m
@@ -0,0 +1,38 @@
+.TH pathopens.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pathopens.d \- full pathnames opened ok count. Uses DTrace.
+.SH SYNOPSIS
+.B pathopens.d
+.SH DESCRIPTION
+This program prints a count of the number of times files have been
+successfully opened. This is somewhat special in that the full pathname
+is calculated, even if the file open referred to a relative pathname.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B pathopens.d
+.PP
+.SH FIELDS
+.TP
+PATHNAME
+full pathname
+.TP
+COUNT
+number of successful opens
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pathopens.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+opensnoop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pfilestat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pfilestat.1m
new file mode 100644
index 0000000..8780c2e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pfilestat.1m
@@ -0,0 +1,87 @@
+.TH pfilestat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pfilestat \- show I/O latency break down by FD. Uses DTrace.
+.SH SYNOPSIS
+.B pfilestat [\-r|\-w] pid
+.SH DESCRIPTION
+This prints I/O statistics for each file descriptor within a process.
+In particular, the time break down during read() and write() events is
+measured.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-r
+reads only
+.TP
+\-w
+writes only
+.TP
+pid
+process ID to examine
+.PP
+.SH EXAMPLES
+.TP
+Sample both read and write activity for PID 81,
+#
+.B pfilestat 81
+.TP
+Sample reads only for PID 81,
+#
+.B pfilestat
+\-r 81
+.PP
+.SH FIELDS
+.TP
+STATE
+microstate. see STATES below.
+.TP
+FDUM
+file Descriptor ID
+.TP
+Time
+percentage of wallclock time in each STATE
+.TP
+File
+Name of file, if known
+.PP
+.SH STATES
+.TP
+read
+Time spent during the execution of the read() syscall.
+.TP
+write
+Time spent during the execution of the write() syscall.
+.TP
+waitcpu
+Latency spent waiting to be scheduled after becoming runnable.
+.TP
+running
+Process running user-mode code.
+.TP
+sleep-r
+Process sleeping on reads.
+.TP
+sleep-w
+Process sleeping on writes.
+.PP
+.SH DOCUMENTATION
+pfilestat is discussed and demonstrated in Solaris Internals 2nd edition,
+volume 2.
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pfilestat will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Richard McDougall
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbypid.d.1m
new file mode 100644
index 0000000..fdaa297
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbypid.d.1m
@@ -0,0 +1,47 @@
+.TH pgpginbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pgpginbypid.d \- pages paged in by PID. Uses DTrace.
+.SH SYNOPSIS
+.B pgpginbypid.d
+.SH DESCRIPTION
+pgpginbypid.d reports the rumber of pages paged in from the disks
+by process ID. This is an indicator that processes are reading
+from the disks.
+
+This is based on a script from DExplorer.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B pgpginbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+PAGES
+number of pages paged in
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pgpginbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1m), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbyproc.d.1m
new file mode 100644
index 0000000..413043a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pgpginbyproc.d.1m
@@ -0,0 +1,50 @@
+.TH pgpginbyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pgpginbyproc.d \- pages pagedin by process name. Uses DTrace.
+.SH SYNOPSIS
+.B pgpginbyproc.d
+.SH DESCRIPTION
+pgpginbyproc.d is a DTrace OneLiner to a report the number of pages
+paged in by process name.
+
+This may be one way to help identify the process responsible for
+causing heavy read traffic to the disks.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B pgpginbyproc.d
+.PP
+.SH FIELDS
+.TP
+first field
+The process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+The number of pages paged in
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pgpginbyproc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1m), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_calldist.d.1m
new file mode 100644
index 0000000..065d6db
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_calldist.d.1m
@@ -0,0 +1,49 @@
+.TH php_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_calldist.d - measure PHP elapsed times for functions.
+.SH SYNOPSIS
+.B php_calldist.d
+
+.SH DESCRIPTION
+This traces PHP activity from all programs running on the system with
+PHP provider support.
+
+This script prints distribution plots of elapsed time for PHP
+operations. Use php_calltime.d for summary reports.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the PHP program
+.TP
+2
+Type of call (func)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_calltime.d.1m
new file mode 100644
index 0000000..f090b6e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH php_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_calltime.d - measure PHP elapsed times for functions.
+.SH SYNOPSIS
+.B php_calltime.d
+
+.SH DESCRIPTION
+This traces PHP activity from all programs running on the system with
+PHP provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the PHP program
+.TP
+TYPE
+Type of call (func/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_cpudist.d.1m
new file mode 100644
index 0000000..54ea0d1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_cpudist.d.1m
@@ -0,0 +1,49 @@
+.TH php_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_cpudist.d - measure PHP on-CPU times for functions.
+.SH SYNOPSIS
+.B php_cpudist.d
+
+.SH DESCRIPTION
+This traces PHP activity from all programs running on the system with
+PHP provider support.
+
+This script prints distribution plots of elapsed time for PHP
+operations. Use php_cputime.d for summary reports.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the PHP program
+.TP
+2
+Type of call (func)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_cputime.d.1m
new file mode 100644
index 0000000..2020969
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH php_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_cputime.d - measure PHP on-CPU times for functions.
+.SH SYNOPSIS
+.B php_cputime.d
+
+.SH DESCRIPTION
+This traces PHP activity from all programs running on the system with
+PHP provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the PHP program
+.TP
+TYPE
+Type of call (func/total)
+.TP
+NAME
+Name of call (function name)
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_flow.d.1m
new file mode 100644
index 0000000..bda09e3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_flow.d.1m
@@ -0,0 +1,60 @@
+.TH php_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_flow.d - snoop PHP execution showing function flow.
+.SH SYNOPSIS
+.B php_flow.d
+
+.SH DESCRIPTION
+This traces PHP activity from all PHP programs on the system
+running with PHP provider support.
+
+This watches PHP function entries and returns, and indents child
+function calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+FUNC
+Function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_flowinfo.d.1m
new file mode 100644
index 0000000..2e9282e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_flowinfo.d.1m
@@ -0,0 +1,68 @@
+.TH php_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_flowinfo.d - snoop PHP function flow with info using DTrace.
+.SH SYNOPSIS
+.B php_flowinfo.d
+
+.SH DESCRIPTION
+This traces activity from all PHP programs on the system that are
+running with PHP provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the PHP program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func)
+.TP
+FUNC
+PHP function
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_flowtime.d.1m
new file mode 100644
index 0000000..f30c283
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_flowtime.d.1m
@@ -0,0 +1,65 @@
+.TH php_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_flowtime.d - snoop PHP functions with flow and delta times.
+.SH SYNOPSIS
+.B php_flowtime.d
+
+.SH DESCRIPTION
+This traces shell activity from PHP programs on the system that are
+running with PHP provider support.
+
+This watches PHP function entries and returns, and indents child
+function calls.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FUNC
+PHP function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_funccalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_funccalls.d.1m
new file mode 100644
index 0000000..eb01963
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_funccalls.d.1m
@@ -0,0 +1,43 @@
+.TH php_funccalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_funccalls.d - measure PHP function calls using DTrace.
+.SH SYNOPSIS
+.B php_funccalls.d
+
+.SH DESCRIPTION
+This traces PHP activity from all running programs on the system
+which support the PHP DTrace provider.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_funccalls.d
+.PP
+.SH FIELDS
+.TP
+FUNC
+PHP function name
+.TP
+CALLS
+Function calls during this sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_funccalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_malloc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_malloc.d.1m
new file mode 100644
index 0000000..a11944d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_malloc.d.1m
@@ -0,0 +1,39 @@
+.TH php_malloc.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_malloc.d - PHP libc malloc analysis.
+.SH SYNOPSIS
+.B php_malloc.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This is an expiremental script to identify who is calling malloc() for
+memory allocation, and to print distribution plots of the requested bytes.
+If a malloc() occured while in a PHP function, then that function is
+identified as responsible; else the caller of malloc() is identified as
+responsible - which will be a function from the PHP engine.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_malloc.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_malloc.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_syscalls.d.1m
new file mode 100644
index 0000000..e2b10b0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_syscalls.d.1m
@@ -0,0 +1,54 @@
+.TH php_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_syscalls.d - count PHP function calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B php_syscalls.d
+
+.SH DESCRIPTION
+This traces syscalls that occured during a PHP function call.
+
+Filename and function names are printed if available.
+The filename for syscalls may be printed as "php", if the program
+was invoked using the form "php filename" rather than running the
+program with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_syscalls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+FILE
+Filename of the PHP program
+.TP
+TYPE
+Type of call (func/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_syscolors.d.1m
new file mode 100644
index 0000000..0a29ffb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_syscolors.d.1m
@@ -0,0 +1,61 @@
+.TH php_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_syscolors.d - trace PHP function flow plus syscalls, in color.
+.SH SYNOPSIS
+.B php_syscolors.d
+
+.SH DESCRIPTION
+This watches PHP function entries and returns, and indents child
+function calls.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the PHP program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func/syscall)
+.TP
+NAME
+PHP function or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/php_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/php_who.d.1m
new file mode 100644
index 0000000..9aacba6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/php_who.d.1m
@@ -0,0 +1,49 @@
+.TH php_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+php_who.d - trace PHP function execution by process using DTrace.
+.SH SYNOPSIS
+.B php_who.d
+
+.SH DESCRIPTION
+This traces PHP activity from all PHP programs on the system that are
+running with PHP provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Php provider, which may change
+as additional features are introduced. Check Php/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B php_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of PHP
+.TP
+UID
+User ID of the owner
+.TP
+FUNCS
+Number of function calls
+.TP
+FILE
+Pathname of the PHP program
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+php_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pidpersec.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pidpersec.d.1m
new file mode 100644
index 0000000..4040ae5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pidpersec.d.1m
@@ -0,0 +1,42 @@
+.TH pidpersec.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pidpersec.d \- print new PIDs per sec. Uses DTrace.
+.SH SYNOPSIS
+.B pidpersec.d
+.SH DESCRIPTION
+This script prints the number of new processes created per second.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the proc provider.
+.SH EXAMPLES
+.TP
+Print PID statistics per second,
+#
+.B pidpersec.d
+.PP
+.SH FIELDS
+.TP
+TIME
+time, as a string
+.TP
+LASTPID
+last PID created
+.TP
+PID/s
+Number of processes created per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pidpersec.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+execsnoop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_calldist.d.1m
new file mode 100644
index 0000000..ad2d1b8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_calldist.d.1m
@@ -0,0 +1,49 @@
+.TH pl_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_calldist.d - measure Perl elapsed times for subroutines.
+.SH SYNOPSIS
+.B pl_calldist.d
+
+.SH DESCRIPTION
+This traces Perl activity from all programs running on the system with
+Perl provider support.
+
+This script prints distribution plots of elapsed time for Perl subroutines.
+Use pl_calltime.d for summary reports.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Perl program
+.TP
+2
+Type of call (sub)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_calltime.d.1m
new file mode 100644
index 0000000..7de6eaf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH pl_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_calltime.d - measure Perl elapsed times for subroutines.
+.SH SYNOPSIS
+.B pl_calltime.d
+
+.SH DESCRIPTION
+This traces Perl activity from all programs running on the system with
+Perl provider support.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Perl program
+.TP
+TYPE
+Type of call (sub/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_cpudist.d.1m
new file mode 100644
index 0000000..6df61f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_cpudist.d.1m
@@ -0,0 +1,49 @@
+.TH pl_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_cpudist.d - measure Perl on-CPU times for subroutines.
+.SH SYNOPSIS
+.B pl_cpudist.d
+
+.SH DESCRIPTION
+This traces Perl activity from all programs running on the system with
+Perl provider support.
+
+This script prints distribution plots of elapsed time for Perl subrotines.
+Use pl_cputime.d for summary reports.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Perl program
+.TP
+2
+Type of call (sub)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_cputime.d.1m
new file mode 100644
index 0000000..f8cf75a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH pl_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_cputime.d - measure Perl on-CPU times for subroutines.
+.SH SYNOPSIS
+.B pl_cputime.d
+
+.SH DESCRIPTION
+This traces Perl activity from all programs running on the system with
+Perl provider support.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Perl program
+.TP
+TYPE
+Type of call (sub/total)
+.TP
+NAME
+Name of call (subroutine name)
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flow.d.1m
new file mode 100644
index 0000000..d66e493
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flow.d.1m
@@ -0,0 +1,60 @@
+.TH pl_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_flow.d - snoop Perl execution showing subroutine flow.
+.SH SYNOPSIS
+.B pl_flow.d
+
+.SH DESCRIPTION
+This traces Perl activity from all Perl programs on the system
+running with Perl provider support.
+
+This watches Perl subroutine entries and returns, and indents child
+subroutine calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this subroutine belongs to
+.TP
+SUB
+Subroutine name
+.SH LEGEND
+.TP
+\->
+subroutine entry
+.TP
+<\-
+subroutine return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowinfo.d.1m
new file mode 100644
index 0000000..0bf1384
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowinfo.d.1m
@@ -0,0 +1,68 @@
+.TH pl_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_flowinfo.d - snoop Perl subroutine flow with info using DTrace.
+.SH SYNOPSIS
+.B pl_flowinfo.d
+
+.SH DESCRIPTION
+This traces activity from all Perl programs on the system that are
+running with Perl provider support.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Perl program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (sub)
+.TP
+SUB
+Perl subroutine
+.SH LEGEND
+.TP
+\->
+subroutine entry
+.TP
+<\-
+subroutine return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowtime.d.1m
new file mode 100644
index 0000000..59acddf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_flowtime.d.1m
@@ -0,0 +1,65 @@
+.TH pl_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_flowtime.d - snoop Perl subroutines with flow and delta times.
+.SH SYNOPSIS
+.B pl_flowtime.d
+
+.SH DESCRIPTION
+This traces shell activity from Perl programs on the system that are
+running with Perl provider support.
+
+This watches Perl subroutine entries and returns, and indents child
+subroutine calls.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this subroutine belongs to
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+SUB
+Perl subroutine name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_malloc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_malloc.d.1m
new file mode 100644
index 0000000..babee557
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_malloc.d.1m
@@ -0,0 +1,39 @@
+.TH pl_malloc.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_malloc.d - Perl libc malloc analysis.
+.SH SYNOPSIS
+.B pl_malloc.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This is an expiremental script to identify who is calling malloc() for
+memory allocation, and to print distribution plots of the requested bytes.
+If a malloc() occured while in a Perl subroutine, then that subroutine is
+identified as responsible; else the caller of malloc() is identified as
+responsible - which will be a function from the Perl engine.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_malloc.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_malloc.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_subcalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_subcalls.d.1m
new file mode 100644
index 0000000..710b39d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_subcalls.d.1m
@@ -0,0 +1,43 @@
+.TH pl_subcalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_subcalls.d - measure Perl subroutine calls using DTrace.
+.SH SYNOPSIS
+.B pl_subcalls.d
+
+.SH DESCRIPTION
+This traces Perl activity from all running programs on the system
+which support the Perl DTrace provider.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_subcalls.d
+.PP
+.SH FIELDS
+.TP
+SUB
+Perl subroutine name
+.TP
+CALLS
+Subroutine calls during this sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_subcalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscalls.d.1m
new file mode 100644
index 0000000..bd35e5c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscalls.d.1m
@@ -0,0 +1,49 @@
+.TH pl_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_syscalls.d - count Perl subroutine calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B pl_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+Filename and subroutine names are printed if available.
+The filename for syscalls may be printed as "perl", if the program
+was invoked using the form "perl filename" rather than running the
+program with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_syscalls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Perl program
+.TP
+TYPE
+Type of call (sub/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscolors.d.1m
new file mode 100644
index 0000000..5c4c4ba
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_syscolors.d.1m
@@ -0,0 +1,61 @@
+.TH pl_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_syscolors.d - trace Perl subroutine flow plus syscalls, in color.
+.SH SYNOPSIS
+.B pl_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This watches Perl subroutine entries and returns, and indents child
+subroutine calls.
+
+Filename and subroutine names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Perl program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (sub/syscall)
+.TP
+NAME
+Perl subroutine or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pl_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pl_who.d.1m
new file mode 100644
index 0000000..9239a70
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pl_who.d.1m
@@ -0,0 +1,49 @@
+.TH pl_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+pl_who.d - trace Perl subroutine execution by process using DTrace.
+.SH SYNOPSIS
+.B pl_who.d
+
+.SH DESCRIPTION
+This traces Perl activity from all Perl programs on the system that are
+running with Perl provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Perl provider, which may change
+as additional features are introduced. Check Perl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B pl_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of Perl
+.TP
+UID
+User ID of the owner
+.TP
+SUBS
+Number of subroutine calls
+.TP
+FILE
+Pathname of the Perl program
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+pl_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/priclass.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/priclass.d.1m
new file mode 100644
index 0000000..d726ac2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/priclass.d.1m
@@ -0,0 +1,66 @@
+.TH priclass.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+priclass.d \- priority distribution by scheduling class. Uses DTrace.
+.SH SYNOPSIS
+.B priclass.d
+.SH DESCRIPTION
+This is a simple DTrace script that samples at 1000 Hz the current
+thread's scheduling class and priority. A distribution plot is printed.
+
+With priorities, the higher the priority the better chance the thread
+has of being scheduled.
+
+This idea came from the script /usr/demo/dtrace/pri.d, which
+produces similar output for priority changes, not samples.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B priclass.d
+.PP
+.SH FIELDS
+.TP
+value
+process priority
+.TP
+count
+number of samples of at least this priority
+.PP
+.SH SCHEDULING CLASSES
+.TP
+TS
+time sharing
+.TP
+IA
+interactive
+.TP
+RT
+real time
+.TP
+SYS
+system
+.TP
+FSS
+fair share scheduler
+.PP
+.SH BASED ON
+/usr/demo/dtrace/pri.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "profile Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+priclass.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+pridist.d(1M), dispadmin(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/pridist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/pridist.d.1m
new file mode 100644
index 0000000..1e7aba6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/pridist.d.1m
@@ -0,0 +1,55 @@
+.TH pridist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+pridist.d \- process priority distribution. Uses DTrace.
+.SH SYNOPSIS
+.B pridist.d
+.SH DESCRIPTION
+This is a simple DTrace script that samples at 1000 Hz which process
+is on the CPUs, and what the priority is. A distribution plot is printed.
+
+With priorities, the higher the priority the better chance the process
+(actually, thread) has of being scheduled.
+
+This idea came from the script /usr/demo/dtrace/profpri.d, which
+produces similar output for one particular PID.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B pridist.d
+.PP
+.SH FIELDS
+.TP
+CMD
+process name
+.TP
+PID
+process ID
+.TP
+value
+process priority
+.TP
+count
+number of samples of at least this priority
+.PP
+.SH BASED ON
+/usr/demo/dtrace/profpri.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "profile Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+pridist.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+dispadmin(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/procsystime.1m b/cddl/contrib/dtracetoolkit/Man/man1m/procsystime.1m
new file mode 100644
index 0000000..0df87cf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/procsystime.1m
@@ -0,0 +1,108 @@
+.TH procsystime 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+procsystime \- analyse system call times. Uses DTrace.
+.SH SYNOPSIS
+.B procsystime
+[\-acehoT] [ -p PID | -n name | command ]
+.SH DESCRIPTION
+procsystime prints details on system call times for processes,
+both the elapsed times and on-cpu times can be printed.
+
+The elapsed times are interesting, to help identify syscalls
+that take some time to complete (during which the process may
+have slept). CPU time helps us identify syscalls that
+are consuming CPU cycles to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-c
+print syscall counts
+.TP
+\-e
+print elapsed times, ns
+.TP
+\-o
+print CPU times, ns
+.TP
+\-T
+print totals
+.TP
+\-p PID
+examine this PID
+.TP
+\-n name
+examine processes which have this name
+.SH EXAMPLES
+.TP
+Print elapsed times for PID 1871,
+#
+.B procsystime
+\-p 1871
+.PP
+.TP
+Print elapsed times for processes called "tar",
+#
+.B procsystime
+\-n tar
+.PP
+.TP
+Print CPU times for "tar" processes,
+#
+.B procsystime
+\-on tar
+.PP
+.TP
+Print syscall counts for "tar" processes,
+#
+.B procsystime
+\-cn tar
+.PP
+.TP
+Print elapsed and CPU times for "tar" processes,
+#
+.B procsystime
+\-eon tar
+.PP
+.TP
+print all details for "bash" processes,
+#
+.B procsystime
+\-aTn bash
+.PP
+.TP
+run and print details for "df -h",
+#
+.B procsystime
+df \-h
+.PP
+.SH FIELDS
+.TP
+SYSCALL
+System call name
+.TP
+TIME (ns)
+Total time, nanoseconds
+.TP
+COUNT
+Number of occurrences
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+procsystime will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtruss(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/putnexts.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/putnexts.d.1m
new file mode 100644
index 0000000..5933567
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/putnexts.d.1m
@@ -0,0 +1,27 @@
+.TH putnexts.d 1m "$Date:: 2007-09-12 #$" "USER COMMANDS"
+.SH NAME
+putnexts.d -
+.SH SYNOPSIS
+.SH DESCRIPTION
+
+.SH OS
+Solaris
+.SH STABILITY
+stable -
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B putnexts.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+putnexts.d will run until Ctrl-C is hit.
+.SH AUTHOR
+
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_calldist.d.1m
new file mode 100644
index 0000000..1592af5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_calldist.d.1m
@@ -0,0 +1,49 @@
+.TH py_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_calldist.d - measure Python elapsed times for functions.
+.SH SYNOPSIS
+.B py_calldist.d
+
+.SH DESCRIPTION
+This traces Python activity from all programs running on the system with
+Python provider support.
+
+This script prints distribution plots of elapsed time for Python
+operations. Use py_calltime.d for summary reports.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Python program
+.TP
+2
+Type of call (func)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_calltime.d.1m
new file mode 100644
index 0000000..e055eb3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH py_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_calltime.d - measure Python elapsed times for functions.
+.SH SYNOPSIS
+.B py_calltime.d
+
+.SH DESCRIPTION
+This traces Python activity from all programs running on the system with
+Python provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Python program
+.TP
+TYPE
+Type of call (func/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_cpudist.d.1m
new file mode 100644
index 0000000..825fc64
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_cpudist.d.1m
@@ -0,0 +1,49 @@
+.TH py_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_cpudist.d - measure Python on-CPU times for functions.
+.SH SYNOPSIS
+.B py_cpudist.d
+
+.SH DESCRIPTION
+This traces Python activity from all programs running on the system with
+Python provider support.
+
+This script prints distribution plots of elapsed time for Python
+operations. Use py_cputime.d for summary reports.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Python program
+.TP
+2
+Type of call (func)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_cputime.d.1m
new file mode 100644
index 0000000..f926204
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH py_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_cputime.d - measure Python on-CPU times for functions.
+.SH SYNOPSIS
+.B py_cputime.d
+
+.SH DESCRIPTION
+This traces Python activity from all programs running on the system with
+Python provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Python program
+.TP
+TYPE
+Type of call (func/total)
+.TP
+NAME
+Name of call (function name)
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_flow.d.1m
new file mode 100644
index 0000000..3659e0f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_flow.d.1m
@@ -0,0 +1,60 @@
+.TH py_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_flow.d - snoop Python execution showing function flow.
+.SH SYNOPSIS
+.B py_flow.d
+
+.SH DESCRIPTION
+This traces Python activity from all Python programs on the system
+running with Python provider support.
+
+This watches Python function entries and returns, and indents child
+function calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+FUNC
+Function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_flowinfo.d.1m
new file mode 100644
index 0000000..4a25d0d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_flowinfo.d.1m
@@ -0,0 +1,68 @@
+.TH py_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_flowinfo.d - snoop Python function flow with info using DTrace.
+.SH SYNOPSIS
+.B py_flowinfo.d
+
+.SH DESCRIPTION
+This traces activity from all Python programs on the system that are
+running with Python provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Python program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func)
+.TP
+FUNC
+Python function
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_flowtime.d.1m
new file mode 100644
index 0000000..6788295
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_flowtime.d.1m
@@ -0,0 +1,65 @@
+.TH py_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_flowtime.d - snoop Python functions with flow and delta times.
+.SH SYNOPSIS
+.B py_flowtime.d
+
+.SH DESCRIPTION
+This traces shell activity from Python programs on the system that are
+running with Python provider support.
+
+This watches Python function entries and returns, and indents child
+function calls.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FUNC
+Python function name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_funccalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_funccalls.d.1m
new file mode 100644
index 0000000..8a54976
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_funccalls.d.1m
@@ -0,0 +1,43 @@
+.TH py_funccalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_funccalls.d - measure Python function calls using DTrace.
+.SH SYNOPSIS
+.B py_funccalls.d
+
+.SH DESCRIPTION
+This traces Python activity from all running programs on the system
+which support the Python DTrace provider.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_funccalls.d
+.PP
+.SH FIELDS
+.TP
+FUNC
+Python function name
+.TP
+CALLS
+Function calls during this sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_funccalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_malloc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_malloc.d.1m
new file mode 100644
index 0000000..4468da8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_malloc.d.1m
@@ -0,0 +1,39 @@
+.TH py_malloc.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_malloc.d - Python libc malloc analysis.
+.SH SYNOPSIS
+.B py_malloc.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This is an expiremental script to identify who is calling malloc() for
+memory allocation, and to print distribution plots of the requested bytes.
+If a malloc() occured while in a Python function, then that function is
+identified as responsible; else the caller of malloc() is identified as
+responsible - which will be a function from the Python engine.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_malloc.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_malloc.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_mallocstk.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_mallocstk.d.1m
new file mode 100644
index 0000000..fac0a17
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_mallocstk.d.1m
@@ -0,0 +1,33 @@
+.TH py_mallocstk.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_mallocstk.d - Python libc malloc analysis with full stack traces.
+.SH SYNOPSIS
+.B py_mallocstk.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_mallocstk.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_mallocstk.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_profile.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_profile.d.1m
new file mode 100644
index 0000000..282bf48
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_profile.d.1m
@@ -0,0 +1,54 @@
+.TH py_profile.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_profile.d - sample stack traces with Python translations using DTrace.
+.SH SYNOPSIS
+.B py_profile.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This samples stack traces for the process specified. This stack trace
+will cross the Python engine and system libraries, and insert
+translations for Python stack frames where appropriate. This is best
+explained with an example stack frame output,
+
+libpython2.4.so.1.0`PyEval_EvalFrame+0x2fbf
+[ ./func_loop.py:5 (func_c) ]
+libpython2.4.so.1.0`fast_function+0xa8
+libpython2.4.so.1.0`call_function+0xda
+libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+[ ./func_loop.py:11 (func_b) ]
+libpython2.4.so.1.0`fast_function+0xa8
+libpython2.4.so.1.0`call_function+0xda
+libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+[ ./func_loop.py:14 (func_a) ]
+libpython2.4.so.1.0`fast_function+0xa8
+libpython2.4.so.1.0`call_function+0xda
+libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+[ ./func_loop.py:16 (?) ]
+
+The lines in square brackets are the native Python frames, the rest
+are the Python engine.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_profile.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_profile.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_syscalls.d.1m
new file mode 100644
index 0000000..cd471234
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_syscalls.d.1m
@@ -0,0 +1,49 @@
+.TH py_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_syscalls.d - count Python function calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B py_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+Filename and function names are printed if available.
+The filename for syscalls may be printed as "python", if the program
+was invoked using the form "python filename" rather than running the
+program with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_syscalls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Python program
+.TP
+TYPE
+Type of call (func/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_syscolors.d.1m
new file mode 100644
index 0000000..210fa1b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_syscolors.d.1m
@@ -0,0 +1,61 @@
+.TH py_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_syscolors.d - trace Python function flow plus syscalls, in color.
+.SH SYNOPSIS
+.B py_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This watches Python function entries and returns, and indents child
+function calls.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Python program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func/syscall)
+.TP
+NAME
+Python function or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/py_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/py_who.d.1m
new file mode 100644
index 0000000..e88190e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/py_who.d.1m
@@ -0,0 +1,49 @@
+.TH py_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+py_who.d - trace Python function execution by process using DTrace.
+.SH SYNOPSIS
+.B py_who.d
+
+.SH DESCRIPTION
+This traces Python activity from all Python programs on the system that are
+running with Python provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Python provider, which may change
+as additional features are introduced. Check Python/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B py_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of Python
+.TP
+UID
+User ID of the owner
+.TP
+FUNCS
+Number of function calls
+.TP
+FILE
+Pathname of the Python program
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+py_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calldist.d.1m
new file mode 100644
index 0000000..57a9756
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calldist.d.1m
@@ -0,0 +1,49 @@
+.TH rb_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_calldist.d - measure Ruby elapsed times for types of operation.
+.SH SYNOPSIS
+.B rb_calldist.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+This script prints distribution plots of elapsed time for Ruby
+operations. Use rb_calltime.d for summary reports.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Ruby program
+.TP
+2
+Type of call (method/obj-new/gc)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_calls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calls.d.1m
new file mode 100644
index 0000000..3e328f3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calls.d.1m
@@ -0,0 +1,49 @@
+.TH rb_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_calls.d - count Ruby calls using DTrace.
+.SH SYNOPSIS
+.B rb_calls.d
+
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_calls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+TYPE
+Type of call (method/obj-new/...)
+.TP
+NAME
+Descriptive name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calltime.d.1m
new file mode 100644
index 0000000..0787a93
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH rb_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_calltime.d - measure Ruby elapsed times for types of operation.
+.SH SYNOPSIS
+.B rb_calltime.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+TYPE
+Type of call (method/obj-new/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_cpudist.d.1m
new file mode 100644
index 0000000..ff4f283
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_cpudist.d.1m
@@ -0,0 +1,49 @@
+.TH rb_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_cpudist.d - measure Ruby on-CPU times for types of operation.
+.SH SYNOPSIS
+.B rb_cpudist.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+This script prints distribution plots of elapsed time for Ruby
+operations. Use rb_cputime.d for summary reports.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Ruby program
+.TP
+2
+Type of call (method/obj-new/gc)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_cputime.d.1m
new file mode 100644
index 0000000..7e8302b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH rb_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_cputime.d - measure Ruby on-CPU times for types of operation.
+.SH SYNOPSIS
+.B rb_cputime.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+TYPE
+Type of call (method/obj-new/gc/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flow.d.1m
new file mode 100644
index 0000000..fa1f518
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flow.d.1m
@@ -0,0 +1,59 @@
+.TH rb_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_flow.d - snoop Ruby execution showing method flow using DTrace.
+.SH SYNOPSIS
+.B rb_flow.d
+
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this method belongs to
+.TP
+CLASS::METHOD
+Ruby classname and method
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowinfo.d.1m
new file mode 100644
index 0000000..08e124f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowinfo.d.1m
@@ -0,0 +1,68 @@
+.TH rb_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_flowinfo.d - snoop Ruby function (method) flow with info using DTrace.
+.SH SYNOPSIS
+.B rb_flowinfo.d
+
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Ruby program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (method)
+.TP
+NAME
+Ruby class and method name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowtime.d.1m
new file mode 100644
index 0000000..64425b3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_flowtime.d.1m
@@ -0,0 +1,62 @@
+.TH rb_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_flowtime.d - snoop Ruby function (method) flow using DTrace.
+.SH SYNOPSIS
+.B rb_flowtime.d
+
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this method belongs to
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+CLASS::METHOD
+Ruby class and method name
+.SH LEGEND
+.TP
+\->
+method entry
+.TP
+<\-
+method return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_funccalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_funccalls.d.1m
new file mode 100644
index 0000000..c4fe9fa
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_funccalls.d.1m
@@ -0,0 +1,46 @@
+.TH rb_funccalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_funccalls.d - count Ruby function (method) calls using DTrace.
+.SH SYNOPSIS
+.B rb_funccalls.d
+
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_funccalls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+METHOD
+Method name
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_funccalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_lines.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_lines.d.1m
new file mode 100644
index 0000000..4bdbabc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_lines.d.1m
@@ -0,0 +1,46 @@
+.TH rb_lines.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_lines.d - trace Ruby line execution by process using DTrace.
+.SH SYNOPSIS
+.B rb_who.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_lines.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+LINE
+Line number
+.TP
+COUNT
+Number of times a line was executed
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_lines.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_malloc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_malloc.d.1m
new file mode 100644
index 0000000..d86bc46
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_malloc.d.1m
@@ -0,0 +1,47 @@
+.TH rb_malloc.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_malloc.d - Ruby operations and libc malloc statistics.
+.SH SYNOPSIS
+.B rb_malloc.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_malloc.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the Ruby program
+.TP
+2
+Type of operation (method/objnew/startup)
+.TP
+3
+Name of operation
+.SH WARNING
+This script is not 100% accurate; This prints libc malloc() byte
+distributions by "recent" Ruby operation, which we hope will be usually
+relevant. This is an experimental script that may be improved over time.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_malloc.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_objcpu.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_objcpu.d.1m
new file mode 100644
index 0000000..6d1d8b1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_objcpu.d.1m
@@ -0,0 +1,36 @@
+.TH rb_objcpu.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_objcpu.d - measure Ruby object creation on-CPU time using DTrace.
+.SH SYNOPSIS
+.B rb_objcpu.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+Class names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_objcpu.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_objcpu.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_objnew.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_objnew.d.1m
new file mode 100644
index 0000000..e40f493
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_objnew.d.1m
@@ -0,0 +1,46 @@
+.TH rb_objnew.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_objnew.d - count Ruby object creation using DTrace.
+.SH SYNOPSIS
+.B rb_objnew.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all programs running on the system with
+Ruby provider support.
+
+Filename and class names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_objnew.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+CLASS
+Class of new object
+.TP
+COUNT
+Number of object creations during tracing
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_objnew.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_stat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_stat.d.1m
new file mode 100644
index 0000000..070faf4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_stat.d.1m
@@ -0,0 +1,66 @@
+.TH rb_stat.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_stat.d - Ruby operation stats using DTrace.
+.SH SYNOPSIS
+.B rb_stat.d
+[interval [count]]
+.SH DESCRIPTION
+This traces activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+The numbers are counts for the interval specified. The default interval
+is 1 second.
+
+If you see a count in "EXECS" but not in the other columns, then your
+Ruby software is probably not running with the DTrace Ruby provider.
+See Ruby/Readme.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_stat.d
+.PP
+.SH FIELDS
+.TP
+EXEC/s
+Ruby programs executed per second, including
+those without Ruby provider support
+.TP
+METHOD/s
+Methods called, per second
+.TP
+OBJNEW/s
+Objects created, per second
+.TP
+OBJFRE/s
+Objects freed, per second
+.TP
+RAIS/s
+Raises, per second
+.TP
+RESC/s
+Rescues, per second
+.TP
+GC/s
+Garbage collects, per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_stat.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscalls.d.1m
new file mode 100644
index 0000000..9fbe81d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscalls.d.1m
@@ -0,0 +1,49 @@
+.TH rb_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_syscalls.d - count Ruby calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B rb_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+Filename and method names are printed if available.
+The filename for syscalls may be printed as "ruby", if the program
+was invoked using the form "ruby filename" rather than running the
+program with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_syscalls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the Ruby program
+.TP
+TYPE
+Type of call (method/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscolors.d.1m
new file mode 100644
index 0000000..bd18be9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_syscolors.d.1m
@@ -0,0 +1,61 @@
+.TH rb_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_syscolors.d - trace Ruby method flow plus syscalls, in color.
+.SH SYNOPSIS
+.B rb_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This watches Ruby method entries and returns, and indents child
+function calls.
+
+Filename and method names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the Ruby program
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (method/line/syscall)
+.TP
+NAME
+Ruby method or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rb_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rb_who.d.1m
new file mode 100644
index 0000000..5dd13d5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rb_who.d.1m
@@ -0,0 +1,49 @@
+.TH rb_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+rb_who.d - trace Ruby line execution by process using DTrace.
+.SH SYNOPSIS
+.B rb_who.d
+
+.SH DESCRIPTION
+This traces Ruby activity from all Ruby programs on the system that are
+running with Ruby provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Ruby provider, which may change
+as additional features are introduced. Check Ruby/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rb_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of Ruby
+.TP
+UID
+User ID of the owner
+.TP
+LINES
+Number of times a line was executed
+.TP
+FILE
+Pathname of the Ruby program
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+rb_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/readbytes.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/readbytes.d.1m
new file mode 100644
index 0000000..697339d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/readbytes.d.1m
@@ -0,0 +1,47 @@
+.TH readbytes.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+readbytes.d \- read bytes by process name. Uses DTrace.
+.SH SYNOPSIS
+.B readbytes.d
+.SH DESCRIPTION
+readbytes.d is a DTrace OneLiner to a report of the number of
+bytes read by process name.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B readbytes.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+This is the number of bytes read.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+readbytes.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/readdist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/readdist.d.1m
new file mode 100644
index 0000000..e11b21c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/readdist.d.1m
@@ -0,0 +1,54 @@
+.TH readdist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+readdist.d \- read distrib. by process name. Uses DTrace.
+.SH SYNOPSIS
+.B readdist.d
+.SH DESCRIPTION
+readdist.d is a DTrace OneLiner to a report the read size and
+number of occurrences as a frequency distribution by process name.
+
+This can be useful to identify the behaviour of processes
+that are doing reads. Are they using many small reads, or
+fewer large reads.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B readdist.d
+.PP
+.SH FIELDS
+.TP
+process name
+The process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+value
+The size in bytes
+.TP
+count
+The number of occurrences that were at least this size
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+readdist.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rfileio.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rfileio.d.1m
new file mode 100644
index 0000000..08c25e9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rfileio.d.1m
@@ -0,0 +1,41 @@
+.TH rfileio.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rfileio.d \- read file I/O stats, with cache miss rate. Uses DTrace.
+.SH SYNOPSIS
+.B rfileio.d
+.SH DESCRIPTION
+This script provides statistics on the number of reads and the bytes
+read from filesystems (logical), and the number of bytes read from
+disk (physical). A summary is printed every five seconds by file.
+
+A total miss-rate is also provided for the file system cache.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Print a summary of activity every five seconds.
+#
+.B rfileio.d
+.PP
+.SH IDEA
+Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rfileio.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rfsio.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rfsio.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rfsio.d.1m
new file mode 100644
index 0000000..ecbb786
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rfsio.d.1m
@@ -0,0 +1,41 @@
+.TH rfsio.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rfsio.d \- read FS I/O stats, with cache miss rate. Uses DTrace.
+.SH SYNOPSIS
+.B rfsio.d
+.SH DESCRIPTION
+This script provides statistics on the number of reads and the bytes
+read from filesystems (logical), and the number of bytes read from
+disk (physical). A summary is printed every five seconds by filesystem.
+
+A total miss-rate is also provided for the file system cache.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Print a summary of activity every five seconds.
+#
+.B rfsio.d
+.PP
+.SH IDEA
+Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rfsio.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rfileio.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/runocc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/runocc.d.1m
new file mode 100644
index 0000000..0ba529f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/runocc.d.1m
@@ -0,0 +1,46 @@
+.TH runocc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+runocc.d \- run queue occupancy by CPU. Uses DTrace.
+.SH SYNOPSIS
+.B runocc.d
+.SH DESCRIPTION
+This prints the dispatcher run queue occupancy by CPU each second.
+A consistant run queue occupancy is a sign of CPU saturation.
+
+The value is similar to that seen in "sar -q", however this is
+calculated in a more accurate manner - sampling at 1000 Hertz.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+Print %runocc by CPU every second,
+#
+.B runocc.d
+.PP
+.SH FIELDS
+.TP
+CPU
+cpu ID
+.TP
+%runocc
+percent run queue occupancy, sampled at 1000 Hertz
+.PP
+.SH SEE ALSO
+Solaris Internals 2nd Ed, vol 2, CPU chapter
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+runocc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rwbbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rwbbypid.d.1m
new file mode 100644
index 0000000..36ab3f2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rwbbypid.d.1m
@@ -0,0 +1,48 @@
+.TH rwbbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rwbbypid.d \- read/write bytes by PID. Uses DTrace.
+.SH SYNOPSIS
+.B rwbbypid.d
+.SH DESCRIPTION
+This script tracks the bytes read and written at the syscall level
+by processes, printing the totals in a report. This is tracking the
+successful number of bytes read or written.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B rwbbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+DIR
+direction, Read or Write
+.TP
+BYTES
+total bytes
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rwbbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rwbypid.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rwbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rwbypid.d.1m
new file mode 100644
index 0000000..869eb80
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rwbypid.d.1m
@@ -0,0 +1,48 @@
+.TH rwbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rwbypid.d \- read/write calls by PID. Uses DTrace.
+.SH SYNOPSIS
+.B rwbypid.d
+.SH DESCRIPTION
+This script tracks the number of reads and writes at the syscall level
+by processes, printing the totals in a report. This matches reads
+and writes whether they succeed or not.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B rwbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+DIR
+direction, Read or Write
+.TP
+COUNT
+total calls
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rwbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rwbbypid.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rwbytype.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rwbytype.d.1m
new file mode 100644
index 0000000..85c8194
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rwbytype.d.1m
@@ -0,0 +1,54 @@
+.TH rwbytype.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rwbytype.d \- read/write bytes by vnode type. Uses DTrace.
+.SH SYNOPSIS
+.B rwbytype.d
+.SH DESCRIPTION
+This program identifies the vnode type of read/write activity - whether
+that is for regular files, sockets, character special devices, etc. This
+is measuring at the application level, so file activity may well be
+cached by the system.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B rwbytype.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+VNODE
+vnode type (describes I/O type)
+.TP
+DIR
+direction, Read or Write
+.TP
+BYTES
+total bytes
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rwbytype.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rwbypid.d(1M), rwbbypid.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rwsnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rwsnoop.1m
new file mode 100644
index 0000000..d6e5441
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rwsnoop.1m
@@ -0,0 +1,104 @@
+.TH rwsnoop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rwsnoop \- snoop read/write events. Uses DTrace.
+.SH SYNOPSIS
+.B rwsnoop
+[\-jPtvZ] [\-n name] [\-p PID]
+.SH DESCRIPTION
+This is measuring reads and writes at the application level. This
+matches the syscalls read, write, pread and pwrite.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-j
+print project ID
+.TP
+\-P
+print parent process ID
+.TP
+\-t
+print timestamp, us
+.TP
+\-v
+print time, string
+.TP
+\-Z
+print zone ID
+.TP
+\-n name
+process name to track
+.TP
+\-p PID
+PID to track
+.PP
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B rwsnoop
+.TP
+Print zone ID,
+#
+.B rwsnoop
+-\Z
+.TP
+Monitor processes named "bash",
+#
+.B rwsnoop
+\-n bash
+.PP
+.SH FIELDS
+.TP
+TIME
+timestamp, us
+.TP
+TIMESTR
+time, string
+.TP
+ZONE
+zone ID
+.TP
+PROJ
+project ID
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+PPID
+parent process ID
+.TP
+CMD
+command name for the process
+.TP
+D
+direction, Read or Write
+.TP
+BYTES
+total bytes during sample
+.TP
+FILE
+filename, if file based.
+Reads and writes that are not file based, for example with sockets, will
+print "<unknown>" as the filename.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rwsnoop will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+rwtop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/rwtop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/rwtop.1m
new file mode 100644
index 0000000..82af043
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/rwtop.1m
@@ -0,0 +1,115 @@
+.TH rwtop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+rwtop \- display top read/write bytes process. Uses DTrace.
+.SH SYNOPSIS
+.B rwtop
+[\-Cc] [\-j|\-Z] [\-n name] [\-p PID]
+[\-t top] [interval [count]]
+.SH DESCRIPTION
+This is measuring reads and writes at the application level.
+This matches read and write system calls.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-c
+print counts
+.TP
+\-j
+print project ID
+.TP
+\-Z
+print zone ID
+.TP
+\-n name
+process name to track
+.TP
+\-p PID
+PID to track
+.TP
+\-t top
+print top number only
+.PP
+.SH EXAMPLES
+.TP
+Default output, print summary every 5 seconds
+#
+.B rwtop
+.PP
+.TP
+One second samples,
+#
+.B rwtop
+1
+.TP
+Print top 10 lines only,
+#
+.B rwtop
+\-t 10
+.TP
+Monitor processes named "bash",
+#
+.B rwtop
+\-n bash
+.TP
+Print 12 x 5 second samples, scrolling,
+#
+.B rwtop
+\-C 5 12
+.PP
+.SH FIELDS
+.TP
+PROJ
+project ID
+.TP
+ZONE
+zone ID
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+PPID
+parent process ID
+.TP
+CMD
+command name for the process
+.TP
+D
+direction, Read or Write
+.TP
+BYTES
+total bytes during sample
+.TP
+load
+1 minute load average
+.TP
+app_r
+total read Kb for sample
+.TP
+app_w
+total write Kb for sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+rwtop will run forever until Ctrl\-C is hit, or the specified
+interval is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iotop(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sampleproc.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sampleproc.1m
new file mode 100644
index 0000000..0ae3a2d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sampleproc.1m
@@ -0,0 +1,55 @@
+.TH sampleproc 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+sampleproc \- sample processes on the CPUs. Uses DTrace.
+.SH SYNOPSIS
+.B sampleproc [hertz]
+.SH DESCRIPTION
+This program samples which process is on each CPU, at a particular
+configurable rate. This can be used as an estimate for which process
+is consuming the most CPU time.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses the ncpus_online kernel symbol.
+.SH EXAMPLES
+.TP
+Sample at 100 hertz,
+#
+.B sampleproc
+.TP
+Sample at 400 hertz,
+#
+.B sampleproc
+400
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+COMMAND
+command name
+.TP
+COUNT
+number of samples
+.TP
+PERCENT
+percent of CPU usage
+.PP
+.SH BASED ON
+/usr/demo/dtrace/prof.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "profile Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+sampleproc will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sar-c.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sar-c.d.1m
new file mode 100644
index 0000000..10192fb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sar-c.d.1m
@@ -0,0 +1,62 @@
+.TH sar\-c.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+sar\-c.d \- sar \-c demo in DTrace. Uses DTrace.
+.SH SYNOPSIS
+.B sar\-c.d
+.SH DESCRIPTION
+This has been written to demonstrate fetching the same data as sar \-c
+from DTrace. This program is intended as a starting point for other
+DTrace scripts, by beginning with familiar statistics.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall and sysinfo providers.
+.SH EXAMPLES
+.TP
+Print system call counts every second,
+#
+.B sar\-c.d
+.PP
+.SH FIELDS
+.TP
+scall/s
+System calls
+.TP
+sread/s
+reads
+.TP
+swrit/s
+writes
+.TP
+fork/s
+forks
+.TP
+exec/s
+execs
+.TP
+rchar/s
+read characters
+.TP
+wchar/s
+write characters
+.PP
+.SH IDEA
+David Rubio, who also wrote the original.
+.PP
+.SH NOTES
+As this program does not use Kstat, there is no summary since boot line.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+sar\-c.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+sar(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/seeksize.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/seeksize.d.1m
new file mode 100644
index 0000000..f15743d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/seeksize.d.1m
@@ -0,0 +1,51 @@
+.TH seeksize.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+seeksize.d \- print disk event seek report. Uses DTrace.
+.SH SYNOPSIS
+.B seeksize.d
+.SH DESCRIPTION
+seeksize.d is a simple DTrace program to print a report of disk
+event seeks by process.
+
+This can be used to identify whether processes are accessing the
+disks in a "random" or "sequential" manner. Sequential is often
+desirable, indicated by mostly zero length seeks.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the io provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B seeksize.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command and argument list
+.TP
+value
+distance in disk blocks (sectors)
+.TP
+count
+number of I/O operations
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+seeksize.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+iosnoop(1M), bitesize.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/setuids.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/setuids.d.1m
new file mode 100644
index 0000000..50d131c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/setuids.d.1m
@@ -0,0 +1,53 @@
+.TH setuids.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+setuids.d \- snoop setuid calls as they occur. Uses DTrace.
+.SH SYNOPSIS
+.B setuids.d
+.SH DESCRIPTION
+setuids.d is a simple DTrace program to print details of setuid
+calls, where a process assumes a different UID. These are usually
+related to login events.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+Default output, print setuids as they occur,
+#
+.B setuids.d
+.PP
+.SH FIELDS
+.TP
+UID
+user ID (from)
+.TP
+SUID
+set user ID (to)
+.TP
+PPID
+parent process ID
+.TP
+PID
+process ID
+.TP
+PCMD
+parent command
+.TP
+CMD
+command (with arguments)
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+setuids.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), bsmconv(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calldist.d.1m
new file mode 100644
index 0000000..760e699
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calldist.d.1m
@@ -0,0 +1,49 @@
+.TH sh_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_calldist.d - measure Bourne shell elapsed times for types of operation.
+.SH SYNOPSIS
+.B sh_calldist.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+This script prints distribution plots of elapsed time for shell
+operations. Use sh_calltime.d for summary reports.
+
+Filename and call names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the shell or shellscript
+.TP
+2
+Type of call (func/builtin/cmd)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_calls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calls.d.1m
new file mode 100644
index 0000000..0afeaab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calls.d.1m
@@ -0,0 +1,49 @@
+.TH sh_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_calls.d - count Bourne calls (func/builtin/cmd/subsh) using DTrace.
+.SH SYNOPSIS
+.B sh_calls.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_calls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+TYPE
+Type of call (func/builtin/cmd/subsh)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calltime.d.1m
new file mode 100644
index 0000000..6863d87
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_calltime.d.1m
@@ -0,0 +1,49 @@
+.TH sh_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_calltime.d - measure Bourne shell elapsed times for types of operation.
+.SH SYNOPSIS
+.B sh_calltime.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+Filename and call names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_calltime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+TYPE
+Type of call (func/builtin/cmd/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_cpudist.d.1m
new file mode 100644
index 0000000..998e6ee
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_cpudist.d.1m
@@ -0,0 +1,49 @@
+.TH sh_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_cpudist.d - measure Bourne shell on-CPU times for types of operation.
+.SH SYNOPSIS
+.B sh_cpudist.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+This script prints distribution plots of on-CPU time for shell
+operations. Use sh_cputime.d for summary reports.
+
+Filename and call names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Filename of the shell or shellscript
+.TP
+2
+Type of call (func/builtin/cmd)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_cputime.d.1m
new file mode 100644
index 0000000..3c98f94
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_cputime.d.1m
@@ -0,0 +1,49 @@
+.TH sh_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_cputime.d - measure Bourne shell on-CPU times for types of operation.
+.SH SYNOPSIS
+.B sh_cputime.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+Filename and call names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_cputime.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+TYPE
+Type of call (func/builtin/cmd/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flow.d.1m
new file mode 100644
index 0000000..42dc5cc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flow.d.1m
@@ -0,0 +1,66 @@
+.TH sh_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_flow.d - snoop Bourne shell execution showing function flow using DTrace.
+.SH SYNOPSIS
+.B sh_flow.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+This watches shell function entries and returns, and indents child
+function calls. Shell builtins are also printed.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+NAME
+Shell function, builtin or command name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.TP
+>
+builtin
+.TP
+|
+external command
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowinfo.d.1m
new file mode 100644
index 0000000..6fa1500
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowinfo.d.1m
@@ -0,0 +1,62 @@
+.TH sh_flowinfo.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_flowinfo.d - snoop Bourne shell flow with additional info.
+.SH SYNOPSIS
+.B sh_flowinfo.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+This watches shell function entries and returns, and indents child
+function calls. Shell builtins and external commands are also printed.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_flowinfo.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the shell script
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func/builtin/cmd/subsh)
+.TP
+NAME
+Shell function, builtin or command name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_flowinfo.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowtime.d.1m
new file mode 100644
index 0000000..87906b6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_flowtime.d.1m
@@ -0,0 +1,76 @@
+.TH sh_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_flowtime.d - snoop Bourne shell execution with flow and delta times.
+.SH SYNOPSIS
+.B sh_flowtime.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+This watches shell function entries and returns, and indents child
+function calls. Shell builtins are also printed.
+
+DELTAs:
+-> previous line to the start of this function
+<- previous line to the end of this function
+> previous line to the end of this builtin
+| previous line to the end of this command
+
+See sh_flowinfo.d for more verbose and more straightforward delta times.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+FILE
+Filename that this function belongs to
+.TP
+NAME
+Shell function or builtin name
+.SH LEGEND
+.TP
+\->
+function entry
+.TP
+<\-
+function return
+.TP
+>
+builtin
+.TP
+|
+external command
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_lines.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_lines.d.1m
new file mode 100644
index 0000000..e3d8508
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_lines.d.1m
@@ -0,0 +1,46 @@
+.TH sh_lines.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_lines.d - trace Bourne shell line execution using DTrace.
+.SH SYNOPSIS
+.B sh_lines.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_lines.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+LINE
+Line number
+.TP
+COUNT
+Number of times a line was executed
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_lines.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_pidcolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_pidcolors.d.1m
new file mode 100644
index 0000000..3f6380a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_pidcolors.d.1m
@@ -0,0 +1,70 @@
+.TH sh_pidcolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_pidcolors.d - Demonstration of deeper DTrace Bourne shell analysis.
+.SH SYNOPSIS
+.B sh_pidcolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This extends sh_syscolors.d by including some "pid" provider tracing
+as a starting point for deeper analysis. Currently it adds the probes,
+
+pid$target:a.out:e*:entry,
+pid$target:a.out:e*:return
+
+which means, all functions from the /usr/bin/sh binary that begin with
+the letter "e". This adds about 34 probes. Customise it to whichever
+parts of /usr/bin/sh or the system libraries you are interested in.
+
+The filename for syscalls may be printed as the shell name, if the
+script was invoked using the form "shell filename" rather than running
+the script with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_pidcolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the shell script
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func/builtin/cmd/line/shell)
+.TP
+NAME
+Shell function, builtin or command name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_pidcolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_stat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_stat.d.1m
new file mode 100644
index 0000000..40624f9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_stat.d.1m
@@ -0,0 +1,59 @@
+.TH sh_stat.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_stat.d - Bourne shell operation stats using DTrace.
+.SH SYNOPSIS
+.B sh_stat.d
+[interval [count]]
+.SH DESCRIPTION
+This traces activity from all sh processes on the system that are running
+with sh provider support.
+
+The numbers are counts for the interval specified. The default interval
+is 1 second.
+
+If you see a count in "EXECS" but not in the other columns, then sh
+scripts may be running without the DTrace sh provider. See Shell/Readme.
+
+Filename and function names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_stat.d
+.PP
+.SH FIELDS
+.TP
+EXEC/s
+Bourne shells executed per second, including
+those without sh provider support
+.TP
+FUNC/s
+Functions called, per second
+.TP
+BLTIN/s
+Builtins called, per second
+.TP
+SUB-SH/s
+Sub-shells called, per second
+.TP
+CMD/s
+External commands called, per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_stat.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscalls.d.1m
new file mode 100644
index 0000000..67d74a3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscalls.d.1m
@@ -0,0 +1,49 @@
+.TH sh_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_syscalls.d - count Bourne calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B sh_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+Filename and function names are printed if available.
+The filename for syscalls may be printed as the shell name, if the
+script was invoked using the form "shell filename" rather than running
+the script with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_syscalls.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+TYPE
+Type of call (func/builtin/cmd/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscolors.d.1m
new file mode 100644
index 0000000..bfd1de5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_syscolors.d.1m
@@ -0,0 +1,63 @@
+.TH sh_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_syscolors.d - trace Bourne shell flow plus syscalls, in color.
+.SH SYNOPSIS
+.B sh_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This watches shell function entries and returns, and indents child
+function calls. Shell builtins, commands and lines are also printed.
+
+The filename for syscalls may be printed as the shell name, if the
+script was invoked using the form "shell filename" rather than running
+the script with an interpreter line.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+FILE
+Filename of the shell script
+.TP
+LINE
+Line number of filename
+.TP
+TYPE
+Type of call (func/builtin/cmd/line/shell)
+.TP
+NAME
+Shell function, builtin or command name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_wasted.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_wasted.d.1m
new file mode 100644
index 0000000..1b98389
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_wasted.d.1m
@@ -0,0 +1,49 @@
+.TH sh_wasted.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_wasted.d - measure Bourne shell elapsed times for "wasted" commands.
+.SH SYNOPSIS
+.B sh_wasted.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This script measures "wasted" commands - those which are called externally
+but are in fact builtins to the shell. Ever seen a script which calls
+/usr/bin/echo needlessly? This script measures that cost.
+
+Filename and call names are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_wasted.d
+.PP
+.SH FIELDS
+.TP
+FILE
+Filename of the shell or shellscript
+.TP
+NAME
+Name of call
+.TP
+TIME
+Total elapsed time for calls (us)
+.SH IDEA
+Mike Shapiro
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_wasted.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sh_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sh_who.d.1m
new file mode 100644
index 0000000..f98bef8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sh_who.d.1m
@@ -0,0 +1,49 @@
+.TH sh_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+sh_who.d - trace Bourne shell line execution by process using DTrace.
+.SH SYNOPSIS
+.B sh_who.d
+
+.SH DESCRIPTION
+This traces shell activity from all Bourne shells on the system that are
+running with sh provider support.
+
+Filenames are printed if available.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Shell provider, which may change
+as additional features are introduced. Check Shell/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B sh_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of the shell
+.TP
+UID
+User ID of the owner
+.TP
+LINES
+Number of times a line was executed
+.TP
+FILE
+Pathname of the shell or shellscript
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+sh_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/shellsnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/shellsnoop.1m
new file mode 100644
index 0000000..a533ab0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/shellsnoop.1m
@@ -0,0 +1,99 @@
+.TH shellsnoop 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+shellsnoop \- snoop live shell activity. Uses DTrace.
+.SH SYNOPSIS
+.B shellsnoop
+[\-hqsv] [\-p PID] [\-u UID]
+.SH DESCRIPTION
+A program to print read/write details from shells,
+such as keystrokes and command outputs.
+
+This program sounds somewhat dangerous (snooping keystrokes), but is
+no more so than /usr/bin/truss, and both need root or dtrace privileges to
+run. In fact, less dangerous, as we only print visible text (not password
+text, for example). Having said that, it goes without saying that this
+program shouldn't be used for breeching privacy of other users.
+
+This was written as a tool to demonstrate the capabilities of DTrace.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - this script uses the syscall provider.
+.SH OPTIONS
+.TP
+\-q
+quiet, only print data
+.TP
+\-s
+include start time, us
+.TP
+\-v
+include start time, string
+.TP
+\-p PID
+PID to snoop
+.TP
+\-u UID
+user ID to snoop
+.PP
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B shellsnoop
+.TP
+human readable timestamps,
+#
+.B shellsnoop
+\-v
+.TP
+watch this PID only,
+#
+.B shellsnoop
+\-p 1892
+.TP
+watch this PID data only,
+#
+.B shellsnoop
+\-qp 1892
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+PPID
+parent process ID
+.TP
+COMM
+command name
+.TP
+DIR
+direction (R read, W write)
+.TP
+TEXT
+text contained in the read/write
+.TP
+TIME
+timestamp for the command, us
+.TP
+STRTIME
+timestamp for the command, string
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+shellsnoop will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/shortlived.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/shortlived.d.1m
new file mode 100644
index 0000000..cb49507
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/shortlived.d.1m
@@ -0,0 +1,37 @@
+.TH shortlived.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+shortlived.d \- check short lived process time. Uses DTrace.
+.SH SYNOPSIS
+.B shortlived.d
+.SH DESCRIPTION
+shortlived.d is a DTrace program to measure the time consumed by
+short lived processes.
+
+Many short lived processes can be a burden on the system, and may be
+the cause of performance problems. This program can help identify
+that case.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall and proc providers.
+.SH EXAMPLES
+.TP
+This prints a report after Ctrl\-C has been hit,
+#
+.B shortlived.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+shortlived.d will run until Ctrl\-C is hit to end the sample.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sigdist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sigdist.d.1m
new file mode 100644
index 0000000..f9f02fe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sigdist.d.1m
@@ -0,0 +1,50 @@
+.TH sigdist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+sigdist.d \- signal distribution by process. Uses DTrace.
+.SH SYNOPSIS
+.B sigdist.d
+.SH DESCRIPTION
+This is a simple DTrace script that prints the number of signals
+recieved by process and signal number. This script is also available
+as /usr/demo/dtrace/sig.d, where it originates.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the proc provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B sigdist.d
+.PP
+.SH FIELDS
+.TP
+SENDER
+process name of sender
+.TP
+RECIPIENT
+process name of target
+.TP
+SIG
+signal number, see signal(3head)
+.TP
+COUNT
+number of signals sent
+.PP
+.SH BASED ON
+/usr/demo/dtrace/sig.d
+.PP
+.SH DOCUMENTATION
+DTrace Guide "proc Provider" chapter (docs.sun.com)
+
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+sigdist.d will sample until Ctrl\-C is hit.
+.SH SEE ALSO
+kill.d(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/stacksize.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/stacksize.d.1m
new file mode 100644
index 0000000..5b5a916
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/stacksize.d.1m
@@ -0,0 +1,42 @@
+.TH stacksize.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+stacksize.d \- measure stack size for running threads. Uses DTrace.
+.SH SYNOPSIS
+.B stacksize.d
+.SH DESCRIPTION
+This samples the user stack size by process name, and prints a
+distribution plot so that the average stack size can be easily
+identified.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sched provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B stacksize.d
+.PP
+.SH FIELDS
+.TP
+value
+size of the user stack
+.TP
+count
+number of samples at this size
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+stacksize.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Jonathan Adams
+.SH SEE ALSO
+pmap(1), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/statsnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/statsnoop.1m
new file mode 100644
index 0000000..9a1011d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/statsnoop.1m
@@ -0,0 +1,140 @@
+.TH statsnoop 1m "$Date:: 2007-09-23 #$" "USER COMMANDS"
+.SH NAME
+statsnoop \- snoop file stats as they occur. Uses DTrace.
+.SH SYNOPSIS
+.B statsnoop
+[\-a|\-A|\-ceghsvxZ] [\-f pathname] [\-n name] [\-p PID]
+.SH DESCRIPTION
+statsnoop traces the stat variety of syscalls.
+As a process issues a file stat, details
+such as UID, PID and pathname are printed out.
+
+The returned file descriptor is printed,
+a value of -1 indicates an error. This can be useful
+for troubleshooting to determine if appliacions are attempting to
+stat files that do not exist.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-A
+dump all data, space delimited
+.TP
+\-c
+print current working directory of process
+.TP
+\-e
+print errno value
+.TP
+\-g
+print full command arguments
+.TP
+\-s
+print start time, us
+.TP
+\-v
+print start time, string
+.TP
+\-x
+only print failed stats
+.TP
+\-Z
+print zonename
+.TP
+\-f pathname
+file pathname to snoop
+.TP
+\-n name
+process name to snoop
+.TP
+\-p PID
+process ID to snoop
+.PP
+.SH EXAMPLES
+.TP
+Default output, print file stats by process as they occur,
+#
+.B statsnoop
+.PP
+.TP
+Print human readable timestamps,
+#
+.B statsnoop
+\-v
+.PP
+.TP
+See error codes,
+#
+.B statsnoop
+\-e
+.PP
+.TP
+Snoop this file only,
+#
+.B statsnoop
+\-f /etc/passwd
+.PP
+.SH FIELDS
+.TP
+ZONE
+Zone name
+.TP
+UID
+User ID
+.TP
+PID
+Process ID
+.TP
+PPID
+Parent Process ID
+.TP
+FD
+File Descriptor (-1 is error)
+.TP
+ERR
+errno value (see /usr/include/sys/errno.h)
+.TP
+CWD
+current working directory of process
+.TP
+PATH
+pathname for file stat
+.TP
+COMM
+command name for the process
+.TP
+ARGS
+argument listing for the process
+.TP
+TIME
+timestamp for the stat event, us
+.TP
+STRTIME
+timestamp for the stat event, string
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+statsnoop will run forever until Ctrl\-C is hit.
+.SH BUGS
+occasionally the pathname for the file stat cannot be read
+and the following error will be seen,
+
+dtrace: error on enabled probe ID 6 (...): invalid address
+
+this is normal behaviour.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/swapinfo.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/swapinfo.d.1m
new file mode 100644
index 0000000..322d29d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/swapinfo.d.1m
@@ -0,0 +1,88 @@
+.TH swapinfo.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+swapinfo.d \- print virtual memory info. Uses DTrace.
+.SH SYNOPSIS
+.B swapinfo.d
+.SH DESCRIPTION
+Prints swap usage details for RAM and disk based swap.
+
+This script is UNDER CONSTRUCTION, check for newer versions.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses various kernel symbols.
+.SH FIELDS
+.TP
+RAM Total
+Total RAM installed
+.TP
+RAM Unusable
+RAM consumed by the OBP and TSBs
+.TP
+RAM Kernel
+Kernel resident in RAM (and usually locked)
+.TP
+RAM Locked
+Locked memory pages from swap (Anon)
+.TP
+RAM Used
+anon + exec + file pages used
+.TP
+RAM Free
+free memory + page cache free
+.TP
+Disk Total
+Total disk swap configured
+.TP
+Disk Resv
+Disk swap allocated + reserved
+.TP
+Disk Avail
+Disk swap available for reservation
+.TP
+Swap Total
+Total Virtual Memory usable
+.TP
+Swap Resv
+VM allocated + reserved
+.TP
+Swap Avail
+VM available for reservation
+.TP
+Swap MinFree
+VM kept free from reservations
+.PP
+.SH EXAMPLES
+.TP
+Print info,
+#
+.B swapinfo.d
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH ADDITIONAL RESOURCES
+swapstat - K9Toolkit
+
+vmstat 1 2; swap -s; echo ::memstat | mdb -k
+
+RMCmem - The MemTool Package
+
+RICHPse - The SE Toolkit
+
+"Clearing up swap space confusion" Unix Insider, Adrian Cockcroft
+
+"Solaris Internals", Jim Mauro, Richard McDougall
+
+/usr/include/vm/anon.h, /usr/include/sys/systm.h
+
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/sysbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/sysbypid.d.1m
new file mode 100644
index 0000000..b956f12
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/sysbypid.d.1m
@@ -0,0 +1,50 @@
+.TH sysbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+sysbypid.d \- system stats by PID. Uses DTrace.
+.SH SYNOPSIS
+.B sysbypid.d
+.SH DESCRIPTION
+sysbypid.d is a simple DTrace program to print System
+statistics by process.
+
+The system statistics are documented in the cpu_sysinfo struct
+in the /usr/include/sys/sysinfo.h file; and also in the sysinfo provider
+chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B sysbypid.d
+.PP
+.SH FIELDS
+.TP
+EXEC
+process name
+.TP
+PID
+process ID
+.TP
+VM
+Virtual Memory statistic
+.TP
+VALUE
+Value by which statistic was incremented
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+sysbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), vmstat(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/syscallbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbypid.d.1m
new file mode 100644
index 0000000..e799dba
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbypid.d.1m
@@ -0,0 +1,50 @@
+.TH syscallbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+syscallbypid.d \- syscalls by process ID. Uses DTrace.
+.SH SYNOPSIS
+.B syscallbypid.d
+.SH DESCRIPTION
+This reports the number of each type of system call made by PID.
+This is useful to identify which process is causing the most
+system calls.
+
+This is based on a script from DExplorer.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B syscallbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+SYSCALL
+system call name
+.TP
+COUNT
+number of system calls made in this sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+syscallbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+procsystime(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/syscallbyproc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbyproc.d.1m
new file mode 100644
index 0000000..bb32348
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbyproc.d.1m
@@ -0,0 +1,50 @@
+.TH syscallbyproc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+syscallbyproc.d \- syscalls by process name. Uses DTrace.
+.SH SYNOPSIS
+.B syscallbyproc.d
+.SH DESCRIPTION
+syscallbyproc.d is a DTrace OneLiner to a report of the number of
+system calls made by process name.
+
+This is useful to identify which process is causing the most
+system calls.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Any
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B syscallbyproc.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+This is the count, the number of system calls made.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+syscallbyproc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+procsystime(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/syscallbysysc.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbysysc.d.1m
new file mode 100644
index 0000000..c8f34f2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/syscallbysysc.d.1m
@@ -0,0 +1,47 @@
+.TH syscallbysysc.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+syscallbysysc.d \- syscalls by syscall. Uses DTrace.
+.SH SYNOPSIS
+.B syscallbysysc.d
+.SH DESCRIPTION
+syscallbysysc.d is a DTrace OneLiner to a report of the number of
+each type of system call made.
+
+This is useful to identify which system call is the most common.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Any
+.SH STABILITY
+stable - needs the syscall provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B syscallbysysc.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the system call type. Most have man pages in section 2.
+.TP
+second field
+This is the count, the number of occurrances for this system call.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+syscallbysysc.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+procsystime(1M), dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calldist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calldist.d.1m
new file mode 100644
index 0000000..351a3f4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calldist.d.1m
@@ -0,0 +1,47 @@
+.TH tcl_calldist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_calldist.d - measure Tcl elapsed time for different types of operation.
+.SH SYNOPSIS
+.B tcl_calldist.d
+[top]
+eg,
+tcl_calldist.d # default, truncate to 10 lines
+tcl_calldist.d 25 # truncate each report section to 25 lines
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_calldist.d
+.PP
+.SH FIELDS
+.TP
+1
+Process ID
+.TP
+2
+Type of call (proc/cmd/total)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_calldist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calls.d.1m
new file mode 100644
index 0000000..df65cde
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calls.d.1m
@@ -0,0 +1,68 @@
+.TH tcl_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_calls.d - count Tcl calls (proc/cmd) using DTrace.
+.SH SYNOPSIS
+.B tcl_calls.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+TYPEs:
+proc procedure
+cmd command
+
+PORTIONS: Copyright (c) 2007 Brendan Gregg.
+
+CDDL HEADER START
+
+The contents of this file are subject to the terms of the
+Common Development and Distribution License, Version 1.0 only
+(the "License"). You may not use this file except in compliance
+with the License.
+
+You can obtain a copy of the license at Docs/cddl1.txt
+or http://www.opensolaris.org/os/licensing.
+See the License for the specific language governing permissions
+and limitations under the License.
+
+CDDL HEADER END
+
+09-Sep-2007 Brendan Gregg Created this.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_calls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (see below)
+.TP
+NAME
+Name of proc or cmd call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calltime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calltime.d.1m
new file mode 100644
index 0000000..14074af
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_calltime.d.1m
@@ -0,0 +1,50 @@
+.TH tcl_calltime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_calltime.d - measure Tcl elapsed times for different types of operation.
+.SH SYNOPSIS
+.B tcl_calltime.d
+[top]
+eg,
+tcl_calltime.d # default, truncate to 10 lines
+tcl_calltime.d 25 # truncate each report section to 25 lines
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_calltime.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (proc/cmd/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total elapsed time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_calltime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cpudist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cpudist.d.1m
new file mode 100644
index 0000000..7ae55d8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cpudist.d.1m
@@ -0,0 +1,47 @@
+.TH tcl_cpudist.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_cpudist.d - measure Tcl on-CPU time for different types of operation.
+.SH SYNOPSIS
+.B tcl_cpudist.d
+[top]
+eg,
+tcl_cpudist.d # default, truncate to 10 lines
+tcl_cpudist.d 25 # truncate each report section to 25 lines
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_cpudist.d
+.PP
+.SH FIELDS
+.TP
+1
+Process ID
+.TP
+2
+Type of call (proc/cmd/total)
+.TP
+3
+Name of call
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_cpudist.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cputime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cputime.d.1m
new file mode 100644
index 0000000..efbac89
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_cputime.d.1m
@@ -0,0 +1,50 @@
+.TH tcl_cputime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_cputime.d - measure Tcl on-CPU times for different types of operation.
+.SH SYNOPSIS
+.B tcl_cputime.d
+[top]
+eg,
+tcl_cputime.d # default, truncate to 10 lines
+tcl_cputime.d 25 # truncate each report section to 25 lines
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_cputime.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (proc/cmd/total)
+.TP
+NAME
+Name of call
+.TP
+TOTAL
+Total on-CPU time for calls (us)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_cputime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flow.d.1m
new file mode 100644
index 0000000..bba2e3a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flow.d.1m
@@ -0,0 +1,66 @@
+.TH tcl_flow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_flow.d - snoop Tcl execution showing procedure flow using DTrace.
+.SH SYNOPSIS
+.B tcl_flow.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+This watches Tcl method entries and returns, and indents child
+method calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_flow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+PID
+Process ID
+.TP
+CALL
+Tcl command or procedure name
+.SH LEGEND
+.TP
+\->
+procedure entry
+.TP
+<\-
+procedure return
+.TP
+>
+command entry
+.TP
+<
+command return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_flow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flowtime.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flowtime.d.1m
new file mode 100644
index 0000000..56194d2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_flowtime.d.1m
@@ -0,0 +1,69 @@
+.TH tcl_flowtime.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_flowtime.d - snoop Tcl execution showing procedure flow and delta times.
+.SH SYNOPSIS
+.B tcl_flowtime.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+This watches Tcl method entries and returns, and indents child
+method calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_flowtime.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+TIME(us)
+Time since boot, us
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+CALL
+Tcl command or procedure name
+.SH LEGEND
+.TP
+\->
+procedure entry
+.TP
+<\-
+procedure return
+.TP
+>
+command entry
+.TP
+<
+command return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_flowtime.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_ins.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_ins.d.1m
new file mode 100644
index 0000000..f3ab7fe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_ins.d.1m
@@ -0,0 +1,50 @@
+.TH tcl_calls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_calls.d - count Tcl calls (method/...) using DTrace.
+.SH SYNOPSIS
+.B tcl_calls.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+TYPEs:
+inst instruction
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_calls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (see below)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_calls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_insflow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_insflow.d.1m
new file mode 100644
index 0000000..877757d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_insflow.d.1m
@@ -0,0 +1,69 @@
+.TH tcl_insflow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_insflow.d - snoop Tcl execution showing procedure flow and delta times.
+.SH SYNOPSIS
+.B tcl_insflow.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+This watches Tcl method entries and returns, and indents child
+method calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_insflow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+TIME(us)
+Time since boot, us
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+TYPE
+Type of call (proc/cmd/inst)
+.TP
+CALL
+Tcl command or procedure name
+.SH LEGEND
+.TP
+proc
+procedure
+.TP
+cmd
+command
+.TP
+inst
+instruction
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_insflow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_proccalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_proccalls.d.1m
new file mode 100644
index 0000000..9fda802
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_proccalls.d.1m
@@ -0,0 +1,44 @@
+.TH tcl_methodcalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_methodcalls.d - count Tcl method calls DTrace.
+.SH SYNOPSIS
+.B tcl_methodcalls.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_methodcalls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+COUNT
+Number of calls during sample
+.TP
+PROCEDURE
+Tcl procedure name
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_methodcalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_procflow.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_procflow.d.1m
new file mode 100644
index 0000000..aa79e91
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_procflow.d.1m
@@ -0,0 +1,60 @@
+.TH tcl_procflow.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_procflow.d - snoop Tcl execution showing procedure flow using DTrace.
+.SH SYNOPSIS
+.B tcl_procflow.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+This watches Tcl method entries and returns, and indents child
+method calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_procflow.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+TIME(us)
+Time since boot, us
+.TP
+PID
+Process ID
+.TP
+PROCEDURE
+Tcl procedure name
+.SH LEGEND
+.TP
+\->
+proc entry
+.TP
+<\-
+proc return
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_procflow.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_stat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_stat.d.1m
new file mode 100644
index 0000000..280b8c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_stat.d.1m
@@ -0,0 +1,61 @@
+.TH tcl_stat.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_stat.d - Tcl operation stats using DTrace.
+.SH SYNOPSIS
+.B tcl_stat.d
+[interval [count]]
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+The numbers are counts for the interval specified. The default interval
+is 1 second.
+
+If you see a count in "EXECS" but not in the other columns, then you
+may have older Tcl software that does not have the integrated DTrace
+provider (or newer software where the provider has changed).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_stat.d
+.PP
+.SH FIELDS
+.TP
+EXEC/s
+Tcl programs executed per second, including
+those without Tcl provider support
+.TP
+PROC/s
+Procedures called, per second
+.TP
+CMD/s
+Commands created, per second
+.TP
+OBJNEW/s
+Objects created, per second
+.TP
+OBJFRE/s
+Objects freed, per second
+.TP
+OP/s
+Bytecode operations, per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_stat.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscalls.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscalls.d.1m
new file mode 100644
index 0000000..ef4e5fe
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscalls.d.1m
@@ -0,0 +1,47 @@
+.TH tcl_syscalls.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_syscalls.d - count Tcl calls and syscalls using DTrace.
+.SH SYNOPSIS
+.B tcl_syscalls.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_syscalls.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID
+.TP
+TYPE
+Type of call (method/syscall)
+.TP
+NAME
+Name of call
+.TP
+COUNT
+Number of calls during sample
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_syscalls.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscolors.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscolors.d.1m
new file mode 100644
index 0000000..4b920d5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_syscolors.d.1m
@@ -0,0 +1,59 @@
+.TH tcl_syscolors.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_syscolors.d - trace Tcl program flow plus syscalls, in color.
+.SH SYNOPSIS
+.B tcl_syscolors.d
+{ \-p PID | \-c cmd }
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+This watches Tcl method entries and returns, and indents child
+method calls.
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_syscolors.d
+.PP
+.SH FIELDS
+.TP
+C
+CPU-id
+.TP
+PID
+Process ID
+.TP
+TID
+Thread ID
+.TP
+DELTA(us)
+Elapsed time from previous line to this line
+.TP
+TYPE
+Type of call (proc/cmd/syscall)
+.TP
+NAME
+Tcl proc/cmd or syscall name
+.SH WARNING
+Watch the first column carefully, it prints the CPU-id. If it
+changes, then it is very likely that the output has been shuffled.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_syscolors.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcl_who.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_who.d.1m
new file mode 100644
index 0000000..f6a6994
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcl_who.d.1m
@@ -0,0 +1,54 @@
+.TH tcl_who.d 1m "$Date:: 2007-10-03 #$" "USER COMMANDS"
+.SH NAME
+tcl_who.d - trace Tcl calls by process using DTrace.
+.SH SYNOPSIS
+.B tcl_who.d
+
+.SH DESCRIPTION
+This traces activity from all Tcl processes on the system with DTrace
+provider support (tcl8.4.16).
+
+Calls is a measure of activity, and is a count of the procedures and
+commands that Tcl called.
+
+The argument list is truncated at 55 characters (up to 80 is easily
+available). To easily read the full argument list, use other system tools;
+on Solaris use "pargs PID".
+.SH OS
+Any
+.SH STABILITY
+Evolving - uses the DTrace Tcl provider, which may change
+as additional features are introduced. Check Tcl/Readme
+to see what version these scripts are based on.
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B tcl_who.d
+.PP
+.SH FIELDS
+.TP
+PID
+Process ID of Tcl
+.TP
+UID
+User ID of the owner
+.TP
+CALLS
+Number of calls made (proc + cmd)
+.TP
+ARGS
+Process name and arguments
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Examples, Notes and Docs directories. The example files may be
+especially useful as they aim to demonstrate how to interpret
+the output.
+.SH EXIT
+tcl_who.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.1m
new file mode 100644
index 0000000..7fff62c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.1m
@@ -0,0 +1,116 @@
+.TH tcpsnoop 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcpsnoop \- snoop TCP network packets by process. Uses DTrace.
+.SH SYNOPSIS
+.B tcpsnoop
+[\-a|hjsvZ] [\-n name] [\-p pid]
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris 10 3/05
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-j
+print project ID
+.TP
+\-s
+print time, us
+.TP
+\-v
+print time, string
+.TP
+\-Z
+print zone ID
+.TP
+\-n name
+command name to snoop
+.TP
+\-p PID
+process ID to snoop
+.PP
+.SH EXAMPLES
+.TP
+Default output, snoop TCP network packets with details,
+#
+.B tcpsnoop
+.TP
+Print human readable timestamps,
+#
+.B tcpsnoop
+\-v
+.TP
+Print zonename,
+#
+.B tcpsnoop
+\-Z
+.TP
+Print sshd traffic only,
+#
+.B tcpsnoop
+\-n sshd
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+DR
+direction
+.TP
+SIZE
+packet size, bytes
+.TP
+TIME
+timestamp, us
+.TP
+STRTIME
+human readable timestamp, string
+.TP
+ZONE
+zone ID
+.TP
+PROJ
+project ID
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpsnoop will print traffic until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcptop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.d.1m
new file mode 100644
index 0000000..e1cfd3c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop.d.1m
@@ -0,0 +1,68 @@
+.TH tcpsnoop.d 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcpsnoop.d \- snoop TCP network packets by process. DTrace.
+.SH SYNOPSIS
+.B tcpsnoop.d
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+This is a DTrace only version of "tcpsnoop" - an enhanced program that
+provides command line options.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris 10 3/05
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Default output, snoop TCP network packets with details,
+#
+.B tcpsnoop.d
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+DR
+direction
+.TP
+SIZE
+packet size, bytes
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpsnoop.d will print traffic until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcpsnoop(1M), tcptop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.1m
new file mode 100644
index 0000000..36e880d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.1m
@@ -0,0 +1,116 @@
+.TH tcpsnoop 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcpsnoop \- snoop TCP network packets by process. Uses DTrace.
+.SH SYNOPSIS
+.B tcpsnoop
+[\-a|hjsvZ] [\-n name] [\-p pid]
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris Nevada / OpenSolaris, circa late 2007
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-a
+print all data
+.TP
+\-j
+print project ID
+.TP
+\-s
+print time, us
+.TP
+\-v
+print time, string
+.TP
+\-Z
+print zone ID
+.TP
+\-n name
+command name to snoop
+.TP
+\-p PID
+process ID to snoop
+.PP
+.SH EXAMPLES
+.TP
+Default output, snoop TCP network packets with details,
+#
+.B tcpsnoop
+.TP
+Print human readable timestamps,
+#
+.B tcpsnoop
+\-v
+.TP
+Print zonename,
+#
+.B tcpsnoop
+\-Z
+.TP
+Print sshd traffic only,
+#
+.B tcpsnoop
+\-n sshd
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+DR
+direction
+.TP
+SIZE
+packet size, bytes
+.TP
+TIME
+timestamp, us
+.TP
+STRTIME
+human readable timestamp, string
+.TP
+ZONE
+zone ID
+.TP
+PROJ
+project ID
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpsnoop will print traffic until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcptop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.d.1m
new file mode 100644
index 0000000..79bfda3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpsnoop_snv.d.1m
@@ -0,0 +1,68 @@
+.TH tcpsnoop.d 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcpsnoop.d \- snoop TCP network packets by process. DTrace.
+.SH SYNOPSIS
+.B tcpsnoop.d
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+This is a DTrace only version of "tcpsnoop" - an enhanced program that
+provides command line options.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris Nevada / OpenSolaris, circa late 2007
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Default output, snoop TCP network packets with details,
+#
+.B tcpsnoop.d
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+DR
+direction
+.TP
+SIZE
+packet size, bytes
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpsnoop.d will print traffic until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcpsnoop(1M), tcptop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpstat.d.1m
new file mode 100644
index 0000000..4db577c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpstat.d.1m
@@ -0,0 +1,58 @@
+.TH tcpstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+tcpstat.d \- print TCP statistics. Uses DTrace.
+.SH SYNOPSIS
+.B tcpstat.d
+.SH DESCRIPTION
+tcpstat.d is a DTrace program to print TCP statistics every second,
+retrieved from the MIB provider.
+
+This program can be used to help identify how utilised the network
+interfaces may be, as well as TCP transmission errors.
+
+The TCP statistics are documented in the mib2_tcp struct
+in /usr/include/inet/mib2.h; and also in the mib provider
+chapter of the DTrace Guide, found at
+http://docs.sun.com/db/doc/817-6223.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the mib provider.
+.SH EXAMPLES
+.TP
+Print statistics every second,
+#
+.B tcpstat.d
+.PP
+.SH FIELDS
+.TP
+TCP_out
+TCP bytes sent
+.TP
+TCP_outRe
+TCP bytes retransmitted
+.TP
+TCP_in
+TCP bytes received
+.TP
+TCP_inDup
+TCP bytes received duplicated
+.TP
+TCP_inUn
+TCP bytes received out of order
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpstat.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+nicstat(1M), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcptop.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcptop.1m
new file mode 100644
index 0000000..156aaf5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcptop.1m
@@ -0,0 +1,111 @@
+.TH tcptop 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcptop \- display top TCP network packets by process. Uses DTrace.
+.SH SYNOPSIS
+.B tcptop
+[-Ch] [-j|-Z] [interval [count]]
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris 10 3/05
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-j
+print project IDs
+.TP
+\-Z
+print zone IDs
+.TP
+interval
+sample seconds between refreshing the screen
+.TP
+count
+number of samples
+.PP
+.SH EXAMPLES
+.TP
+Print a report every 5 seconds,
+#
+.B tcptop
+.TP
+Don't clear the screen, scrolling output,
+#
+.B tcptop
+\-C
+.TP
+Print project IDs,
+#
+.B tcptop
+\-j
+.TP
+Print zone IDs,
+#
+.B tcptop
+\-Z
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+SIZE
+packet size, bytes
+.TP
+load
+1 minute load average
+.TP
+TCPin
+total TCP inbound payload data
+.TP
+TCPout
+total TCP outbound payload data
+.TP
+ZONE
+zone ID
+.TP
+PROJ
+project ID
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcptop will print reports until Ctrl\-C is hit, or the specified
+count is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcpsnoop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcptop_snv.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcptop_snv.1m
new file mode 100644
index 0000000..9ac14ac
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcptop_snv.1m
@@ -0,0 +1,111 @@
+.TH tcptop 1m "$Date:: 2007-10-04 #$" "USER COMMANDS"
+.SH NAME
+tcptop \- display top TCP network packets by process. Uses DTrace.
+.SH SYNOPSIS
+.B tcptop
+[-Ch] [-j|-Z] [interval [count]]
+.SH DESCRIPTION
+This analyses TCP network packets and prints the responsible PID and UID,
+plus standard details such as IP address and port. This captures traffic
+of newly created TCP connections that were established while this program
+was running. It can help identify which processes is causing TCP traffic.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris Nevada / OpenSolaris, circa late 2007
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-j
+print project IDs
+.TP
+\-Z
+print zone IDs
+.TP
+interval
+sample seconds between refreshing the screen
+.TP
+count
+number of samples
+.PP
+.SH EXAMPLES
+.TP
+Print a report every 5 seconds,
+#
+.B tcptop
+.TP
+Don't clear the screen, scrolling output,
+#
+.B tcptop
+\-C
+.TP
+Print project IDs,
+#
+.B tcptop
+\-j
+.TP
+Print zone IDs,
+#
+.B tcptop
+\-Z
+.PP
+.SH FIELDS
+.TP
+UID
+user ID
+.TP
+PID
+process ID
+.TP
+CMD
+command name
+.TP
+LADDR
+local IP address
+.TP
+RADDR
+remote IP address
+.TP
+LPORT
+local port number
+.TP
+RPORT
+remote port number
+.TP
+SIZE
+packet size, bytes
+.TP
+load
+1 minute load average
+.TP
+TCPin
+total TCP inbound payload data
+.TP
+TCPout
+total TCP outbound payload data
+.TP
+ZONE
+zone ID
+.TP
+PROJ
+project ID
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcptop will print reports until Ctrl\-C is hit, or the specified
+count is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcpsnoop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/tcpwdist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/tcpwdist.d.1m
new file mode 100644
index 0000000..626d66e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/tcpwdist.d.1m
@@ -0,0 +1,60 @@
+.TH tcpwdist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+tcpwdist.d \- simple TCP write dist by process. Uses DTrace.
+.SH SYNOPSIS
+.B tcpwdist.d
+.SH DESCRIPTION
+This measures the size of writes from applications to the TCP level, which
+may well be much larger than the MTU size (this is application writes not
+packet writes). It can help identify which process is creating network
+traffic, and the size of the writes by that application. It uses a simple
+probe that produces meaningful output for most protocols.
+
+Tracking TCP activity by process is complex for a number of reasons,
+the greatest is that inbound TCP traffic is asynchronous to the process.
+The easiest TCP traffic to match is writes, which this script demonstrates.
+However there are still issues - for an inbound telnet connection the
+writes are associated with the command, for example "ls -l", not something
+meaningful such as "in.telnetd".
+
+Scripts that match TCP traffic properly include tcpsnoop and tcptop.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B tcpwdist.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+command and argument list
+.TP
+value
+TCP write payload size in bytes
+.TP
+count
+number of writes
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+tcpwdist.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+tcpsnoop(1M), tcptop(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/threaded.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/threaded.d.1m
new file mode 100644
index 0000000..c17ad9a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/threaded.d.1m
@@ -0,0 +1,50 @@
+.TH threaded.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+threaded.d \- sample multi-threaded CPU usage. Uses DTrace.
+.SH SYNOPSIS
+.B threaded.d
+.SH DESCRIPTION
+This measures thread IDs as a process runs across multiple CPUs.
+It is a simple script that can help determine if a multi-threaded
+application is effectively using it's threads, or if the threads have
+serialised. See the example file in Docs/Examples/threaded_example.txt
+for a demonstration.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Any
+.SH STABILITY
+stable.
+.SH EXAMPLES
+.TP
+This runs until Ctrl\-C is hit.
+#
+.B threaded.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+value
+thread ID
+.TP
+count
+number of samples
+.PP
+.SH SEE ALSO
+prstat \-L
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+threaded.d will run until Ctrl\-C is hit.
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/topsyscall.1m b/cddl/contrib/dtracetoolkit/Man/man1m/topsyscall.1m
new file mode 100644
index 0000000..3473454
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/topsyscall.1m
@@ -0,0 +1,73 @@
+.TH topsyscall 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+topsyscall \- top syscalls by syscall name. Uses DTrace.
+.SH SYNOPSIS
+.B topsyscall
+[-Cs] [interval [count]]
+.SH DESCRIPTION
+This program continually prints a report of the top system calls,
+and refreshes the display every 1 second or as specified at the
+command line.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses the hp_avenrun kernel symbol.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-s
+print per second values
+.PP
+.SH EXAMPLES
+.TP
+Default output, 1 second updates,
+#
+.B topsyscall
+.TP
+Print every 5 seconds,
+#
+.B topsyscall
+5
+.TP
+Print a scrolling output,
+#
+.B topsyscall
+\-C
+.PP
+.SH FIELDS
+.TP
+load avg
+load averages, see uptime(1)
+.TP
+syscalls
+total syscalls in this interval
+.TP
+syscalls/s
+syscalls per second
+.TP
+SYSCALL
+system call name
+.TP
+COUNT
+total syscalls in this interval
+.TP
+COUNT/s
+syscalls per second
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+topsyscall will run until Ctrl\-C is hit, or the specified
+interval is reached.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), prstat(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/topsysproc.1m b/cddl/contrib/dtracetoolkit/Man/man1m/topsysproc.1m
new file mode 100644
index 0000000..2f5e1c3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/topsysproc.1m
@@ -0,0 +1,75 @@
+.TH topsysproc 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+topsysproc \- top syscalls by process name. Uses DTrace.
+.SH SYNOPSIS
+.B topsysproc
+[-Cs] [interval [count]]
+.SH DESCRIPTION
+This program continually prints a report of the number of system calls
+by process name, and refreshes the display every 1 second or as specified
+at the command line. Similar data can be fetched with "prstat -m".
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses the hp_avenrun kernel symbol.
+.SH OPTIONS
+.TP
+\-C
+don't clear the screen
+.TP
+\-s
+print per second values
+.PP
+.SH EXAMPLES
+.TP
+Default output, 1 second updates,
+#
+.B topsysproc
+.TP
+Print every 5 seconds,
+#
+.B topsysproc
+5
+.TP
+Print a scrolling output,
+#
+.B topsysproc
+\-C
+.PP
+.SH FIELDS
+.TP
+load avg
+load averages, see uptime(1)
+.TP
+syscalls
+total syscalls in this interval
+.TP
+syscalls/s
+syscalls per second
+.TP
+PROCESS
+process name
+.TP
+COUNT
+total syscalls in this interval
+.TP
+COUNT/s
+syscalls per second
+.PP
+.SH NOTES
+There may be several PIDs with the same process name.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+topsysproc will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), prstat(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/udpstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/udpstat.d.1m
new file mode 100644
index 0000000..340f659d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/udpstat.d.1m
@@ -0,0 +1,55 @@
+.TH udpstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+udpstat.d \- print UDP statistics. Uses DTrace.
+.SH SYNOPSIS
+.B udpstat.d
+.SH DESCRIPTION
+udpstat.d is a DTrace program to print UDP statistics every second,
+retrieved from the MIB provider.
+
+The UDP statistics are documented in the mib2_tcp struct
+in /usr/include/inet/mib2.h; and also in the mib provider
+chapter of the DTrace Guide, found at
+http://docs.sun.com/db/doc/817-6223.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the mib provider.
+.SH EXAMPLES
+.TP
+Print statistics every second,
+#
+.B udpstat.d
+.PP
+.SH FIELDS
+.TP
+UDP_out
+UDP datagrams sent
+.TP
+UDP_outErr
+UDP datagrams errored on send
+.TP
+UDP_in
+UDP datagrams received
+.TP
+UDP_inErr
+UDP datagrams undeliverable
+.TP
+UDP_noPort
+UDP datagrams received to closed ports
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+udpstat.d will run forever until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/uname-a.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/uname-a.d.1m
new file mode 100644
index 0000000..60d10f7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/uname-a.d.1m
@@ -0,0 +1,35 @@
+.TH uname\-a.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+uname\-a.d \- "uname \-a" demo in DTrace. Uses DTrace.
+.SH SYNOPSIS
+.B uname\-a.d
+.SH DESCRIPTION
+This has been written to demonstrate fetching the "uname -a" info
+from a DTrace script, which turns out to be all kernel variables.
+This is intended as a starting point for other DTrace scripts, by
+beginning with familiar statistics.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses various kernel symbols.
+.SH EXAMPLES
+.TP
+Print system call counts every second,
+#
+.B uname\-c.d
+.PP
+.SH FIELDS
+See uname(1) manpage for documentation.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+uname(1), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/vmbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/vmbypid.d.1m
new file mode 100644
index 0000000..3c8b875
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/vmbypid.d.1m
@@ -0,0 +1,50 @@
+.TH vmbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+vmbypid.d \- virtual memory stats by PID. Uses DTrace.
+.SH SYNOPSIS
+.B vmbypid.d
+.SH DESCRIPTION
+vmbypid.d is a simple DTrace program to print Virtual Memory
+statistics by process.
+
+The virtual memory statistics are documented in the cpu_vminfo struct
+in the /usr/include/sys/sysinfo.h file; and also in the vminfo provider
+chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the vminfo provider.
+.SH EXAMPLES
+.TP
+Sample until Ctrl\-C is hit then print report,
+#
+.B vmbypid.d
+.PP
+.SH FIELDS
+.TP
+EXEC
+process name
+.TP
+PID
+process ID
+.TP
+VM
+Virtual Memory statistic
+.TP
+VALUE
+Value by which statistic was incremented
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+vmbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), vmstat(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/vmstat-p.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/vmstat-p.d.1m
new file mode 100644
index 0000000..8198f3d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/vmstat-p.d.1m
@@ -0,0 +1,85 @@
+.TH vmstat-p.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+vmstat-p.d \- vmstat -p demo in DTrace. Uses DTrace.
+.SH SYNOPSIS
+.B vmstat-p.d
+.SH DESCRIPTION
+This has been written to demonstrate fetching similar data as vmstat
+from DTrace. This program is intended as a starting point for other
+DTrace scripts, by beginning with familiar statistics.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses various kernel symbols.
+.SH EXAMPLES
+.TP
+Print virtual memory statistics every second,
+#
+.B vmstat-p.d
+.PP
+.SH FIELDS
+.TP
+swap
+virtual memory free, Kbytes
+.TP
+free
+free RAM, Kbytes
+.TP
+re
+page reclaims, Kbytes
+.TP
+mf
+minor faults, Kbytes
+.TP
+sr
+scan rate, pages
+.TP
+epi
+executable page ins, Kbytes
+.TP
+epo
+executable page outs, Kbytes
+.TP
+epf
+executable frees, Kbytes
+.TP
+api
+anonymous page ins, Kbytes
+.TP
+apo
+anonymous page outs, Kbytes
+.TP
+apf
+anonymous frees, Kbytes
+.TP
+fpi
+filesystem page ins, Kbytes
+.TP
+fpo
+filesystem page outs, Kbytes
+.TP
+fpf
+filesystem frees, Kbytes
+.PP
+.SH NOTES
+Most of the statistics are in units of kilobytes, unlike the
+original vmstat command which sometimes uses page counts.
+
+As this program does not use Kstat, there is no summary since boot line.
+
+Free RAM is both free free + cache free.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+vmstat-p.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+vmstat(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/vmstat.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/vmstat.d.1m
new file mode 100644
index 0000000..dfbc360
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/vmstat.d.1m
@@ -0,0 +1,79 @@
+.TH vmstat.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+vmstat.d \- vmstat demo in DTrace. Uses DTrace.
+.SH SYNOPSIS
+.B vmstat.d
+.SH DESCRIPTION
+This has been written to demonstrate fetching the same data as vmstat
+from DTrace. This program is intended as a starting point for other
+DTrace scripts, by beginning with familiar statistics.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - uses various kernel symbols.
+.SH EXAMPLES
+.TP
+Print virtual memory statistics every second,
+#
+.B vmstat.d
+.PP
+.SH FIELDS
+.TP
+w
+swapped out light weight processes
+.TP
+swap
+virtual memory free, Kbytes
+.TP
+free
+free RAM, Kbytes
+.TP
+re
+page reclaims, Kbytes
+.TP
+mf
+minor faults, Kbytes
+.TP
+pi
+page ins, Kbytes
+.TP
+po
+page outs, Kbytes
+.TP
+fr
+pages freed, Kbytes
+.TP
+sr
+scan rate, pages
+.TP
+in
+interrupts, number
+.TP
+sy
+system calls, number
+.TP
+cs
+context switches, number
+.PP
+.SH NOTES
+Most of the statistics are in units of kilobytes, unlike the
+original vmstat command which sometimes uses page counts.
+
+As this program does not use Kstat, there is no summary since boot line.
+
+Free RAM is both free free + cache free.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+vmstat.d will run until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+vmstat(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/vopstat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/vopstat.1m
new file mode 100644
index 0000000..fa81cc1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/vopstat.1m
@@ -0,0 +1,77 @@
+.TH vopstat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+vopstat \- vnode interface statistics. Uses DTrace.
+.SH SYNOPSIS
+.B vopstat [\-t] [/mountname]
+.SH DESCRIPTION
+This will either produce summary reports of vnode statistics, or
+trace activity.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH OPTIONS
+.TP
+\-t
+trace activity as it occurs
+.TP
+/mountname
+examine this FS only
+.PP
+.SH EXAMPLES
+.TP
+default output, summary each 5 secs,
+#
+.B vopstat
+.TP
+only examine /var,
+#
+.B vopstat
+/var
+.TP
+trace activity to /var,
+#
+.B vopstat
+\-t /var
+.PP
+.SH FIELDS
+.TP
+Count
+number of calls
+.TP
+mSeconds
+total of elapsed times
+.TP
+Event
+vop call name
+.TP
+Device
+device instance name
+.TP
+Path
+full pathname to file
+.TP
+RW
+Read or Write
+.TP
+Size
+size in bytes, if available
+.TP
+Offset
+offset in bytes, if available
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+vopstat will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Richard McDougall
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/weblatency.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/weblatency.d.1m
new file mode 100644
index 0000000..c7ff3d3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/weblatency.d.1m
@@ -0,0 +1,63 @@
+.TH weblatency.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+weblatency.d \- website latency statistics. Uses DTrace.
+.SH SYNOPSIS
+.B weblatency.d
+.SH DESCRIPTION
+This prints statistics for hostnames that browers have set GET requests
+for, in particular latency by hostname.
+
+The latency measured is from the browser sending the GET
+request to when the browser begins to recieve the response. It
+is an overall response time for the client, and encompasses
+connection speed delays, DNS lookups, proxy delays, and web server
+response time.
+
+This is written as an experimental tool, and may not work at all with
+your browser.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - depends on browser implementation.
+.SH EXAMPLES
+.TP
+Print report after Ctrl-C is hit,
+#
+.B weblatency.d
+.PP
+.SH FIELDS
+.TP
+HOST
+hostname from URL
+.TP
+NUM
+number of GETs
+.TP
+AVGTIME(ms)
+Average time for response, ms
+.TP
+MAXTIME(ms)
+Maximum time for response, ms
+.PP
+.SH NOTES
+See the source code for the "BROWSER" variable, which sets the browser
+to trace (currently set to "mozilla-bin").
+.PP
+.SH IDEA
+Bryan Cantrill (who wrote an elegant version for Sol 10 update 1)
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+weblatency.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/whatexec.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/whatexec.d.1m
new file mode 100644
index 0000000..9c29b8e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/whatexec.d.1m
@@ -0,0 +1,53 @@
+.TH whatexec.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+whatexec.d \- Examine the type of files exec'd. Uses DTrace.
+.SH SYNOPSIS
+.B whatexec.d
+.SH DESCRIPTION
+This prints the first four chacacters of files that are executed.
+This traces the kernel function findexec_by_hdr(), which checks for
+a known magic number in the file's header.
+
+The idea came from a demo I heard about from the UK, where a
+"blue screen of death" was displayed for "MZ" files (although I
+haven't seen the script or the demo).
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - this script uses fbt provider probes which may change for
+future updates of the OS, invalidating this script. Please read
+Docs/Notes/ALLfbt_notes.txt for further details about these fbt scripts.
+.SH EXAMPLES
+.TP
+Trace execs as they occur,
+#
+.B whatexec.d
+.PP
+.SH FIELDS
+.TP
+PEXEC
+parent command name
+.TP
+EXEC
+pathname to file exec'd
+.TP
+OK
+is type runnable, Y/N
+.TP
+TYPE
+first four characters from file
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+whatexec.d will trace until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/woof.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/woof.d.1m
new file mode 100644
index 0000000..212346d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/woof.d.1m
@@ -0,0 +1,46 @@
+.TH woof.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+woof.d \- Bark for new processes. Needs /dev/audio. Uses DTrace.
+.SH SYNOPSIS
+.B woof.d &
+.SH DESCRIPTION
+This is an audio alert daemon for process creation. It is a virtual dog which
+barks when it sees new processes. If many processes are being created
+quickly, it will bark a lot (and become a nuisance - not just the noise,
+but also from consuming too much CPU).
+
+This exists in the DTraceToolkit more for entertainment than
+practicality.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the proc provider, /usr/bin/audioplay, and bark.au.
+.SH EXAMPLES
+.TP
+Run the dog,
+#
+.B woof.d &
+.TP
+Hear the dog,
+$ find /etc -type f -exec grep localhost {} +
+.TP
+Drive the dog crazy,
+$ find /etc -type f -exec grep localhost {} \\;
+.PP
+.SH NOTES
+Beware of the dog!
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+woof.d will exit on Ctrl-C.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+sdtaudiocontrol(1), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/wpm.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/wpm.d.1m
new file mode 100644
index 0000000..8022ae4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/wpm.d.1m
@@ -0,0 +1,34 @@
+.TH wpm.d 1m "$Date:: 2007-09-12 #$" "USER COMMANDS"
+.SH NAME
+wpm.d - Measure words per minute of typing.
+.SH SYNOPSIS
+.B wpm.d
+commandname
+eg,
+wpm.d bash
+wpm.d vim
+.SH DESCRIPTION
+This script assumes that keystrokes arrive one at a time on STDIN. This
+isn't the case for all processes that read keyboard input (eg, sh).
+.SH OS
+Solaris
+.SH STABILITY
+stable - Written in DTrace (Solaris 10 3/05).
+.SH EXAMPLES
+.TP
+Default output,
+#
+.B wpm.d
+.PP
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+wpm.d will run until Ctrl-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[CA, USA]
+.SH SEE ALSO
+dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/writebytes.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/writebytes.d.1m
new file mode 100644
index 0000000..6fb3d85
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/writebytes.d.1m
@@ -0,0 +1,47 @@
+.TH writebytes.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+writebytes.d \- write bytes by process name. Uses DTrace.
+.SH SYNOPSIS
+.B writebytes.d
+.SH DESCRIPTION
+writebytes.d is a DTrace OneLiner to a report of the number of
+bytes write by process name.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B writebytes.d
+.PP
+.SH FIELDS
+.TP
+first field
+This is the process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+second field
+This is the number of bytes write.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+writebytes.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/writedist.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/writedist.d.1m
new file mode 100644
index 0000000..bdced08
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/writedist.d.1m
@@ -0,0 +1,54 @@
+.TH writedist.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+writedist.d \- write distrib. by process name. Uses DTrace.
+.SH SYNOPSIS
+.B writedist.d
+.SH DESCRIPTION
+writedist.d is a DTrace OneLiner to a report the write size and
+number of occurrences as a frequency distribution by process name.
+
+This can be useful to identify the behaviour of processes
+that are doing writes. Are they using many small writes, or
+fewer large writes.
+
+Docs/oneliners.txt and Docs/Examples/oneliners_examples.txt
+in the DTraceToolkit contain this as a oneliner that can be cut-n-paste
+to run.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B writedist.d
+.PP
+.SH FIELDS
+.TP
+process name
+The process name. There may be several PIDs that have the
+same process name, for example with numerous instances of "bash". The
+value reported will be the sum of them all.
+.TP
+value
+The size in bytes
+.TP
+count
+The number of occurrences that were at least this size
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+writedist.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+dtrace(1M), truss(1)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/xcallsbypid.d.1m b/cddl/contrib/dtracetoolkit/Man/man1m/xcallsbypid.d.1m
new file mode 100644
index 0000000..173a14f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/xcallsbypid.d.1m
@@ -0,0 +1,46 @@
+.TH xcallsbypid.d 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+xcallsbypid.d \- CPU cross calls by PID. Uses DTrace.
+.SH SYNOPSIS
+.B xcallsbypid.d
+.SH DESCRIPTION
+xcallsbypid.d reports the number of CPU cross calls by process name
+and process ID. Cross calls occur when a CPU requests another CPU to
+do work on it's behalf. A great number of these can be a burden
+on the system.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the sysinfo provider.
+.SH EXAMPLES
+.TP
+This samples until Ctrl\-C is hit.
+#
+.B xcallsbypid.d
+.PP
+.SH FIELDS
+.TP
+PID
+process ID
+.TP
+CMD
+process name
+.TP
+XCALLS
+number cross calls
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+xcallsbypid.d will sample until Ctrl\-C is hit.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+mpstat(1m), dtrace(1M)
+
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/xvmstat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/xvmstat.1m
new file mode 100644
index 0000000..9f27d95
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/xvmstat.1m
@@ -0,0 +1,104 @@
+.TH xvmstat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+xvmstat \- extended vmstat demo in DTrace. Uses DTrace.
+.SH SYNOPSIS
+.B xvmstat
+[interval [count]]
+.SH DESCRIPTION
+This has been written to demonstrate fetching similar data as vmstat
+from DTrace, with a few extra fields.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+unstable - needs various kernel symbols.
+.SH EXAMPLES
+.TP
+Print virtual memory statistics every second,
+#
+.B xvmstat
+.TP
+Print every 5 seconds, 6 times,
+#
+.B xvmstat
+5 6
+.PP
+.SH FIELDS
+.TP
+w
+swapped out LWPs, number
+.TP
+swap
+virtual memory free, Mb
+.TP
+free
+free RAM, Mb
+.TP
+re
+page reclaims, pages
+.TP
+maj
+major faults, pages
+.TP
+mf
+minor faults, pages
+.TP
+cow
+copy-on-write faults, pages
+.TP
+pro
+protection faults, pages
+sr
+scan rate, pages
+.TP
+epi
+executable page ins, pages
+.TP
+epo
+executable page outs, pages
+.TP
+epf
+executable frees, pages
+.TP
+api
+anonymous page ins, pages
+.TP
+apo
+anonymous page outs, pages
+.TP
+apf
+anonymous frees, pages
+.TP
+fpi
+filesystem page ins, pages
+.TP
+fpo
+filesystem page outs, pages
+.TP
+fpf
+filesystem frees, pages
+.PP
+.SH NOTES
+Most of the statistics are in units of pages, unlike the
+original vmstat command which sometimes uses kilobytes.
+
+All page values are per second values.
+
+As this program does not use Kstat, there is no summary since boot line.
+
+Free RAM is both free free + cache free.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+xvmstat will run until Ctrl\-C is hit, or until the count argument
+has been satisfied.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+vmstat(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Man/man1m/zvmstat.1m b/cddl/contrib/dtracetoolkit/Man/man1m/zvmstat.1m
new file mode 100644
index 0000000..cd830e0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Man/man1m/zvmstat.1m
@@ -0,0 +1,101 @@
+.TH zvmstat 1m "$Date:: 2007-08-05 #$" "USER COMMANDS"
+.SH NAME
+zvmstat \- print vmstat style info per Zone. Uses DTrace.
+.SH SYNOPSIS
+.B zvmstat
+[\-t] [interval [count]]
+.SH DESCRIPTION
+This program must be run from the global zone as root.
+
+Since this uses DTrace, only the root user or users with the
+dtrace_kernel privilege can run this command.
+.SH OS
+Solaris
+.SH STABILITY
+stable - needs the syscall and vminfo providers.
+.SH OPTIONS
+.TP
+\-t
+Print timestamps, string
+.TP
+interval
+Duration for each sample, seconds. default is 1.
+.TP
+count
+Number of samples. default is 1.
+.PP
+.SH EXAMPLES
+.TP
+Print virtual memory statistics every second,
+#
+.B zvmstat
+.TP
+Print every 5 seconds, 6 times,
+#
+.B zvmstat
+5 6
+.PP
+.SH FIELDS
+.TP
+ZONE
+zonename
+.TP
+re
+page reclaims, pages
+.TP
+mf
+minor faults, pages
+.TP
+fr
+pages freed, pages
+.TP
+sr
+scan rate, pages
+.TP
+epi
+executable page ins, pages
+.TP
+epo
+executable page outs, pages
+.TP
+epf
+executable frees, pages
+.TP
+api
+anonymous page ins, pages
+.TP
+apo
+anonymous page outs, pages
+.TP
+apf
+anonymous frees, pages
+.TP
+fpi
+filesystem page ins, pages
+.TP
+fpo
+filesystem page outs, pages
+.TP
+fpf
+filesystem frees, pages
+.PP
+.SH NOTES
+Most of the statistics are in units of pages, unlike the
+original vmstat command which sometimes uses kilobytes.
+
+All page values are a total for the sample duration.
+
+As this program does not use Kstat, there is no summary since boot line.
+.PP
+.SH DOCUMENTATION
+See the DTraceToolkit for further documentation under the
+Docs directory. The DTraceToolkit docs may include full worked
+examples with verbose descriptions explaining the output.
+.SH EXIT
+zvmstat will run until Ctrl\-C is hit, or until the count argument
+has been satisfied.
+.SH AUTHOR
+Brendan Gregg
+[Sydney, Australia]
+.SH SEE ALSO
+vmstat(1M), dtrace(1M)
diff --git a/cddl/contrib/dtracetoolkit/Mem/Readme b/cddl/contrib/dtracetoolkit/Mem/Readme
new file mode 100644
index 0000000..c4f7e3d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/Readme
@@ -0,0 +1,3 @@
+Mem - Memory based analysis
+
+ These scripts analyse memory and virtual memory related activity.
diff --git a/cddl/contrib/dtracetoolkit/Mem/anonpgpid.d b/cddl/contrib/dtracetoolkit/Mem/anonpgpid.d
new file mode 100755
index 0000000..73971d9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/anonpgpid.d
@@ -0,0 +1,75 @@
+#!/usr/sbin/dtrace -Cs
+/*
+ * anonpgpid.d - anonymous memory paging info by process on CPU.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This scripts may help identify which processes are affected by a system
+ * with low memory, which is paging to the physical swap device. A report
+ * of the process on the CPU when paging occured is printed.
+ *
+ * $Id: anonpgpid.d 8 2007-08-06 05:55:26Z brendan $
+ *
+ * USAGE: anonpgpid.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * CMD Process name
+ * D Direction, Read or Write
+ * BYTES Total bytes during sample
+ *
+ * NOTES:
+ *
+ * This program is currently an approximation - often the process when writing
+ * pages to swap will be "pageout" the pageout scanner, or "rcapd" the
+ * resource capping daemon.
+ *
+ * THANKS: James Dickens
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * TODO:
+ *
+ * Track processes accurately. This is a little difficult - anonpgout
+ * occurs asynchronously to the process, and events related to this don't
+ * point back to the process.
+ *
+ * Author: Brendan Gregg [Sydney, Australia]
+ *
+ * 25-Jul-2005 Brendan Gregg Created this.
+ * 18-Feb-2006 " " Last update.
+ */
+
+#include <sys/vnode.h>
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+fbt::pageio_setup:entry
+/((args[2]->v_flag & (VISSWAP | VSWAPLIKE)) != 0)/
+{
+ @total[pid, execname, args[3] & B_READ ? "R" : "W"] = sum(arg1);
+}
+
+dtrace:::END
+{
+ printf("%6s %-16s %1s %s\n", "PID", "CMD", "D", "BYTES");
+ printa("%6d %-16s %1s %@d\n", @total);
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/minfbypid.d b/cddl/contrib/dtracetoolkit/Mem/minfbypid.d
new file mode 100755
index 0000000..43f6f83
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/minfbypid.d
@@ -0,0 +1,57 @@
+#!/usr/sbin/dtrace -s
+/*
+ * minfbypid.d - minor faults by PID.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This program prints a report of minor faults by PID. Minor faults are
+ * an indiction of memory consumption. This script could be used to help
+ * determine which process was consuming the most memory during the sample.
+ *
+ * $Id: minfbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: minfbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * MINFAULTS number of minor faults
+ *
+ * This is based on a script from DExplorer.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+vminfo:::as_fault
+{
+ @mem[pid, execname] = sum(arg0);
+}
+
+dtrace:::END
+{
+ printf("%6s %-16s %16s\n", "PID", "CMD", "MINFAULTS");
+ printa("%6d %-16s %@16d\n", @mem);
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/minfbyproc.d b/cddl/contrib/dtracetoolkit/Mem/minfbyproc.d
new file mode 100755
index 0000000..4d7316c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/minfbyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * minfbyproc.d - minor faults by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: minfbyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+vminfo:::as_fault { @mem[execname] = sum(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Mem/pgpginbypid.d b/cddl/contrib/dtracetoolkit/Mem/pgpginbypid.d
new file mode 100755
index 0000000..bd0ee53
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/pgpginbypid.d
@@ -0,0 +1,53 @@
+#!/usr/sbin/dtrace -s
+/*
+ * pgpginbypid.d - pages paged in by PID.
+ * Writen using DTrace (Solaris 10 3/05).
+ *
+ * $Id: pgpginbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: pgpginbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * PAGES number of pages paged in
+ *
+ * This is based on a script from DExplorer.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+vminfo:::pgpgin
+{
+ @pg[pid, execname] = sum(arg0);
+}
+
+dtrace:::END
+{
+ printf("%6s %-16s %16s\n", "PID", "CMD", "PAGES");
+ printa("%6d %-16s %@16d\n", @pg);
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/pgpginbyproc.d b/cddl/contrib/dtracetoolkit/Mem/pgpginbyproc.d
new file mode 100755
index 0000000..572271b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/pgpginbyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * pgpginbyproc.d - pages paged in by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: pgpginbyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+vminfo:::pgpgin { @pg[execname] = sum(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Mem/swapinfo.d b/cddl/contrib/dtracetoolkit/Mem/swapinfo.d
new file mode 100755
index 0000000..045cd72
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/swapinfo.d
@@ -0,0 +1,149 @@
+#!/usr/sbin/dtrace -s
+/*
+ * swapinfo.d - print virtual memory info (swap).
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * Prints swap usage details for RAM and disk based swap.
+ * This script is UNDER CONSTRUCTION, check for newer versions.
+ *
+ * $Id: swapinfo.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: swapinfo.d (check for newer versions)
+ *
+ * FIELDS:
+ * RAM Total Total RAM installed
+ * RAM Unusable RAM consumed by the OBP and TSBs
+ * RAM Kernel Kernel resident in RAM (and usually locked)
+ * RAM Locked Locked memory pages from swap (Anon)
+ * RAM Used anon + exec + file pages used
+ * RAM Free free memory + page cache free
+ * Disk Total Total disk swap configured
+ * Disk Resv Disk swap allocated + reserved
+ * Disk Avail Disk swap available for reservation
+ * Swap Total Total Virtual Memory usable
+ * Swap Resv VM allocated + reserved
+ * Swap Avail VM available for reservation
+ * Swap MinFree VM kept free from reservations
+ *
+ * SEE ALSO: swapinfo - K9Toolkit, http://www.brendangregg.com/k9toolkit.html
+ * vmstat 1 2; swap -s; echo ::memstat | mdb -k
+ * RMCmem - The MemTool Package
+ * RICHPse - The SE Toolkit
+ * "Clearing up swap space confusion" Unix Insider, Adrian Cockcroft
+ * "Solaris Internals", Jim Mauro, Richard McDougall
+ * /usr/include/vm/anon.h, /usr/include/sys/systm.h
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * Author: Brendan Gregg [Sydney, Australia]
+ *
+ * 11-Jun-2005 Brendan Gregg Created this.
+ * 24-Apr-2006 " " Improved disk measurements; changed terms.
+ * 24-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=16k
+
+inline int DEBUG = 0;
+
+dtrace:::BEGIN
+{
+ /* Debug stats */
+ this->ani_max = `k_anoninfo.ani_max;
+ this->ani_phys_resv = `k_anoninfo.ani_phys_resv;
+ this->ani_mem_resv = `k_anoninfo.ani_mem_resv;
+ this->ani_locked = `k_anoninfo.ani_locked_swap;
+ this->availrmem = `availrmem;
+
+ /* RAM stats */
+ this->ram_total = `physinstalled;
+ this->unusable = `physinstalled - `physmem;
+ this->locked = `pages_locked;
+ this->ram_used = `availrmem - `freemem;
+ this->freemem = `freemem;
+ this->kernel = `physmem - `pages_locked - `availrmem;
+
+ /* Disk stats */
+ this->disk_total = `k_anoninfo.ani_max;
+ this->disk_resv = `k_anoninfo.ani_phys_resv;
+ this->disk_avail = this->disk_total - this->disk_resv;
+
+ /* Total Swap stats */
+ this->minfree = `swapfs_minfree;
+ this->reserve = `swapfs_reserve;
+ /* this is TOTAL_AVAILABLE_SWAP from /usr/include/vm/anon.h, */
+ this->swap_total = `k_anoninfo.ani_max +
+ (`availrmem - `swapfs_minfree > 0 ?
+ `availrmem - `swapfs_minfree : 0);
+ /* this is CURRENT_TOTAL_AVAILABLE_SWAP from /usr/include/vm/anon.h, */
+ this->swap_avail = `k_anoninfo.ani_max - `k_anoninfo.ani_phys_resv +
+ (`availrmem - `swapfs_minfree > 0 ?
+ `availrmem - `swapfs_minfree : 0);
+ this->swap_resv = this->swap_total - this->swap_avail;
+
+ /* Convert to Mbytes */
+ this->ani_phys_resv *= `_pagesize; this->ani_phys_resv /= 1048576;
+ this->ani_mem_resv *= `_pagesize; this->ani_mem_resv /= 1048576;
+ this->ani_locked *= `_pagesize; this->ani_locked /= 1048576;
+ this->ani_max *= `_pagesize; this->ani_max /= 1048576;
+ this->availrmem *= `_pagesize; this->availrmem /= 1048576;
+ this->ram_total *= `_pagesize; this->ram_total /= 1048576;
+ this->unusable *= `_pagesize; this->unusable /= 1048576;
+ this->kernel *= `_pagesize; this->kernel /= 1048576;
+ this->locked *= `_pagesize; this->locked /= 1048576;
+ this->ram_used *= `_pagesize; this->ram_used /= 1048576;
+ this->freemem *= `_pagesize; this->freemem /= 1048576;
+ this->disk_total *= `_pagesize; this->disk_total /= 1048576;
+ this->disk_resv *= `_pagesize; this->disk_resv /= 1048576;
+ this->disk_avail *= `_pagesize; this->disk_avail /= 1048576;
+ this->swap_total *= `_pagesize; this->swap_total /= 1048576;
+ this->swap_avail *= `_pagesize; this->swap_avail /= 1048576;
+ this->swap_resv *= `_pagesize; this->swap_resv /= 1048576;
+ this->minfree *= `_pagesize; this->minfree /= 1048576;
+ this->reserve *= `_pagesize; this->reserve /= 1048576;
+
+ /* Print debug */
+ DEBUG ? printf("DEBUG availrmem %5d MB\n", this->availrmem) : 1;
+ DEBUG ? printf("DEBUG freemem %5d MB\n", this->freemem) : 1;
+ DEBUG ? printf("DEBUG ani_max %5d MB\n", this->ani_max) : 1;
+ DEBUG ? printf("DEBUG ani_phys_re %5d MB\n", this->ani_phys_resv) : 1;
+ DEBUG ? printf("DEBUG ani_mem_re %5d MB\n", this->ani_mem_resv) : 1;
+ DEBUG ? printf("DEBUG ani_locked %5d MB\n", this->ani_locked) : 1;
+ DEBUG ? printf("DEBUG reserve %5d MB\n", this->reserve) : 1;
+ DEBUG ? printf("\n") : 1;
+
+ /* Print report */
+ printf("RAM _______Total %5d MB\n", this->ram_total);
+ printf("RAM Unusable %5d MB\n", this->unusable);
+ printf("RAM Kernel %5d MB\n", this->kernel);
+ printf("RAM Locked %5d MB\n", this->locked);
+ printf("RAM Used %5d MB\n", this->ram_used);
+ printf("RAM Free %5d MB\n", this->freemem);
+ printf("\n");
+ printf("Disk _______Total %5d MB\n", this->disk_total);
+ printf("Disk Resv %5d MB\n", this->disk_resv);
+ printf("Disk Avail %5d MB\n", this->disk_avail);
+ printf("\n");
+ printf("Swap _______Total %5d MB\n", this->swap_total);
+ printf("Swap Resv %5d MB\n", this->swap_resv);
+ printf("Swap Avail %5d MB\n", this->swap_avail);
+ printf("Swap (Minfree) %5d MB\n", this->minfree);
+
+ DEBUG ? printf("\nNow run other commands for confirmation.\n") : 1;
+ ! DEBUG ? exit(0) : 1;
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/vmbypid.d b/cddl/contrib/dtracetoolkit/Mem/vmbypid.d
new file mode 100755
index 0000000..5160c14
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/vmbypid.d
@@ -0,0 +1,54 @@
+#!/usr/sbin/dtrace -s
+/*
+ * vmbypid.d - print vminfo events by process. DTrace.
+ *
+ * $Id: vmbypid.d 8 2007-08-06 05:55:26Z brendan $
+ *
+ * USAGE: vmbypid.d
+ *
+ * FIELDS:
+ * EXEC Process name
+ * PID Process ID
+ * VM Virtual Memory statistic (/usr/include/sys/sysinfo.h)
+ * VALUE Value by which statistic was incremented
+ *
+ * The virtual memory statistics are documented in the cpu_vminfo struct
+ * in the /usr/include/sys/sysinfo.h file; and also in the vminfo provider
+ * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 14-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+vminfo:::
+{
+ @VM[execname, pid, probename] = sum(arg0);
+}
+
+dtrace:::END {
+ printf("%16s %8s %22s %8s\n", "EXEC", "PID", "VM", "VALUE");
+ printa("%16s %8d %22s %@8d\n", @VM);
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/vmstat-p.d b/cddl/contrib/dtracetoolkit/Mem/vmstat-p.d
new file mode 100755
index 0000000..835a0a6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/vmstat-p.d
@@ -0,0 +1,155 @@
+#!/usr/sbin/dtrace -s
+/*
+ * vmstat-p.d - vmstat -p demo in DTrace.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This has been written to demonstrate fetching similar data as vmstat
+ * from DTrace. This program is intended as a starting point for other
+ * DTrace scripts, by beginning with familiar statistics.
+ *
+ * $Id: vmstat-p.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: vmstat-p.d
+ *
+ * FIELDS:
+ * swap virtual memory free Kbytes
+ * free free RAM Kbytes
+ * re page reclaims Kbytes
+ * mf minor faults Kbytes
+ * sr scan rate pages
+ * epi executable page ins Kbytes
+ * epo executable page outs Kbytes
+ * epf executable frees Kbytes
+ * api anonymous page ins Kbytes
+ * apo anonymous page outs Kbytes
+ * apf anonymous frees Kbytes
+ * fpi filesystem page ins Kbytes
+ * fpo filesystem page outs Kbytes
+ * fpf filesystem frees Kbytes
+ *
+ * NOTES:
+ * Most of the statistics are in units of kilobytes, unlike the
+ * original vmstat command which sometimes uses page counts.
+ * As this program does not use Kstat, there is no summary since
+ * boot line. Free RAM is both free free + cache free.
+ *
+ * SEE ALSO: vmstat(1M)
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 11-Jun-2005 Brendan Gregg Created this.
+ * 08-Jan-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+inline int SCREEN = 21;
+
+/*
+ * Initialise variables
+ */
+dtrace:::BEGIN
+{
+ pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
+ sy = 0; in = 0; cs = 0; maj = 0; cow = 0; pro = 0;
+ epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
+ fpi = 0; fpo = 0; fpf = 0;
+ lines = SCREEN + 1;
+}
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN,
+tick-1sec
+/lines++ > SCREEN/
+{
+ printf("%14s %13s %16s %14s %13s\n",
+ "memory", "page", "executable", "anonymous", "filesystem");
+ printf("%9s %7s %5s %4s %3s ",
+ "swap", "free", "re", "mf", "sr");
+ printf("%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
+ "epi", "epo", "epf", "api", "apo", "apf", "fpi", "fpo", "fpf");
+ lines = 0;
+}
+
+/*
+ * Probe events
+ */
+vminfo:::pgrec { re += arg0; }
+vminfo:::scan { sr += arg0; }
+vminfo:::as_fault { mf += arg0; }
+vminfo:::execpgin { epi += arg0; }
+vminfo:::execpgout { epo += arg0; }
+vminfo:::execfree { epf += arg0; }
+vminfo:::anonpgin { api += arg0; }
+vminfo:::anonpgout { apo += arg0; }
+vminfo:::anonfree { apf += arg0; }
+vminfo:::fspgin { fpi += arg0; }
+vminfo:::fspgout { fpo += arg0; }
+vminfo:::fsfree { fpf += arg0; }
+
+/*
+ * Print output line
+ */
+profile:::tick-1sec
+{
+ /* fetch free mem */
+ this->free = `freemem;
+
+ /*
+ * fetch free swap
+ *
+ * free swap is described in /usr/include/vm/anon.h as,
+ * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
+ */
+ this->ani_max = `k_anoninfo.ani_max;
+ this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv;
+ this->swap = (this->ani_max - this->ani_resv > 0 ?
+ this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree;
+
+ /* fetch w */
+ this->w = `nswapped;
+
+ /* convert to Kbytes */
+ epi *= `_pagesize / 1024;
+ epo *= `_pagesize / 1024;
+ epf *= `_pagesize / 1024;
+ api *= `_pagesize / 1024;
+ apo *= `_pagesize / 1024;
+ apf *= `_pagesize / 1024;
+ fpi *= `_pagesize / 1024;
+ fpo *= `_pagesize / 1024;
+ fpf *= `_pagesize / 1024;
+ re *= `_pagesize / 1024;
+ sr *= `_pagesize / 1024;
+ mf *= `_pagesize / 1024;
+ this->swap *= `_pagesize / 1024;
+ this->free *= `_pagesize / 1024;
+
+ /* print line */
+ printf("%9d %7d %5d %4d %3d ",
+ this->swap, this->free, re, mf, sr);
+ printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
+ epi, epo, epf, api, apo, apf, fpi, fpo, fpf);
+
+ /* clear counters */
+ pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
+ sy = 0; in = 0; cs = 0; maj = 0; cow = 0; pro = 0;
+ epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
+ fpi = 0; fpo = 0; fpf = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/vmstat.d b/cddl/contrib/dtracetoolkit/Mem/vmstat.d
new file mode 100755
index 0000000..f8e0ead
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/vmstat.d
@@ -0,0 +1,137 @@
+#!/usr/sbin/dtrace -s
+/*
+ * vmstat.d - vmstat demo in DTrace.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This has been written to demonstrate fetching the same data as vmstat
+ * from DTrace. This program is intended as a starting point for other
+ * DTrace scripts, by beginning with familiar statistics.
+ *
+ * $Id: vmstat.d 8 2007-08-06 05:55:26Z brendan $
+ *
+ * USAGE: vmstat.d
+ *
+ * FIELDS:
+ * w swapped out LWPs number
+ * swap virtual memory free Kbytes
+ * free free RAM Kbytes
+ * re page reclaims Kbytes
+ * mf minor faults Kbytes
+ * pi page ins Kbytes
+ * po page outs Kbytes
+ * fr pages freed Kbytes
+ * sr scan rate pages
+ * in interrupts number
+ * sy system calls number
+ * cs context switches number
+ *
+ * NOTES:
+ * Most of the statistics are in units of kilobytes, unlike the
+ * original vmstat command which sometimes uses page counts.
+ * As this program does not use Kstat, there is no summary since boot line.
+ * Free RAM is both free free + cache free.
+ *
+ * SEE ALSO: vmstat(1M)
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 11-Jun-2005 Brendan Gregg Created this.
+ * 08-Jan-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+inline int SCREEN = 21;
+
+/*
+ * Initialise variables
+ */
+dtrace:::BEGIN
+{
+ pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
+ sy = 0; in = 0; cs = 0;
+ lines = SCREEN + 1;
+}
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/lines++ > SCREEN/
+{
+ printf(" %1s %10s %8s %5s %5s %4s %4s %4s %4s %5s %6s %4s\n",
+ "w", "swap", "free", "re", "mf", "pi", "po", "fr", "sr",
+ "in", "sy", "cs");
+ lines = 0;
+}
+
+/*
+ * Probe events
+ */
+vminfo:::pgpgin { pi += arg0; }
+vminfo:::pgpgout { po += arg0; }
+vminfo:::pgrec { re += arg0; }
+vminfo:::scan { sr += arg0; }
+vminfo:::as_fault { mf += arg0; }
+vminfo:::dfree { fr += arg0; }
+
+syscall:::entry { sy++; }
+sdt:::interrupt-start { in++; }
+sched::resume:on-cpu { cs++; }
+
+/*
+ * Print output line
+ */
+profile:::tick-1sec
+{
+ /* fetch free mem */
+ this->free = `freemem;
+
+ /*
+ * fetch free swap
+ *
+ * free swap is described in /usr/include/vm/anon.h as,
+ * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
+ */
+ this->ani_max = `k_anoninfo.ani_max;
+ this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv;
+ this->swap = (this->ani_max - this->ani_resv > 0 ?
+ this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree;
+
+ /* fetch w */
+ this->w = `nswapped;
+
+ /* convert to Kbytes */
+ pi *= `_pagesize / 1024;
+ po *= `_pagesize / 1024;
+ re *= `_pagesize / 1024;
+ sr *= `_pagesize / 1024;
+ mf *= `_pagesize / 1024;
+ fr *= `_pagesize / 1024;
+ this->swap *= `_pagesize / 1024;
+ this->free *= `_pagesize / 1024;
+
+ /* print line */
+ printf(" %1d %10d %8d %5d %5d %4d %4d %4d %4d %5d %6d %4d\n",
+ this->w, this->swap, this->free, re, mf, pi, po, fr, sr,
+ in, sy, cs);
+
+ /* clear counters */
+ pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
+ sy = 0; in = 0; cs = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Mem/xvmstat b/cddl/contrib/dtracetoolkit/Mem/xvmstat
new file mode 100755
index 0000000..ce13ce7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Mem/xvmstat
@@ -0,0 +1,217 @@
+#!/usr/bin/sh
+#
+# xvmstat - extended vmstat demo in DTrace.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This has been written to demonstrate fetching similar data as vmstat
+# from DTrace, with a few extra fields.
+#
+# $Id: xvmstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: xvmstat [interval [count]]
+#
+# FIELDS:
+# w swapped out LWPs number
+# swap virtual memory free Mbytes
+# free free RAM Mbytes
+# re page reclaims pages/sec
+# maj major faults pages/sec
+# mf minor faults pages/sec
+# cow copy-on-write faults pages/sec
+# pro protection faults pages/sec
+# sr scan rate pages/sec
+# epi executable page ins pages/sec
+# epo executable page outs pages/sec
+# epf executable frees pages/sec
+# api anonymous page ins pages/sec
+# apo anonymous page outs pages/sec
+# apf anonymous frees pages/sec
+# fpi filesystem page ins pages/sec
+# fpo filesystem page outs pages/sec
+# fpf filesystem frees pages/sec
+#
+# NOTES:
+# - Most of the statistics are in units of pages, unlike the
+# original vmstat command which sometimes uses kilobytes.
+# - As this program does not use Kstat, there is no summary since boot line.
+# - Free RAM is both free free + cache free.
+#
+# SEE ALSO: vmstat(1M)
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 12-Jun-2005 Brendan Gregg Created this.
+# 01-Mar-2006 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default values
+interval=1; count=-1
+
+### check arguments
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+ cat <<-END >&2
+ USAGE: xvmstat [interval [count]]
+ xvmstat # 1 second samples, infinite
+ eg,
+ xvmstat 1 # print every 1 second
+ xvmstat 5 6 # print every 5 seconds, 6 times
+ END
+ exit 1
+fi
+
+### argument logic
+if [ "$1" -gt 0 ]; then
+ interval=$1; count=-1; shift
+fi
+if [ "$1" -gt 0 ]; then
+ count=$1; shift
+fi
+if [ $interval -eq 0 ]; then
+ interval=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int SCREEN = 21;
+
+ /*
+ * Initialise variables
+ */
+ dtrace:::BEGIN
+ {
+ re = 0; sr = 0; mf = 0; maj = 0; cow = 0; pro = 0;
+ epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
+ fpi = 0; fpo = 0; fpf = 0;
+ lines = SCREEN + 1;
+ counts = COUNTER;
+ secs = INTERVAL;
+ first = 1;
+ }
+
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN,
+ profile:::tick-1sec
+ /first || (secs == 0 && lines > SCREEN)/
+ {
+ printf("%2s %6s %5s %5s %3s %4s %3s %3s %3s ",
+ "w", "swap", "free", "re", "maj", "mf", "cow", "pro", "sr");
+ printf("%3s %3s %3s %3s %3s %3s %3s %3s %3s\n",
+ "epi", "epo", "epf", "api", "apo", "apf", "fpi", "fpo", "fpf");
+ lines = 0;
+ first = 0;
+ }
+
+ /*
+ * Probe events
+ */
+ vminfo:::pgrec { re += arg0; }
+ vminfo:::scan { sr += arg0; }
+ vminfo:::as_fault { mf += arg0; }
+ vminfo:::execpgin { epi += arg0; }
+ vminfo:::execpgout { epo += arg0; }
+ vminfo:::execfree { epf += arg0; }
+ vminfo:::anonpgin { api += arg0; }
+ vminfo:::anonpgout { apo += arg0; }
+ vminfo:::anonfree { apf += arg0; }
+ vminfo:::fspgin { fpi += arg0; }
+ vminfo:::fspgout { fpo += arg0; }
+ vminfo:::fsfree { fpf += arg0; }
+ vminfo:::maj_fault { maj += arg0; }
+ vminfo:::cow_fault { cow += arg0; }
+ vminfo:::prot_fault { pro += arg0; }
+
+ /*
+ * Print output line
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch free mem */
+ this->free = `freemem;
+
+ /*
+ * fetch free swap
+ *
+ * free swap is described in /usr/include/vm/anon.h as,
+ * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
+ */
+ this->ani_max = `k_anoninfo.ani_max;
+ this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv;
+ this->swap = (this->ani_max - this->ani_resv > 0 ?
+ this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree;
+
+ /* fetch w */
+ this->w = `nswapped;
+
+ /* convert to Mbytes */
+ this->swap *= `_pagesize; this->swap /= 1048576;
+ this->free *= `_pagesize; this->free /= 1048576;
+
+ /* convert to per second values */
+ re /= INTERVAL; maj /= INTERVAL; mf /= INTERVAL;
+ cow /= INTERVAL; pro /= INTERVAL; sr /= INTERVAL;
+ epi /= INTERVAL; epo /= INTERVAL; epf /= INTERVAL;
+ api /= INTERVAL; apo /= INTERVAL; apf /= INTERVAL;
+ fpi /= INTERVAL; fpo /= INTERVAL; fpf /= INTERVAL;
+
+ /* print line */
+ printf("%2d %6d %5d %5d %3d %4d %3d %3d %3d ",
+ this->w, this->swap, this->free, re, maj, mf, cow, pro, sr);
+ printf("%3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
+ epi, epo, epf, api, apo, apf, fpi, fpo, fpf);
+
+ /* clear counters */
+ re = 0; sr = 0; mf = 0; maj = 0; cow = 0; pro = 0;
+ epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
+ fpi = 0; fpo = 0; fpf = 0;
+
+ /* process counts */
+ secs = INTERVAL;
+ counts--;
+ lines++;
+ }
+
+ /*
+ * End
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Misc/Readme b/cddl/contrib/dtracetoolkit/Misc/Readme
new file mode 100644
index 0000000..2b77f60
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Misc/Readme
@@ -0,0 +1,5 @@
+Extra - Extra DTrace scripts
+
+ These are scripts that fall into no other category. They probably aren't
+ very useful, and are here as a particular coding example rather than
+ a useful tool.
diff --git a/cddl/contrib/dtracetoolkit/Misc/guess.d b/cddl/contrib/dtracetoolkit/Misc/guess.d
new file mode 100755
index 0000000..3ebcd39
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Misc/guess.d
@@ -0,0 +1,118 @@
+#!/usr/sbin/dtrace -wqs
+/*
+ * guess.d - guessing game in D (DTrace)
+ *
+ * $Id: guess.d 32 2007-09-15 05:08:49Z brendan $
+ *
+ * USAGE: guess.d
+ *
+ * SEE: http://www.brendangregg.com/guessinggame.html
+ *
+ * This is written to demonstrate this language versus the same program
+ * written in other languages.
+ *
+ * 11-May-2005 Brendan Gregg Created this.
+ */
+
+inline string scorefile = "highscores_d";
+
+dtrace:::BEGIN
+{
+ printf("guess.d - Guess a number between 1 and 100\n\n");
+ num = 1;
+ state = 1;
+
+ /* Generate random number */
+ answer = (rand() % 100) + 1;
+ answer = answer > 0 ? answer : - answer;
+}
+
+syscall::write:entry
+/state == 1 && pid == $pid/
+{
+ state = 2;
+ printf("Enter guess %d: ", num);
+ system("read guess");
+ pos = 0;
+}
+
+syscall::read:entry
+/state == 2 && ppid == $pid && arg0 == 3/
+{
+ self->inguess = 1;
+ self->buf = arg1;
+}
+
+syscall::read:return
+/self->inguess/
+{
+ key = copyin(self->buf, arg0);
+ keys[pos] = *(char *)key;
+ self->buf = 0;
+ pos++;
+}
+
+syscall::read:return
+/self->inguess && keys[pos-1] == '\n'/
+{
+ pos -= 2;
+ fac = 1;
+ guess = fac * (keys[pos] - '0');
+ pos--;
+ fac *= 10;
+ guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
+ pos--;
+ fac *= 10;
+ guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
+ self->doneguess = 1;
+}
+
+syscall::read:return
+/self->inguess/
+{
+ self->inguess = 0;
+}
+
+/* Play game */
+syscall::read:return
+/self->doneguess && guess == answer/
+{
+ printf("Correct! That took %d guesses.\n\n", num);
+ self->doneguess = 0;
+ state = 3;
+ printf("Please enter your name: ");
+ system("/usr/bin/read name");
+}
+
+syscall::read:return
+/self->doneguess && guess != answer/
+{
+ num++;
+
+ printf("%s...\n", guess < answer ? "Higher" : "Lower");
+
+ printf("Enter guess %d: ", num);
+ system("read line");
+ pos = 0;
+}
+
+syscall::read:entry
+/state == 3 && curthread->t_procp->p_parent->p_ppid == $pid && arg0 == 0/
+{
+ self->inname = 1;
+ self->buf = arg1;
+}
+
+/* Save high score */
+syscall::read:return
+/self->inname/
+{
+ self->inname = 0;
+ name = stringof(copyin(self->buf, arg0 - 1));
+ system("echo %s %d >> %s", name, num, scorefile);
+
+ /* Print high scores */
+ printf("\nPrevious high scores,\n");
+ system("cat %s", scorefile);
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Misc/woof.d b/cddl/contrib/dtracetoolkit/Misc/woof.d
new file mode 100755
index 0000000..d856a09
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Misc/woof.d
@@ -0,0 +1,63 @@
+#!/usr/sbin/dtrace -s
+/*
+ * woof.d - Bark whenever new processes appear. Needs /dev/audio.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: woof.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: woof.d &
+ *
+ * SEE ALSO: /usr/dt/bin/sdtaudiocontrol # to set volume
+ *
+ * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 14-Aug-2006 Brendan Gregg Created this.
+ * 14-Aug-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option destructive
+#pragma D option switchrate=10hz
+
+inline int SCREEN_OUTPUT = 0; /* Set to 1 for screen output */
+
+/* barks prevents woof.d from barking too much (up to 20 barks/second) */
+int barks;
+
+dtrace:::BEGIN
+{
+ SCREEN_OUTPUT ? trace("Beware of the dog!\n") : 1;
+}
+
+/*
+ * Call the shell to run a background audioplay command (cat > /dev/audio
+ * doesn't always work). One problem this creates is a feedback loop,
+ * where we bark at our own barks, or at other dogs barks; entertaining
+ * as this is, it can really slog the system and has been avoided by
+ * checking our ancestory.
+ */
+proc:::exec-success
+/!progenyof($pid) && barks++ < 2/
+{
+ SCREEN_OUTPUT ? trace("Woof! ") : 1;
+ system("audioplay /usr/share/audio/samples/au/bark.au &");
+}
+
+profile:::tick-10hz
+{
+ barks = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Misc/wpm.d b/cddl/contrib/dtracetoolkit/Misc/wpm.d
new file mode 100755
index 0000000..7f3bff2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Misc/wpm.d
@@ -0,0 +1,143 @@
+#!/usr/sbin/dtrace -s
+/*
+ * wpm.d - Measure words per minute of typing.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: wpm.d 52 2007-09-24 04:28:01Z brendan $
+ *
+ * USAGE: wpm.d commandname
+ * eg,
+ * wpm.d bash
+ * wpm.d vim
+ *
+ * This script assumes that keystrokes arrive one at a time on STDIN. This
+ * isn't the case for all processes that read keyboard input (eg, sh).
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 05-Aug-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+#pragma D option defaultargs
+
+inline int STDIN = 0;
+
+enum tracing_state {
+ BEGIN,
+ TRACING
+};
+
+dtrace:::BEGIN
+/$$1 == ""/
+{
+ trace("USAGE: wpm.d commandname\n");
+ trace(" eg,\n");
+ trace(" wpm.d bash\n");
+ trace(" wpm.d vim\n");
+ exit(1);
+}
+
+dtrace:::BEGIN
+{
+ state = BEGIN;
+ keys = 0;
+ words = 0;
+ wordsize = 0;
+ countdown = 5;
+ last = 0;
+ printf("Measuring will start in : %2d seconds", countdown);
+}
+
+profile:::tick-1sec
+/--countdown >= 0/
+{
+ printf("\b\b\b\b\b\b\b\b\b\b%2d seconds", countdown);
+}
+
+profile:::tick-1sec
+/state == BEGIN && countdown == -1/
+{
+ state = TRACING;
+ countdown = 60;
+ printf("\nMeasuring will stop in : %2d seconds", countdown);
+}
+
+syscall::read:entry
+/state == TRACING && execname == $$1 && arg0 == STDIN/
+{
+ self->buf = arg1;
+}
+
+syscall::read:return
+/self->buf && last/
+{
+ this->elapsed = (timestamp - last) / 1000000;
+ @dist = quantize(this->elapsed);
+ @avg = avg(this->elapsed);
+ @min = min(this->elapsed);
+ @max = max(this->elapsed);
+}
+
+syscall::read:return
+/self->buf/
+{
+ keys++;
+ wordsize++;
+ this->key = stringof(copyin(self->buf, arg0));
+ last = timestamp;
+}
+
+syscall::read:return
+/self->buf && (this->key == " " || this->key == "\n" || this->key == "\r") &&
+ wordsize == 1/
+{
+ /* recurring space */
+ wordsize = 0;
+ self->buf = 0;
+}
+
+syscall::read:return
+/self->buf && (this->key == " " || this->key == "\n" || this->key == "\r")/
+{
+ words++;
+ @sizes = lquantize(wordsize - 1, 0, 32, 1);
+ wordsize = 0;
+}
+
+syscall::read:return
+/self->buf/
+{
+ self->buf = 0;
+}
+
+profile:::tick-1sec
+/state == TRACING && countdown == -1/
+{
+ printf("\n\nCharacters typed : %d\n", keys);
+ printf("Words per minute : %d\n\n", words);
+
+ printa("Minimum keystroke latency : %@d ms\n", @min);
+ printa("Average keystroke latency : %@d ms\n", @avg);
+ printa("Maximum keystroke latency : %@d ms\n\n", @max);
+
+ printa("Word size distribution (letters),\n%@d\n", @sizes);
+ printa("Keystroke latency distribution (ms),\n%@d\n", @dist);
+
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/Readme b/cddl/contrib/dtracetoolkit/Net/Readme
new file mode 100644
index 0000000..3a53744
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/Readme
@@ -0,0 +1,4 @@
+Net - Network based analysis
+
+ These scripts analyse activity of the network interfaces, the TCP/IP
+ stack, socket activity, etc.
diff --git a/cddl/contrib/dtracetoolkit/Net/connections b/cddl/contrib/dtracetoolkit/Net/connections
new file mode 100755
index 0000000..523b880
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/connections
@@ -0,0 +1,178 @@
+#!/usr/bin/ksh
+#
+# connections - print inbound TCP connections by process.
+# Written in DTrace (Solaris 10 3/05).
+#
+# This displays the PID and command name of the processes accepting
+# connections, along with the source IP address and destination port number.
+#
+# $Id: connections 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: connections [-htvZ]
+#
+# -t # print timestamps, us
+# -v # print timestamps, string
+# -Z # print zonename
+# eg,
+# connections -v # snoop connections with times
+#
+# FIELDS:
+# UID user ID of the server
+# PID process ID for the server
+# CMD server command name
+# TIME timestamp, us
+# TIMESTR timestamp, string
+# PORT server port
+# IP_SOURCE source IP of the client, written in IPv4 style
+# ZONE zonename
+#
+# SEE ALSO: snoop 'tcp[13:1] = 0x02' # snoop new connections
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# TODO: IPv6
+#
+# 10-Apr-2004 Brendan Gregg Created this.
+# 23-May-2004 " " Fixed issues on SPARC.
+# 08-May-2005 " " Updated for newer Solaris 10.
+# 17-Jun-2005 " " Rewrote, changed probes, wrapped in sh.
+# 04-Dec-2005 " " Changed tcp_accept_finish -> sotpi_accept
+# 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+# 20-Apr-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_time=0; opt_timestr=0; opt_zone=0
+
+### Process options
+while getopts htvZ name
+do
+ case $name in
+ t) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: connections [-htvZ]
+ -t # print timestamps, us
+ -v # print timestamps, string
+ -Z # print zonename
+ eg,
+ connections -v # snoop connections with times
+ END
+ exit 1
+ esac
+done
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -C -s <( print -r '
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_zone = '$opt_zone';
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "TIMESTR") : 1;
+ OPT_zone ? printf("%-10s ", "ZONE") : 1;
+
+ /* print header */
+ printf("%5s %5s %-12s %4s %5s %s\n",
+ "UID", "PID", "CMD", "TYPE", "PORT", "IP_SOURCE");
+ }
+
+ /*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+ fbt:sockfs:sotpi_accept:entry
+ /(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+ {
+ self->sop = args[0];
+ }
+
+ fbt:sockfs:sotpi_create:return
+ /self->sop/
+ {
+ self->nsop = (struct sonode *)arg1;
+ }
+
+
+ /*
+ * Probe TCP connections
+ */
+ fbt:sockfs:sotpi_accept:return
+ /self->nsop/
+ {
+ /* fetch connection details */
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ this->connp = (conn_t *)this->tcpp->tcp_connp;
+
+#if defined(_BIG_ENDIAN)
+ this->port0 = this->connp->u_port.tcpu_ports.tcpu_lport;
+#else
+ this->port0 = BSWAP_16(this->connp->u_port.tcpu_ports.tcpu_lport);
+#endif
+ this->rem12 =
+ (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->rem13 =
+ (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->rem14 =
+ (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->rem15 =
+ (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%-10s ", zonename) : 1;
+
+ /* print output line */
+ printf("%5d %5d %-12s %4s %5d %d.%d.%d.%d\n",
+ uid, pid, execname, "tcp", this->port0,
+ this->rem12, this->rem13, this->rem14, this->rem15);
+ }
+
+ fbt:sockfs:sotpi_accept:return
+ {
+ self->nsop = 0;
+ self->sop = 0;
+ }
+')
+
diff --git a/cddl/contrib/dtracetoolkit/Net/icmpstat.d b/cddl/contrib/dtracetoolkit/Net/icmpstat.d
new file mode 100755
index 0000000..3df5199
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/icmpstat.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -s
+/*
+ * icmpstat.d - print ICMP statistics. Uses DTrace.
+ *
+ * This prints ICMP statistics every second, retrieved from the MIB provider.
+ * This is a simple script to demonstrate the ability to trace ICMP events.
+ *
+ * $Id: icmpstat.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: icmpstat.d
+ *
+ * FIELDS:
+ * STATISTIC ICMP statistic name
+ * VALUE total of statistic during sample
+ *
+ * The above ICMP statistics are documented in the mib2_icmp struct
+ * in the /usr/include/inet/mib2.h file; and also in the mib provider
+ * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 25-Jul-2005 Brendan Gregg Created this.
+ * 25-Jul-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Save Data
+ */
+mib:::icmp*
+{
+ @icmp[probename] = sum(arg0);
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+{
+ printf("%Y,\n\n", walltimestamp);
+ printf("%32s %8s\n", "STATISTIC", "VALUE");
+ printa("%32s %@8d\n", @icmp);
+ printf("\n");
+
+ trunc(@icmp);
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpsnoop b/cddl/contrib/dtracetoolkit/Net/tcpsnoop
new file mode 100755
index 0000000..e06912d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpsnoop
@@ -0,0 +1,581 @@
+#!/usr/bin/ksh
+#
+# tcpsnoop - snoop TCP network packets by process.
+# Written using DTrace (Solaris 10 3/05)
+#
+# This analyses TCP network packets and prints the responsible PID and UID,
+# plus standard details such as IP address and port. This captures traffic
+# of newly created TCP connections that were established while this program
+# was running. It can help identify which processes is causing TCP traffic.
+#
+# WARNING: This script may only work on Solaris 10 3/05, since it uses the
+# fbt provider to trace the raw operation of a specific version of the kernel.
+# In the future, a 'stable' network provider should exist which will allow
+# this to be written for that and subsequent versions of the kernel. In the
+# meantime, check for other versions of this script in the /Net directory,
+# and read the Notes/ALLfbt_notes.txt for more background on fbt.
+#
+# $Id: tcpsnoop 69 2007-10-04 13:40:00Z brendan $
+#
+# USAGE: tcpsnoop [-a|hjsvZ] [-n name] [-p pid]
+#
+# -a # print all data
+# -j # print project ID
+# -s # print time, us
+# -v # print time, string
+# -Z # print zone ID
+# -n name # command name to snoop
+# -p pid # PID to snoop
+# eg,
+# tcpsnoop -v # human readable timestamps
+# tcpsnoop -Z # print zonename
+# tcpsnoop -n sshd # snoop sshd traffic only
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# CMD command
+# LADDR local IP address
+# RADDR remote IP address
+# LPORT local port number
+# RPORT remote port number
+# DR direction
+# SIZE packet size, bytes
+# TIME timestamp, us
+# STRTIME human readable timestamp, string
+# ZONE zone ID
+# PROJ project ID
+#
+# SEE ALSO: snoop -rS
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# TODO: IPv6
+#
+# CODE:
+# The FILTER syntax matches on packets rather than initial
+# connections, so that it can follow inetd connections properly.
+#
+# 09-Jul-2004 Brendan Gregg Created this.
+# 12-Mar-2005 " " Changed probes, size info now printed.
+# 02-Jul-2005 " " Many more probes. Renamed "tcpsnoop.d".
+# 04-Jul-2005 " " Now wrapped in shell, called "tcpsnoop".
+# 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+# execname. Thanks Kias Belgaied for expertise.
+# 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+# 20-Apr-2006 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_name=0; opt_time=0; opt_timestr=0; filter=0; pname=.
+opt_zone=0; opt_proj=0; opt_pid=0; pid=0
+
+### process options
+while getopts ahjsvZn:p: name
+do
+ case $name in
+ a) opt_time=1; opt_timestr=1; opt_zone=1; opt_proj=1 ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ j) opt_proj=1 ;;
+ s) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: tcpsnoop [-a|hjsvZ] [-n name] [-p pid]
+ tcpsnoop # default output
+ -a # print all data
+ -j # print project ID
+ -s # print start time, us
+ -v # print start time, string
+ -Z # print zonename
+ -n name # command name to snoop
+ -p pid # PID to snoop
+ eg,
+ tcpsnoop -v # human readable timestamps
+ tcpsnoop -Z # print zonename
+ tcpsnoop -n sshd # snoop sshd traffic only
+ END
+ exit 1
+ esac
+done
+
+### option logic
+if (( opt_name || opt_pid )); then
+ filter=1
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -Cs <( print -r '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_name = '$opt_name';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_proj = '$opt_proj';
+ inline int PID = '$pid';
+ inline int FILTER = '$filter';
+ inline string NAME = "'$pname'";
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
+ OPT_zone ? printf("%4s ", "ZONE") : 1;
+ OPT_proj ? printf("%4s ", "PROJ") : 1;
+
+ /* print main headers */
+ printf("%5s %6s %-15s %5s %2s %-15s %5s %5s %s\n",
+ "UID", "PID", "LADDR", "LPORT", "DR", "RADDR", "RPORT",
+ "SIZE", "CMD");
+}
+
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+ OPT_proj ? tproj[(int)self->connp] = curpsinfo->pr_projid : 1;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+ tproj[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+/FILTER == 0/
+{
+ this->queuep = (queue_t *)`tcp_g_q; /* ` */
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+ self->zoneid = this->connp->conn_zoneid;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+/FILTER == 0/
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->proj = 0;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+ self->zoneid = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "->";
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "<-";
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+ self->dir = "->";
+}
+
+fbt:ip:tcp_connect:return
+/(self->connp) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* this packet occured before connp was fully established */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+}
+
+fbt:sockfs:sotpi_accept:return
+/(self->connp) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* these packets occured before connp was fully established */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "<-";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * Print output
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/(self->ok == 2) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+
+ /* print output line */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->dir = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+ self->zoneid = 0;
+ self->proj = 0;
+}
+')
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpsnoop.d b/cddl/contrib/dtracetoolkit/Net/tcpsnoop.d
new file mode 100755
index 0000000..ca01864
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpsnoop.d
@@ -0,0 +1,424 @@
+#!/usr/sbin/dtrace -Cs
+/*
+ * tcpsnoop.d - snoop TCP network packets by process.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This analyses TCP network packets and prints the responsible PID and UID,
+ * plus standard details such as IP address and port. This captures traffic
+ * of newly created TCP connections that were established while this program
+ * was running. It can help identify which processes is causing TCP traffic.
+ *
+ * WARNING: This script may only work on Solaris 10 3/05, since it uses the
+ * fbt provider to trace the raw operation of a specific version of the kernel.
+ * In the future, a 'stable' network provider should exist which will allow
+ * this to be written for that and subsequent versions of the kernel. In the
+ * meantime, check for other versions of this script in the /Net directory,
+ * and read the Notes/ALLfbt_notes.txt for more background on fbt.
+ *
+ * $Id: tcpsnoop.d 69 2007-10-04 13:40:00Z brendan $
+ *
+ * USAGE: tcpsnoop.d
+ *
+ * FIELDS:
+ * UID user ID
+ * PID process ID
+ * CMD command
+ * LADDR local IP address
+ * RADDR remote IP address
+ * LPORT local port number
+ * RPORT remote port number
+ * DR direction
+ * SIZE packet size, bytes
+ *
+ * SEE ALSO: snoop -rS
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * Author: Brendan Gregg [Sydney, Australia]
+ *
+ * TODO: IPv6
+ *
+ * 09-Jul-2004 Brendan Gregg Created this.
+ * 12-Mar-2005 " " Changed probes, size info now printed.
+ * 02-Jul-2005 " " Many more probes. Renamed "tcpsnoop.d".
+ * 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+ * execname. Thanks Kias Belgaied for expertise.
+ * 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* print main headers */
+ printf("%5s %6s %-15s %5s %2s %-15s %5s %5s %s\n",
+ "UID", "PID", "LADDR", "LPORT", "DR", "RADDR", "RPORT",
+ "SIZE", "CMD");
+}
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+{
+ this->queuep = (queue_t *)`tcp_g_q; /* ` */
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "->";
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "<-";
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->size = 54; /* should check trailers */
+ self->dir = "->";
+ /* this packet occured before connp was fully established */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->size = 54; /* should check trailers */
+ /* these packets occured before connp was fully established */
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * Print output
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/self->ok == 2/
+{
+ /* print output line */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->dir = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv b/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv
new file mode 100755
index 0000000..85ebb6c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv
@@ -0,0 +1,583 @@
+#!/usr/bin/ksh
+#
+# tcpsnoop_snv - snoop TCP network packets by process.
+# Written using DTrace (Solaris Nevada)
+#
+# This analyses TCP network packets and prints the responsible PID and UID,
+# plus standard details such as IP address and port. This captures traffic
+# of newly created TCP connections that were established while this program
+# was running. It can help identify which processes is causing TCP traffic.
+#
+# WARNING: This script may only work on Solaris Nevada and OpenSolaris
+# of the late 2007 vintage, since it uses the fbt provider to trace the raw
+# operation of a specific version of the kernel. In the future, a 'stable'
+# network provider should exist which will allow this to be written for that
+# and subsequent versions of the kernel. In the meantime, check for other
+# versions of this script in the /Net directory, and read the
+# Notes/ALLfbt_notes.txt for more background on fbt.
+#
+# $Id: tcpsnoop_snv 69 2007-10-04 13:40:00Z brendan $
+#
+# USAGE: tcpsnoop [-a|hjsvZ] [-n name] [-p pid]
+#
+# -a # print all data
+# -j # print project ID
+# -s # print time, us
+# -v # print time, string
+# -Z # print zone ID
+# -n name # command name to snoop
+# -p pid # PID to snoop
+# eg,
+# tcpsnoop -v # human readable timestamps
+# tcpsnoop -Z # print zonename
+# tcpsnoop -n sshd # snoop sshd traffic only
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# CMD command
+# LADDR local IP address
+# RADDR remote IP address
+# LPORT local port number
+# RPORT remote port number
+# DR direction
+# SIZE packet size, bytes
+# TIME timestamp, us
+# STRTIME human readable timestamp, string
+# ZONE zone ID
+# PROJ project ID
+#
+# SEE ALSO: snoop -rS
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# TODO: IPv6
+#
+# CODE:
+# The FILTER syntax matches on packets rather than initial
+# connections, so that it can follow inetd connections properly.
+#
+# 09-Jul-2004 Brendan Gregg Created this.
+# 12-Mar-2005 " " Changed probes, size info now printed.
+# 02-Jul-2005 " " Many more probes. Renamed "tcpsnoop.d".
+# 04-Jul-2005 " " Now wrapped in shell, called "tcpsnoop".
+# 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+# execname. Thanks Kias Belgaied for expertise.
+# 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+# 20-Apr-2006 " " Last update.
+# 30-Sep-2007 " " Bumped this for recent OpenSolaris/Nevada.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_name=0; opt_time=0; opt_timestr=0; filter=0; pname=.
+opt_zone=0; opt_proj=0; opt_pid=0; pid=0
+
+### process options
+while getopts ahjsvZn:p: name
+do
+ case $name in
+ a) opt_time=1; opt_timestr=1; opt_zone=1; opt_proj=1 ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ j) opt_proj=1 ;;
+ s) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: tcpsnoop [-a|hjsvZ] [-n name] [-p pid]
+ tcpsnoop # default output
+ -a # print all data
+ -j # print project ID
+ -s # print start time, us
+ -v # print start time, string
+ -Z # print zonename
+ -n name # command name to snoop
+ -p pid # PID to snoop
+ eg,
+ tcpsnoop -v # human readable timestamps
+ tcpsnoop -Z # print zonename
+ tcpsnoop -n sshd # snoop sshd traffic only
+ END
+ exit 1
+ esac
+done
+
+### option logic
+if (( opt_name || opt_pid )); then
+ filter=1
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -Cs <( print -r '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_name = '$opt_name';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_proj = '$opt_proj';
+ inline int PID = '$pid';
+ inline int FILTER = '$filter';
+ inline string NAME = "'$pname'";
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
+ OPT_zone ? printf("%4s ", "ZONE") : 1;
+ OPT_proj ? printf("%4s ", "PROJ") : 1;
+
+ /* print main headers */
+ printf("%5s %6s %-15s %5s %2s %-15s %5s %5s %s\n",
+ "UID", "PID", "LADDR", "LPORT", "DR", "RADDR", "RPORT",
+ "SIZE", "CMD");
+}
+
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+ OPT_proj ? tproj[(int)self->connp] = curpsinfo->pr_projid : 1;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+ tproj[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+/FILTER == 0/
+{
+ this->queuep = args[7]->tcps_g_q;
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+ self->zoneid = this->connp->conn_zoneid;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+/FILTER == 0/
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->proj = 0;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+ self->zoneid = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "->";
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "<-";
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+ self->dir = "->";
+}
+
+fbt:ip:tcp_connect:return
+/(self->connp) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* this packet occured before connp was fully established */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+}
+
+fbt:sockfs:sotpi_accept:return
+/(self->connp) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* these packets occured before connp was fully established */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "<-";
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * Print output
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/(self->ok == 2) &&
+ ((FILTER == 0) ||
+ (OPT_pid && self->pid == PID) ||
+ (OPT_name && self->name == NAME))/
+{
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%4d ", self->zoneid) : 1;
+ OPT_proj ? printf("%4d ", self->proj) : 1;
+
+ /* print output line */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->dir = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+ self->zoneid = 0;
+ self->proj = 0;
+}
+')
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv.d b/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv.d
new file mode 100755
index 0000000..b696f0e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpsnoop_snv.d
@@ -0,0 +1,426 @@
+#!/usr/sbin/dtrace -Cs
+/*
+ * tcpsnoop_snv.d - snoop TCP network packets by process.
+ * Written using DTrace (Solaris Nevada)
+ *
+ * This analyses TCP network packets and prints the responsible PID and UID,
+ * plus standard details such as IP address and port. This captures traffic
+ * of newly created TCP connections that were established while this program
+ * was running. It can help identify which processes is causing TCP traffic.
+ *
+ * WARNING: This script may only work on Solaris Nevada and OpenSolaris
+ * of the late 2007 vintage, since it uses the fbt provider to trace the raw
+ * operation of a specific version of the kernel. In the future, a 'stable'
+ * network provider should exist which will allow this to be written for that
+ * and subsequent versions of the kernel. In the meantime, check for other
+ * versions of this script in the /Net directory, and read the
+ * Notes/ALLfbt_notes.txt for more background on fbt.
+ *
+ * $Id: tcpsnoop_snv.d 69 2007-10-04 13:40:00Z brendan $
+ *
+ * USAGE: tcpsnoop.d
+ *
+ * FIELDS:
+ * UID user ID
+ * PID process ID
+ * CMD command
+ * LADDR local IP address
+ * RADDR remote IP address
+ * LPORT local port number
+ * RPORT remote port number
+ * DR direction
+ * SIZE packet size, bytes
+ *
+ * SEE ALSO: snoop -rS
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * Author: Brendan Gregg [Sydney, Australia]
+ *
+ * TODO: IPv6
+ *
+ * 09-Jul-2004 Brendan Gregg Created this.
+ * 12-Mar-2005 " " Changed probes, size info now printed.
+ * 02-Jul-2005 " " Many more probes. Renamed "tcpsnoop.d".
+ * 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+ * execname. Thanks Kias Belgaied for expertise.
+ * 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+ * 20-Apr-2006 " " Last update.
+ * 30-Sep-2007 " " Bumped this for recent OpenSolaris/Nevada.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* print main headers */
+ printf("%5s %6s %-15s %5s %2s %-15s %5s %5s %s\n",
+ "UID", "PID", "LADDR", "LPORT", "DR", "RADDR", "RPORT",
+ "SIZE", "CMD");
+}
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+{
+ this->queuep = args[7]->tcps_g_q;
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->size = 54; /* should check trailers */
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "->";
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->dir = "<-";
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->size = 54; /* should check trailers */
+ self->dir = "->";
+ /* this packet occured before connp was fully established */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->size = 54; /* should check trailers */
+ /* these packets occured before connp was fully established */
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "->";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+ self->dir = "<-";
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * Print output
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/self->ok == 2/
+{
+ /* print output line */
+ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n",
+ self->uid, self->pid, self->laddr, self->lport, self->dir,
+ self->faddr, self->fport, self->size, self->name);
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->dir = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpstat.d b/cddl/contrib/dtracetoolkit/Net/tcpstat.d
new file mode 100755
index 0000000..1fe4004
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpstat.d
@@ -0,0 +1,91 @@
+#!/usr/sbin/dtrace -s
+/*
+ * tcpstat.d - print TCP statistics. Uses DTrace.
+ *
+ * This prints TCP statistics every second, retrieved from the MIB provider.
+ *
+ * $Id: tcpstat.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: tcpstat.d
+ *
+ * FIELDS:
+ * TCP_out TCP bytes sent
+ * TCP_outRe TCP bytes retransmitted
+ * TCP_in TCP bytes received
+ * TCP_inDup TCP bytes received duplicated
+ * TCP_inUn TCP bytes received out of order
+ *
+ * The above TCP statistics are documented in the mib2_tcp struct
+ * in the /usr/include/inet/mib2.h file; and also in the mib provider
+ * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 15-May-2005 Brendan Gregg Created this.
+ * 15-May-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Declare Globals
+ */
+dtrace:::BEGIN
+{
+ TCP_out = 0; TCP_outRe = 0;
+ TCP_in = 0; TCP_inDup = 0; TCP_inUn = 0;
+ LINES = 20; line = 0;
+}
+
+/*
+ * Print Header
+ */
+profile:::tick-1sec { line--; }
+
+profile:::tick-1sec
+/line <= 0 /
+{
+ printf("%11s %11s %11s %11s %11s\n",
+ "TCP_out", "TCP_outRe", "TCP_in", "TCP_inDup", "TCP_inUn");
+
+ line = LINES;
+}
+
+/*
+ * Save Data
+ */
+mib:::tcpOutDataBytes { TCP_out += arg0; }
+mib:::tcpRetransBytes { TCP_outRe += arg0; }
+mib:::tcpInDataInorderBytes { TCP_in += arg0; }
+mib:::tcpInDataDupBytes { TCP_inDup += arg0; }
+mib:::tcpInDataUnorderBytes { TCP_inUn += arg0; }
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+{
+ printf("%11d %11d %11d %11d %11d\n",
+ TCP_out, TCP_outRe, TCP_in, TCP_inDup, TCP_inUn);
+
+ /* clear values */
+ TCP_out = 0;
+ TCP_outRe = 0;
+ TCP_in = 0;
+ TCP_inDup = 0;
+ TCP_inUn = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/tcptop b/cddl/contrib/dtracetoolkit/Net/tcptop
new file mode 100755
index 0000000..70b6e6f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcptop
@@ -0,0 +1,579 @@
+#!/usr/bin/ksh
+#
+# tcptop - display top TCP network packets by process.
+# Written using DTrace (Solaris 10 3/05)
+#
+# This analyses TCP network packets and prints the responsible PID and UID,
+# plus standard details such as IP address and port. This captures traffic
+# of newly created TCP connections that were established while this program
+# was running. It can help identify which processes is causing TCP traffic.
+#
+# WARNING: This script may only work on Solaris 10 3/05, since it uses the
+# fbt provider to trace the raw operation of a specific version of the kernel.
+# In the future, a 'stable' network provider should exist which will allow
+# this to be written for that and subsequent versions of the kernel. In the
+# meantime, check for other versions of this script in the /Net directory,
+# and read the Notes/ALLfbt_notes.txt for more background on fbt.
+#
+# $Id: tcptop 69 2007-10-04 13:40:00Z brendan $
+#
+# USAGE: tcptop [-Ch] [-j|-Z] [interval [count]]
+#
+# -C # don't clear the screen
+# -j # print project IDs
+# -Z # print zone IDs
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# CMD command
+# LADDR local IP address
+# RADDR remote IP address
+# LPORT local port number
+# RPORT remote port number
+# SIZE packet size, bytes
+# load 1 min load average
+# TCPin TCP inbound payload data
+# TCPout TCP outbound payload data
+# ZONE zone ID
+# PROJ project ID
+#
+# SEE ALSO: tcpsnoop
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# ToDo: IPv6
+#
+# 05-Jul-2005 Brendan Gregg Created this.
+# 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+# execname. Thanks Kias Belgaied for expertise.
+# 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+# 20-Apr-2006 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_def=1; opt_clear=1; opt_zone=0; opt_proj=0; interval=5; count=-1
+
+### process options
+while getopts ChjZ name
+do
+ case $name in
+ C) opt_clear=0 ;;
+ j) opt_proj=1; opt_def=0 ;;
+ Z) opt_zone=1; opt_def=0 ;;
+ h|?) cat <<-END >&2
+ USAGE: tcptop [-h] [-j|-Z] [interval [count]]
+ tcptop # default output
+ -C # don't clear the screen
+ -j # print project ID
+ -Z # print zonename
+ eg,
+ tcptop # default is 5 sec interval
+ tcptop 2 # 2 second interval
+ tcptop -C 1 10 # 10 x 1 sec samples, no clear
+ END
+ exit 1
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_proj && opt_zone )); then
+ opt_proj=0
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -Cs <( print -r '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_proj = '$opt_proj';
+ inline int OPT_clear = '$opt_clear';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline string CLEAR = "'$clearstr'";
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ TCP_out = 0;
+ TCP_in = 0;
+
+ printf("Tracing... Please wait.\n");
+}
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+ OPT_proj ? tproj[(int)self->connp] = curpsinfo->pr_projid : 1;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+ tproj[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+{
+ this->queuep = (queue_t *)`tcp_g_q; /* ` */
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+ self->zoneid = this->connp->conn_zoneid;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->proj = 0;
+ self->size = 54 * 2; /* should check trailers */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+
+ /* this packet occured before connp was fully established */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54 * 3; /* should check trailers */
+
+ /* these packets occured before connp was fully established */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Save data
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/self->ok == 2/
+{
+ /* save r+w data*/
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+ self->zoneid = 0;
+ self->proj = 0;
+}
+
+/*
+ * TCP Systemwide Stats
+ */
+mib:::tcpOutDataBytes { TCP_out += args[0]; }
+mib:::tcpRetransBytes { TCP_out += args[0]; }
+mib:::tcpInDataInorderBytes { TCP_in += args[0]; }
+mib:::tcpInDataDupBytes { TCP_in += args[0]; }
+mib:::tcpInDataUnorderBytes { TCP_in += args[0]; }
+
+/*
+ * Timer
+ */
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert TCP counters to Kbytes */
+ TCP_out /= 1024;
+ TCP_in /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, TCPin: %6d KB, TCPout: %6d KB\n\n",
+ walltimestamp, this->load1a, this->load1b, TCP_in, TCP_out);
+
+ /* print headers */
+ OPT_def ? printf(" UID ") : 1;
+ OPT_proj ? printf("PROJ ") : 1;
+ OPT_zone ? printf("ZONE ") : 1;
+ printf("%6s %-15s %5s %-15s %5s %9s %s\n",
+ "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE", "NAME");
+
+ /* print data */
+ printa("%4d %6d %-15s %5d %-15s %5d %@9d %s\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ TCP_in = 0;
+ TCP_out = 0;
+ secs = INTERVAL;
+ counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+ trunc(@out);
+}
+')
diff --git a/cddl/contrib/dtracetoolkit/Net/tcptop_snv b/cddl/contrib/dtracetoolkit/Net/tcptop_snv
new file mode 100755
index 0000000..56714e3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcptop_snv
@@ -0,0 +1,581 @@
+#!/usr/bin/ksh
+#
+# tcptop_snv - display top TCP network packets by process.
+# Written using DTrace (Solaris Nevada)
+#
+# This analyses TCP network packets and prints the responsible PID and UID,
+# plus standard details such as IP address and port. This captures traffic
+# of newly created TCP connections that were established while this program
+# was running. It can help identify which processes is causing TCP traffic.
+#
+# WARNING: This script may only work on Solaris Nevada and OpenSolaris
+# of the late 2007 vintage, since it uses the fbt provider to trace the raw
+# operation of a specific version of the kernel. In the future, a 'stable'
+# network provider should exist which will allow this to be written for that
+# and subsequent versions of the kernel. In the meantime, check for other
+# versions of this script in the /Net directory, and read the
+# Notes/ALLfbt_notes.txt for more background on fbt.
+#
+# $Id: tcptop_snv 69 2007-10-04 13:40:00Z brendan $
+#
+# USAGE: tcptop [-Ch] [-j|-Z] [interval [count]]
+#
+# -C # don't clear the screen
+# -j # print project IDs
+# -Z # print zone IDs
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# CMD command
+# LADDR local IP address
+# RADDR remote IP address
+# LPORT local port number
+# RPORT remote port number
+# SIZE packet size, bytes
+# load 1 min load average
+# TCPin TCP inbound payload data
+# TCPout TCP outbound payload data
+# ZONE zone ID
+# PROJ project ID
+#
+# SEE ALSO: tcpsnoop
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# ToDo: IPv6
+#
+# 05-Jul-2005 Brendan Gregg Created this.
+# 03-Dec-2005 " " Fixed tcp_accept_finish bug, now 100% correct
+# execname. Thanks Kias Belgaied for expertise.
+# 20-Apr-2006 " " Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
+# 20-Apr-2006 " " Last update.
+# 30-Sep-2007 " " Bumped this for recent OpenSolaris/Nevada.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_def=1; opt_clear=1; opt_zone=0; opt_proj=0; interval=5; count=-1
+
+### process options
+while getopts ChjZ name
+do
+ case $name in
+ C) opt_clear=0 ;;
+ j) opt_proj=1; opt_def=0 ;;
+ Z) opt_zone=1; opt_def=0 ;;
+ h|?) cat <<-END >&2
+ USAGE: tcptop [-h] [-j|-Z] [interval [count]]
+ tcptop # default output
+ -C # don't clear the screen
+ -j # print project ID
+ -Z # print zonename
+ eg,
+ tcptop # default is 5 sec interval
+ tcptop 2 # 2 second interval
+ tcptop -C 1 10 # 10 x 1 sec samples, no clear
+ END
+ exit 1
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_proj && opt_zone )); then
+ opt_proj=0
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -Cs <( print -r '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_proj = '$opt_proj';
+ inline int OPT_clear = '$opt_clear';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline string CLEAR = "'$clearstr'";
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+#include <sys/file.h>
+#include <inet/common.h>
+#include <sys/byteorder.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ TCP_out = 0;
+ TCP_in = 0;
+
+ printf("Tracing... Please wait.\n");
+}
+
+/*
+ * TCP Process inbound connections
+ *
+ * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
+ * renamed to SS_DIRECT around build 31.
+ */
+fbt:sockfs:sotpi_accept:entry
+/(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
+{
+ self->sop = args[0];
+}
+
+fbt:sockfs:sotpi_create:return
+/self->sop/
+{
+ self->nsop = (struct sonode *)arg1;
+}
+
+fbt:sockfs:sotpi_accept:return
+/self->nsop/
+{
+ this->tcpp = (tcp_t *)self->nsop->so_priv;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+}
+
+fbt:sockfs:sotpi_accept:return
+{
+ self->nsop = 0;
+ self->sop = 0;
+}
+
+/*
+ * TCP Process outbound connections
+ */
+fbt:ip:tcp_connect:entry
+{
+ this->tcpp = (tcp_t *)arg0;
+ self->connp = (conn_t *)this->tcpp->tcp_connp;
+ tname[(int)self->connp] = execname;
+ tpid[(int)self->connp] = pid;
+ tuid[(int)self->connp] = uid;
+ OPT_proj ? tproj[(int)self->connp] = curpsinfo->pr_projid : 1;
+}
+
+/*
+ * TCP Data translations
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ /* fetch ports */
+#if defined(_BIG_ENDIAN)
+ self->lport = self->connp->u_port.tcpu_ports.tcpu_lport;
+ self->fport = self->connp->u_port.tcpu_ports.tcpu_fport;
+#else
+ self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport);
+ self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport);
+#endif
+
+ /* fetch IPv4 addresses */
+ this->fad12 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
+ this->fad13 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
+ this->fad14 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
+ this->fad15 =
+ (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
+ this->lad12 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12];
+ this->lad13 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13];
+ this->lad14 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14];
+ this->lad15 =
+ (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15];
+
+ /* convert type for use with lltostr() */
+ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12;
+ this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13;
+ this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14;
+ this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15;
+ this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12;
+ this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13;
+ this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14;
+ this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15;
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ /* fix direction and save values */
+ tladdr[(int)self->connp] = self->laddr;
+ tfaddr[(int)self->connp] = self->faddr;
+ tlport[(int)self->connp] = self->lport;
+ tfport[(int)self->connp] = self->fport;
+
+ /* all systems go */
+ tok[(int)self->connp] = 1;
+}
+
+/*
+ * TCP Clear connp
+ */
+fbt:ip:tcp_get_conn:return
+{
+ /* Q_TO_CONN */
+ this->connp = (conn_t *)arg1;
+ tok[(int)this->connp] = 0;
+ tpid[(int)this->connp] = 0;
+ tuid[(int)this->connp] = 0;
+ tname[(int)this->connp] = 0;
+ tproj[(int)this->connp] = 0;
+}
+
+/*
+ * TCP Process "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:entry
+{
+ this->queuep = args[7]->tcps_g_q;
+ this->connp = (conn_t *)this->queuep->q_ptr;
+ this->tcpp = (tcp_t *)this->connp->conn_tcp;
+ self->zoneid = this->connp->conn_zoneid;
+
+ /* split addresses */
+ this->ipha = (ipha_t *)args[1]->b_rptr;
+ this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24;
+ this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16;
+ this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8;
+ this->fad12 = (this->ipha->ipha_src & 0x000000ff);
+ this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24;
+ this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16;
+ this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8;
+ this->lad12 = (this->ipha->ipha_dst & 0x000000ff);
+
+ /* stringify addresses */
+ self->faddr = strjoin(lltostr(this->fad12), ".");
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), "."));
+ self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), "."));
+ self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0));
+ self->laddr = strjoin(lltostr(this->lad12), ".");
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), "."));
+ self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), "."));
+ self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0));
+
+ self->reset = 1;
+}
+
+/*
+ * TCP Fetch "port closed" ports
+ */
+fbt:ip:tcp_xchg:entry
+/self->reset/
+{
+#if defined(_BIG_ENDIAN)
+ self->lport = (uint16_t)arg0;
+ self->fport = (uint16_t)arg1;
+#else
+ self->lport = BSWAP_16((uint16_t)arg0);
+ self->fport = BSWAP_16((uint16_t)arg1);
+#endif
+ self->lport = BE16_TO_U16(arg0);
+ self->fport = BE16_TO_U16(arg1);
+}
+
+/*
+ * TCP Print "port closed"
+ */
+fbt:ip:tcp_xmit_early_reset:return
+{
+ self->name = "<closed>";
+ self->pid = 0;
+ self->uid = 0;
+ self->proj = 0;
+ self->size = 54 * 2; /* should check trailers */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ self->reset = 0;
+ self->size = 0;
+ self->name = 0;
+}
+
+/*
+ * TCP Process Write
+ */
+fbt:ip:tcp_send_data:entry
+{
+ self->conn_p = (conn_t *)args[0]->tcp_connp;
+}
+
+fbt:ip:tcp_send_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->size = msgdsize(args[2]) + 14; /* should check trailers */
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Process Read
+ */
+fbt:ip:tcp_rput_data:entry
+{
+ self->conn_p = (conn_t *)arg0;
+ self->size = msgdsize(args[1]) + 14; /* should check trailers */
+}
+
+fbt:ip:tcp_rput_data:entry
+/tok[(int)self->conn_p]/
+{
+ self->uid = tuid[(int)self->conn_p];
+ self->laddr = tladdr[(int)self->conn_p];
+ self->faddr = tfaddr[(int)self->conn_p];
+ self->lport = tlport[(int)self->conn_p];
+ self->fport = tfport[(int)self->conn_p];
+ OPT_proj ? self->proj = tproj[(int)self->conn_p] : 1;
+ self->zoneid = self->conn_p->conn_zoneid;
+ self->ok = 2;
+
+ /* follow inetd -> in.* transitions */
+ self->name = pid && (tname[(int)self->conn_p] == "inetd") ?
+ execname : tname[(int)self->conn_p];
+ self->pid = pid && (tname[(int)self->conn_p] == "inetd") ?
+ pid : tpid[(int)self->conn_p];
+ tname[(int)self->conn_p] = self->name;
+ tpid[(int)self->conn_p] = self->pid;
+}
+
+/*
+ * TCP Complete printing outbound handshake
+ */
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54; /* should check trailers */
+
+ /* this packet occured before connp was fully established */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Complete printing inbound handshake
+ */
+fbt:sockfs:sotpi_accept:return
+/self->connp/
+{
+ self->name = tname[(int)self->connp];
+ self->pid = tpid[(int)self->connp];
+ self->uid = tuid[(int)self->connp];
+ self->zoneid = self->connp->conn_zoneid;
+ OPT_proj ? self->proj = tproj[(int)self->connp] : 1;
+ self->size = 54 * 3; /* should check trailers */
+
+ /* these packets occured before connp was fully established */
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Save data
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+/self->ok == 2/
+{
+ /* save r+w data*/
+ OPT_def ? @out[self->uid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_zone ? @out[self->zoneid, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+ OPT_proj ? @out[self->proj, self->pid, self->laddr, self->lport,
+ self->faddr, self->fport, self->name] = sum(self->size) : 1;
+}
+
+/*
+ * TCP Clear connect variables
+ */
+fbt:sockfs:sotpi_accept:return,
+fbt:ip:tcp_connect:return
+/self->connp/
+{
+ self->faddr = 0;
+ self->laddr = 0;
+ self->fport = 0;
+ self->lport = 0;
+ self->connp = 0;
+ self->name = 0;
+ self->pid = 0;
+ self->uid = 0;
+}
+
+/*
+ * TCP Clear r/w variables
+ */
+fbt:ip:tcp_send_data:entry,
+fbt:ip:tcp_rput_data:entry
+{
+ self->ok = 0;
+ self->uid = 0;
+ self->pid = 0;
+ self->size = 0;
+ self->name = 0;
+ self->lport = 0;
+ self->fport = 0;
+ self->laddr = 0;
+ self->faddr = 0;
+ self->conn_p = 0;
+ self->zoneid = 0;
+ self->proj = 0;
+}
+
+/*
+ * TCP Systemwide Stats
+ */
+mib:::tcpOutDataBytes { TCP_out += args[0]; }
+mib:::tcpRetransBytes { TCP_out += args[0]; }
+mib:::tcpInDataInorderBytes { TCP_in += args[0]; }
+mib:::tcpInDataDupBytes { TCP_in += args[0]; }
+mib:::tcpInDataUnorderBytes { TCP_in += args[0]; }
+
+/*
+ * Timer
+ */
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert TCP counters to Kbytes */
+ TCP_out /= 1024;
+ TCP_in /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, TCPin: %6d KB, TCPout: %6d KB\n\n",
+ walltimestamp, this->load1a, this->load1b, TCP_in, TCP_out);
+
+ /* print headers */
+ OPT_def ? printf(" UID ") : 1;
+ OPT_proj ? printf("PROJ ") : 1;
+ OPT_zone ? printf("ZONE ") : 1;
+ printf("%6s %-15s %5s %-15s %5s %9s %s\n",
+ "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE", "NAME");
+
+ /* print data */
+ printa("%4d %6d %-15s %5d %-15s %5d %@9d %s\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ TCP_in = 0;
+ TCP_out = 0;
+ secs = INTERVAL;
+ counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+ trunc(@out);
+}
+')
diff --git a/cddl/contrib/dtracetoolkit/Net/tcpwdist.d b/cddl/contrib/dtracetoolkit/Net/tcpwdist.d
new file mode 100755
index 0000000..20753c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/tcpwdist.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -s
+/*
+ * tcpwdist.d - simple TCP write distribution by process.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * This measures the size of writes from applications to the TCP level, which
+ * may well be much larger than the MTU size (this is application writes not
+ * packet writes). It can help identify which process is creating network
+ * traffic, and the size of the writes by that application. It uses a simple
+ * probe that produces meaningful output for most protocols.
+ *
+ * Tracking TCP activity by process is complex for a number of reasons,
+ * the greatest is that inbound TCP traffic is asynchronous to the process.
+ * The easiest TCP traffic to match is writes, which this script demonstrates.
+ * However there are still issues - for an inbound telnet connection the
+ * writes are associated with the command, for example "ls -l", not something
+ * meaningful such as "in.telnetd".
+ *
+ * Scripts that match TCP traffic properly include tcpsnoop and tcptop.
+ *
+ * $Id: tcpwdist.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: tcpwdist.d # wait several seconds, then hit Ctrl-C
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD command and argument list
+ * value TCP write payload size in bytes
+ * count number of writes
+ *
+ * SEE ALSO: tcpsnoop, tcptop
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Jul-2004 Brendan Gregg Created this.
+ * 14-Jun-2005 " " Rewrote this as tcpwdist.d.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+/*
+ * Process TCP Write
+ */
+fbt:ip:tcp_output:entry
+{
+ /* fetch details */
+ this->size = msgdsize(args[1]);
+
+ /* store details */
+ @Size[pid, curpsinfo->pr_psargs] = quantize(this->size);
+}
+
+/*
+ * Print final report
+ */
+dtrace:::END
+{
+ printa(" PID: %-6d CMD: %S\n%@d\n", @Size);
+}
diff --git a/cddl/contrib/dtracetoolkit/Net/udpstat.d b/cddl/contrib/dtracetoolkit/Net/udpstat.d
new file mode 100755
index 0000000..7b27e4e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Net/udpstat.d
@@ -0,0 +1,92 @@
+#!/usr/sbin/dtrace -s
+/*
+ * udpstat.d - print UDP statistics. Uses DTrace.
+ *
+ * This prints UDP statistics every second, retrieved from the MIB provider.
+ *
+ * $Id: udpstat.d 59 2007-10-03 08:21:58Z brendan $
+ *
+ * USAGE: udpstat.d
+ *
+ * FIELDS:
+ * UDP_out UDP datagrams sent
+ * UDP_outErr UDP datagrams errored on send
+ * UDP_in UDP datagrams received
+ * UDP_inErr UDP datagrams undeliverable
+ * UDP_noPort UDP datagrams received to closed ports
+ *
+ * The above UDP statistics are documented in the mib2_udp struct
+ * in the /usr/include/inet/mib2.h file; and also in the mib provider
+ * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 25-Jul-2005 Brendan Gregg Created this.
+ * 25-Jul-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Declare Globals
+ */
+dtrace:::BEGIN
+{
+ UDP_in = 0; UDP_out = 0;
+ UDP_inErr = 0; UDP_outErr = 0; UDP_noPort = 0;
+ LINES = 20; line = 0;
+}
+
+/*
+ * Print Header
+ */
+profile:::tick-1sec { line--; }
+
+profile:::tick-1sec
+/line <= 0 /
+{
+ printf("%11s %11s %11s %11s %11s\n",
+ "UDP_out", "UDP_outErr", "UDP_in", "UDP_inErr", "UDP_noPort");
+
+ line = LINES;
+}
+
+/*
+ * Save Data
+ */
+mib:::udp*InDatagrams { UDP_in += arg0; }
+mib:::udp*OutDatagrams { UDP_out += arg0; }
+mib:::udpInErrors { UDP_inErr += arg0; }
+mib:::udpInCksumErrs { UDP_inErr += arg0; }
+mib:::udpOutErrors { UDP_outErr += arg0; }
+mib:::udpNoPorts { UDP_noPort += arg0; }
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+{
+ printf("%11d %11d %11d %11d %11d\n",
+ UDP_out, UDP_outErr, UDP_in, UDP_inErr, UDP_noPort);
+
+ /* clear values */
+ UDP_out = 0;
+ UDP_outErr = 0;
+ UDP_in = 0;
+ UDP_inErr = 0;
+ UDP_noPort = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLcolors_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLcolors_notes.txt
new file mode 100644
index 0000000..bed6f95
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLcolors_notes.txt
@@ -0,0 +1,127 @@
+**************************************************************************
+* The following are additional notes on all programs that print a colorized
+* ("colourised") output, *color*.d.
+*
+* $Id: ALLcolors_notes.txt 58 2007-10-01 13:36:29Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+* The colors aren't working, I see rubbish characters
+
+Try using a terminal that supports colors, such as gnome-terminal or dtterm.
+
+The following text should test the spectrum of colors for your terminal.
+Read this using "more" or "cat" (not "less" or "vim") to check if your
+terminal will print colors, and what they will look like:
+
+ Color Test String Dark Background
+ ---------------------------------------------------------
+ black color test color test
+ red color test color test
+ green color test color test
+ yellow color test color test
+ blue color test color test
+ magenta color test color test
+ cyan color test color test
+ white color test color test
+
+and now for a test of attributes:
+
+ Color Bold Faint
+ ---------------------------------------------------------
+ black color test color test
+ red color test color test
+ green color test color test
+ yellow color test color test
+ blue color test color test
+ magenta color test color test
+ cyan color test color test
+ white color test color test
+
+
+* Why so much green and violet in the toolkit scripts?
+
+As DTrace can examine the entire software stack, it is conceivable that
+your script could print events from many different layers each with their
+own color. Color scripts in the DTraceToolkit generally start by tracing
+two layers, with extra layers added by the end user as needed (you). The
+general plan is:
+
+ Software Layer Example Provider Color
+ -------------------------------------------------------
+ Dynamic Language perl violet
+ User Library pid:libperl blue
+ OS Library pid:libc cyan
+ System Calls syscall green
+ Kernel and Drivers fbt red
+
+How these colors will look will depend on your terminal software. Useful
+variations can be made, for example using red/bold for kernel abstraction
+providers (io, vminfo, ...); and red/faint for raw kernel tracing (fbt).
+
+The color examples in this toolkit usually trace the syscall and dynamic
+language layers, hense the green and violet.
+
+
+* I don't like the choosen terminal colors / your colors suck
+
+It should be easy to customize them by tweaking the script. I've tried
+to use the following convention for declaring colors in D scripts:
+
+ dtrace:::BEGIN
+ {
+ color_shell = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+ }
+
+That way, printf() statements can print these string variables to turn
+on and off colors, as needed. These strings contain an escape sequence to
+inform your terminal software to change the output color. Customizations
+can be made by tweaking the variables; refer to documentation for your
+terminal software to see what numbers will print what colors.
+
+For my terminal (dtterm), the numbers are (from dtterm(5)):
+
+ Attributes
+
+ 1 bold
+ 2 faint
+
+ Forground colors
+
+ 30 black
+ 31 red
+ 32 green
+ 33 yellow
+ 34 blue
+ 35 magenta
+ 36 cyan
+ 37 white
+
+ Background colors
+
+ 40 black
+ 41 red
+ ... etc, as above
+
+
+* I'd like to use this colored output on a website.
+
+The easiest way would be to change the script to output HTML rather than
+escape sequences. eg:
+
+ dtrace:::BEGIN
+ {
+ color_shell = "<font color=\"#FFAAFF\">"; /* violet, faint */
+ color_line = "<font color=\"#FF44FF\">"; /* violet, bold */
+ color_syscall = "<font color=\"#44CC44\">"; /* green, faint */
+ color_off = "</font>"; /* default */
+ }
+
+Other tweaks can be made to either print the output in a <pre> tagged block;
+or as seperate lines ending in <br> along with changing the font to be
+fixed width.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLelapsed_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLelapsed_notes.txt
new file mode 100644
index 0000000..9e8f314
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLelapsed_notes.txt
@@ -0,0 +1,46 @@
+**************************************************************************
+* The following are notes for all scripts that measure elapsed time.
+*
+* $Id: ALLelapsed_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What is "elapsed" time?
+
+Elapsed time is the absolute time from one point to another. This time
+includes everything that happened between these points, including
+off-CPU time due to other system events such as I/O, scheduling,
+interrupts, etc. It also includes the small overheads of DTrace itself.
+
+Elapsed times are useful for identifying where latencies are, since
+regardless of their nature (CPU, I/O, ...), they will be visible in
+elapsed time.
+
+Since elapsed times don't filter out anything, they are suseptible to
+"noise" - random system events that are unrelated to the analysis target.
+For that reason, it may be best to take several measurements of elapsed
+time and take the average (or run your workload several times and let
+DTrace take the average).
+
+See Notes/ALLoncpu_notes.txt for a description of a different time
+measurement, "on-CPU" time.
+
+
+* How is "elapsed" time measured?
+
+In DTrace, the following template provides elapsed time as "this->elapsed",
+
+ <start-probe>
+ {
+ self->start = timestamp;
+ }
+
+ <end-probe>
+ {
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ ...
+ }
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLexclusive_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLexclusive_notes.txt
new file mode 100644
index 0000000..7aeb9ff
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLexclusive_notes.txt
@@ -0,0 +1,78 @@
+**************************************************************************
+* Notes for all scripts that print exclusive function times (or method,
+* or subroutine).
+*
+* $Id: ALLexclusive_notes.txt 45 2007-09-17 08:54:56Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What is "exclusive" function time?
+
+This is the time of function execution, from when the function begins to
+when it completes, excluding the time spent executing any child function.
+
+Exclusive function time can be calculated like this,
+
+ exclusive function time = time(function end) - time(function start) -
+ time(total child exclusive time)
+
+To do this, the DTrace script needs to keep trace of child function execution
+time, so that it can be subtracted from the parent execution time.
+
+Consider this Bourne shell program,
+ 1 #!./sh
+ 2
+ 3 func_c()
+ 4 {
+ 5 echo "Function C"
+ 6 sleep 1
+ 7 }
+ 8
+ 9 func_b()
+ 10 {
+ 11 echo "Function B"
+ 12 sleep 1
+ 13 func_c
+ 14 }
+ 15
+ 16 func_a()
+ 17 {
+ 18 echo "Function A"
+ 19 sleep 1
+ 20 func_b
+ 21 }
+ 22
+ 23 func_a
+
+func_a() calls func_b() which calls func_c(). Tracing the flow using
+sh_flowtime.d shows,
+
+# ./sh_flowtime.d | cat -n
+ 1 C TIME(us) FILE DELTA(us) -- NAME
+ 2 0 3052991099265 func_abc.sh 2 -> func_a
+ 3 0 3052991099324 func_abc.sh 59 > echo
+ 4 0 3052992111638 func_abc.sh 1012314 | sleep
+ 5 0 3052992111678 func_abc.sh 39 -> func_b
+ 6 0 3052992111729 func_abc.sh 51 > echo
+ 7 0 3052993121633 func_abc.sh 1009903 | sleep
+ 8 0 3052993121693 func_abc.sh 60 -> func_c
+ 9 0 3052993121745 func_abc.sh 52 > echo
+ 10 0 3052994131634 func_abc.sh 1009888 | sleep
+ 11 0 3052994131685 func_abc.sh 50 <- func_c
+ 12 0 3052994131699 func_abc.sh 14 <- func_b
+ 13 0 3052994131707 func_abc.sh 7 <- func_a
+
+the output of DTrace was piped through "cat -n" to enumerate the lines.
+
+Exclusive function time for func_a() in the above output would be the
+time from line 2 to line 13 minus the time from line 5 to 12 to subtract
+the time spent in both func_b() and func_c(). Or, you could say that
+exclusive time for func_a() is the time from lines 2 to 4.
+
+Looking back at the code, exclusive time for func_a() is the time spent
+in code lines 18 and 19 (and not line 20).
+
+See Notes/ALLinclusive_notes.txt for details on "inclusive" function time.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLfbt_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLfbt_notes.txt
new file mode 100644
index 0000000..ef5f2b8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLfbt_notes.txt
@@ -0,0 +1,77 @@
+**************************************************************************
+* The following are notes for any script that uses the "fbt" provider.
+* To identify these scripts, check the "STABILITY" section of the script's
+* man page, or try grepping for "fbt" on the script.
+*
+* $Id: ALLfbt_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+What is the "fbt" provider?...
+
+* A DTrace library of probes that instruments raw kernel function calls.
+* An "unstable" provider; meaning, scripts written using "fbt" are not
+ guarenteed to work on future versions of the OS - including after
+ patching the kernel.
+
+In a perfect world...
+
+* None of the DTraceToolkit scripts would use the "fbt" provider; instead
+ they would all use stable providers such as "proc", "sched", "io", etc.
+* All the DTraceToolkit scripts would run on any system that supports DTrace.
+
+In the real world...
+
+* Not all stable providers exist yet. Many are in development, such as
+ stable networking providers.
+* In the meantime, useful tools such as "tcpsnoop" and "tcptop" can
+ only be written using the unstable "fbt" provider (and these scripts have
+ broken several times due to kernel changes since they were first written).
+* "fbt" provider based scripts,
+ - only run on a particular OS (eg, Solaris)
+ - may only run on a particular version of an OS (eg, Solaris 10 3/05)
+ - are likely to break for future OS releases (eg, Solaris 10 6/06)
+* "fbt" provider based scripts also make the impossible possible, albiet
+ in a very unstable way, as a temporary solution while stable providers
+ are still in development.
+* Once stable providers exist, "fbt" scripts can be rewritten to use them;
+ however these new scripts will only run on newer OS builds that support
+ the stable providers. (in other words, this won't help you if you remain
+ on Solaris 10 6/06; you'll need to upgrade, or survive with "fbt").
+* Only some of the DTraceToolkit scripts use "fbt", and only a portion of
+ those have encountered stability issues - so this issue is limited.
+
+The "fbt" provider exports raw kernel implementation, which isn't guarenteed
+to be stable nor should it ever be (to do so would freeze kernel development
+and bug fixes). The only practical solution is the development and
+integration of stable providers (although that doesn't help people who keep
+running older versions of the OS).
+
+More harm than good?...
+
+Is the inclusion of these "fbt" scripts more harm than good? Consider,
+
+* the good,
+ - shows what is possible with DTrace
+ - should help a number of people solve specific performance issues,
+ on systems where they run
+ - a customer who really wants these scripts but on an OS version
+ where they don't work, have at least the source as a starting
+ point (and in some cases, the fix was trivial)
+
+* the bad,
+ - teases and frustrates people who find these scripts don't work
+ on their OS
+
+To minimise this issue, only a small number of "fbt" scripts have been
+included, and they have been documented (see their man page) as unstable.
+
+Can I help?...
+
+If you really like an "fbt" based script and would like to keep using it
+in a stable way, it may help to raise that with your vendor (Sun for Solaris,
+Apple for MacOS). Sun has OpenSolaris forums, such as dtrace-discuss, which
+are read by their engineers and the public.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLflow_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLflow_notes.txt
new file mode 100644
index 0000000..4571491
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLflow_notes.txt
@@ -0,0 +1,64 @@
+**************************************************************************
+* Notes for all scripts that print a function or method flow.
+*
+* $Id: ALLflow_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What is a flow?
+
+Output that has some meaningful indent, such as function flow indented by
+stack depth. eg,
+
+ # ./pl_flow.d
+ C TIME(us) FILE -- SUB
+ 0 2963130861619 func_abc.pl -> func_a
+ 0 2963131870998 func_abc.pl -> func_b
+ 0 2963132871121 func_abc.pl -> func_c
+ 0 2963133881150 func_abc.pl <- func_c
+ 0 2963133881166 func_abc.pl <- func_b
+ 0 2963133881174 func_abc.pl <- func_a
+ ^C
+
+
+* The output looks shuffled?
+
+Eg,
+
+ # ./pl_flow.d
+ C TIME(us) FILE -- SUB
+ 0 2963130861619 func_abc.pl -> func_a
+ 0 2963131870998 func_abc.pl -> func_b
+ 0 2963132871121 func_abc.pl -> func_c
+ 0 2963133881166 func_abc.pl <- func_b
+ 0 2963133881174 func_abc.pl <- func_a
+ 1 2963133881150 func_abc.pl <- func_c
+ ^C
+
+Yes, this is shuffled. DTrace has been designed with a number of important
+goals in mind - including minimising the enabled performance overhead. To do
+this, per-CPU kernel buffers have been used to collect output, which are
+(currently) dumped in sequence by /usr/sbin/dtrace whenever it wakes
+up ("switchrate" tunable). So, on multi-CPU servers, there is always the
+possibility that any DTrace script can print out-of-order data.
+
+To deal with this behaviour, the flow scripts may,
+
+- print a "C" CPU column. If this changes from one line to the next then
+ the output is probably shuffled around that point. This is why the "C"
+ column appears in these flow scripts.
+- print a "TIME(us)" column. You can eyeball this for shuffles, or just
+ post sort the dtrace output.
+
+Now have a closer look at the pl_flow.d output above. The change in C
+indicates that a shuffle may have happened, and the out-of-order TIME(us)
+shows that it did happen.
+
+It is possible that DTrace will be enhanced to always sort output before
+printing, and this behaviour is no longer an issue.
+
+See "The output seems shuffled?" in Notes/ALLsnoop_notes.txt for more
+notes on this behaviour.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLinclusive_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLinclusive_notes.txt
new file mode 100644
index 0000000..eea4b5d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLinclusive_notes.txt
@@ -0,0 +1,74 @@
+**************************************************************************
+* Notes for all scripts that print inclusive function times (or method,
+* or subroutine).
+*
+* $Id: ALLinclusive_notes.txt 45 2007-09-17 08:54:56Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What is "inclusive" function time?
+
+This is the time of function execution, from when the function begins to
+when it completes. This includes the times from all child functions called.
+
+Inclusive function time is calculated in a very simple way,
+
+ inclusive function time = time(function end) - time(function start)
+
+Consider this Bourne shell program,
+
+ 1 #!./sh
+ 2
+ 3 func_c()
+ 4 {
+ 5 echo "Function C"
+ 6 sleep 1
+ 7 }
+ 8
+ 9 func_b()
+ 10 {
+ 11 echo "Function B"
+ 12 sleep 1
+ 13 func_c
+ 14 }
+ 15
+ 16 func_a()
+ 17 {
+ 18 echo "Function A"
+ 19 sleep 1
+ 20 func_b
+ 21 }
+ 22
+ 23 func_a
+
+func_a() calls func_b() which calls func_c(). Tracing the flow using
+sh_flowtime.d shows,
+
+# ./sh_flowtime.d | cat -n
+ 1 C TIME(us) FILE DELTA(us) -- NAME
+ 2 0 3052991099265 func_abc.sh 2 -> func_a
+ 3 0 3052991099324 func_abc.sh 59 > echo
+ 4 0 3052992111638 func_abc.sh 1012314 | sleep
+ 5 0 3052992111678 func_abc.sh 39 -> func_b
+ 6 0 3052992111729 func_abc.sh 51 > echo
+ 7 0 3052993121633 func_abc.sh 1009903 | sleep
+ 8 0 3052993121693 func_abc.sh 60 -> func_c
+ 9 0 3052993121745 func_abc.sh 52 > echo
+ 10 0 3052994131634 func_abc.sh 1009888 | sleep
+ 11 0 3052994131685 func_abc.sh 50 <- func_c
+ 12 0 3052994131699 func_abc.sh 14 <- func_b
+ 13 0 3052994131707 func_abc.sh 7 <- func_a
+
+the output of DTrace was piped through "cat -n" to enumerate the lines.
+
+Inclusive function time for func_a() in the above output would be the
+time from line 2 to line 13. This inclusive time includes the time
+for both func_b() and func_c().
+
+Looking back at the code, inclusive time for func_a() is the time spent
+in code lines 18, 19 and 20.
+
+See Notes/ALLexclusive_notes.txt for details on "exclusive" function time.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLjava_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLjava_notes.txt
new file mode 100644
index 0000000..2d033c1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLjava_notes.txt
@@ -0,0 +1,35 @@
+**************************************************************************
+* Notes for all scripts that trace Java using the hotspot provider.
+*
+* $Id: ALLjava_notes.txt 52 2007-09-24 04:28:01Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+* I see "drops"
+
+If you see the following output,
+
+ dtrace: 2547 drops on CPU 0
+
+This means that JVM events (usually methods) were executed too quickly for
+DTrace to keep up, and as a safety measure DTrace has let events slip by.
+This means, at least, that the output is missing lines. At worst, the
+output may contain corrupted values (time deltas between events that were
+dropped).
+
+If you see drops, you should first ask yourself whether you need to be
+tracing such frequent events at all - is there another way to get the same
+data? For example, see the j_profile.d script, which uses a different
+technique (sampling) than most of the other Java scripts (tracing).
+
+You can try tweaking DTrace tunables to prevent DTrace from dropping events.
+A key tunable is "bufsize", and can be set in scripts like so,
+
+ #pragma D option bufsize=32m
+
+That line means that 32 Mbytes will be allocated to the DTrace primary
+buffer per-CPU (how depends on bufpolicy). If you have many CPUs, say 8,
+then the above line means that 256 Mbytes (32 * 8) will be allocated as a
+buffer while your D script is running.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLoncpu_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLoncpu_notes.txt
new file mode 100644
index 0000000..41aead0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLoncpu_notes.txt
@@ -0,0 +1,42 @@
+**************************************************************************
+* The following are notes for all scripts that measure on-CPU times.
+*
+* $Id: ALLoncpu_notes.txt 58 2007-10-01 13:36:29Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What is "on-CPU" time?
+
+This is the time that a thread spent running on a CPU. It does not include
+time spent off-CPU time such as sleeping for I/O or waiting for scheduling.
+
+On-CPU times are useful for showing who is causing the CPUs to be busy,
+since they measure how much CPU time has been consumed by that thread.
+
+On-CPU times are also less susceptible to system "noise" than elapsed times,
+since much of the noise will be filtered out. DTrace itself also tries
+to subtract the small overheads of DTrace from the on-CPU time, to improve
+the accuracy of this time.
+
+See Notes/ALLelapsed_notes.txt for a description of a different time
+measurement, "elapsed" time.
+
+
+* How is "on-CPU" time measured?
+
+In DTrace, the following template provides on-CPU time as "this->oncpu",
+
+ <start-probe>
+ {
+ self->vstart = vtimestamp;
+ }
+
+ <end-probe>
+ {
+ this->oncpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ ...
+ }
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLoverhead.txt b/cddl/contrib/dtracetoolkit/Notes/ALLoverhead.txt
new file mode 100644
index 0000000..844b3c0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLoverhead.txt
@@ -0,0 +1,96 @@
+**************************************************************************
+* The following are notes regarding the overheads of running DTrace.
+*
+* $Id: ALLoverhead.txt 58 2007-10-01 13:36:29Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+The following are notes regarding the overheads of running DTrace.
+
+* What are the overheads of running DTrace?
+
+Often negligible.
+
+It depends what the DTrace script does, in particular, the frequency of
+events that it is tracing.
+
+The following tips should explain what the overheads probably are,
+
+- if your script traces less than 1000 events per second, then the overhead
+ is probably negligible. ie, less than 0.1% CPU.
+- if your script traces more than 100,000 events per second, then the
+ overhead will start to be significant. If you are tracing kernel events,
+ then perhaps this could be 10% per CPU. If you are tracing user land
+ application events, then the overhead can be greater than 30% per CPU.
+- if your script produes pages of output, then the CPU cost of drawing
+ this output to the screen and rendering the fonts is usually far greater
+ than DTrace itself. Redirect the output of DTrace to a file in /tmp
+ ("-o" or ">").
+- a ballpark figure for the overhead of a DTrace probe would be 500 ns.
+ This can be much less (kernel only), or much more (many user to kerel
+ copyin()s); I've provided it to give you a very rough idea. Of course,
+ as CPUs become faster, this overhead will become smaller.
+
+If overheads are a concern - then perform tests to measure their magnitude
+for both your workload and the scripts applied, such as benchmarks with
+and without DTrace running. Also read the scripts you are using, and
+consider how frequent the probes will fire, and if you can customise the
+script to reduce the frequency of probes.
+
+For example, scripts that trace,
+
+ pid$target:::entry,
+ pid$target:::return
+
+would usually cause significant performance overhead, since they fire two
+probes for every function called (and can easily reach 100,000 per second).
+You could reduce this by modifying the script to only trace the libraries
+you are interested in. For example, if you were only interested in
+libsocket and libnsl, then change the above lines wherever they appeared to,
+
+ pid$target:libsocket::entry,
+ pid$target:libsocket::return,
+ pid$target:libnsl::entry,
+ pid$target:libnsl::return
+
+and you may notice the overheads are significantly reduced (especially anytime
+you drop libc and libdl). To go further, only list functions of interest,
+
+ pid$target:libsocket:connect:entry,
+ pid$target:libsocket:connect:return,
+ pid$target:libsocket:listen:entry,
+ pid$target:libsocket:listen:return,
+ [...]
+
+There are additional notes in Docs/Faq about the DTraceToolkit's scripts
+and performance overhead.
+
+
+* When are the overheads a problem?
+
+When they are significant (due to frequent events), and you are tracing
+in a production environment that is sensitive to additional CPU load.
+
+Overheads should be considered if you are measuring times (delta, elapsed,
+on-CPU, etc) for performance analysis. In practise, overheads aren't
+that much of a problem -- the script will either identify your issues
+correctly (great), or not (keep looking). Any it is usually easy to quickly
+confirm what DTrace does find by using other tools, or by hacking quick
+code changes. You might be using DTrace output that you know has a
+significant margin of error - but that becomes moot after you prove that
+the performance fix works through benchmarking a quick fix.
+
+At the end of the day, if DTrace helps find real measurable performance wins
+(and it should), then it has been successful.
+
+
+* When are overheads not a problem?
+
+When the script is not tracing extreamly frequent events.
+
+Also, when you are in development and tracing events for troubleshooting
+purposes (args to functions, for example), DTrace overheads are usually
+not an issue at all.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLperl_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLperl_notes.txt
new file mode 100644
index 0000000..2403950
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLperl_notes.txt
@@ -0,0 +1,44 @@
+**************************************************************************
+* The following are notes for all the Perl tracing scripts,
+*
+* $Id: ALLperl_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* Where did those "BEGIN" subroutine calls come from?
+
+The following counts subroutines from the example program, Code/Perl/hello.pl,
+
+ # pl_subcalls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE SUB CALLS
+
+no subroutines were called, so there is no data to output.
+
+Now a similar program is traced, Code/Perl/hello_strict.pl, which uses
+the "strict" pragma,
+
+ # pl_subcalls.d
+ Tracing... Hit Ctrl-C to end.
+ ^C
+ FILE SUB CALLS
+ hello_strict.pl BEGIN 1
+ strict.pm bits 1
+ strict.pm import 1
+
+not only were functions from "strict.pm" traced, but a "BEGIN" function
+ran from the "hello_strict.pl" program - which doesn't appear to use "BEGIN",
+
+ # cat -n ../Code/Perl/hello_strict.pl
+ 1 #!./perl -w
+ 2
+ 3 use strict;
+ 4
+ 5 print "Hello World!\n";
+
+Perl appears to add a BEGIN block to process the "use" keyword. This makes
+some degree of sense.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/ALLsnoop_notes.txt b/cddl/contrib/dtracetoolkit/Notes/ALLsnoop_notes.txt
new file mode 100644
index 0000000..b43c70a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/ALLsnoop_notes.txt
@@ -0,0 +1,94 @@
+**************************************************************************
+* The following are additional notes on ALL of the *snoop programs (such as
+* execsnoop, iosnoop, ..., and dapptrace, dtruss).
+*
+* $Id: ALLsnoop_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* The output seems shuffled?
+
+Beware - due to the (current) way DTrace works, on multi-CPU systems there
+is no guarentee that if you print traced events the output is in the same
+order that the events occured.
+
+This is because events details are placed in kernel per-CPU buffers, and then
+dumped in sequence by the DTrace consumer (/usr/sbin/dtrace) whenever it
+wakes up ("switchrate" tunable). The DTrace consumer reads and prints the
+buffers one by one, it doesn't combine them and sort them.
+
+To demonstrate this,
+
+ # dtrace -n 'profile:::profile-3hz { trace(timestamp); }'
+ dtrace: description 'profile-3hz ' matched 1 probe
+ CPU ID FUNCTION:NAME
+ 0 41241 :profile-3hz 1898015274778547
+ 0 41241 :profile-3hz 1898015608118262
+ 0 41241 :profile-3hz 1898015941430060
+ 1 41241 :profile-3hz 1898015275499014
+ 1 41241 :profile-3hz 1898015609173485
+ 1 41241 :profile-3hz 1898015942505828
+ 2 41241 :profile-3hz 1898015275351257
+ 2 41241 :profile-3hz 1898015609180861
+ 2 41241 :profile-3hz 1898015942512708
+ 3 41241 :profile-3hz 1898015274803528
+ 3 41241 :profile-3hz 1898015608120522
+ 3 41241 :profile-3hz 1898015941449884
+ ^C
+
+If you read the timestamps carefully, you'll see that they aren't quite
+in chronological order. If you look at the CPU column while reading the
+timestamps, the way DTrace works should become clear.
+
+Most of the snoop tools have a switchrate of 10hz, so events may be shuffled
+within a tenth of a second - not hugely noticable.
+
+This isn't really a problem anyway. If you must have the output in the correct
+order, find the switch that prints timestamps and then sort the output.
+As an example,
+
+ # iosnoop -t > out.iosnoop
+ ^C
+ # sort -n out.iosnoop
+
+ TIME UID PID D BLOCK SIZE COMM PATHNAME
+ 183710958520 0 3058 W 10507848 4096 sync /var/log/pool/poold
+ 183710990358 0 3058 W 6584858 1024 sync /etc/motd
+ 183711013469 0 3058 W 60655 9216 sync <none>
+ 183711020149 0 3058 W 60673 1024 sync <none>
+
+All shell-wrapped scripts should have some way to print timestamps, and
+many DTrace-only scripts print timestamps by default. If you find a script
+that doesn't print timestamps, it should be trivial for you to add an
+extra column.
+
+To add a microsecond-since-boot time column to a script, try adding this
+before every printf() you find,
+
+ printf("%-16d ", timestamp / 1000);
+
+except for the header line, where you can add this,
+
+ printf("%-16s ", "TIME(us)");
+
+Now you will be able to post sort the script output on the TIME(us) column.
+
+In practise, I find post sorting the output a little annoying at times,
+and use a couple of other ways to prevent shuffling from happening in the
+first place:
+
+- offline all CPUs but one when running flow scripts. Naturally, you
+ probably don't want to do this on production servers, this is a trick
+ that may be handy for when developing on workstations or laptops. Bear
+ in mind that if you are trying to DTrace certain issues, such as
+ multi-thread locking contention, then offlining most CPUs may eliminate
+ the issue you are trying to observe.
+- pbind the target process of interest to a single CPU. Most OSes provide
+ a way to glue a process to a single CPU; Solaris has both pbind and psrset.
+
+Another way to solve this problem would be to enhance DTrace to always print
+in-order output. Maybe this will be done one day; maybe by the time you
+are reading this it has already been done?
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/Readme b/cddl/contrib/dtracetoolkit/Notes/Readme
new file mode 100644
index 0000000..99a1807
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/Readme
@@ -0,0 +1,21 @@
+Notes - Discussion about tools and their output
+
+ This directory contains files that provide deeper discussions about
+ tools and their output.
+
+ Files are either named,
+
+ ALL*_notes.txt - notes that cover a collection of tools
+ *_notes.txt - notes that cover a specific tool
+
+ These files are exist as an informal place to dump "stuff". This might
+ range from caveats to bear in mind when interpreting tool output, to
+ general or bizzare knowledge. Tool documentation is placed in,
+
+ /Man - formal man pages
+ /Examples - demos and how to read the output
+ *.d - implementation notes within the code itself
+ /Notes - everything else
+
+ Many of the scripts and man pages refer to files in this directory.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/cputimes_notes.txt b/cddl/contrib/dtracetoolkit/Notes/cputimes_notes.txt
new file mode 100644
index 0000000..cdf7ecd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/cputimes_notes.txt
@@ -0,0 +1,138 @@
+**************************************************************************
+* The following are additional notes on the cputimes command.
+*
+* $Id: cputimes_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* How cputimes works
+
+cputimes measures time consumed by the kernel, idle therads and processes,
+by tracking the activity of the schedular. In particular we track on-cpu
+and off-cpu events for kernel therads, measuring the timestamps at each event.
+
+
+* Why cputimes?
+
+If you are interested in how much time processes are consuming, the data
+given by "prstat" or "prstat -m" is fine. However there is no easy way to
+see kernel consumed time, which is the idea behind cputimes.
+
+
+* What does it mean?
+
+The output shows categories of threads by the sum of time, in nanoseconds.
+
+A nanosecond is 10^-9, or 0.000000001 of a second. This program uses
+nanoseconds as units, but does not have nanosecond accuracy. It would be
+reasonable to assume that this has microsecond accuracy (10^-6), so in
+practise ignore the last three digits of the times.
+
+The sections reported are,
+
+PROCESSES - the sum of all the process time on the CPU.
+KERNEL - the sum of the time spent in the kernel.
+IDLE - the time the kernel spent in the idle thread, waiting for some work.
+
+If your system isn't doing much, then the idle time will be quite large. If
+your system is running many applications, then there may be no idle time
+at all - instead most of the time appearing under processes.
+
+
+* When is there a problem?
+
+Expect to see most of the time in processes or idle, depending on how busy
+your server is. Seeing a considerable amout of time in kernel would
+definately be interesting.
+
+The kernel generally doesn't use much CPU time, usually less than 5%.
+If it were using more, that may indicate heavy activity from an interrupt
+thread, or activity caused by DTrace.
+
+For example,
+
+ # cputimes 1
+ 2005 Apr 27 23:49:32,
+ THREADS TIME (ns)
+ IDLE 28351679
+ KERNEL 436022725
+ PROCESS 451304688
+
+In this sample the kernel is using a massive amount of the CPUs, around 47%.
+This sample was taken during heavy network utilisation, the time consumed
+by the TCP/IP and network driver threads (and DTrace). The "intrstat" command
+could be used for further analysis of the interrupt threads responsible
+for servicing the network interface.
+
+
+* Problems with cputimes
+
+The way cputimes measures schedular activity turns out to be a lot of work.
+There are many scheduling events per second where one thread steps onto a
+CPU and another leaves. It turns out that cputimes itself causes some degree
+of kernel load.
+
+Here we run 1 cputimes,
+
+ # cputimes 1
+ 2005 May 15 12:00:41,
+ THREADS TIME (ns)
+ KERNEL 12621985
+ PROCESS 982751579
+ 2005 May 15 12:00:42,
+ THREADS TIME (ns)
+ KERNEL 12267577
+ PROCESS 983513765
+ [...]
+
+Now a second cputimes is run at the same time,
+
+ # cputimes 1
+ 2005 May 15 12:02:06,
+ THREADS TIME (ns)
+ KERNEL 17366426
+ PROCESS 978804165
+ 2005 May 15 12:02:07,
+ THREADS TIME (ns)
+ KERNEL 17614829
+ PROCESS 978671601
+ [...]
+
+And now a third,
+
+ # cputimes 1
+ 2005 May 15 12:03:09,
+ THREADS TIME (ns)
+ KERNEL 21303089
+ PROCESS 974925124
+ 2005 May 15 12:03:10,
+ THREADS TIME (ns)
+ KERNEL 21222992
+ PROCESS 975152727
+ [...]
+
+Each extra cputimes is consuming an extra 4 to 5 ms of the CPU as kernel time.
+Around 0.5%. This can be used as an estimate of the kernel load caused by
+running cputimes, and a similar strategy could be used to measure the kernel
+load of other DTrace scripts.
+
+However the following CPU characteristics must be taken into consideration,
+
+ # psrinfo -v
+ Status of virtual processor 0 as of: 05/15/2005 12:06:05
+ on-line since 04/30/2005 13:32:32.
+ The i386 processor operates at 867 MHz,
+ and has an i387 compatible floating point processor.
+
+as well as the type of activity that was also running on the system, which
+cputimes was monitoring (frequency of scheduling events).
+
+A system with a slower CPU will use a larger proportion of kernel time to
+perform the same tasks. Also, a system that is context switching more
+(switching between different processes) is likely to consume more kernel time
+as well.
+
+
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/dappprof_notes.txt b/cddl/contrib/dtracetoolkit/Notes/dappprof_notes.txt
new file mode 100644
index 0000000..d617f2a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/dappprof_notes.txt
@@ -0,0 +1,14 @@
+**************************************************************************
+* The following are extra notes on the dappprof command.
+*
+* $Id: dappprof_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* Can I trust the elapsed and on-cpu times?
+
+See the documentation for this point in the dtruss_notes.txt file.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/dapptrace_notes.txt b/cddl/contrib/dtracetoolkit/Notes/dapptrace_notes.txt
new file mode 100644
index 0000000..579c2df
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/dapptrace_notes.txt
@@ -0,0 +1,19 @@
+**************************************************************************
+* The following are extra notes on the dapptrace command.
+*
+* $Id: dapptrace_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* Can I trust the elapsed and on-cpu times?
+
+See the documentation for this point in the dtruss_notes.txt file.
+
+
+
+* The output appears shuffled?
+
+Read the answer to this in ALLsnoop_notes.txt.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/dtruss_notes.txt b/cddl/contrib/dtracetoolkit/Notes/dtruss_notes.txt
new file mode 100644
index 0000000..8ecbecf
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/dtruss_notes.txt
@@ -0,0 +1,97 @@
+**************************************************************************
+* The following are additional notes on the dtruss program.
+*
+* $Id: dtruss_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* Can I trust the elapsed and on-cpu times?
+
+Firstly, lets see dtruss do something cool,
+
+ # dtruss -eo -n bash
+ PID/LWP ELAPSD CPU SYSCALL(args) = return
+ 6215/1: 57 37 write(0x2, "h\0", 0x1) = 1 0
+ 6215/1: 357210 45 read(0x0, "e\0", 0x1) = 1 0
+ 6215/1: 53 37 write(0x2, "e\0", 0x1) = 1 0
+ 6215/1: 359510 46 read(0x0, "l\0", 0x1) = 1 0
+ 6215/1: 57 42 write(0x2, "l\0", 0x1) = 1 0
+ 6215/1: 166495 47 read(0x0, "l\0", 0x1) = 1 0
+ 6215/1: 56 40 write(0x2, "l\0", 0x1) = 1 0
+ 6215/1: 346076 44 read(0x0, "o\0", 0x1) = 1 0
+ 6215/1: 54 38 write(0x2, "o\0", 0x1) = 1 0
+ 6215/1: 349852 45 read(0x0, " \0", 0x1) = 1 0
+ 6215/1: 54 39 write(0x2, " \0", 0x1) = 1 0
+
+In the above, the slow elapsed times for reads are due to the process context
+switching off the CPU while we wait for the next keystroke. For example,
+the second line shows an on-CPU time of 45 us and an elapsed time of 357210 us.
+In fact, the elapsed times are equal to the inter-keystroke delays.
+
+
+What about the writes? Their elapsed times are longer than the on-CPU times
+also. Did we context switch off for them too? ... Lets run a different demo,
+
+ # dtruss -eo date
+ ELAPSD CPU SYSCALL(args) = return
+ Mon Jul 25 21:41:40 EST 2005
+ 44 23 resolvepath("/usr/bin/date\0", 0x80476CC, 0x3FF) = 13 0
+ 10 1 sysconfig(0x6, 0xB25A1, 0xFEC1D444) = 4096 0
+ 36 28 resolvepath("/usr/lib/ld.so.1\0", 0x80476CC, 0x3FF) = 12 0
+ 18 9 xstat(0x2, 0x8047FEB, 0x8047AF8) = 0 0
+ 25 16 open("/var/ld/ld.config\0", 0x0, 0x0) = -1 Err#2
+ 27 18 xstat(0x2, 0xD27FBF38, 0x80473B0) = 0 0
+ 17 9 resolvepath("/lib/libc.so.1\0", 0x8047438, 0x3FF) = 14 0
+ 21 13 open("/lib/libc.so.1\0", 0x0, 0x0) = 3 0
+ 30 22 mmap(0x10000, 0x1000, 0x5) = -763559936 0
+ 15 6 mmap(0x10000, 0xCE000, 0x0) = -764411904 0
+ 24 16 mmap(0xD2700000, 0xB5A45, 0x5) = -764411904 0
+ 21 12 mmap(0xD27C6000, 0x5EB3, 0x3) = -763600896 0
+ 18 9 mmap(0xD27CC000, 0x15C0, 0x3) = -763576320 0
+ 14 5 munmap(0xD27B6000, 0x10000) = 0 0
+ 186 176 memcntl(0xD2700000, 0x1B8D8, 0x4) = 0 0
+ 17 7 close(0x3) = 0 0
+ [...]
+
+For every syscall, the elapsed time is around 10 us (microseconds) slower
+than the on-cpu time. These aren't micro context switches, this is due to
+DTrace slowing down the program! The more closely we measure something the
+more we effect it. (See Heisenberg's uncertainty principle).
+
+Ok, so for the above output we can tell that each elapsed time is around 10 us
+longer than it should be. That's fine, since it's fairly consistant and not
+a huge difference. This is an x86 server with a 867 MHz CPU.
+
+
+Now lets try the same on an Ultra 5 with a 360 MHz CPU,
+
+ # dtruss -eo date
+ ELAPSD CPU SYSCALL(args) = return
+ 216 142 resolvepath("/usr/bin/date\0", 0xFFBFF338, 0x3FF) = 13 0
+ 234 187 resolvepath("/usr/lib/ld.so.1\0", 0xFFBFF338, 0x3FF) = 12 0
+ 113 67 stat("/usr/bin/date\0", 0xFFBFF818, 0xFFBFFFEB) = 0 0
+ 136 90 open("/var/ld/ld.config\0", 0x0, 0x0) = -1 Err#2
+ 107 61 stat("/opt/onbld/lib/libc.so.1\0", 0xFFBFF330, 0xFFBFF55C) = -1 Err#2
+ 98 54 stat("/opt/SUNWspro/lib/libc.so.1\0", 0xFFBFF330, 0xFFBFF55C) = -1 Err#2
+ 96 53 stat("/opt/SUNWmlib/lib/libc.so.1\0", 0xFFBFF330, 0xFFBFF55C) = -1 Err#2
+ 97 54 stat("/usr/sfw/lib/libc.so.1\0", 0xFFBFF330, 0xFFBFF55C) = -1 Err#2
+ 96 53 stat("/lib/libc.so.1\0", 0xFFBFF330, 0xFFBFF55C) = 0 0
+ 134 92 resolvepath("/lib/libc.so.1\0", 0xFFBFEF30, 0x3FF) = 14 0
+ 109 69 open("/lib/libc.so.1\0", 0x0, 0x0) = 3 0
+ 177 132 mmap(0x10000, 0x2000, 0x5) = -12976128 0
+ [...]
+
+Now the time difference is around 40 us, and fairly consistant.
+
+
+This difference is find so long as we bear it in mind. Or, run DTrace
+on faster servers where the difference is much less.
+
+
+
+* The output appears shuffled?
+
+Read the answer to this in ALLsnoop_notes.txt.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/iosnoop_notes.txt b/cddl/contrib/dtracetoolkit/Notes/iosnoop_notes.txt
new file mode 100644
index 0000000..af3ab9b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/iosnoop_notes.txt
@@ -0,0 +1,99 @@
+**************************************************************************
+* The following are additional notes on the iosnoop program.
+*
+* $Id: iosnoop_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* What does the output represent?
+
+The output is disk events - I/O operations that cause the disk to physically
+read or write data. The output is not application I/O events which may be
+absorbed by memory caches - many of which will be. The output really is
+physical disk events.
+
+iosnoop uses probes from the "io" provider - which traces the block device
+driver before disk events happen. disk events. The stack goes like this,
+
+ application
+ |
+ V
+ syscall
+ |
+ V
+ vfs
+ |
+ V
+ ufs/zfs/...
+ |
+ V
+ block device driver
+ |
+ V
+ physical device driver
+ |
+ V
+ disk
+
+Due to caching (after vfs) few events will make it to the disk for iosnoop
+to see. If you want to trace all I/O activity, try using syscall provider
+based scripts first.
+
+
+* What do the elapsed and delta times mean?
+
+Glad you asked!
+
+The times may *not* be as useful as they appear. I should also add that
+this quickly becomes a very complex topic,
+
+There are two different delta times reported. -D prints the
+elapsed time from the disk request (strategy) to the disk completion
+iodone); -o prints the time for the disk to complete that event
+since it's last event (time between iodones, or since idle->strategy).
+
+The elapsed time is equivalent to the response time from the application
+request to the application completion. The delta time resembles the
+service time for this request (resembles means it will be generally
+correct, but not 100% accurate). The service time is the the time for the
+disk to complete the request, after it has travelled through any bus or
+queue.
+
+buuuttt.... you need to think carefully about what these times mean before
+jumping to conclusions. For example,
+
+ You troubleshoot an application by running iosnoop and filtering
+ on your application's PID. You notice large times for the disk events
+ (responce, service, for this example it doesn't matter).
+ Does this mean there is a problem with that application?
+ What could be happening is that a different application is also using
+ the disks at the same time, and is causing the disk heads to seek to
+ elsewhere on the disk surface - increasing both service and response time.
+
+hmmm! so you can't just look at one application, one set of numbers, and
+understand fully what is going on.
+
+But it gets worse. Disks implement "tagged queueing", where events in the
+queue are reshuffeled to promote "elevator seeking" of the disk heads (this
+reduces head seeking). So the time for a disk event can be effected not
+just by the previous event (and previous location the heads had seeked to),
+but the surrounding events that enter the queue.
+
+So the good and the bad. The good news is that iosnoop makes it easy to
+fetch disk event data on a live system, the bad news is that understanding
+all the data is not really easy.
+
+For further information on disk measurements see,
+
+ "How do disks really work?" - Adrian Cockcroft, SunWorld Online, June 1996
+ "Sun Performance and Tuning" - Adrian Cockcroft, Richard Pettit
+ "Solaris Internals" - Richard McDougall, Jim Mauro
+
+
+
+* The output appears shuffled?
+
+Read the answer to this in ALLsnoop_notes.txt.
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/iotop_notes.txt b/cddl/contrib/dtracetoolkit/Notes/iotop_notes.txt
new file mode 100644
index 0000000..9663ec7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/iotop_notes.txt
@@ -0,0 +1,48 @@
+**************************************************************************
+* The following are additional notes on the iotop program.
+*
+* $Id: iotop_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* When using -P, how can a process exceed 100% I/O?
+
+These percentages are based on disk time. They are in terms of a single disk.
+
+200% could mean 2 disks @ 100%, or 4 @ 50%, or some such combination.
+
+I could have capped it at 100% by dividing by disk count. I didn't. Disk
+utilisation is an asymmetric resource (unlike CPUs, which are (mostly)
+symmetric), so it's unfair to divide by all the disks capacity as an
+application cannot use every disks capacity (eg, writing to a /opt disk only).
+
+Would it be wise to report utilisation as 10% of overall capacity, if it
+could mean that 1 disk was SATURATED out of ten? A value of 10% could
+understate the problem.
+
+Instead I add the utilisations and don't divide. 1 disk saturated out of 10
+would be reported as 100% utilisation. This has the danger of overstating
+the problem (consider all ten disks at 10% utilisation, this would also be
+reported as 100%).
+
+Nothing is perfect when you are summarising to a single value!
+
+
+
+* Beware of overcounting metadevices, such as SVM and Veritas.
+
+The current version of iotop reports on anything the kernel believes to be
+a block disk device. A problem happens when a metadevice contains physical
+disk devices, and iotop reports on activity to both the metadevice and
+the physical devices, which overcounts activity.
+
+Consider a metadevice that contains two physical disks which are both
+running at 100% utilised. iotop -P may report 300% utilisation, which is
+200% for the disks + 100% for the metadevice. We'd probably want to see
+a value of 200%, not 300%. Eliminating the counting of metadevices in DTrace
+isn't easy (without inelegant "hardwiring" of device types), however I do
+intend to find a way to fix this in future versions.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Notes/procsystime_notes.txt b/cddl/contrib/dtracetoolkit/Notes/procsystime_notes.txt
new file mode 100644
index 0000000..5e1c52f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Notes/procsystime_notes.txt
@@ -0,0 +1,14 @@
+**************************************************************************
+* The following are extra notes on the procsystime command.
+*
+* $Id: procsystime_notes.txt 44 2007-09-17 07:47:20Z brendan $
+*
+* COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+**************************************************************************
+
+
+* Can I trust the elapsed and on-cpu times?
+
+See the documentation for this point in the dtruss_notes.txt file.
+
+
diff --git a/cddl/contrib/dtracetoolkit/Perl/Readme b/cddl/contrib/dtracetoolkit/Perl/Readme
new file mode 100644
index 0000000..36fcab5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/Readme
@@ -0,0 +1,38 @@
+Perl - DTracing Perl
+
+ These scripts trace the Perl programming language, and require a version
+ of Perl to be built with the DTrace probes patch applied.
+
+ The Perl DTrace provider was originally written by Alan Burlison, and
+ later rewritten by Richard Dawe. These scripts were written and tested
+ with Richard's patch to perl, which can be found in the comments on
+ Alan's original blog entry,
+
+ http://blogs.sun.com/alanbur/entry/dtrace_and_perl
+
+ To get this and these scripts working, the rough steps are,
+
+ 1. Download and extract perl 5.8.8 (www.cpan.org)
+ 2. Download Richard's patch
+ 3. Apply Richard's patch (gpatch -p1 -i patchfile)
+ 4. sh Configure
+ 5. make perldtrace.h
+ 6. /usr/sbin/dtrace -h -s perldtrace.d -o perldtrace.h
+ 7. make
+
+ If things go awry, you might find help by asking on the
+ dtrace-discuss@opensolaris.org mailing list.
+
+ Since the DTrace Perl provider may be developed further, there is a chance
+ that it has changed slightly by the time you are reading this, causing
+ these scripts to either break or behave oddly. Firstly, check for newer
+ versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider perl {
+ probe sub-entry(subroutine, file, lineno)
+ probe sub-return(subroutine, file, lineno)
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_calldist.d b/cddl/contrib/dtracetoolkit/Perl/pl_calldist.d
new file mode 100755
index 0000000..a4bd2da
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_calldist.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_calldist.d - measure Perl elapsed times for subroutines.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_calldist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Perl activity from all programs running on the system with
+ * Perl provider support.
+ *
+ * USAGE: pl_calldist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Perl subroutines.
+ * Use pl_calltime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Perl program
+ * 2 Type of call (sub)
+ * 3 Name of call
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->sub[self->depth] = timestamp;
+}
+
+perl*:::sub-return
+/self->sub[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->sub[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->sub[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @types_incl[this->file, "sub", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "sub", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive subroutine elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive subroutine elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_calltime.d b/cddl/contrib/dtracetoolkit/Perl/pl_calltime.d
new file mode 100755
index 0000000..0bf1804
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_calltime.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_calltime.d - measure Perl elapsed times for subroutines.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_calltime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Perl activity from all programs running on the system with
+ * Perl provider support.
+ *
+ * USAGE: pl_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Perl program
+ * TYPE Type of call (sub/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->sub[self->depth] = timestamp;
+}
+
+perl*:::sub-return
+/self->sub[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->sub[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->sub[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "sub", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "sub", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "sub", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive subroutine elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive subroutine elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_cpudist.d b/cddl/contrib/dtracetoolkit/Perl/pl_cpudist.d
new file mode 100755
index 0000000..94c421f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_cpudist.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_cpudist.d - measure Perl on-CPU times for subroutines.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_cpudist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Perl activity from all programs running on the system with
+ * Perl provider support.
+ *
+ * USAGE: pl_cpudist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Perl subrotines.
+ * Use pl_cputime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Perl program
+ * 2 Type of call (sub)
+ * 3 Name of call
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->sub[self->depth] = vtimestamp;
+}
+
+perl*:::sub-return
+/self->sub[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->sub[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->sub[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @types_incl[this->file, "sub", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "sub", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive subroutine on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive subroutine on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_cputime.d b/cddl/contrib/dtracetoolkit/Perl/pl_cputime.d
new file mode 100755
index 0000000..150f204
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_cputime.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_cputime.d - measure Perl on-CPU times for subroutines.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_cputime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Perl activity from all programs running on the system with
+ * Perl provider support.
+ *
+ * USAGE: pl_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Perl program
+ * TYPE Type of call (sub/total)
+ * NAME Name of call (subroutine name)
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->sub[self->depth] = vtimestamp;
+}
+
+perl*:::sub-return
+/self->sub[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->sub[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->sub[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "sub", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "sub", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "sub", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive subroutine on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive subroutine on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_flow.d b/cddl/contrib/dtracetoolkit/Perl/pl_flow.d
new file mode 100755
index 0000000..7948db2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_flow.d
@@ -0,0 +1,70 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_flow.d - snoop Perl execution showing subroutine flow.
+ * Written for the Solaris Perl DTrace provider.
+ *
+ * $Id: pl_flow.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Perl activity from all Perl programs on the system
+ * running with Perl provider support.
+ *
+ * USAGE: pl_flow.d # hit Ctrl-C to end
+ *
+ * This watches Perl subroutine entries and returns, and indents child
+ * subroutine calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this subroutine belongs to
+ * SUB Subroutine name
+ *
+ * LEGEND:
+ * -> subroutine entry
+ * <- subroutine return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s -- %s\n", "C", "TIME(us)", "FILE", "SUB");
+}
+
+perl*:::sub-entry
+{
+ printf("%3d %-16d %-16s %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+}
+
+perl*:::sub-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), self->depth * 2, "", copyinstr(arg0));
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_flowinfo.d b/cddl/contrib/dtracetoolkit/Perl/pl_flowinfo.d
new file mode 100755
index 0000000..06769fd
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_flowinfo.d
@@ -0,0 +1,86 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_flowinfo.d - snoop Perl subroutine flow with info using DTrace.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_flowinfo.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Perl programs on the system that are
+ * running with Perl provider support.
+ *
+ * USAGE: pl_flowinfo.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Perl program
+ * LINE Line number of filename
+ * TYPE Type of call (sub)
+ * SUB Perl subroutine
+ *
+ * LEGEND:
+ * -> subroutine entry
+ * <- subroutine return
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "SUB");
+}
+
+perl*:::sub-entry,
+perl*:::sub-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+perl*:::sub-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg1)), arg2, "sub", self->depth * 2, "",
+ copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+perl*:::sub-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg1)), arg2, "sub", self->depth * 2, "",
+ copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_flowtime.d b/cddl/contrib/dtracetoolkit/Perl/pl_flowtime.d
new file mode 100755
index 0000000..1fa727c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_flowtime.d
@@ -0,0 +1,88 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_flowtime.d - snoop Perl subroutines with flow and delta times.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_flowtime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces shell activity from Perl programs on the system that are
+ * running with Perl provider support.
+ *
+ * USAGE: pl_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches Perl subroutine entries and returns, and indents child
+ * subroutine calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this subroutine belongs to
+ * DELTA(us) Elapsed time from previous line to this line
+ * SUB Perl subroutine name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+self int last;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "SUB");
+}
+
+perl*:::sub-entry,
+perl*:::sub-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+perl*:::sub-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), this->delta, self->depth * 2, "",
+ copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+perl*:::sub-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %9d %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), this->delta, self->depth * 2, "",
+ copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_malloc.d b/cddl/contrib/dtracetoolkit/Perl/pl_malloc.d
new file mode 100755
index 0000000..b71e765
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_malloc.d
@@ -0,0 +1,81 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_malloc.d - Perl libc malloc analysis.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_malloc.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This is an expiremental script to identify who is calling malloc() for
+ * memory allocation, and to print distribution plots of the requested bytes.
+ * If a malloc() occured while in a Perl subroutine, then that subroutine is
+ * identified as responsible; else the caller of malloc() is identified as
+ * responsible - which will be a function from the Perl engine.
+ *
+ * USAGE: pl_malloc.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl$target:::sub-entry
+{
+ self->file = basename(copyinstr(arg1));
+ self->name = copyinstr(arg0);
+}
+
+perl$target:::sub-return
+{
+ self->file = 0;
+ self->name = 0;
+}
+
+pid$target:libc:malloc:entry
+/self->file != NULL/
+{
+ @malloc_sub_size[self->file, self->name] = sum(arg0);
+ @malloc_sub_dist[self->file, self->name] = quantize(arg0);
+}
+
+pid$target:libc:malloc:entry
+/self->name == NULL/
+{
+ @malloc_lib_size[usym(ucaller)] = sum(arg0);
+ @malloc_lib_dist[usym(ucaller)] = quantize(arg0);
+}
+
+
+dtrace:::END
+{
+ printf("\nPerl malloc byte distributions by engine caller,\n\n");
+ printa(" %A, total bytes = %@d %@d\n", @malloc_lib_size,
+ @malloc_lib_dist);
+
+ printf("\nPerl malloc byte distributions by Perl file and ");
+ printf("subroutine,\n\n");
+ printa(" %s, %s, bytes total = %@d %@d\n", @malloc_sub_size,
+ @malloc_sub_dist);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_subcalls.d b/cddl/contrib/dtracetoolkit/Perl/pl_subcalls.d
new file mode 100755
index 0000000..30d922f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_subcalls.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_subcalls.d - measure Perl subroutine calls using DTrace.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_subcalls.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces Perl activity from all running programs on the system
+ * which support the Perl DTrace provider.
+ *
+ * USAGE: pl_subcalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename that contained the subroutine
+ * SUB Perl subroutine name
+ * CALLS Subroutine calls during this sample
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ @subs[basename(copyinstr(arg1)), copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-32s %-32s %8s\n", "FILE", "SUB", "CALLS");
+ printa(" %-32s %-32s %@8d\n", @subs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_syscalls.d b/cddl/contrib/dtracetoolkit/Perl/pl_syscalls.d
new file mode 100755
index 0000000..9c5a765
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_syscalls.d
@@ -0,0 +1,65 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_syscalls.d - count Perl subroutine calls and syscalls using DTrace.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_syscalls.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * USAGE: pl_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Perl program
+ * TYPE Type of call (sub/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and subroutine names are printed if available.
+ * The filename for syscalls may be printed as "perl", if the program
+ * was invoked using the form "perl filename" rather than running the
+ * program with an interpreter line.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+self string filename;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl$target:::sub-entry
+{
+ @calls[basename(copyinstr(arg1)), "sub", copyinstr(arg0)] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[basename(execname), "syscall", probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf("\nCalls for PID %d,\n\n", $target);
+ printf(" %-32s %-10s %-22s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-32s %-10s %-22s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_syscolors.d b/cddl/contrib/dtracetoolkit/Perl/pl_syscolors.d
new file mode 100755
index 0000000..ec689f2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_syscolors.d
@@ -0,0 +1,119 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_syscolors.d - trace Perl subroutine flow plus syscalls, in color.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_syscolors.d 27 2007-09-13 09:26:01Z brendan $
+ *
+ * USAGE: pl_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches Perl subroutine entries and returns, and indents child
+ * subroutine calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Perl program
+ * LINE Line number of filename
+ * TYPE Type of call (sub/syscall)
+ * NAME Perl subroutine or syscall name
+ *
+ * Filename and subroutine names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ /*
+ * The following are terminal color escape sequences.
+ * Change them to whatever you prefer, eg HTML font tags.
+ */
+ color_perl = "\033[2;35m"; /* violet, faint */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+perl$target:::sub-entry,
+perl$target:::sub-return,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+perl$target:::sub-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_perl,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "sub",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+perl$target:::sub-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_perl,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "sub",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Perl/pl_who.d b/cddl/contrib/dtracetoolkit/Perl/pl_who.d
new file mode 100755
index 0000000..a461311
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Perl/pl_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * pl_who.d - trace Perl subroutine execution by process using DTrace.
+ * Written for the Perl DTrace provider.
+ *
+ * $Id: pl_who.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces Perl activity from all Perl programs on the system that are
+ * running with Perl provider support.
+ *
+ * USAGE: pl_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of Perl
+ * UID User ID of the owner
+ * SUBS Number of subroutine calls
+ * FILE Pathname of the Perl program
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+perl*:::sub-entry
+{
+ @lines[pid, uid, copyinstr(arg1)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %s\n", "PID", "UID", "SUBS", "FILE");
+ printa(" %6d %6d %@6d %s\n", @lines);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/Readme b/cddl/contrib/dtracetoolkit/Php/Readme
new file mode 100644
index 0000000..5c9101f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/Readme
@@ -0,0 +1,39 @@
+Php - DTracing PHP
+
+ These scripts trace the PHP programming language, and require the PHP
+ DTrace extension module to be installed and enabled.
+
+ The PHP DTrace provider was written by Wes Furlong, and is available
+ for download both as source and in binary form. The easiest instructions
+ are currently at,
+
+ http://blogs.sun.com/shanti/entry/dtrace_support_for_php
+
+ which were written for Solaris and the coolstack distribution of PHP.
+ The steps are roughly,
+
+ 1. Download the extension library from the URL above
+ 2. Copy the library to your php/extensions/* directory
+ 3. Edit your php.ini and add,
+ extension="dtrace.so"
+
+ The website with the PHP DTrace provider source is,
+
+ http://pecl.php.net/package/DTrace
+
+ Here you can fetch the source to build the library yourself, especially
+ if Solaris binaries from the previous URL aren't going to work for you.
+
+ Since the DTrace PHP provider may be developed further, there is a chance
+ that it has changed slightly by the time you are reading this, causing
+ these scripts to either break or behave oddly. Firstly, check for newer
+ versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider php {
+ probe function-entry(function, file, lineno)
+ probe function-return(function, file, lineno)
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/Php/php_calldist.d b/cddl/contrib/dtracetoolkit/Php/php_calldist.d
new file mode 100755
index 0000000..7a1b19e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_calldist.d
@@ -0,0 +1,83 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_calldist.d - measure PHP elapsed times for functions.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_calldist.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all programs running on the system with
+ * PHP provider support.
+ *
+ * USAGE: php_calldist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for PHP
+ * operations. Use php_calltime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the PHP program
+ * 2 Type of call (func)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+php*:::function-return
+/arg0 && self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_calltime.d b/cddl/contrib/dtracetoolkit/Php/php_calltime.d
new file mode 100755
index 0000000..dcb708c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_calltime.d
@@ -0,0 +1,90 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_calltime.d - measure PHP elapsed times for functions.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_calltime.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all programs running on the system with
+ * PHP provider support.
+ *
+ * USAGE: php_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the PHP program
+ * TYPE Type of call (func/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+php*:::function-return
+/arg0 && self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_cpudist.d b/cddl/contrib/dtracetoolkit/Php/php_cpudist.d
new file mode 100755
index 0000000..e10566c7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_cpudist.d
@@ -0,0 +1,83 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_cpudist.d - measure PHP on-CPU times for functions.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_cpudist.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all programs running on the system with
+ * PHP provider support.
+ *
+ * USAGE: php_cpudist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for PHP
+ * operations. Use php_cputime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the PHP program
+ * 2 Type of call (func)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+php*:::function-return
+/arg0 && self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_cputime.d b/cddl/contrib/dtracetoolkit/Php/php_cputime.d
new file mode 100755
index 0000000..856d551
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_cputime.d
@@ -0,0 +1,90 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_cputime.d - measure PHP on-CPU times for functions.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_cputime.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all programs running on the system with
+ * PHP provider support.
+ *
+ * USAGE: php_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the PHP program
+ * TYPE Type of call (func/total)
+ * NAME Name of call (function name)
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+php*:::function-return
+/arg0 && self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg1));
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_flow.d b/cddl/contrib/dtracetoolkit/Php/php_flow.d
new file mode 100755
index 0000000..49472ea
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_flow.d
@@ -0,0 +1,72 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_flow.d - snoop PHP execution showing function flow.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_flow.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all PHP programs on the system
+ * running with PHP provider support.
+ *
+ * USAGE: php_flow.d # hit Ctrl-C to end
+ *
+ * This watches PHP function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * FUNC Function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s -- %s\n", "C", "TIME(us)", "FILE", "FUNC");
+}
+
+php*:::function-entry
+/arg0/
+{
+ printf("%3d %-16d %-16s %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+}
+
+php*:::function-return
+/arg0/
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), self->depth * 2, "", copyinstr(arg0));
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_flowinfo.d b/cddl/contrib/dtracetoolkit/Php/php_flowinfo.d
new file mode 100755
index 0000000..e537574
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_flowinfo.d
@@ -0,0 +1,88 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_flowinfo.d - snoop PHP function flow with info using DTrace.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_flowinfo.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces activity from all PHP programs on the system that are
+ * running with PHP provider support.
+ *
+ * USAGE: php_flowinfo.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the PHP program
+ * LINE Line number of filename
+ * TYPE Type of call (func)
+ * FUNC PHP function
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%s %6s/%-4s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "TID",
+ "DELTA(us)", "FILE", "LINE", "TYPE", "FUNC");
+}
+
+php*:::function-entry,
+php*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+php*:::function-entry
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%d %6d/%-4d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, tid,
+ this->delta, basename(copyinstr(arg1)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+php*:::function-return
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%d %6d/%-4d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, tid,
+ this->delta, basename(copyinstr(arg1)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_flowtime.d b/cddl/contrib/dtracetoolkit/Php/php_flowtime.d
new file mode 100755
index 0000000..cadb66a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_flowtime.d
@@ -0,0 +1,91 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_flowtime.d - snoop PHP functions with flow and delta times.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_flowtime.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces shell activity from PHP programs on the system that are
+ * running with PHP provider support.
+ *
+ * USAGE: php_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches PHP function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * DELTA(us) Elapsed time from previous line to this line
+ * FUNC PHP function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+self int last;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "FUNC");
+}
+
+php*:::function-entry,
+php*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+php*:::function-entry
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), this->delta, self->depth * 2, "",
+ copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+php*:::function-return
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %9d %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg1)), this->delta, self->depth * 2, "",
+ copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_funccalls.d b/cddl/contrib/dtracetoolkit/Php/php_funccalls.d
new file mode 100755
index 0000000..8a0ddce
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_funccalls.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_funccalls.d - measure PHP function calls using DTrace.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_funccalls.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This traces PHP activity from all running programs on the system
+ * which support the PHP DTrace provider.
+ *
+ * USAGE: php_funccalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename that contained the function
+ * FUNC PHP function name
+ * CALLS Function calls during this sample
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ @funcs[basename(copyinstr(arg1)), copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-32s %-32s %8s\n", "FILE", "FUNC", "CALLS");
+ printa(" %-32s %-32s %@8d\n", @funcs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_malloc.d b/cddl/contrib/dtracetoolkit/Php/php_malloc.d
new file mode 100755
index 0000000..1ebab26
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_malloc.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_malloc.d - PHP libc malloc analysis.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_malloc.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * This is an expiremental script to identify who is calling malloc() for
+ * memory allocation, and to print distribution plots of the requested bytes.
+ * If a malloc() occured while in a PHP function, then that function is
+ * identified as responsible; else the caller of malloc() is identified as
+ * responsible - which will be a function from the PHP engine.
+ *
+ * USAGE: php_malloc.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php$target:::function-entry
+/arg0/
+{
+ self->file = basename(copyinstr(arg1));
+ self->name = copyinstr(arg0);
+}
+
+php$target:::function-return
+{
+ self->file = 0;
+ self->name = 0;
+}
+
+pid$target:libc:malloc:entry
+/self->file != NULL/
+{
+ @malloc_func_size[self->file, self->name] = sum(arg1);
+ @malloc_func_dist[self->file, self->name] = quantize(arg1);
+}
+
+pid$target:libc:malloc:entry
+/self->name == NULL/
+{
+ @malloc_lib_size[usym(ucaller)] = sum(arg1);
+ @malloc_lib_dist[usym(ucaller)] = quantize(arg1);
+}
+
+
+dtrace:::END
+{
+ printf("\nPHP malloc byte distributions by engine caller,\n\n");
+ printa(" %A, total bytes = %@d %@d\n", @malloc_lib_size,
+ @malloc_lib_dist);
+
+ printf("\nPHP malloc byte distributions by PHP file and ");
+ printf("function,\n\n");
+ printa(" %s, %s, bytes total = %@d %@d\n", @malloc_func_size,
+ @malloc_func_dist);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_syscalls.d b/cddl/contrib/dtracetoolkit/Php/php_syscalls.d
new file mode 100755
index 0000000..7917c24
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_syscalls.d
@@ -0,0 +1,75 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_syscalls.d - count PHP function calls and syscalls using DTrace.
+ * Written for the PHP DTrace provider.
+ *
+ * This traces syscalls that occured during a PHP function call.
+ *
+ * $Id: php_syscalls.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * USAGE: php_syscalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * FILE Filename of the PHP program
+ * TYPE Type of call (func/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and function names are printed if available.
+ * The filename for syscalls may be printed as "php", if the program
+ * was invoked using the form "php filename" rather than running the
+ * program with an interpreter line.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+/arg0/
+{
+ @calls[pid, basename(copyinstr(arg1)), "func", copyinstr(arg0)] =
+ count();
+ self->php++;
+}
+
+php*:::function-return
+/arg0/
+{
+ self->php -= self->php == 0 ? 0 : 1;
+}
+
+syscall:::entry
+/self->php > 0/
+{
+ @calls[pid, basename(execname), "syscall", probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-6s %-26s %-10s %-22s %8s\n", "PID", "FILE", "TYPE", "NAME",
+ "COUNT");
+ printa(" %-6d %-26s %-10s %-22s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_syscolors.d b/cddl/contrib/dtracetoolkit/Php/php_syscolors.d
new file mode 100755
index 0000000..ff5e9c9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_syscolors.d
@@ -0,0 +1,116 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_syscolors.d - trace PHP function flow plus syscalls, in color.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_syscolors.d 53 2007-09-24 04:58:38Z brendan $
+ *
+ * USAGE: php_syscolors.d # hit Ctrl-C to end
+ *
+ * This watches PHP function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the PHP program
+ * LINE Line number of filename
+ * TYPE Type of call (func/syscall)
+ * NAME PHP function or syscall name
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ color_php = "\033[2;35m"; /* violet, faint */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ self->depth = 0;
+ printf("%s %6s/%-4s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "TID",
+ "DELTA(us)", "FILE", "LINE", "TYPE", "NAME");
+}
+
+php*:::function-entry,
+php*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+php*:::function-entry
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d/%-4d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_php,
+ cpu, pid, tid, this->delta, basename(copyinstr(arg1)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg0), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+php*:::function-return
+/arg0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg1), "::"), copyinstr(arg0));
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d/%-4d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_php,
+ cpu, pid, tid, this->delta, basename(copyinstr(arg1)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg0), color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/self->last/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d/%-4d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, tid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/self->last/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d/%-4d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, tid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Php/php_who.d b/cddl/contrib/dtracetoolkit/Php/php_who.d
new file mode 100755
index 0000000..2ebb4b4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Php/php_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * php_who.d - trace PHP function execution by process using DTrace.
+ * Written for the PHP DTrace provider.
+ *
+ * $Id: php_who.d 51 2007-09-24 00:55:23Z brendan $
+ *
+ * This traces PHP activity from all PHP programs on the system that are
+ * running with PHP provider support.
+ *
+ * USAGE: php_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of PHP
+ * UID User ID of the owner
+ * FUNCS Number of function calls
+ * FILE Pathname of the PHP program
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+php*:::function-entry
+{
+ @lines[pid, uid, copyinstr(arg1)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %s\n", "PID", "UID", "FUNCS", "FILE");
+ printa(" %6d %6d %@6d %s\n", @lines);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/Readme b/cddl/contrib/dtracetoolkit/Proc/Readme
new file mode 100644
index 0000000..acc3634
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/Readme
@@ -0,0 +1,3 @@
+Proc - Process based analysis
+
+ This would include activity by PID, and syscall analysis.
diff --git a/cddl/contrib/dtracetoolkit/Proc/crash.d b/cddl/contrib/dtracetoolkit/Proc/crash.d
new file mode 100755
index 0000000..c1ed397
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/crash.d
@@ -0,0 +1,181 @@
+#!/usr/sbin/dtrace -Cs
+/*
+ * crash.d - Crashed Application info.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: crash.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * When applications crash via a SIGSEGV or SIGBUS, a report of the
+ * process state is printed out.
+ *
+ * USAGE: crash.d
+ *
+ * FIELDS:
+ * Type Signal type
+ * Program Execname of process
+ * Agrs Argument listing of process
+ * PID Process ID
+ * TID Thread ID
+ * LWPs Number of Light Weight Processes
+ * PPID Parent Process ID
+ * UID User ID
+ * GID Group ID
+ * TaskID Task ID
+ * ProjID Project ID
+ * PoolID Pool ID
+ * ZoneID Zone ID
+ * zone Zone name
+ * CWD Current working directory
+ * errno Error number of last syscall
+ *
+ * SEE ALSO: mdb, pstack, coreadm
+ * app_crash.d - Greg Nakhimovsky & Morgan Herrington
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 29-May-2005 Brendan Gregg Created this.
+ * 24-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option destructive
+
+dtrace:::BEGIN
+{
+ printf("Waiting for crashing applications...\n");
+}
+
+/*
+ * Print Report Header
+ */
+proc:::signal-send
+/(args[2] == SIGBUS || args[2] == SIGSEGV) && pid == args[1]->pr_pid/
+{
+ stop();
+ self->elapsed = timestamp - curthread->t_procp->p_mstart;
+ self->crash = 1;
+
+ printf("\n-----------------------------------------------------\n");
+ printf("CRASH DETECTED at %Y\n", walltimestamp);
+ printf("-----------------------------------------------------\n");
+ printf("Type: %s\n", args[2] == SIGBUS ? "SIGBUS" : "SIGSEGV");
+ printf("Program: %s\n", execname);
+ printf("Args: %S\n", curpsinfo->pr_psargs);
+ printf("PID: %d\n", pid);
+ printf("TID: %d\n", tid);
+ printf("LWPs: %d\n", curthread->t_procp->p_lwpcnt);
+ printf("PPID: %d\n", ppid);
+ printf("UID: %d\n", uid);
+ printf("GID: %d\n", gid);
+ printf("TaskID: %d\n", curpsinfo->pr_taskid);
+ printf("ProjID: %d\n", curpsinfo->pr_projid);
+ printf("PoolID: %d\n", curpsinfo->pr_poolid);
+ printf("ZoneID: %d\n", curpsinfo->pr_zoneid);
+ printf("zone: %s\n", zonename);
+ printf("CWD: %s\n", cwd);
+ printf("errno: %d\n", errno);
+
+ printf("\nUser Stack Backtrace,");
+ ustack();
+
+ printf("\nKernel Stack Backtrace,");
+ stack();
+}
+
+/*
+ * Print Java Details
+ */
+proc:::signal-send
+/self->crash && execname == "java"/
+{
+ printf("\nJava Stack Backtrace,");
+ jstack();
+}
+
+/*
+ * Print Ancestors
+ */
+proc:::signal-send
+/self->crash/
+{
+ printf("\nAnsestors,\n");
+ self->level = 1;
+ self->procp = curthread->t_procp;
+ self->ptr = self->procp;
+}
+
+/* ancestory un-rolled loop, reverse order, 6 deep */
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+proc:::signal-send /self->crash && self->ptr != 0/
+{
+ printf("%*s %d %S\n", self->level += 2, "",
+ self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
+ self->ptr = self->ptr->p_parent;
+}
+
+/*
+ * Print Report Footer
+ */
+proc:::signal-send
+/self->crash/
+{
+
+ printf("\nTimes,\n");
+ printf(" User: %d ticks\n", self->procp->p_utime);
+ printf(" Sys: %d ticks\n", self->procp->p_stime);
+ printf(" Elapsed: %d ms\n", self->elapsed/1000000);
+
+ printf("\nSizes,\n");
+ printf(" Heap: %d bytes\n", self->procp->p_brksize);
+ printf(" Stack: %d bytes\n", self->procp->p_stksize);
+
+ self->ptr = 0;
+ self->procp = 0;
+ self->crash = 0;
+ self->level = 0;
+ self->elapsed = 0;
+ system("/usr/bin/prun %d", pid);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/creatbyproc.d b/cddl/contrib/dtracetoolkit/Proc/creatbyproc.d
new file mode 100755
index 0000000..23e1f54
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/creatbyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * creatbyproc.d - file creat()s by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: creatbyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+syscall::creat*:entry { printf("%s %s", execname, copyinstr(arg0)); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/dappprof b/cddl/contrib/dtracetoolkit/Proc/dappprof
new file mode 100755
index 0000000..5aed3cb
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/dappprof
@@ -0,0 +1,239 @@
+#!/usr/bin/sh
+#
+# dappprof - profile user and library function usage.
+# Written using DTrace (Solaris 10 3/05).
+#
+# The default output traces user functions as they are called. Options
+# can be used to examine libraries and timestamps.
+#
+# $Id: dappprof 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: dappprof [-acehoTU] [-u lib] { -p PID | command }
+#
+# -p PID # examine this PID
+# -a # print all details
+# -c # print call counts
+# -e # print elapsed times (us)
+# -o # print on cpu times (us)
+# -T # print totals
+# -u lib # trace this library instead
+# -U # trace all libraries + user functions
+# -b bufsize # dynamic variable buf size (default is "4m")
+# eg,
+# dappprof df -h # run and examine the "df -h" command
+# dappprof -p 1871 # examine PID 1871
+#
+# The elapsed times are interesting, to help identify calls that take
+# some time to complete (during which the process may have context
+# switched off the CPU).
+#
+# SEE ALSO: dapptrace # DTraceToolkit
+# dtruss # DTraceToolkit
+# apptrace
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 16-May-2005 Brendan Gregg Created this.
+# 17-Jul-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_totals=0; opt_pid=0; pid=0; opt_lib=0; lib=""
+opt_elapsed=0; opt_cpu=0; opt_counts=0; opt_liball=0
+opt_command=0; command=""; opt_buf=0; buf="4m"
+
+### Process options
+while getopts ab:cehop:Tu:U name
+do
+ case $name in
+ a) opt_liball=1; opt_counts=1; opt_elapsed=1; opt_cpu=1
+ opt_totals=1 ;;
+ b) opt_buf=1; buf=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ u) opt_lib=1; lib=$OPTARG ;;
+ U) opt_liball=1 ;;
+ c) opt_counts=1 ;;
+ e) opt_elapsed=1 ;;
+ o) opt_cpu=1 ;;
+ T) opt_totals=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: dappprof [-cehoTU] [-u lib] { -p PID | command }
+
+ -p PID # examine this PID
+ -a # print all details
+ -c # print syscall counts
+ -e # print elapsed times (us)
+ -o # print on cpu times
+ -T # print totals
+ -u lib # trace this library instead
+ -U # trace all libraries + user funcs
+ -b bufsize # dynamic variable buf size
+ eg,
+ dappprof df -h # run and examine "df -h"
+ dappprof -p 1871 # examine PID 1871
+ dappprof -ap 1871 # print all data
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+### Option logic
+if [ $opt_pid -eq 0 ]; then
+ opt_command=1
+ if [ "$*" = "" ]; then
+ $0 -h
+ exit
+ fi
+ command="$*"
+fi
+if [ $opt_elapsed -eq 0 -a $opt_cpu -eq 0 -a $opt_counts -eq 0 ]; then
+ opt_elapsed=1;
+fi
+
+
+### Probe logic
+if [ $opt_liball -eq 1 ]; then
+ probe_entry='pid$target:::entry'
+ probe_return='pid$target:::return'
+elif [ $opt_lib -eq 1 ]; then
+ probe_entry='pid$target:'$lib'::entry'
+ probe_return='pid$target:'$lib'::return'
+else
+ probe_entry='pid$target:a.out::entry'
+ probe_return='pid$target:a.out::return'
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+
+### Define D Script
+dtrace='
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_command = '$opt_command';
+ inline int OPT_liball = '$opt_liball';
+ inline int OPT_elapsed = '$opt_elapsed';
+ inline int OPT_cpu = '$opt_cpu';
+ inline int OPT_counts = '$opt_counts';
+ inline int OPT_totals = '$opt_totals';
+ inline int OPT_pid = '$opt_pid';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+
+ dtrace:::BEGIN
+ /! OPT_command/
+ {
+ printf("Tracing... Hit Ctrl-C to end...\n");
+ }
+
+ /*
+ * Save syscall entry info
+ */
+ '$probe_entry'
+ {
+ /* set function depth */
+ this->fdepth = ++fdepth[probefunc];
+
+ /* set start details */
+ self->start[probefunc,this->fdepth] = timestamp;
+ self->vstart[probefunc,this->fdepth] = vtimestamp;
+
+ /* count occurances */
+ OPT_counts && OPT_liball ? @Counts[probemod,probefunc] = count() : 1;
+ OPT_counts && ! OPT_liball ? @Counts[probefunc] = count() : 1;
+ OPT_counts && OPT_totals && OPT_liball ?
+ @Counts["TOTAL:",""] = count() : 1;
+ OPT_counts && OPT_totals && ! OPT_liball ?
+ @Counts["TOTAL:"] = count() : 1;
+ }
+
+ /*
+ * Print return data
+ */
+ /* print 3 arg output - default */
+ '$probe_return'
+ /self->start[probefunc,fdepth[probefunc]]/
+ {
+ /* fetch function depth */
+ this->fdepth = fdepth[probefunc];
+
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start[probefunc,this->fdepth];
+ self->start[probefunc,this->fdepth] = 0;
+ this->cpu = vtimestamp - self->vstart[probefunc,this->fdepth];
+ self->vstart[probefunc,this->fdepth] = 0;
+
+ /* save elapsed times */
+ OPT_elapsed && OPT_liball ?
+ @Elapsed[probemod,probefunc] = sum(this->elapsed) : 1;
+ OPT_elapsed && ! OPT_liball ?
+ @Elapsed[probefunc] = sum(this->elapsed) : 1;
+ OPT_elapsed && OPT_totals && OPT_liball ?
+ @Elapsed["TOTAL:",""] = sum(this->elapsed) : 1;
+ OPT_elapsed && OPT_totals && ! OPT_liball ?
+ @Elapsed["TOTAL:"] = sum(this->elapsed) : 1;
+
+ /* save cpu times */
+ OPT_cpu && OPT_liball ? @CPU[probemod,probefunc] = sum(this->cpu) : 1;
+ OPT_cpu && ! OPT_liball ? @CPU[probefunc] = sum(this->cpu) : 1;
+ OPT_cpu && OPT_totals && OPT_liball ?
+ @CPU["TOTAL:",""] = sum(this->cpu) : 1;
+ OPT_cpu && OPT_totals && ! OPT_liball ?
+ @CPU["TOTAL:"] = sum(this->cpu) : 1;
+
+ }
+
+ /* print counts */
+ dtrace:::END
+ {
+ /* print counts */
+ OPT_counts ? printf("\n%-49s %16s\n","CALL","COUNT") : 1;
+ OPT_counts && OPT_liball ? printa("%-16s %-32s %@16d\n",@Counts) : 1;
+ OPT_counts && ! OPT_liball ? printa("%-49s %@16d\n",@Counts) : 1;
+
+ /* print elapsed times */
+ OPT_elapsed ? printf("\n%-49s %16s\n","CALL","ELAPSED") : 1;
+ OPT_elapsed && OPT_liball ? printa("%-16s %-32s %@16d\n",@Elapsed) : 1;
+ OPT_elapsed && ! OPT_liball ? printa("%-49s %@16d\n",@Elapsed) : 1;
+
+ /* print cpu times */
+ OPT_cpu ? printf("\n%-49s %16s\n","CALL","CPU") : 1;
+ OPT_cpu && OPT_liball ? printa("%-16s %-32s %@16d\n",@CPU) : 1;
+ OPT_cpu && ! OPT_liball ? printa("%-49s %@16d\n",@CPU) : 1;
+ }
+'
+
+### Run DTrace
+if [ $opt_command -eq 1 ]; then
+ /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \
+ -c "$command" >&2
+else
+ /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2
+fi
+
diff --git a/cddl/contrib/dtracetoolkit/Proc/dapptrace b/cddl/contrib/dtracetoolkit/Proc/dapptrace
new file mode 100755
index 0000000..7dece4e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/dapptrace
@@ -0,0 +1,259 @@
+#!/usr/bin/sh
+#
+# dapptrace - trace user and library function usage.
+# Written using DTrace (Solaris 10 3/05).
+#
+# The default output traces user functions as they are called. Options
+# can be used to examine libraries and timestamps.
+#
+# $Id: dapptrace 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: dapptrace [-acdeFlhoU] [-u lib] { -p PID | command }
+#
+# -p PID # examine this PID
+# -a # print all details
+# -c # print call counts
+# -d # print relative timestamps (us)
+# -e # print elapsed times (us)
+# -F # print flow indentation
+# -l # print pid/lwpid per line
+# -o # print on cpu times (us)
+# -u lib # trace this library instead
+# -U # trace all libraries + user functions
+# -b bufsize # dynamic variable buf size (default is "4m")
+# eg,
+# dapptrace df -h # run and examine the "df -h" command
+# dapptrace -p 1871 # examine PID 1871
+# dapptrace -Fp 1871 # print using flow indents
+# dapptrace -eop 1871 # print elapsed and CPU times
+#
+# The elapsed times are interesting, to help identify calls that take
+# some time to complete (during which the process may have context
+# switched off the CPU).
+#
+# SEE ALSO: dappprof # DTraceToolkit
+# dtruss # DTraceToolkit
+# apptrace
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 16-May-2005 Brendan Gregg Created this.
+# 17-Jul-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_pid=0; pid=0; opt_indent=0; opt_lib=0; lib=""
+opt_elapsed=0; opt_cpu=0; opt_counts=0;
+opt_relative=0; opt_printid=0; opt_liball=0
+opt_command=0; command=""; opt_buf=0; buf="4m"
+
+### Process options
+while getopts ab:cdeFhlop:u:U name
+do
+ case $name in
+ a) opt_liball=1; opt_counts=1; opt_relative=1; opt_elapsed=1
+ opt_indent=1; opt_printid=1; opt_cpu=1 ;;
+ b) opt_buf=1; buf=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ u) opt_lib=1; lib=$OPTARG ;;
+ U) opt_liball=1 ;;
+ c) opt_counts=1 ;;
+ d) opt_relative=1 ;;
+ e) opt_elapsed=1 ;;
+ F) opt_indent=1 ;;
+ l) opt_printid=1 ;;
+ o) opt_cpu=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: dapptrace [-acdeholFLU] [-u lib] { -p PID | command }
+
+ -p PID # examine this PID
+ -a # print all details
+ -c # print syscall counts
+ -d # print relative times (us)
+ -e # print elapsed times (us)
+ -F # print flow indentation
+ -l # print pid/lwpid
+ -o # print CPU on cpu times
+ -u lib # trace this library instead
+ -U # trace all libraries + user funcs
+ -b bufsize # dynamic variable buf size
+ eg,
+ dapptrace df -h # run and examine "df -h"
+ dapptrace -p 1871 # examine PID 1871
+ dapptrace -Fp 1871 # print using flow indents
+ dapptrace -eop 1871 # print elapsed and CPU times
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+### Option logic
+if [ $opt_pid -eq 0 ]; then
+ opt_command=1
+ if [ "$*" = "" ]; then
+ $0 -h
+ exit
+ fi
+ command="$*"
+fi
+
+### Probe logic
+if [ $opt_liball -eq 1 ]; then
+ probe_entry='pid$target:::entry'
+ probe_return='pid$target:::return'
+elif [ $opt_lib -eq 1 ]; then
+ probe_entry='pid$target:'$lib'::entry'
+ probe_return='pid$target:'$lib'::return'
+else
+ probe_entry='pid$target:a.out::entry'
+ probe_return='pid$target:a.out::return'
+fi
+
+#################################
+# --- Main Program, DTrace ---
+#
+
+### Define D Script
+dtrace='
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_command = '$opt_command';
+ inline int OPT_liball = '$opt_liball';
+ inline int OPT_indent = '$opt_indent';
+ inline int OPT_printid = '$opt_printid';
+ inline int OPT_relative = '$opt_relative';
+ inline int OPT_elapsed = '$opt_elapsed';
+ inline int OPT_cpu = '$opt_cpu';
+ inline int OPT_counts = '$opt_counts';
+ inline int OPT_pid = '$opt_pid';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+
+ dtrace:::BEGIN
+ {
+ /* print header */
+ OPT_printid ? printf("%-8s ","PID/LWP") : 1;
+ OPT_relative ? printf("%8s ","RELATIVE") : 1;
+ OPT_elapsed ? printf("%7s ","ELAPSD") : 1;
+ OPT_cpu ? printf("%6s ","CPU") : 1;
+ printf("CALL(args) \t\t = return\n");
+
+ /* indent depth */
+ depth = 0;
+ }
+
+ /*
+ * Save syscall entry info
+ */
+ '$probe_entry'
+ {
+ /* set function depth */
+ this->fdepth = ++fdepth[probefunc];
+ depth += 2;
+
+ /* set start details */
+ self->start[probefunc,this->fdepth] = timestamp;
+ self->vstart[probefunc,this->fdepth] = vtimestamp;
+
+ /* count occurances */
+ OPT_counts && OPT_liball ? @Counts[probemod,probefunc] = count() : 1;
+ OPT_counts && ! OPT_liball ? @Counts[probefunc] = count() : 1;
+
+ /* print optional fields */
+ OPT_printid ? printf("%5d/%d: ",pid,tid) : 1;
+ OPT_relative ? printf("%8d ",vtimestamp/1000) : 1;
+ OPT_elapsed ? printf(" . ") : 1;
+ OPT_cpu ? printf(" . ") : 1;
+ OPT_indent ? printf("%*s",depth,"") : 1;
+
+ /* print main data */
+ printf("-> ");
+ OPT_liball ? printf("%s:",probemod) : 1;
+ printf("%s(0x%X, 0x%X, 0x%X)\t\t\n",probefunc,arg0,arg1,arg2);
+
+ }
+
+ /*
+ * Print return data
+ */
+ /* print 3 arg output - default */
+ '$probe_return'
+ /self->start[probefunc,fdepth[probefunc]]/
+ {
+ /* fetch function depth */
+ this->fdepth = fdepth[probefunc];
+
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start[probefunc,this->fdepth];
+ self->start[probefunc,this->fdepth] = 0;
+ this->cpu = vtimestamp - self->vstart[probefunc,this->fdepth];
+ self->vstart[probefunc,this->fdepth] = 0;
+
+ /* print optional fields */
+ OPT_printid ? printf("%5d/%d: ",pid,tid) : 1;
+ OPT_relative ? printf("%8d ",vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ",this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ",this->cpu/1000) : 1;
+ OPT_indent ? printf("%*s",depth,"") : 1;
+
+ /* print main data */
+ printf("<- ");
+ OPT_liball ? printf("%s:",probemod) : 1;
+ printf("%s = %d\n",probefunc,(int)arg0);
+ depth -= 2;
+ fdepth[probefunc]--;
+ }
+
+ /* reset indent depth */
+ profile:::tick-1sec
+ {
+ /*
+ * some probes generated by the pid provider have entries
+ * but not returns. this is a klude to fix that problem. this
+ * also explains fdepth[probefunc] rather than a single depth.
+ */
+ depth = 0;
+ }
+
+ /* print counts */
+ dtrace:::END
+ {
+ OPT_counts ? printf("\n%-49s %16s\n","CALL","COUNT") : 1;
+ OPT_counts && OPT_liball ? printa("%-16s %-32s %@16d\n",@Counts) : 1;
+ OPT_counts && ! OPT_liball ? printa("%-49s %@16d\n",@Counts) : 1;
+ }
+'
+
+### Run DTrace
+if [ $opt_command -eq 1 ]; then
+ /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \
+ -c "$command" >&2
+else
+ /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2
+fi
+
diff --git a/cddl/contrib/dtracetoolkit/Proc/fddist b/cddl/contrib/dtracetoolkit/Proc/fddist
new file mode 100755
index 0000000..b1fe17a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/fddist
@@ -0,0 +1,116 @@
+#!/usr/bin/sh
+#
+# fddist - file descriptor usage distributions.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This prints distributions for read and write events by file descriptor,
+# by process. This can be used to determine which file descriptor a
+# process is doing the most I/O with.
+#
+# $Id: fddist 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: fddist [-r|-w] # hit Ctrl-C to end sample
+#
+# FIELDS:
+# EXEC process name
+# PID process ID
+# value file descriptor
+# count number of events
+#
+# BASED ON: /usr/demo/dtrace/lquantize.d
+#
+# SEE ALSO:
+# DTrace Guide "Aggregations" chapter (docs.sun.com)
+#
+# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 09-Jun-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_read=0; opt_write=0
+
+### Process options
+while getopts hrw name
+do
+ case $name in
+ r) opt_read=1 ;;
+ w) opt_write=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: fddist [-r|-w]
+ -r # reads only
+ -w # writes only
+ eg,
+ fddist # default, r+w counts
+ fddist -r # read count only
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+### Option logic
+if [ $opt_read -eq 0 -a $opt_write -eq 0 ]; then
+ opt_read=1; opt_write=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ inline int OPT_read = '$opt_read';
+ inline int OPT_write = '$opt_write';
+ inline int FDMAX = 255;
+
+ /* print header */
+ dtrace:::BEGIN
+ {
+ printf("Tracing ");
+ OPT_read && OPT_write ? printf("reads and writes") : 1;
+ OPT_read && ! OPT_write ? printf("reads") : 1;
+ ! OPT_read && OPT_write ? printf("writes") : 1;
+ printf("... Hit Ctrl-C to end.\n");
+ }
+
+ /* sample reads */
+ syscall::*read*:entry
+ /OPT_read/
+ {
+ @Count[execname, pid] = lquantize(arg0, 0, FDMAX, 1);
+ }
+
+ /* sample writes */
+ syscall::*write*:entry
+ /OPT_write/
+ {
+ @Count[execname, pid] = lquantize(arg0, 0, FDMAX, 1);
+ }
+
+ /* print report */
+ dtrace:::END
+ {
+ printa("EXEC: %-16s PID: %d\n%@d\n",@Count);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Proc/filebyproc.d b/cddl/contrib/dtracetoolkit/Proc/filebyproc.d
new file mode 100755
index 0000000..d1f7589
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/filebyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * filebyproc.d - snoop files opened by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: filebyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+syscall::open*:entry { printf("%s %s", execname, copyinstr(arg0)); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/kill.d b/cddl/contrib/dtracetoolkit/Proc/kill.d
new file mode 100755
index 0000000..215625f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/kill.d
@@ -0,0 +1,63 @@
+#!/usr/sbin/dtrace -qs
+/*
+ * kill.d - watch process signals as they are sent (eg, kill -9).
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: kill.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: kill.d
+ *
+ * FIELDS:
+ * FROM source PID
+ * COMMAND source command name
+ * TO destination PID
+ * SIG destination signal ("9" for a kill -9)
+ * RESULT result of signal (-1 is for failure)
+ *
+ * SEE ALSO: Chapter 25, Solaris Dynamic Tracing Guide, docs.sun.com,
+ * for a solution using proc:::signal-send.
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-May-2004 Brendan Gregg Created this.
+ * 28-Jun-2005 " " Last update.
+ */
+
+dtrace:::BEGIN
+{
+ /* Print header */
+ printf("%5s %12s %5s %-6s %s\n",
+ "FROM", "COMMAND", "SIG", "TO", "RESULT");
+}
+
+syscall::kill:entry
+{
+ /* Record target PID and signal */
+ self->target = arg0;
+ self->signal = arg1;
+}
+
+syscall::kill:return
+{
+ /* Print source, target, and result */
+ printf("%5d %12s %5d %-6d %d\n",
+ pid, execname, self->signal, self->target, (int)arg0);
+
+ /* Cleanup memory */
+ self->target = 0;
+ self->signal = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/lastwords b/cddl/contrib/dtracetoolkit/Proc/lastwords
new file mode 100755
index 0000000..1258cc9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/lastwords
@@ -0,0 +1,90 @@
+#!/usr/bin/ksh
+#
+# lastwords - print last few syscalls for dying processes.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: lastwords 3 2007-08-01 10:50:08Z brendan $
+#
+# This prints the last few system calls for processes matching
+# the given name, when they exit. This makes use of a ring buffer
+# so that the impact on the system is minimised.
+#
+# USAGE: lastwords command
+# eg,
+# lastwords netscape
+#
+# FIELDS:
+# TIME Time of syscall return, ns
+# PID Process ID
+# EXEC Process name (execname)
+# SYSCALL System call
+# RETURN Return value for system call
+# ERR errno for system call
+#
+# BASED ON: /usr/demo/dtrace/ring.d
+#
+# SEE ALSO: DTrace Guide "Buffers and Buffering" chapter (docs.sun.com)
+# dtruss (DTraceToolkit)
+#
+# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 09-Jun-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+### Usage
+function usage
+{
+ cat <<-END >&2
+ USAGE: lastwords command
+ eg,
+ lastwords netscape
+ END
+ exit 1
+}
+
+### Process arguments
+if (( $# != 1 )); then
+ usage
+fi
+command=$1
+
+print "Tracing... Waiting for $command to exit..."
+
+### Run DTrace
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ #pragma D option bufpolicy=ring
+ #pragma D option bufsize=16k
+
+ syscall:::return
+ /execname == $$1/
+ {
+ /* buffer syscall details */
+ printf("%-18d %5d %12s %12s %10x %3d\n",
+ timestamp,pid,execname,probefunc,(int)arg0,errno);
+ }
+
+ proc::proc_exit:exit
+ /execname == $$1/
+ {
+ /* print, erm, footer */
+ printf("%-18s %5s %12s %12s %10s %3s\n",
+ "TIME","PID","EXEC","SYSCALL","RETURN","ERR");
+ exit(0);
+ }
+' "$command"
diff --git a/cddl/contrib/dtracetoolkit/Proc/mmapfiles.d b/cddl/contrib/dtracetoolkit/Proc/mmapfiles.d
new file mode 100755
index 0000000..7690f50
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/mmapfiles.d
@@ -0,0 +1,62 @@
+#!/usr/sbin/dtrace -s
+/*
+ * mmapfiles.d - mmap'd files by process.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: mmapfiles.d 14 2007-09-11 08:03:35Z brendan $
+ *
+ * USAGE: mmapfiles.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * MMAPS number of mmaps
+ * CMD process name
+ * PATHNAME pathname of mmap'd file
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 18-Oct-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+syscall::mmap:entry
+/(int)arg4 > 0/
+{
+ /*
+ * Fetch filename
+ */
+ this->filep = curthread->t_procp->p_user.u_finfo.fi_list[arg4].uf_file;
+ this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
+ self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+
+ /* Store Details */
+ @hits[execname, self->vpath] = count();
+}
+
+dtrace:::END
+{
+ /* Print Details */
+ printf("%5s %-16s %s\n", "MMAPS", "CMD", "PATHNAME");
+ printa("%@5d %-16s %s\n", @hits);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/newproc.d b/cddl/contrib/dtracetoolkit/Proc/newproc.d
new file mode 100755
index 0000000..6b6fad2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/newproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * newproc.d - snoop new processes as they are executed. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: newproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+proc:::exec-success { trace(curpsinfo->pr_psargs); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/pathopens.d b/cddl/contrib/dtracetoolkit/Proc/pathopens.d
new file mode 100755
index 0000000..10cd0c8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/pathopens.d
@@ -0,0 +1,100 @@
+#!/usr/sbin/dtrace -s
+/*
+ * pathopens.d - full pathnames opened successfully count.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This program prints a count of the number of times files have been
+ * successfully opened. This is somewhat special in that the full pathname
+ * is calculated, even if the file open referred to a relative pathname.
+ *
+ * $Id: pathopens.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: fileopens.d
+ *
+ * FIELDS:
+ * PATHNAME full pathname
+ * COUNT number of successful opens
+ *
+ * Similar to a script from DExplorer.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 12-Jan-2006 " " Fixed known error.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+syscall::open*:entry
+{
+ self->pathp = arg0;
+ self->ok = 1;
+}
+
+syscall::open*:return
+/self->ok && arg0 != -1/
+{
+ self->file = copyinstr(self->pathp);
+ self->char0 = copyin(self->pathp, 1);
+
+ /* fetch current working directory */
+ this->path = curthread->t_procp->p_user.u_cdir->v_path;
+
+ /*
+ * Make the full pathname
+ *
+ * This routine takes the cwd and the filename, and generates a
+ * full pathname. Sometimes the filename is absolute, so we must
+ * ignore the cwd. This also checks if the cwd ends in an
+ * unnecessary '/'.
+ */
+ this->len = strlen(this->path);
+ self->join = *(char *)(this->path + this->len - 1) == '/' ? "" : "/";
+ self->dir = strjoin(cwd, self->join);
+ self->dir = *(char *)self->char0 == '/' ? "" : self->dir;
+ self->full = strjoin(self->dir, self->file);
+
+ /* save to aggregation */
+ @num[self->full] = count();
+
+ /* cleanup */
+ self->join = 0;
+ self->full = 0;
+ self->dir = 0;
+ self->file = 0;
+ self->char0 = 0;
+}
+
+syscall::open*:return
+/self->ok/
+{
+ /* cleanup */
+ self->ok = 0;
+ self->pathp = 0;
+}
+
+dtrace:::END
+{
+ printf("%6s %s\n", "COUNT", "PATHNAME");
+ printa("%@6d %s\n", @num);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/pfilestat b/cddl/contrib/dtracetoolkit/Proc/pfilestat
new file mode 100755
index 0000000..c6aaba3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/pfilestat
@@ -0,0 +1,282 @@
+#!/usr/bin/sh
+#
+# pfilestat
+#
+# This prints I/O statistics for each file descriptor within a process.
+# In particular, the time break down during read() and write() events is
+# measured.
+#
+# $Id: pfilestat 4 2007-08-01 11:01:38Z brendan $
+#
+# USAGE: pfilestat [-r|-w] pid
+#
+# FIELDS:
+# STATE microstate: running, sleeping, waitcpu, read, write
+# FDUM File Descriptor ID
+# Time Percentage of wallclock time in each STATE
+# File Name of file, if known
+#
+# COPYRIGHT: Copyright (c) 2006 Richard McDougall.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# ToDo:
+# Trace readv() and writev().
+#
+# 20-Feb-2006 Richard McDougall created this.
+# 24-Feb-2006 Brendan Gregg tweaked code.
+# 20-Mar-2006 " " tweaked code.
+# 20-Mar-2006 " " last update.
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_read=0; opt_write=0
+
+### Process options
+while getopts hrw name
+do
+ case $name in
+ r) opt_read=1 ;;
+ w) opt_write=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: pfilestat [-r|-w] pid
+ -r # reads only
+ -w # writes only
+ eg,
+ pfilestat pid # default, r+w counts
+ pfilestat -r pid # read count only
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+PID=$1
+clearstr=`clear`
+
+if [ -z "$PID" ]
+then
+ echo "Must supply pid"
+ exit 1
+fi
+
+### Option logic
+if [ $opt_read -eq 0 -a $opt_write -eq 0 ]; then
+ opt_read=1; opt_write=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ inline string CLEAR = "'$clearstr'";
+ inline int OPT_read = '$opt_read';
+ inline int OPT_write = '$opt_write';
+ inline int PID = '$PID';
+
+ unsigned long long totaltime;
+ unsigned long long totalbytes;
+
+ enum runstate {
+ READ,
+ WRITE,
+ OTHER
+ };
+
+ /* print header */
+ dtrace:::BEGIN
+ {
+ printf("Tracing ");
+ OPT_read && OPT_write ? printf("reads and writes") : 1;
+ OPT_read && ! OPT_write ? printf("reads") : 1;
+ ! OPT_read && OPT_write ? printf("writes") : 1;
+ printf("...");
+ totaltime = 0;
+ totalbytes = 0;
+ last = timestamp;
+ stamp = timestamp;
+ }
+
+ /* sample reads */
+ syscall::read:entry,
+ syscall::pread*:entry
+ /pid == PID && OPT_read/
+ {
+ runstate = READ;
+ @logical["running", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+
+ self->fd = arg0 + 1;
+ }
+
+ fbt::fop_read:entry,
+ fbt::fop_write:entry
+ /self->fd/
+ {
+ self->path = args[0]->v_path == 0 ? "<none>" :
+ cleanpath(args[0]->v_path);
+ }
+
+ syscall::read:return,
+ syscall::pread*:return
+ /pid == PID && OPT_read/
+ {
+ runstate = OTHER;
+ this->bytes = (int)arg0 > 0 ? (int)arg0 : 0;
+ @logical["read", self->fd - 1, self->path] = sum(timestamp - last);
+ @bytes["read", self->fd - 1, self->path] = sum(this->bytes);
+ totalbytes += this->bytes;
+ totaltime += timestamp - last;
+ last = timestamp;
+ self->path = 0;
+ self->fd = 0;
+ }
+
+
+ /* sample writes */
+ syscall::write:entry,
+ syscall::pwrite*:entry
+ /pid == PID && OPT_write/
+ {
+ runstate = WRITE;
+ @logical["running", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+
+ self->fd = (int)arg0 + 1;
+ }
+
+ syscall::write:return,
+ syscall::pwrite*:return
+ /pid == PID && OPT_write/
+ {
+ runstate = OTHER;
+ this->bytes = (int)arg0 > 0 ? (int)arg0 : 0;
+ @logical["write", self->fd - 1, self->path] = sum(timestamp - last);
+ @bytes["write", self->fd - 1, self->path] = sum(this->bytes);
+ totalbytes += this->bytes;
+ totaltime += timestamp - last;
+ last = timestamp;
+ self->path = 0;
+ self->fd = 0;
+ }
+
+ sched:::on-cpu
+ /pid == PID/
+ {
+ @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+
+ sched:::off-cpu
+ /pid == PID/
+ {
+ @logical["running", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::sleep
+ /pid == PID/
+ {
+ @logical["running", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::wakeup
+ /args[1]->pr_pid == PID && runstate == OTHER/
+ {
+ @logical["sleep", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::wakeup
+ /args[1]->pr_pid == PID && runstate == READ/
+ {
+ @logical["sleep-r", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::wakeup
+ /args[1]->pr_pid == PID && runstate == WRITE/
+ {
+ @logical["sleep-w", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::enqueue
+ /args[1]->pr_pid == PID/
+ {
+ @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ sched:::dequeue
+ /args[1]->pr_pid == PID/
+ {
+ @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last);
+ totaltime += timestamp - last;
+ last = timestamp;
+ }
+
+ /* print report */
+ profile:::tick-5s
+ {
+ printf("%s", CLEAR);
+ normalize(@logical, totaltime / 100);
+ trunc(@logical, 10);
+ printf("%10s %7s %9s %-44s\n", "STATE", "FDNUM", "Time", "Filename");
+ printa("%10s %7d %@8d%% %-44.44s\n", @logical);
+ trunc(@logical);
+
+ delta = timestamp - stamp;
+ stamp = timestamp;
+ normalize(@bytes, (1024 * delta) / 1000000000);
+ trunc(@bytes, 10);
+ printf("\n%10s %7s %9s %-44s\n", "STATE", "FDNUM", "KB/s",
+ "Filename");
+ printa("%10s %7d %@9d %-44.44s\n", @bytes);
+ trunc(@bytes);
+
+ printf("\nTotal event time (ms): %d Total Mbytes/sec: %d\n",
+ totaltime / 1000000,
+ (totalbytes * 1000000000) / (delta * 1048576));
+
+ totaltime = 0;
+ totalbytes = 0;
+ last = timestamp;
+ }
+
+ dtrace:::END
+ {
+ trunc(@logical);
+ trunc(@bytes);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Proc/pidpersec.d b/cddl/contrib/dtracetoolkit/Proc/pidpersec.d
new file mode 100755
index 0000000..71080b9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/pidpersec.d
@@ -0,0 +1,57 @@
+#!/usr/sbin/dtrace -s
+/*
+ * pidpersec.d - print new PIDs per sec.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This script prints the number of new processes created per second.
+ *
+ * $Id: pidpersec.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: pidpersec.d
+ *
+ * FIELDS:
+ *
+ * TIME Time, as a string
+ * LASTPID Last PID created
+ * PID/s Number of processes created per second
+ *
+ * SEE ALSO: execsnoop
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Jun-2005 Brendan Gregg Created this.
+ * 09-Jun-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("%-22s %8s %6s\n", "TIME", "LASTPID", "PID/s");
+ pids = 0;
+}
+
+proc:::exec-success
+{
+ pids++;
+}
+
+profile:::tick-1sec
+{
+ printf("%-22Y %8d %6d\n", walltimestamp, `mpid, pids);
+ pids = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/readbytes.d b/cddl/contrib/dtracetoolkit/Proc/readbytes.d
new file mode 100755
index 0000000..67612a2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/readbytes.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * readbytes.d - read bytes by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: readbytes.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+sysinfo:::readch { @bytes[execname] = sum(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/readdist.d b/cddl/contrib/dtracetoolkit/Proc/readdist.d
new file mode 100755
index 0000000..0d0346d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/readdist.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * readdist.d - read distribution by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: readdist.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+sysinfo:::readch { @dist[execname] = quantize(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/rwbbypid.d b/cddl/contrib/dtracetoolkit/Proc/rwbbypid.d
new file mode 100755
index 0000000..72cb00d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/rwbbypid.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -s
+/*
+ * rwbbypid.d - read/write bytes by PID.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This script tracks the bytes read and written at the syscall level
+ * by processes, printing the totals in a report. This is tracking the
+ * successful number of bytes read or written.
+ *
+ * $Id: rwbbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: rwbbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * DIR direction, Read or Write
+ * BYTES total bytes
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sysinfo:::readch
+{
+ @bytes[pid, execname, "R"] = sum(arg0);
+}
+
+sysinfo:::writech
+{
+ @bytes[pid, execname, "W"] = sum(arg0);
+}
+
+dtrace:::END
+{
+ printf("%6s %-24s %4s %16s\n", "PID", "CMD", "DIR", "BYTES");
+ printa("%6d %-24s %4s %@16d\n", @bytes);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/rwbypid.d b/cddl/contrib/dtracetoolkit/Proc/rwbypid.d
new file mode 100755
index 0000000..e4f0432
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/rwbypid.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -s
+/*
+ * rwbypid.d - read/write calls by PID.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This script tracks the number of reads and writes at the syscall level
+ * by processes, printing the totals in a report. This matches reads
+ * and writes whether they succeed or not.
+ *
+ * $Id: rwbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: rwbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * DIR Read or Write
+ * COUNT total calls
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 28-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+syscall::*read*:entry
+{
+ @calls[pid, execname, "R"] = sum(arg0);
+}
+
+syscall::*write*:entry
+{
+ @calls[pid, execname, "W"] = sum(arg0);
+}
+
+dtrace:::END
+{
+ printf("%6s %-24s %4s %8s\n", "PID", "CMD", "DIR", "COUNT");
+ printa("%6d %-24s %4s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/rwbytype.d b/cddl/contrib/dtracetoolkit/Proc/rwbytype.d
new file mode 100755
index 0000000..6705d99
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/rwbytype.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -s
+/*
+ * rwbytype.d - read/write bytes by vnode type.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This program identifies the vnode type of read/write activity - whether
+ * that is for regular files, sockets, character special devices, etc.
+ *
+ * $Id: rwbytype.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: rwbytype.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID number of rwbytype
+ * CMD process name
+ * VTYPE vnode type (describes I/O type)
+ * DIR direction (Read/Write)
+ * BYTES bytes transferred
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 18-Oct-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+typedef struct vtype2str {
+ string code;
+};
+
+translator struct vtype2str < int T > {
+ /* the order has been picked for performance reasons */
+ code =
+ T == 1 ? "reg" :
+ T == 9 ? "sock" :
+ T == 4 ? "chr" :
+ T == 6 ? "fifo" :
+ T == 8 ? "proc" :
+ T == 2 ? "dir" :
+ T == 3 ? "blk" :
+ T == 5 ? "lnk" :
+ T == 7 ? "door" :
+ T == 10 ? "port" :
+ T == 11 ? "bad" : "non";
+};
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+fbt::fop_read:entry,
+fbt::fop_write:entry
+{
+ self->type = xlate <struct vtype2str *>(args[0]->v_type)->code;
+ self->size = args[1]->uio_resid;
+ self->uiop = args[1];
+}
+
+fbt::fop_read:return
+/self->uiop/
+{
+ this->resid = self->uiop->uio_resid;
+ @bytes[pid, execname, self->type, "R"] = sum(self->size - this->resid);
+ self->type = 0;
+ self->size = 0;
+ self->uiop = 0;
+}
+
+/* this is delibrately redundant code for performance reasons */
+fbt::fop_write:return
+/self->uiop/
+{
+ this->resid = self->uiop->uio_resid;
+ @bytes[pid, execname, self->type, "W"] = sum(self->size - this->resid);
+ self->type = 0;
+ self->size = 0;
+ self->uiop = 0;
+}
+
+dtrace:::END
+{
+ printf("%-6s %-16s %6s %4s %9s\n",
+ "PID", "CMD", "VTYPE", "DIR", "BYTES");
+ printa("%-6d %-16s %6s %4s %@9d\n", @bytes);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/sampleproc b/cddl/contrib/dtracetoolkit/Proc/sampleproc
new file mode 100755
index 0000000..891be14
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/sampleproc
@@ -0,0 +1,105 @@
+#!/usr/bin/ksh
+#
+# sampleproc - sample processes on the CPUs.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program samples which process is on each CPU, at a particular
+# configurable rate. This can be used as an estimate for which process
+# is consuming the most CPU time.
+#
+# $Id: sampleproc 8 2007-08-06 05:55:26Z brendan $
+#
+# USAGE: sampleproc [hertz] # hit Ctrl-C to end sample
+#
+# FIELDS:
+# PID Process ID
+# COMMAND Command name
+# COUNT Number of samples
+# PERCENT Percent of CPU usage
+#
+# BASED ON: /usr/demo/dtrace/prof.d
+#
+# SEE ALSO:
+# DTrace Guide "profile Provider" chapter (docs.sun.com)
+#
+# PORTIONS: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 09-Jun-2005 Brendan Gregg Created this.
+# 09-Jul-2005 " " Last update.
+
+### Usage
+function usage
+{
+ cat <<-END >&2
+ USAGE: sampleproc [hertz]
+ eg,
+ sampleproc # defaults to 100 hertz
+ sampleproc 1000 # 1000 hertz
+ END
+ exit 1
+}
+
+### Process arguments
+if (( $# == 0 )); then
+ hertz=100
+elif (( $# == 1 )); then
+ hertz=$1
+ if [[ "$hertz" = *[a-zA-Z]* ]]; then
+ print "ERROR2: $hertz hertz is invalid." >&2
+ exit 2
+ fi
+ if (( hertz > 5000 )); then
+ print "ERROR3: $hertz hertz is too fast (max 5000)." >&2
+ exit 3
+ fi
+ if (( hertz < 1 )); then
+ print "ERROR4: $hertz hertz is too low (min 1)." >&2
+ exit 4
+ fi
+else
+ usage
+fi
+
+### Run DTrace
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+
+ dtrace:::BEGIN
+ {
+ printf("Sampling at %d hertz... Hit Ctrl-C to end.\n",$1);
+ self->start = timestamp;
+ }
+
+ profile:::profile-$1
+ {
+ @Proc[pid, execname] = count();
+ @BigProc[pid, execname] = sum(1000); /* dont ask */
+ }
+
+ dtrace:::END
+ {
+ this->end = timestamp;
+
+ printf("%5s %-20s %10s\n", "PID", "CMD", "COUNT");
+ printa("%5d %-20s %10@d\n", @Proc);
+
+ normalize(@BigProc,
+ ((`ncpus_online * $1 * (this->end - self->start))/100000000));
+ printf("\n%5s %-20s %10s\n", "PID", "CMD", "PERCENT");
+ printa("%5d %-20s %10@d\n", @BigProc);
+ }
+' $hertz
diff --git a/cddl/contrib/dtracetoolkit/Proc/shortlived.d b/cddl/contrib/dtracetoolkit/Proc/shortlived.d
new file mode 100755
index 0000000..268c370
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/shortlived.d
@@ -0,0 +1,118 @@
+#!/usr/sbin/dtrace -qs
+/*
+ * shortlived.d - determine time spent by short lived processes.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: shortlived.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: shortlived.d # wait, then hit Ctrl-C
+ *
+ * Applications that run many short lived processes can cause load
+ * on the system that is difficult to identify - the processes
+ * aren't sampled in time by programs such as prstat. This program
+ * illustrates how much time was spent processing those extra
+ * processes, and a table of process name by total times for each.
+ *
+ * SEE ALSO: execsnoop
+ *
+ * Notes:
+ * - The measurements are minimum values, not all of the overheads
+ * caused by process generation and destruction are measured (DTrace
+ * can do so, but the script would become seriously complex).
+ * - The summary values are accurate, the by program and by PPID values
+ * are usually slightly smaller due to rounding errors.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 22-Apr-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+/*
+ * Start
+ */
+dtrace:::BEGIN
+{
+ /* save start time */
+ start = timestamp;
+
+ /* this is time spent on shortlived processes */
+ procs = 0;
+
+ /* print header */
+ printf("Tracing... Hit Ctrl-C to stop.\n");
+}
+
+/*
+ * Measure parent fork time
+ */
+syscall::*fork*:entry
+{
+ /* save start of fork */
+ self->fork = vtimestamp;
+}
+syscall::*fork*:return
+/arg0 != 0 && self->fork/
+{
+ /* record elapsed time for the fork syscall */
+ this->elapsed = vtimestamp - self->fork;
+ procs += this->elapsed;
+ self->fork = 0;
+}
+
+/*
+ * Measure child processes time
+ */
+syscall::*fork*:return
+/arg0 == 0/
+{
+ /* save start of child process */
+ self->start = vtimestamp;
+
+ /* memory cleanup */
+ self->fork = 0;
+}
+proc:::exit
+/self->start/
+{
+ /* record elapsed time for process execution */
+ this->elapsed = vtimestamp - self->start;
+ procs += this->elapsed;
+
+ /* sum elapsed by process name and ppid */
+ @Times_exec[execname] = sum(this->elapsed/1000000);
+ @Times_ppid[ppid] = sum(this->elapsed/1000000);
+
+ /* memory cleanup */
+ self->start = 0;
+}
+
+/*
+ * Print report
+ */
+dtrace:::END
+{
+ this->total = timestamp - start;
+ printf("short lived processes: %6d.%03d secs\n",
+ procs/1000000000, (procs%1000000000)/1000000);
+ printf("total sample duration: %6d.%03d secs\n",
+ this->total/1000000000, (this->total%1000000000)/1000000);
+ printf("\nTotal time by process name,\n");
+ printa("%18s %@12d ms\n", @Times_exec);
+ printf("\nTotal time by PPID,\n");
+ printa("%18d %@12d ms\n", @Times_ppid);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/sigdist.d b/cddl/contrib/dtracetoolkit/Proc/sigdist.d
new file mode 100755
index 0000000..c3b2bc0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/sigdist.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -s
+/*
+ * sigdist.d - signal distribution by process name.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * This is a simple DTrace script that prints the number of signals
+ * recieved by process and signal number. This script is also available
+ * as /usr/demo/dtrace/sig.d, where it originates.
+ *
+ * $Id: sigdist.d 4 2007-08-01 11:01:38Z brendan $
+ *
+ * USAGE: sigdist.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * SENDER process name of sender
+ * RECIPIENT process name of target
+ * SIG signal number, see signal(3head)
+ * COUNT number of signals sent
+ *
+ * BASED ON: /usr/demo/dtrace/sig.d
+ *
+ * SEE ALSO: DTrace Guide "proc Provider" chapter (docs.sun.com)
+ * kill.d(1M)
+ *
+ * PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Jun-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+proc:::signal-send
+{
+ @Count[execname, stringof(args[1]->pr_fname), args[2]] = count();
+}
+
+dtrace:::END
+{
+ printf("%16s %16s %6s %6s\n", "SENDER", "RECIPIENT", "SIG", "COUNT");
+ printa("%16s %16s %6d %6@d\n", @Count);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/stacksize.d b/cddl/contrib/dtracetoolkit/Proc/stacksize.d
new file mode 100755
index 0000000..fedcfbc
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/stacksize.d
@@ -0,0 +1,95 @@
+#!/usr/sbin/dtrace -s
+/*
+ * stacksize.d - measure stack size for running threads.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * $Id: stacksize.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: stacksize.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * value size of the user stack
+ * count number of samples at this size
+ *
+ * SEE ALSO: pmap(1)
+ *
+ * COPYRIGHT: Copyright (c) 2006 Jonathan Adams
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 16-Feb-2006 Jonathan Adams Created this.
+ * 16-Feb-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+this uintptr_t stkinfoptr;
+this uintptr_t stkptr;
+
+dtrace:::BEGIN
+{
+ trace("Sampling... Hit Ctrl-C to end\n");
+}
+
+sched:::on-cpu, profile:::profile-997
+{
+ this->stkinfoptr = 0;
+ this->stkptr = 0;
+}
+
+sched:::on-cpu, profile:::profile-997
+/execname != "sched"/
+{
+ this->stkinfoptr = curthread->t_lwp->lwp_ustack;
+ this->stkptr = (uintptr_t)0;
+}
+
+sched:::on-cpu, profile:::profile-997
+/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_ILP32/
+{
+ this->stkinfo32 = (stack32_t *)copyin(this->stkinfoptr,
+ sizeof (stack32_t));
+ this->stktop = (uintptr_t)this->stkinfo32->ss_sp +
+ this->stkinfo32->ss_size;
+ this->stkptr = (uintptr_t)uregs[R_SP];
+}
+
+sched:::on-cpu, profile:::profile-997
+/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_LP64/
+{
+ this->stkinfo = (stack_t *)copyin(this->stkinfoptr,
+ sizeof (stack_t));
+ this->stktop = (uintptr_t)this->stkinfo->ss_sp +
+ this->stkinfo->ss_size;
+ this->stkptr = (uintptr_t)uregs[R_SP];
+}
+
+sched:::on-cpu, profile:::profile-997
+/this->stkptr != 0/
+{
+ @sizes[execname] = quantize(this->stktop - this->stkptr);
+}
+
+dtrace:::ERROR
+{
+ @errors[execname] = count();
+}
+
+dtrace:::END
+{
+ printa(@sizes);
+ printf("\nErrors:\n");
+ printa(" %@d %s\n", @errors);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/sysbypid.d b/cddl/contrib/dtracetoolkit/Proc/sysbypid.d
new file mode 100755
index 0000000..bb80653
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/sysbypid.d
@@ -0,0 +1,53 @@
+#!/usr/sbin/dtrace -s
+/*
+ * sysbypid.d - print sysinfo events by process.
+ * Uses DTrace (Solaris 10 3/05).
+ *
+ * $Id: sysbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: sysbypid.d
+ *
+ * FIELDS:
+ * EXEC Process name
+ * PID Process ID
+ * SYS System statistic (see /usr/include/sys/sysinfo.h)
+ * VALUE Value by which statistic was incremented
+ *
+ * The virtual memory statistics are documented in the cpu_sysinfo struct
+ * in the /usr/include/sys/sysinfo.h file; and also in the sysinfo provider
+ * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 14-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN {
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sysinfo::: {
+ @Sys[execname, pid, probename] = sum(arg0);
+}
+
+dtrace:::END {
+ printf("%16s %8s %22s %8s\n", "EXEC", "PID", "SYS", "VALUE");
+ printa("%16s %8d %22s %@8d\n", @Sys);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/syscallbypid.d b/cddl/contrib/dtracetoolkit/Proc/syscallbypid.d
new file mode 100755
index 0000000..f33ac02
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/syscallbypid.d
@@ -0,0 +1,54 @@
+#!/usr/sbin/dtrace -s
+/*
+ * syscallbypid.d - report on syscalls by PID.
+ * Written using DTrace (Solaris 10 3/05)
+ *
+ * $Id: syscallbypid.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: syscallbypid.d # hit Ctrl-C to end sample
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * SYSCALL syscall name
+ * COUNT number of syscalls for this PID
+ *
+ * This is based on a script from DExplorer.
+ *
+ * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 15-May-2005 Brendan Gregg Created this.
+ * 20-Apr-2006 " " Last update.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+syscall:::entry
+{
+ @num[pid, execname, probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf("%6s %-24s %-24s %8s\n", "PID", "CMD", "SYSCALL", "COUNT");
+ printa("%6d %-24s %-24s %@8d\n", @num);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/syscallbyproc.d b/cddl/contrib/dtracetoolkit/Proc/syscallbyproc.d
new file mode 100755
index 0000000..d0faa75
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/syscallbyproc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * syscallbyproc.d - report on syscalls by process name . DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: syscallbyproc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+syscall:::entry { @num[execname] = count(); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/threaded.d b/cddl/contrib/dtracetoolkit/Proc/threaded.d
new file mode 100755
index 0000000..7f5770b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/threaded.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -s
+/*
+ * threaded.d - sample multi-threaded CPU usage.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This measures thread IDs as a process runs across multiple CPUs.
+ * It is a simple script that can help determine if a multi-threaded
+ * application is effectively using it's threads, or if the threads have
+ * serialised. See the example file in Docs/Examples/threaded_example.txt
+ * for a demonstration.
+ *
+ * $Id: threaded.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: threaded.d
+ *
+ * FIELDS:
+ * PID process ID
+ * CMD process name
+ * value thread ID
+ * count number of samples
+ *
+ * SEE ALSO: prstat -L
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * Author: Brendan Gregg [Sydney, Australia]
+ *
+ * 25-Jul-2005 Brendan Gregg Created this.
+ * 25-Jul-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Sample at 100 Hertz
+ */
+profile:::profile-100
+/pid != 0/
+{
+ @sample[pid, execname] = lquantize(tid, 0, 128, 1);
+}
+
+/*
+ * Print output every 1 second
+ */
+profile:::tick-1sec
+{
+ printf("%Y,\n", walltimestamp);
+ printa("\n PID: %-8d CMD: %s\n%@d", @sample);
+ printf("\n");
+ trunc(@sample);
+}
diff --git a/cddl/contrib/dtracetoolkit/Proc/topsysproc b/cddl/contrib/dtracetoolkit/Proc/topsysproc
new file mode 100755
index 0000000..5836f68
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/topsysproc
@@ -0,0 +1,121 @@
+#!/usr/bin/sh
+#
+# topsysproc - display top syscalls by process name.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program continually prints a report of the number of system calls
+# by process name, and refreshes the display every 1 second or as specified
+# at the command line. Similar data can be fetched with "prstat -m".
+#
+# $Id: topsysproc 19 2007-09-12 07:47:59Z brendan $
+#
+# USAGE: topsysproc [interval]
+#
+# FIELDS:
+# load avg load averages, see uptime(1)
+# syscalls total number of syscalls in this interval
+# PROCESS process name
+# COUNT number of occurances in this interval
+#
+# NOTE: There may be several PIDs with the same process name.
+#
+# SEE ALSO: prstat(1M)
+#
+# INSPIRATION: top(1) by William LeFebvre
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 13-Jun-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+#
+# Check options
+#
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+ cat <<-END
+ USAGE: topsysproc [interval]
+ eg,
+ topsysproc # default, 1 second updates
+ topsysproc 5 # 5 second updates
+ END
+ exit 1
+fi
+interval=1
+if [ "$1" -gt 0 ]; then
+ interval=$1
+fi
+
+#
+# Run DTrace
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ #pragma D option destructive
+
+ /* constants */
+ inline int INTERVAL = '$interval';
+ inline int SCREEN = 20;
+
+ /* variables */
+ dtrace:::BEGIN
+ {
+ secs = 0;
+ printf("Tracing... Please wait.\n");
+ }
+
+ /* record syscall event */
+ syscall:::entry
+ {
+ @Name[execname] = count();
+ @Total = count();
+ }
+
+ /* update screen */
+ profile:::tick-1sec
+ /++secs >= INTERVAL/
+ {
+ /* fetch load averages */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load5a = `hp_avenrun[1] / 65536;
+ this->load15a = `hp_avenrun[2] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+ this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536;
+ this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
+
+ /* clear screen */
+ system("clear");
+
+ /* print load average */
+ printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
+ walltimestamp, this->load1a, this->load1b, this->load5a,
+ this->load5b, this->load15a, this->load15b);
+
+ /* print syscall count */
+ printa(" syscalls: %@d\n",@Total);
+
+ /* print report */
+ trunc(@Name, SCREEN);
+ printf("\n %-25s %12s\n", "PROCESS", "COUNT");
+ printa(" %-25s %@12d\n", @Name);
+
+ /* reset variables */
+ trunc(@Name);
+ clear(@Total);
+ secs = 0;
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/Proc/writebytes.d b/cddl/contrib/dtracetoolkit/Proc/writebytes.d
new file mode 100755
index 0000000..1fec0e9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/writebytes.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * writebytes.d - write bytes by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: writebytes.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+sysinfo:::writech { @bytes[execname] = sum(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Proc/writedist.d b/cddl/contrib/dtracetoolkit/Proc/writedist.d
new file mode 100755
index 0000000..099c252
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Proc/writedist.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * writedist.d - write distribution by process name. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: writedist.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+sysinfo:::writech { @dist[execname] = quantize(arg0); }
diff --git a/cddl/contrib/dtracetoolkit/Python/Readme b/cddl/contrib/dtracetoolkit/Python/Readme
new file mode 100644
index 0000000..f183c74
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/Readme
@@ -0,0 +1,28 @@
+Python - DTracing Python
+
+ These scripts trace the Python programming language, and require a version
+ of Python which has been built with DTrace probes.
+
+ The Python DTrace provider was originally written by John Levon, and
+ was integrated into Solaris Nevada in build 65. If you are on a different
+ OS with DTrace and would like to use these scripts, you could download
+ Python and the Python DTrace provider patch listed in the comments here,
+
+ http://blogs.sun.com/levon/entry/python_and_dtrace_in_build
+
+ You will need patch and build Python for these probes to work.
+ Or, check if a pre-built package is available someone on opensolaris.org.
+
+ Since the DTrace Python provider may be developed further, there is a chance
+ that it has changed slightly by the time you are reading this, causing
+ these scripts to either break or behave oddly. Firstly, check for newer
+ versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider python {
+ probe function-entry(file, subroutine, lineno)
+ probe function-return(file, subroutine, lineno)
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/Python/py_calldist.d b/cddl/contrib/dtracetoolkit/Python/py_calldist.d
new file mode 100755
index 0000000..1c64c10
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_calldist.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_calldist.d - measure Python elapsed times for functions.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_calldist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Python activity from all programs running on the system with
+ * Python provider support.
+ *
+ * USAGE: py_calldist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Python
+ * operations. Use py_calltime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Python program
+ * 2 Type of call (func)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+python*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_calltime.d b/cddl/contrib/dtracetoolkit/Python/py_calltime.d
new file mode 100755
index 0000000..d152b35
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_calltime.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_calltime.d - measure Python elapsed times for functions.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_calltime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Python activity from all programs running on the system with
+ * Python provider support.
+ *
+ * USAGE: py_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Python program
+ * TYPE Type of call (func/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+python*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_cpudist.d b/cddl/contrib/dtracetoolkit/Python/py_cpudist.d
new file mode 100755
index 0000000..cf0e7b2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_cpudist.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_cpudist.d - measure Python on-CPU times for functions.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_cpudist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Python activity from all programs running on the system with
+ * Python provider support.
+ *
+ * USAGE: py_cpudist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Python
+ * operations. Use py_cputime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Python program
+ * 2 Type of call (func)
+ * 3 Name of call
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+python*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nExclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_cputime.d b/cddl/contrib/dtracetoolkit/Python/py_cputime.d
new file mode 100755
index 0000000..ca40a93
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_cputime.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_cputime.d - measure Python on-CPU times for functions.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_cputime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Python activity from all programs running on the system with
+ * Python provider support.
+ *
+ * USAGE: py_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Python program
+ * TYPE Type of call (func/total)
+ * NAME Name of call (function name)
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+python*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_flow.d b/cddl/contrib/dtracetoolkit/Python/py_flow.d
new file mode 100755
index 0000000..893ea78
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_flow.d
@@ -0,0 +1,70 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_flow.d - snoop Python execution showing function flow.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_flow.d 51 2007-09-24 00:55:23Z brendan $
+ *
+ * This traces Python activity from all Python programs on the system
+ * running with Python provider support.
+ *
+ * USAGE: py_flow.d # hit Ctrl-C to end
+ *
+ * This watches Python function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * FUNC Function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s -- %s\n", "C", "TIME(us)", "FILE", "FUNC");
+}
+
+python*:::function-entry
+{
+ printf("%3d %-16d %-16s %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+ self->depth++;
+}
+
+python*:::function-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_flowinfo.d b/cddl/contrib/dtracetoolkit/Python/py_flowinfo.d
new file mode 100755
index 0000000..ccba1df
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_flowinfo.d
@@ -0,0 +1,86 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_flowinfo.d - snoop Python function flow with info using DTrace.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_flowinfo.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Python programs on the system that are
+ * running with Python provider support.
+ *
+ * USAGE: py_flowinfo.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Python program
+ * LINE Line number of filename
+ * TYPE Type of call (func)
+ * FUNC Python function
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "FUNC");
+}
+
+python*:::function-entry,
+python*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+python*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg0)), arg2, "func", self->depth * 2, "",
+ copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+python*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg0)), arg2, "func", self->depth * 2, "",
+ copyinstr(arg1));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_flowtime.d b/cddl/contrib/dtracetoolkit/Python/py_flowtime.d
new file mode 100755
index 0000000..a339eac
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_flowtime.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_flowtime.d - snoop Python functions with flow and delta times.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_flowtime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces shell activity from Python programs on the system that are
+ * running with Python provider support.
+ *
+ * USAGE: py_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches Python function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * DELTA(us) Elapsed time from previous line to this line
+ * FUNC Python function name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+self int last;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "FUNC");
+}
+
+python*:::function-entry,
+python*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+python*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->delta, self->depth * 2, "",
+ copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+python*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %9d %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->delta, self->depth * 2, "",
+ copyinstr(arg1));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_funccalls.d b/cddl/contrib/dtracetoolkit/Python/py_funccalls.d
new file mode 100755
index 0000000..b430f29
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_funccalls.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_funccalls.d - measure Python function calls using DTrace.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_funccalls.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces Python activity from all running programs on the system
+ * which support the Python DTrace provider.
+ *
+ * USAGE: py_funccalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename that contained the function
+ * FUNC Python function name
+ * CALLS Function calls during this sample
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ @funcs[basename(copyinstr(arg0)), copyinstr(arg1)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-32s %-32s %8s\n", "FILE", "FUNC", "CALLS");
+ printa(" %-32s %-32s %@8d\n", @funcs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_malloc.d b/cddl/contrib/dtracetoolkit/Python/py_malloc.d
new file mode 100755
index 0000000..7f0860e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_malloc.d
@@ -0,0 +1,81 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_malloc.d - Python libc malloc analysis.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_malloc.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * This is an expiremental script to identify who is calling malloc() for
+ * memory allocation, and to print distribution plots of the requested bytes.
+ * If a malloc() occured while in a Python function, then that function is
+ * identified as responsible; else the caller of malloc() is identified as
+ * responsible - which will be a function from the Python engine.
+ *
+ * USAGE: py_malloc.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python$target:::function-entry
+{
+ self->file = basename(copyinstr(arg0));
+ self->name = copyinstr(arg1);
+}
+
+python$target:::function-return
+{
+ self->file = 0;
+ self->name = 0;
+}
+
+pid$target:libc:malloc:entry
+/self->file != NULL/
+{
+ @malloc_func_size[self->file, self->name] = sum(arg0);
+ @malloc_func_dist[self->file, self->name] = quantize(arg0);
+}
+
+pid$target:libc:malloc:entry
+/self->name == NULL/
+{
+ @malloc_lib_size[usym(ucaller)] = sum(arg0);
+ @malloc_lib_dist[usym(ucaller)] = quantize(arg0);
+}
+
+
+dtrace:::END
+{
+ printf("\nPython malloc byte distributions by engine caller,\n\n");
+ printa(" %A, total bytes = %@d %@d\n", @malloc_lib_size,
+ @malloc_lib_dist);
+
+ printf("\nPython malloc byte distributions by Python file and ");
+ printf("function,\n\n");
+ printa(" %s, %s, bytes total = %@d %@d\n", @malloc_func_size,
+ @malloc_func_dist);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_mallocstk.d b/cddl/contrib/dtracetoolkit/Python/py_mallocstk.d
new file mode 100755
index 0000000..ca42801
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_mallocstk.d
@@ -0,0 +1,49 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_mallocstk.d - Python libc malloc analysis with full stack traces.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_mallocstk.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * USAGE: py_mallocstk.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+/* tune as desired, */
+#pragma D option jstackframes=64
+#pragma D option jstackstrsize=1024
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+pid$target:libc:malloc:entry
+{
+ @mallocs[jstack()] = quantize(arg0);
+}
+
+dtrace:::END
+{
+ printf("\nPython malloc byte distributions by stack trace,\n\n");
+ printa(@mallocs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_profile.d b/cddl/contrib/dtracetoolkit/Python/py_profile.d
new file mode 100755
index 0000000..ff02df6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_profile.d
@@ -0,0 +1,79 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * py_profile.d - sample stack traces with Python translations using DTrace.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_profile.d 19 2007-09-12 07:47:59Z brendan $
+ *
+ * USAGE: py_profile.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This samples stack traces for the process specified. This stack trace
+ * will cross the Python engine and system libraries, and insert
+ * translations for Python stack frames where appropriate. This is best
+ * explained with an example stack frame output,
+ *
+ * libpython2.4.so.1.0`PyEval_EvalFrame+0x2fbf
+ * [ ./func_loop.py:5 (func_c) ]
+ * libpython2.4.so.1.0`fast_function+0xa8
+ * libpython2.4.so.1.0`call_function+0xda
+ * libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ * [ ./func_loop.py:11 (func_b) ]
+ * libpython2.4.so.1.0`fast_function+0xa8
+ * libpython2.4.so.1.0`call_function+0xda
+ * libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ * [ ./func_loop.py:14 (func_a) ]
+ * libpython2.4.so.1.0`fast_function+0xa8
+ * libpython2.4.so.1.0`call_function+0xda
+ * libpython2.4.so.1.0`PyEval_EvalFrame+0xbdf
+ * [ ./func_loop.py:16 (?) ]
+ *
+ * The lines in square brackets are the native Python frames, the rest
+ * are the Python engine.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option jstackstrsize=1024
+
+/*
+ * Tunables
+ */
+#define DEPTH 10 /* stack depth, frames */
+#define RATE 1001 /* sampling rate, Hertz */
+#define TOP 25 /* number of stacks to output */
+
+dtrace:::BEGIN
+{
+ printf("Sampling %d-level stacks at %d Hertz... Hit Ctrl-C to end.\n",
+ DEPTH, RATE);
+}
+
+profile-RATE
+/pid == $target/
+{
+ @stacks[jstack(DEPTH)] = count();
+}
+
+dtrace:::END
+{
+ trunc(@stacks, TOP);
+ printf("Top %d most frequently sampled stacks,\n", TOP);
+ printa(@stacks);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_syscalls.d b/cddl/contrib/dtracetoolkit/Python/py_syscalls.d
new file mode 100755
index 0000000..2b3e44d
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_syscalls.d
@@ -0,0 +1,63 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_syscalls.d - count Python function calls and syscalls using DTrace.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_syscalls.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * USAGE: py_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Python program
+ * TYPE Type of call (func/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and function names are printed if available.
+ * The filename for syscalls may be printed as "python", if the program
+ * was invoked using the form "python filename" rather than running the
+ * program with an interpreter line.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python$target:::function-entry
+{
+ @calls[basename(copyinstr(arg0)), "func", copyinstr(arg1)] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[basename(execname), "syscall", probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf("\nCalls for PID %d,\n\n", $target);
+ printf(" %-32s %-10s %-22s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-32s %-10s %-22s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_syscolors.d b/cddl/contrib/dtracetoolkit/Python/py_syscolors.d
new file mode 100755
index 0000000..9f958ef
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_syscolors.d
@@ -0,0 +1,116 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_syscolors.d - trace Python function flow plus syscalls, in color.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_syscolors.d 27 2007-09-13 09:26:01Z brendan $
+ *
+ * USAGE: py_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches Python function entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Python program
+ * LINE Line number of filename
+ * TYPE Type of call (func/syscall)
+ * NAME Python function or syscall name
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ color_python = "\033[2;35m"; /* violet, faint */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ self->depth = 0;
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+python$target:::function-entry,
+python$target:::function-return,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+python$target:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_python,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+python$target:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_python,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Python/py_who.d b/cddl/contrib/dtracetoolkit/Python/py_who.d
new file mode 100755
index 0000000..3a772e3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Python/py_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * py_who.d - trace Python function execution by process using DTrace.
+ * Written for the Python DTrace provider.
+ *
+ * $Id: py_who.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces Python activity from all Python programs on the system that are
+ * running with Python provider support.
+ *
+ * USAGE: py_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of Python
+ * UID User ID of the owner
+ * FUNCS Number of function calls
+ * FILE Pathname of the Python program
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+python*:::function-entry
+{
+ @lines[pid, uid, copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %s\n", "PID", "UID", "FUNCS", "FILE");
+ printa(" %6d %6d %@6d %s\n", @lines);
+}
diff --git a/cddl/contrib/dtracetoolkit/README b/cddl/contrib/dtracetoolkit/README
new file mode 120000
index 0000000..216661b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/README
@@ -0,0 +1 @@
+Guide \ No newline at end of file
diff --git a/cddl/contrib/dtracetoolkit/Ruby/Readme b/cddl/contrib/dtracetoolkit/Ruby/Readme
new file mode 100644
index 0000000..9dc3cc3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/Readme
@@ -0,0 +1,31 @@
+Ruby - DTracing Ruby
+
+ These scripts trace activity of the Ruby programming language, and
+ require the DTrace Ruby provider written by Joyent.
+
+ Currently, the DTrace Ruby provider is a seperate download either in
+ patch, source or binary form. Start with the "Ruby DTrace" link on
+ http://dtrace.joyent.com/, and after getting a version running, the
+ scripts in this directory should work.
+
+ Since the DTrace Ruby provider is under development, there is a chance
+ that it has changed slightly by the time you are reading this, causing
+ these scripts to either break or behave oddly. Firstly, check for newer
+ versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider ruby {
+ probe function-entry(class, method, file, lineno);
+ probe function-return(class, method, file, lineno);
+ probe raise(errinfo, file, lineno);
+ probe rescue(file, lineno);
+ probe line(file, lineno);
+ probe gc-begin();
+ probe gc-end();
+ probe object-create-start(object, file, lineno);
+ probe object-create-done(object, file, lineno);
+ probe object-free(object);
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_calldist.d b/cddl/contrib/dtracetoolkit/Ruby/rb_calldist.d
new file mode 100755
index 0000000..e3018ea
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_calldist.d
@@ -0,0 +1,120 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_calldist.d - measure Ruby elapsed times for types of operation.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_calldist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_calldist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Ruby
+ * operations. Use rb_calltime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Ruby program
+ * 2 Type of call (method/obj-new/gc)
+ * 3 Name of call
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+ruby*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg2));
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+ruby*:::object-create-start
+{
+ self->object = timestamp;
+}
+
+ruby*:::object-create-done
+/self->object/
+{
+ this->elapsed = timestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg1));
+ this->file = this->file != NULL ? this->file : ".";
+
+ @types[this->file, "obj-new", copyinstr(arg0)] =
+ quantize(this->elapsed / 1000);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+ruby*:::gc-begin
+{
+ self->gc = timestamp;
+}
+
+ruby*:::gc-end
+/self->gc/
+{
+ this->elapsed = timestamp - self->gc;
+ self->gc = 0;
+
+ @types[".", "gc", "-"] = quantize(this->elapsed / 1000);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("\nElapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("\nExclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function elapsed times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_calls.d b/cddl/contrib/dtracetoolkit/Ruby/rb_calls.d
new file mode 100755
index 0000000..10e3b5a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_calls.d
@@ -0,0 +1,87 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_calls.d - count Ruby calls using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_calls.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * TYPE Type of call (method/obj-new/...)
+ * NAME Descriptive name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ @calls[basename(copyinstr(arg2)), "method", this->name] = count();
+}
+
+ruby*:::object-create-start
+{
+ this->name = copyinstr(arg0);
+ this->filename = basename(copyinstr(arg1));
+ this->filename = this->filename != NULL ? this->filename : ".";
+ @calls[this->filename, "obj-new", this->name] = count();
+}
+
+ruby*:::object-free
+{
+ this->name = copyinstr(arg0);
+ @calls[".", "obj-free", this->name] = count();
+}
+
+ruby*:::gc-begin
+{
+ @calls[".", "gc", "begin"] = count();
+}
+
+ruby*:::raise
+{
+ this->name = copyinstr(arg0);
+ @calls[basename(copyinstr(arg1)), "raise", this->name] = count();
+}
+
+ruby*:::rescue
+{
+ @calls[basename(copyinstr(arg0)), "rescue", "-"] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-24s %-10s %-30s %8s\n", "FILE", "TYPE", "NAME", "CALLS");
+ printa(" %-24s %-10s %-30s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_calltime.d b/cddl/contrib/dtracetoolkit/Ruby/rb_calltime.d
new file mode 100755
index 0000000..fac1261
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_calltime.d
@@ -0,0 +1,129 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_calltime.d - measure Ruby elapsed times for types of operation.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_calltime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * TYPE Type of call (method/obj-new/gc/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+ruby*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg2));
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+ruby*:::object-create-start
+{
+ self->object = timestamp;
+}
+
+ruby*:::object-create-done
+/self->object/
+{
+ this->elapsed = timestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg1));
+ this->file = this->file != NULL ? this->file : ".";
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "obj-new", this->name] = count();
+ @types[this->file, "obj-new", this->name] = sum(this->elapsed);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+ruby*:::gc-begin
+{
+ self->gc = timestamp;
+}
+
+ruby*:::gc-end
+/self->gc/
+{
+ this->elapsed = timestamp - self->gc;
+ self->gc = 0;
+ @num[".", "gc", "-"] = count();
+ @types[".", "gc", "-"] = sum(this->elapsed);
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nElapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_cpudist.d b/cddl/contrib/dtracetoolkit/Ruby/rb_cpudist.d
new file mode 100755
index 0000000..daa4d1a
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_cpudist.d
@@ -0,0 +1,120 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_cpudist.d - measure Ruby on-CPU times for types of operation.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_cpudist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_cpudist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for Ruby
+ * operations. Use rb_cputime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the Ruby program
+ * 2 Type of call (method/obj-new/gc)
+ * 3 Name of call
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+ruby*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg2));
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+ruby*:::object-create-start
+{
+ self->object = vtimestamp;
+}
+
+ruby*:::object-create-done
+/self->object/
+{
+ this->oncpu = vtimestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg1));
+ this->file = this->file != NULL ? this->file : ".";
+
+ @types[this->file, "obj-new", copyinstr(arg0)] =
+ quantize(this->oncpu / 1000);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+ruby*:::gc-begin
+{
+ self->gc = vtimestamp;
+}
+
+ruby*:::gc-end
+/self->gc/
+{
+ this->oncpu = vtimestamp - self->gc;
+ self->gc = 0;
+
+ @types[".", "gc", "-"] = quantize(this->oncpu / 1000);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+dtrace:::END
+{
+ printf("\nOn-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("\nExclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("\nInclusive function on-CPU times (us),\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_cputime.d b/cddl/contrib/dtracetoolkit/Ruby/rb_cputime.d
new file mode 100755
index 0000000..d5885c8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_cputime.d
@@ -0,0 +1,129 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_cputime.d - measure Ruby on-CPU times for types of operation.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_cputime.d 49 2007-09-17 12:03:20Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * TYPE Type of call (method/obj-new/gc/total)
+ * NAME Name of call
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = vtimestamp;
+}
+
+ruby*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg2));
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+ruby*:::object-create-start
+{
+ self->object = vtimestamp;
+}
+
+ruby*:::object-create-done
+/self->object/
+{
+ this->oncpu = vtimestamp - self->object;
+ self->object = 0;
+ this->file = basename(copyinstr(arg1));
+ this->file = this->file != NULL ? this->file : ".";
+ this->name = copyinstr(arg0);
+
+ @num[this->file, "obj-new", this->name] = count();
+ @types[this->file, "obj-new", this->name] = sum(this->oncpu);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+ruby*:::gc-begin
+{
+ self->gc = vtimestamp;
+}
+
+ruby*:::gc-end
+/self->gc/
+{
+ this->oncpu = vtimestamp - self->gc;
+ self->gc = 0;
+ @num[".", "gc", "-"] = count();
+ @types[".", "gc", "-"] = sum(this->oncpu);
+ self->exclude[self->depth] += this->oncpu;
+}
+
+dtrace:::END
+{
+ printf("\nCount,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nElapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_flow.d b/cddl/contrib/dtracetoolkit/Ruby/rb_flow.d
new file mode 100755
index 0000000..e4ff760
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_flow.d
@@ -0,0 +1,72 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_flow.d - snoop Ruby execution showing method flow using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_flow.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_flow.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this method belongs to
+ * CLASS::METHOD Ruby classname and method
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * Filename and method names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-22s -- %s\n", "C", "TIME(us)", "FILE",
+ "CLASS::METHOD");
+}
+
+ruby*:::function-entry
+{
+ printf("%3d %-16d %-22s %*s-> %s::%s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg2)), self->depth * 2, "", copyinstr(arg0),
+ copyinstr(arg1));
+ self->depth++;
+}
+
+ruby*:::function-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-22s %*s<- %s::%s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg2)), self->depth * 2, "", copyinstr(arg0),
+ copyinstr(arg1));
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_flowinfo.d b/cddl/contrib/dtracetoolkit/Ruby/rb_flowinfo.d
new file mode 100755
index 0000000..4657263
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_flowinfo.d
@@ -0,0 +1,88 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_flowinfo.d - snoop Ruby function (method) flow with info using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_flowinfo.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_flowinfo.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Ruby program
+ * LINE Line number of filename
+ * TYPE Type of call (method)
+ * NAME Ruby class and method name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * Filename and method names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+ruby*:::function-entry,
+ruby*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+ruby*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg2)), arg3, "method", self->depth * 2, "",
+ this->name);
+ self->depth++;
+ self->last = timestamp;
+}
+
+ruby*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta,
+ basename(copyinstr(arg2)), arg3, "method", self->depth * 2, "",
+ this->name);
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_flowtime.d b/cddl/contrib/dtracetoolkit/Ruby/rb_flowtime.d
new file mode 100755
index 0000000..9b1c668
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_flowtime.d
@@ -0,0 +1,84 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_flowtime.d - snoop Ruby function (method) flow using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_flowtime.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_flowtime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this method belongs to
+ * DELTA(us) Elapsed time from previous line to this line
+ * CLASS::METHOD Ruby class and method name
+ *
+ * LEGEND:
+ * -> method entry
+ * <- method return
+ *
+ * Filename and method names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "CLASS::METHOD");
+}
+
+ruby*:::function-entry,
+ruby*:::function-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+ruby*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s-> %s::%s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg2)), this->delta, self->depth * 2, "",
+ copyinstr(arg0), copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+ruby*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %9d %*s<- %s::%s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg2)), this->delta, self->depth * 2, "",
+ copyinstr(arg0), copyinstr(arg1));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_funccalls.d b/cddl/contrib/dtracetoolkit/Ruby/rb_funccalls.d
new file mode 100755
index 0000000..7621500
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_funccalls.d
@@ -0,0 +1,57 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_funccalls.d - count Ruby function (method) calls using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_funccalls.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_funccalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * METHOD Method name
+ * COUNT Number of calls during sample
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::function-entry
+{
+ @funcs[basename(copyinstr(arg2)), copyinstr(arg0), copyinstr(arg1)] =
+ count();
+}
+
+dtrace:::END
+{
+ printf(" %-32.32s %-16s %-16s %8s\n", "FILE", "CLASS", "METHOD",
+ "CALLS");
+ printa(" %-32.32s %-16s %-16s %@8d\n", @funcs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_lines.d b/cddl/contrib/dtracetoolkit/Ruby/rb_lines.d
new file mode 100755
index 0000000..438f1f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_lines.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_lines.d - trace Ruby line execution by process using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_lines.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * This traces Ruby activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * LINE Line number
+ * COUNT Number of times a line was executed
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::line
+{
+ @calls[basename(copyinstr(arg0)), arg1] = count();
+}
+
+dtrace:::END
+{
+ printf(" %32s:%-6s %10s\n", "FILE", "LINE", "COUNT");
+ printa(" %32s:%-6d %@10d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_malloc.d b/cddl/contrib/dtracetoolkit/Ruby/rb_malloc.d
new file mode 100755
index 0000000..891b840
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_malloc.d
@@ -0,0 +1,80 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_malloc.d - Ruby operations and libc malloc statistics.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_malloc.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * WARNING: This script is not 100% accurate; This prints libc malloc() byte
+ * distributions by "recent" Ruby operation, which we hope will be usually
+ * relevant. This is an experimental script that may be improved over time.
+ *
+ * USAGE: rb_malloc.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * 1 Filename of the Ruby program
+ * 2 Type of operation (method/objnew/startup)
+ * 3 Name of operation
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+self string filename;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby$target:::function-entry
+{
+ self->file = basename(copyinstr(arg2));
+ self->type = "method";
+ self->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+}
+
+ruby$target:::object-create-start
+{
+ self->file = basename(copyinstr(arg1));
+ self->type = "objnew";
+ self->name = copyinstr(arg0);
+}
+
+pid$target:libc:malloc:entry
+/self->file != NULL/
+{
+ @mallocs[self->file, self->type, self->name] = quantize(arg0);
+}
+
+pid$target:libc:malloc:entry
+/self->file == NULL/
+{
+ @mallocs["ruby", "startup", "-"] = quantize(arg0);
+}
+
+
+dtrace:::END
+{
+ printf("Ruby malloc byte distributions by recent Ruby operation,\n");
+ printa(" %s, %s, %s %@d\n", @mallocs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_objcpu.d b/cddl/contrib/dtracetoolkit/Ruby/rb_objcpu.d
new file mode 100755
index 0000000..23c55e8
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_objcpu.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_objcpu.d - measure Ruby object creation on-CPU time using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_objcpu.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_objcpu.d # hit Ctrl-C to end
+ *
+ * Class names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::object-create-start
+{
+ self->vstart = vtimestamp;
+}
+
+ruby*:::object-create-done
+/self->vstart/
+{
+ this->oncpu = vtimestamp - self->vstart;
+ @total = sum(this->oncpu);
+ @dist[copyinstr(arg0)] = quantize(this->oncpu / 1000);
+ self->vstart = 0;
+}
+
+dtrace:::END
+{
+ normalize(@total, 1000000);
+ printa("Total object creation on-CPU time (ms): %@d\n\n", @total);
+ printf("Object creation on-CPU time distributions (us),\n");
+ printa(@dist);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_objnew.d b/cddl/contrib/dtracetoolkit/Ruby/rb_objnew.d
new file mode 100755
index 0000000..f6f00f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_objnew.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_objnew.d - count Ruby object creation using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_objnew.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * This traces Ruby activity from all programs running on the system with
+ * Ruby provider support.
+ *
+ * USAGE: rb_objnew.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * CLASS Class of new object
+ * COUNT Number of object creations during tracing
+ *
+ * Filename and class names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::object-create-done
+{
+ @objs[basename(copyinstr(arg1)), copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-24s %-36s %8s\n", "FILE", "CLASS", "COUNT");
+ printa(" %-24.24s %-36s %@8d\n", @objs);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_stat.d b/cddl/contrib/dtracetoolkit/Ruby/rb_stat.d
new file mode 100755
index 0000000..6de19f6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_stat.d
@@ -0,0 +1,146 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_stat.d - Ruby operation stats using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_stat.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * This traces activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_stat.d [interval [count]]
+ *
+ * FIELDS:
+ * EXEC/s Ruby programs executed per second, including
+ * those without Ruby provider support
+ * METHOD/s Methods called, per second
+ * OBJNEW/s Objects created, per second
+ * OBJFRE/s Objects freed, per second
+ * RAIS/s Raises, per second
+ * RESC/s Rescues, per second
+ * GC/s Garbage collects, per second
+ *
+ * The numbers are counts for the interval specified. The default interval
+ * is 1 second.
+ *
+ * If you see a count in "EXECS" but not in the other columns, then your
+ * Ruby software is probably not running with the DTrace Ruby provider.
+ * See Ruby/Readme.
+ *
+ * Filename and method names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+dtrace:::BEGIN
+{
+ execs = methods = objnew = objfree = gc = raised = rescue = 0;
+ lines = SCREEN + 1;
+ interval = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ secs = interval;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %8s %8s %8s %8s %6s %6s %6s\n", "TIME", "EXEC/s",
+ "METHOD/s", "OBJNEW/s", "OBJFRE/s", "RAIS/s", "RESC/s", "GC/s");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Tally Data
+ */
+proc:::exec-success
+/execname == "ruby"/
+{
+ execs++;
+}
+
+ruby*:::function-entry
+{
+ methods++;
+}
+
+ruby*:::object-create-start
+{
+ objnew++;
+}
+
+ruby*:::object-free
+{
+ objfree++;
+}
+
+ruby*:::raise
+{
+ raised++;
+}
+
+ruby*:::rescue
+{
+ rescue++;
+}
+
+ruby*:::gc-begin
+{
+ gc++;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %8d %8d %8d %8d %6d %6d %6d\n", walltimestamp,
+ execs / interval, methods / interval, objnew / interval,
+ objfree / interval, raised / interval, rescue / interval,
+ gc / interval);
+ execs = methods = objnew = objfree = gc = raised = rescue = 0;
+ secs = interval;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_syscalls.d b/cddl/contrib/dtracetoolkit/Ruby/rb_syscalls.d
new file mode 100755
index 0000000..495060b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_syscalls.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_syscalls.d - count Ruby calls and syscalls using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_syscalls.d 20 2007-09-12 09:28:22Z brendan $
+ *
+ * USAGE: rb_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the Ruby program
+ * TYPE Type of call (method/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and method names are printed if available.
+ * The filename for syscalls may be printed as "ruby", if the program
+ * was invoked using the form "ruby filename" rather than running the
+ * program with an interpreter line.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+self string filename;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby$target:::function-entry
+{
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ @calls[basename(copyinstr(arg2)), "method", this->name] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[basename(execname), "syscall", probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf("\nCalls for PID %d,\n\n", $target);
+ printf(" %-32s %-10s %-22s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-32s %-10s %-22s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_syscolors.d b/cddl/contrib/dtracetoolkit/Ruby/rb_syscolors.d
new file mode 100755
index 0000000..e14ac08
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_syscolors.d
@@ -0,0 +1,133 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_syscolors.d - trace Ruby method flow plus syscalls, in color.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_syscolors.d 27 2007-09-13 09:26:01Z brendan $
+ *
+ * USAGE: rb_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches Ruby method entries and returns, and indents child
+ * function calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the Ruby program
+ * LINE Line number of filename
+ * TYPE Type of call (method/line/syscall)
+ * NAME Ruby method or syscall name
+ *
+ * Filename and method names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ /*
+ * The following are terminal color escape sequences.
+ * Change them to whatever you prefer, eg HTML font tags.
+ */
+ color_ruby = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+ruby$target:::function-entry,
+ruby$target:::function-return,
+ruby$target:::line,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+ruby$target:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_ruby,
+ cpu, pid, this->delta, basename(copyinstr(arg2)), arg3, "method",
+ self->depth * 2, "", this->name, color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+ruby$target:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1));
+ self->depth--;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_ruby,
+ cpu, pid, this->delta, basename(copyinstr(arg2)), arg3, "method",
+ self->depth * 2, "", this->name, color_off);
+ self->last = timestamp;
+}
+
+ruby$target:::line
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-- %s\n", color_line,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg1, "line",
+ self->depth * 2, "", color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth--;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, "\"", "syscall", self->depth * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Ruby/rb_who.d b/cddl/contrib/dtracetoolkit/Ruby/rb_who.d
new file mode 100755
index 0000000..0119368
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Ruby/rb_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * rb_who.d - trace Ruby line execution by process using DTrace.
+ * Written for the Ruby DTrace provider.
+ *
+ * $Id: rb_who.d 49 2007-09-17 12:03:20Z brendan $
+ *
+ * This traces Ruby activity from all Ruby programs on the system that are
+ * running with Ruby provider support.
+ *
+ * USAGE: rb_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of Ruby
+ * UID User ID of the owner
+ * LINES Number of times a line was executed
+ * FILE Pathname of the Ruby program
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby*:::line
+{
+ @lines[pid, uid, copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %10s %s\n", "PID", "UID", "LINES", "FILE");
+ printa(" %6d %6d %@10d %s\n", @lines);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/Readme b/cddl/contrib/dtracetoolkit/Shell/Readme
new file mode 100644
index 0000000..9bf96ff
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/Readme
@@ -0,0 +1,35 @@
+Shell - DTracing Shell Scripting
+
+ These scripts trace activity of various shell programming languages,
+ and make use of specific shell DTrace providers, which are either
+ integrated or available for download from the shells page listed below.
+ Each script has a prefix to make the shell language clear.
+
+ http://www.opensolaris.org/os/community/dtrace/shells/
+
+ sh - the Bourne Shell. This provider was written by Alan Hargreaves and
+ is currently available both as a diff and in binary form from the shells
+ page.
+
+ Since the DTrace Shell providers are under development, there is a chance
+ that they have changed slightly by the time you are reading this, causing
+ these scripts to either break or behave oddly. Firstly, check for newer
+ versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the providers when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider sh {
+ probe function-entry(file, function, lineno);
+ probe function-return(file, function, rval);
+ probe builtin-entry(file, function, lineno);
+ probe builtin-return(file, function, rval);
+ probe command-entry(file, function, lineno);
+ probe command-return(file, function, rval);
+ probe script-start(file);
+ probe script-done(file, rval);
+ probe subshell-entry(file, childpid);
+ probe subshell-return(file, rval);
+ probe line(file, lineno);
+ };
+
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_calldist.d b/cddl/contrib/dtracetoolkit/Shell/sh_calldist.d
new file mode 100755
index 0000000..e758bab
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_calldist.d
@@ -0,0 +1,119 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_calldist.d - measure Bourne shell elapsed times for types of operation.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_calldist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_calldist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of elapsed time for shell
+ * operations. Use sh_calltime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the shell or shellscript
+ * 2 Type of call (func/builtin/cmd)
+ * 3 Name of call
+ *
+ * Filename and call names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+sh*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+sh*:::builtin-entry
+{
+ self->builtin = timestamp;
+}
+
+sh*:::builtin-return
+/self->builtin/
+{
+ this->elapsed = timestamp - self->builtin;
+ self->builtin = 0;
+
+ @types[basename(copyinstr(arg0)), "builtin", copyinstr(arg1)] =
+ quantize(this->elapsed / 1000);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+sh*:::command-entry
+{
+ self->command = timestamp;
+}
+
+sh*:::command-return
+/self->command/
+{
+ this->elapsed = timestamp - self->command;
+ self->command = 0;
+
+ @types[basename(copyinstr(arg0)), "cmd", copyinstr(arg1)] =
+ quantize(this->elapsed / 1000);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("Elapsed times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("Exclusive function elapsed times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("Inclusive function elapsed times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_calls.d b/cddl/contrib/dtracetoolkit/Shell/sh_calls.d
new file mode 100755
index 0000000..2ad72f1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_calls.d
@@ -0,0 +1,72 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_calls.d - count Bourne calls (func/builtin/cmd/subsh) using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_calls.d 52 2007-09-24 04:28:01Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * TYPE Type of call (func/builtin/cmd/subsh)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::function-entry
+{
+ @calls[basename(copyinstr(arg0)), "func", copyinstr(arg1)] = count();
+}
+
+sh*:::builtin-entry
+{
+ @calls[basename(copyinstr(arg0)), "builtin", copyinstr(arg1)] = count();
+}
+
+sh*:::command-entry
+{
+ @calls[basename(copyinstr(arg0)), "cmd", copyinstr(arg1)] = count();
+}
+
+sh*:::subshell-entry
+/arg1 != 0/
+{
+ @calls[basename(copyinstr(arg0)), "subsh", "-"] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-22s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-22s %-10s %-32s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_calltime.d b/cddl/contrib/dtracetoolkit/Shell/sh_calltime.d
new file mode 100755
index 0000000..e3c72b4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_calltime.d
@@ -0,0 +1,136 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_calltime.d - measure Bourne shell elapsed times for types of operation.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_calltime.d 46 2007-09-17 10:25:36Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_calltime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * TYPE Type of call (func/builtin/cmd/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * Filename and call names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::function-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->function[self->depth] = timestamp;
+}
+
+sh*:::function-return
+/self->function[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->function[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl);
+ @types_excl["-", "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+sh*:::builtin-entry
+{
+ self->builtin = timestamp;
+}
+
+sh*:::builtin-return
+/self->builtin/
+{
+ this->elapsed = timestamp - self->builtin;
+ self->builtin = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "builtin", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types[this->file, "builtin", this->name] = sum(this->elapsed);
+ @types["-", "total", "-"] = sum(this->elapsed);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+sh*:::command-entry
+{
+ self->command = timestamp;
+}
+
+sh*:::command-return
+/self->command/
+{
+ this->elapsed = timestamp - self->command;
+ self->command = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "cmd", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types[this->file, "cmd", this->name] = sum(this->elapsed);
+ @types["-", "total", "-"] = sum(this->elapsed);
+
+ self->exclude[self->depth] += this->elapsed;
+}
+
+dtrace:::END
+{
+ printf("\nCounts,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nElapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function elapsed times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_cpudist.d b/cddl/contrib/dtracetoolkit/Shell/sh_cpudist.d
new file mode 100755
index 0000000..0809fd5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_cpudist.d
@@ -0,0 +1,142 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_cpudist.d - measure Bourne shell on-CPU times for types of operation.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_cpudist.d 28 2007-09-13 10:49:37Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_cpudist.d # hit Ctrl-C to end
+ *
+ * This script prints distribution plots of on-CPU time for shell
+ * operations. Use sh_cputime.d for summary reports.
+ *
+ * FIELDS:
+ * 1 Filename of the shell or shellscript
+ * 2 Type of call (func/builtin/cmd)
+ * 3 Name of call
+ *
+ * Filename and call names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::function-entry
+{
+ self->depth++;
+ self->function[self->depth] = vtimestamp;
+ self->exclude[self->depth] = 0;
+}
+
+sh*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @types_incl[this->file, "func", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[this->file, "func", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+sh*:::builtin-entry
+{
+ self->builtin = vtimestamp;
+}
+
+sh*:::builtin-return
+/self->builtin/
+{
+ this->oncpu = vtimestamp - self->builtin;
+ self->builtin = 0;
+
+ @types[basename(copyinstr(arg0)), "builtin", copyinstr(arg1)] =
+ quantize(this->oncpu / 1000);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+sh*:::command-entry
+{
+ incmd[pid] = basename(copyinstr(arg0));
+ depth[pid] = self->depth;
+}
+
+sh*:::command-return
+{
+ incmd[pid] = 0;
+}
+
+proc:::exec-success
+{
+ /*
+ * Due to thread timing after fork(), this probe can fire before
+ * sh*:::command-entry has, which means we can't predicate this
+ * exec() away just yet. Store the vtimestamp in case it is needed.
+ */
+ self->command = vtimestamp;
+}
+
+proc:::exit
+/incmd[ppid] == NULL/
+{
+ self->command = 0;
+}
+
+proc:::exit
+/incmd[ppid] != NULL/
+{
+ this->oncpu = vtimestamp - self->command;
+ self->command = 0;
+
+ @types[incmd[ppid], "cmd", execname] = quantize(this->oncpu / 1000);
+
+ self->exclude[depth[ppid]] += this->oncpu;
+ incmd[ppid] = 0;
+ depth[ppid] = 0;
+}
+
+dtrace:::END
+{
+ printf("On-CPU times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types);
+
+ printf("Exclusive function on-CPU times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types_excl);
+
+ printf("Inclusive function on-CPU times (us),\n\n");
+ printa(" %s, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_cputime.d b/cddl/contrib/dtracetoolkit/Shell/sh_cputime.d
new file mode 100755
index 0000000..433ce8e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_cputime.d
@@ -0,0 +1,158 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_cputime.d - measure Bourne shell on-CPU times for types of operation.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_cputime.d 46 2007-09-17 10:25:36Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_cputime.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * TYPE Type of call (func/builtin/cmd/total)
+ * NAME Name of call
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * Filename and call names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::function-entry
+{
+ self->depth++;
+ self->function[self->depth] = vtimestamp;
+ self->exclude[self->depth] = 0;
+}
+
+sh*:::function-return
+/self->function[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->function[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->function[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "func", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types_incl[this->file, "func", this->name] = sum(this->oncpu_incl);
+ @types_excl[this->file, "func", this->name] = sum(this->oncpu_excl);
+ @types_excl["-", "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+sh*:::builtin-entry
+{
+ self->builtin = vtimestamp;
+}
+
+sh*:::builtin-return
+/self->builtin/
+{
+ this->oncpu = vtimestamp - self->builtin;
+ self->builtin = 0;
+ this->file = basename(copyinstr(arg0));
+ this->name = copyinstr(arg1);
+
+ @num[this->file, "builtin", this->name] = count();
+ @num["-", "total", "-"] = count();
+ @types[this->file, "builtin", this->name] = sum(this->oncpu);
+ @types["-", "total", "-"] = sum(this->oncpu);
+
+ self->exclude[self->depth] += this->oncpu;
+}
+
+sh*:::command-entry
+{
+ incmd[pid] = basename(copyinstr(arg0));
+ depth[pid] = self->depth;
+}
+
+sh*:::command-return
+{
+ incmd[pid] = 0;
+}
+
+proc:::exec-success
+{
+ /*
+ * Due to thread timing after fork(), this probe can fire before
+ * sh*:::command-entry has, which means we can't predicate this
+ * exec() away just yet. Store the vtimestamp in case it is needed.
+ */
+ self->command = vtimestamp;
+}
+
+proc:::exit
+/incmd[ppid] == NULL/
+{
+ self->command = 0;
+}
+
+proc:::exit
+/incmd[ppid] != NULL/
+{
+ this->oncpu = vtimestamp - self->command;
+ self->command = 0;
+
+ @num[incmd[ppid], "cmd", execname] = count();
+ @num["-", "total", "-"] = count();
+ @types[incmd[ppid], "cmd", execname] = sum(this->oncpu);
+ @types["-", "total", "-"] = sum(this->oncpu);
+
+ self->exclude[depth[ppid]] += this->oncpu;
+ incmd[ppid] = 0;
+ depth[ppid] = 0;
+}
+
+dtrace:::END
+{
+ printf("\nCounts,\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-20s %-10s %-32s %@8d\n", @num);
+
+ normalize(@types, 1000);
+ printf("\nOn-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types);
+
+ normalize(@types_excl, 1000);
+ printf("\nExclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_excl);
+
+ normalize(@types_incl, 1000);
+ printf("\nInclusive function on-CPU times (us),\n");
+ printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL");
+ printa(" %-20s %-10s %-32s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_flow.d b/cddl/contrib/dtracetoolkit/Shell/sh_flow.d
new file mode 100755
index 0000000..ff24f59
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_flow.d
@@ -0,0 +1,85 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_flow.d - snoop Bourne shell execution showing function flow using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_flow.d 41 2007-09-17 02:20:10Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_flow.d # hit Ctrl-C to end
+ *
+ * This watches shell function entries and returns, and indents child
+ * function calls. Shell builtins are also printed.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * NAME Shell function, builtin or command name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ * > builtin
+ * | external command
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ self->depth = 0;
+ printf("%3s %-16s %-16s -- %s\n", "C", "TIME(us)", "FILE", "NAME");
+}
+
+sh*:::function-entry
+{
+ printf("%3d %-16d %-16s %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+ self->depth++;
+}
+
+sh*:::function-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+}
+
+sh*:::builtin-entry
+{
+ printf("%3d %-16d %-16s %*s> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+}
+
+sh*:::command-entry
+{
+ printf("%3d %-16d %-16s %*s| %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), self->depth * 2, "", copyinstr(arg1));
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_flowinfo.d b/cddl/contrib/dtracetoolkit/Shell/sh_flowinfo.d
new file mode 100755
index 0000000..6da0836
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_flowinfo.d
@@ -0,0 +1,152 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_flowinfo.d - snoop Bourne shell flow with additional info.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_flowinfo.d 52 2007-09-24 04:28:01Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_flowinfo.d # hit Ctrl-C to end
+ *
+ * This watches shell function entries and returns, and indents child
+ * function calls. Shell builtins and external commands are also printed.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the shell script
+ * LINE Line number of filename
+ * TYPE Type of call (func/builtin/cmd/subsh)
+ * NAME Shell function, builtin or command name
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ self->depth = 0;
+ printf("%3s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+sh*:::function-entry,
+sh*:::function-return,
+sh*:::builtin-entry,
+sh*:::builtin-return,
+sh*:::command-entry,
+sh*:::command-return,
+sh*:::subshell-entry,
+sh*:::subshell-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+sh*:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh*:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "func", self->depth * 2,
+ "", copyinstr(arg1));
+ self->last = timestamp;
+}
+
+sh*:::builtin-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), arg2, "builtin",
+ self->depth * 2, "", copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh*:::builtin-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "builtin",
+ self->depth * 2, "", copyinstr(arg1));
+ self->last = timestamp;
+}
+
+sh*:::command-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), arg2, "cmd",
+ self->depth * 2, "", copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh*:::command-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "cmd",
+ self->depth * 2, "", copyinstr(arg1));
+ self->last = timestamp;
+}
+
+sh*:::subshell-entry
+/arg1 != 0/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %10d %16s:- %-8s %*s-> pid %d\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "subsh",
+ self->depth * 2, "", arg1);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh*:::subshell-return
+/self->last/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %10d %16s:- %-8s %*s<- = %d\n", cpu, pid,
+ this->delta, basename(copyinstr(arg0)), "subsh",
+ self->depth * 2, "", arg1);
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_flowtime.d b/cddl/contrib/dtracetoolkit/Shell/sh_flowtime.d
new file mode 100755
index 0000000..5df118b
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_flowtime.d
@@ -0,0 +1,118 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_flowtime.d - snoop Bourne shell execution with flow and delta times.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_flowtime.d 45 2007-09-17 08:54:56Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches shell function entries and returns, and indents child
+ * function calls. Shell builtins are also printed.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * FILE Filename that this function belongs to
+ * NAME Shell function or builtin name
+ *
+ * LEGEND:
+ * -> function entry
+ * <- function return
+ * > builtin
+ * | external command
+ *
+ * DELTAs:
+ * -> previous line to the start of this function
+ * <- previous line to the end of this function
+ * > previous line to the end of this builtin
+ * | previous line to the end of this command
+ *
+ * See sh_flowinfo.d for more verbose and more straightforward delta times.
+ *
+ * Filename and function names are printed if available.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+self uint64_t last;
+
+dtrace:::BEGIN
+{
+ printf("%3s %-16s %-16s %9s -- %s\n", "C", "TIME(us)", "FILE",
+ "DELTA(us)", "NAME");
+}
+
+sh*:::function-entry,
+sh*:::function-return,
+sh*:::builtin-return,
+sh*:::command-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+sh*:::function-entry
+{
+ this->elapsed = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s-> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->elapsed, self->depth * 2, "",
+ copyinstr(arg1));
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh*:::function-return
+{
+ this->elapsed = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %-16d %-16s %9d %*s<- %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->elapsed, self->depth * 2, "",
+ copyinstr(arg1));
+ self->last = timestamp;
+}
+
+sh*:::builtin-return
+{
+ this->elapsed = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s> %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->elapsed, self->depth * 2, "",
+ copyinstr(arg1));
+ self->last = timestamp;
+}
+
+sh*:::command-return
+{
+ this->elapsed = (timestamp - self->last) / 1000;
+ printf("%3d %-16d %-16s %9d %*s| %s\n", cpu, timestamp / 1000,
+ basename(copyinstr(arg0)), this->elapsed, self->depth * 2, "",
+ copyinstr(arg1));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_lines.d b/cddl/contrib/dtracetoolkit/Shell/sh_lines.d
new file mode 100755
index 0000000..5cfeb49
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_lines.d
@@ -0,0 +1,55 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_lines.d - trace Bourne shell line execution using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_lines.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_lines.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * LINE Line number
+ * COUNT Number of times a line was executed
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::line
+{
+ @calls[basename(copyinstr(arg0)), arg1] = count();
+}
+
+dtrace:::END
+{
+ printf(" %32s:%-6s %10s\n", "FILE", "LINE", "COUNT");
+ printa(" %32s:%-6d %@10d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_pidcolors.d b/cddl/contrib/dtracetoolkit/Shell/sh_pidcolors.d
new file mode 100755
index 0000000..0196218
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_pidcolors.d
@@ -0,0 +1,203 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_pidcolors.d - Demonstration of deeper DTrace Bourne shell analysis.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_pidcolors.d 27 2007-09-13 09:26:01Z brendan $
+ *
+ * USAGE: sh_pidcolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This extends sh_syscolors.d by including some "pid" provider tracing
+ * as a starting point for deeper analysis. Currently it adds the probes,
+ *
+ * pid$target:a.out:e*:entry,
+ * pid$target:a.out:e*:return
+ *
+ * which means, all functions from the /usr/bin/sh binary that begin with
+ * the letter "e". This adds about 34 probes. Customise it to whichever
+ * parts of /usr/bin/sh or the system libraries you are interested in.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the shell script
+ * LINE Line number of filename
+ * TYPE Type of call (func/builtin/cmd/line/shell)
+ * NAME Shell function, builtin or command name
+ *
+ * The filename for syscalls may be printed as the shell name, if the
+ * script was invoked using the form "shell filename" rather than running
+ * the script with an interpreter line.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ color_shell = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_lib = "\033[2;34m"; /* blue, faint */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+sh$target:::function-entry,
+sh$target:::function-return,
+sh$target:::builtin-entry,
+sh$target:::command-entry,
+syscall:::entry,
+syscall:::return,
+/* Customize Here, */
+pid$target:a.out:e*:entry,
+pid$target:a.out:e*:return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+sh$target:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::builtin-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::builtin-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::command-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::command-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::line
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-- %s\n", color_line,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg1, "line",
+ self->depth * 2, "", color_off);
+ self->last = timestamp;
+}
+
+/* Customise Here, */
+pid$target:a.out:e*:entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_lib,
+ cpu, pid, this->delta, basename(execname), "sh",
+ self->depth * 2, "", probefunc, color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+/* Customise Here, */
+pid$target:a.out:e*:return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_lib,
+ cpu, pid, this->delta, basename(execname), "sh",
+ self->depth * 2, "", probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, basename(execname), "syscall",
+ self->depth * 2, "", probefunc, color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, basename(execname), "syscall",
+ self->depth * 2, "", probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_stat.d b/cddl/contrib/dtracetoolkit/Shell/sh_stat.d
new file mode 100755
index 0000000..70e29b4
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_stat.d
@@ -0,0 +1,133 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_stat.d - Bourne shell operation stats using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_stat.d 52 2007-09-24 04:28:01Z brendan $
+ *
+ * This traces activity from all sh processes on the system that are running
+ * with sh provider support.
+ *
+ * USAGE: sh_stat.d [interval [count]]
+ *
+ * FIELDS:
+ * EXEC/s Bourne shells executed per second, including
+ * those without sh provider support
+ * FUNC/s Functions called, per second
+ * BLTIN/s Builtins called, per second
+ * SUB-SH/s Sub-shells called, per second
+ * CMD/s External commands called, per second
+ *
+ * The numbers are counts for the interval specified. The default interval
+ * is 1 second.
+ *
+ * If you see a count in "EXECS" but not in the other columns, then sh
+ * scripts may be running without the DTrace sh provider. See Shell/Readme.
+ *
+ * Filename and function names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+dtrace:::BEGIN
+{
+ execs = funcs = builtins = subs = cmds = 0;
+ lines = SCREEN + 1;
+ interval = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ secs = interval;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %8s %8s %8s %8s %8s\n", "TIME", "EXEC/s", "FUNCS/s",
+ "BLTINS/s", "SUB-SH/s", "CMD/s");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Tally Data
+ */
+proc:::exec-success
+/execname == "sh"/
+{
+ execs++;
+}
+
+sh*:::function-entry
+{
+ funcs++;
+}
+
+sh*:::builtin-entry
+{
+ builtins++;
+}
+
+sh*:::subshell-entry
+/arg0 != 0/
+{
+ subs++;
+}
+
+sh*:::command-entry
+{
+ cmds++;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %8d %8d %8d %8d %8d\n", walltimestamp, execs / interval,
+ funcs / interval, builtins / interval, subs / interval,
+ cmds / interval);
+ execs = funcs = builtins = subs = cmds = 0;
+ secs = interval;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_syscalls.d b/cddl/contrib/dtracetoolkit/Shell/sh_syscalls.d
new file mode 100755
index 0000000..127bede
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_syscalls.d
@@ -0,0 +1,83 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_syscalls.d - count Bourne calls and syscalls using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_syscalls.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * USAGE: sh_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * TYPE Type of call (func/builtin/cmd/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * Filename and function names are printed if available.
+ * The filename for syscalls may be printed as the shell name, if the
+ * script was invoked using the form "shell filename" rather than running
+ * the script with an interpreter line.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+self string filename;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh$target:::function-entry,
+sh$target:::builtin-entry,
+sh$target:::command-entry
+/self->filename == NULL/
+{
+ self->filename = basename(copyinstr(arg0));
+}
+
+sh$target:::function-entry
+{
+ @calls[self->filename, "func", copyinstr(arg1)] = count();
+}
+
+sh$target:::builtin-entry
+{
+ @calls[self->filename, "builtin", copyinstr(arg1)] = count();
+}
+
+sh$target:::command-entry
+{
+ @calls[self->filename, "cmd", copyinstr(arg1)] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[basename(execname), "syscall", probefunc] = count();
+}
+
+dtrace:::END
+{
+ printf("\nCalls for PID %d,\n\n", $target);
+ printf(" %-32s %-10s %-22s %8s\n", "FILE", "TYPE", "NAME", "COUNT");
+ printa(" %-32s %-10s %-22s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_syscolors.d b/cddl/contrib/dtracetoolkit/Shell/sh_syscolors.d
new file mode 100755
index 0000000..3622cb3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_syscolors.d
@@ -0,0 +1,169 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_syscolors.d - trace Bourne shell flow plus syscalls, in color.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_syscolors.d 27 2007-09-13 09:26:01Z brendan $
+ *
+ * USAGE: sh_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches shell function entries and returns, and indents child
+ * function calls. Shell builtins, commands and lines are also printed.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * FILE Filename of the shell script
+ * LINE Line number of filename
+ * TYPE Type of call (func/builtin/cmd/line/shell)
+ * NAME Shell function, builtin or command name
+ *
+ * The filename for syscalls may be printed as the shell name, if the
+ * script was invoked using the form "shell filename" rather than running
+ * the script with an interpreter line.
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ color_shell = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
+ "FILE", "LINE", "TYPE", "NAME");
+}
+
+sh$target:::function-entry,
+sh$target:::function-return,
+sh$target:::builtin-entry,
+sh$target:::command-entry,
+sh$target:::line,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+sh$target:::function-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::function-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), "func",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::builtin-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::builtin-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::command-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->depth++;
+ self->last = timestamp;
+}
+
+sh$target:::command-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd",
+ self->depth * 2, "", copyinstr(arg1), color_off);
+ self->last = timestamp;
+}
+
+sh$target:::line
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:%-4d %-8s %*s-- %s\n", color_line,
+ cpu, pid, this->delta, basename(copyinstr(arg0)), arg1, "line",
+ self->depth * 2, "", color_off);
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, basename(execname), "syscall",
+ self->depth * 2, "", probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, basename(execname), "syscall",
+ self->depth * 2, "", probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_wasted.d b/cddl/contrib/dtracetoolkit/Shell/sh_wasted.d
new file mode 100755
index 0000000..e20db8e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_wasted.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_wasted.d - measure Bourne shell elapsed times for "wasted" commands.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_wasted.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * USAGE: sh_wasted.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This script measures "wasted" commands - those which are called externally
+ * but are in fact builtins to the shell. Ever seen a script which calls
+ * /usr/bin/echo needlessly? This script measures that cost.
+ *
+ * FIELDS:
+ * FILE Filename of the shell or shellscript
+ * NAME Name of call
+ * TIME Total elapsed time for calls (us)
+ *
+ * IDEA: Mike Shapiro
+ *
+ * Filename and call names are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ isbuiltin["echo"] = 1;
+ isbuiltin["test"] = 1;
+ /* add builtins here */
+
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ self->start = timestamp;
+}
+
+sh$target:::command-entry
+{
+ self->command = timestamp;
+}
+
+sh$target:::command-return
+{
+ this->elapsed = timestamp - self->command;
+ this->path = copyinstr(arg1);
+ this->cmd = basename(this->path);
+}
+
+sh$target:::command-return
+/self->command && !isbuiltin[this->cmd]/
+{
+ @types_cmd[basename(copyinstr(arg0)), this->path] = sum(this->elapsed);
+ self->command = 0;
+}
+
+sh$target:::command-return
+/self->command/
+{
+ @types_wasted[basename(copyinstr(arg0)), this->path] =
+ sum(this->elapsed);
+ self->command = 0;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
+
+dtrace:::END
+{
+ this->elapsed = (timestamp - self->start) / 1000;
+ printf("Script duration: %d us\n", this->elapsed);
+
+ normalize(@types_cmd, 1000);
+ printf("\nExternal command elapsed times,\n");
+ printf(" %-30s %-22s %8s\n", "FILE", "NAME", "TIME(us)");
+ printa(" %-30s %-22s %@8d\n", @types_cmd);
+
+ normalize(@types_wasted, 1000);
+ printf("\nWasted command elapsed times,\n");
+ printf(" %-30s %-22s %8s\n", "FILE", "NAME", "TIME(us)");
+ printa(" %-30s %-22s %@8d\n", @types_wasted);
+}
diff --git a/cddl/contrib/dtracetoolkit/Shell/sh_who.d b/cddl/contrib/dtracetoolkit/Shell/sh_who.d
new file mode 100755
index 0000000..3e106ff
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Shell/sh_who.d
@@ -0,0 +1,56 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * sh_who.d - trace Bourne shell line execution by process using DTrace.
+ * Written for the sh DTrace provider.
+ *
+ * $Id: sh_who.d 25 2007-09-12 09:51:58Z brendan $
+ *
+ * This traces shell activity from all Bourne shells on the system that are
+ * running with sh provider support.
+ *
+ * USAGE: sh_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of the shell
+ * UID User ID of the owner
+ * LINES Number of times a line was executed
+ * FILE Pathname of the shell or shellscript
+ *
+ * Filenames are printed if available.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+sh*:::line
+{
+ @lines[pid, uid, copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %s\n", "PID", "UID", "LINES", "FILE");
+ printa(" %6d %6d %@6d %s\n", @lines);
+}
diff --git a/cddl/contrib/dtracetoolkit/Snippits/Readme b/cddl/contrib/dtracetoolkit/Snippits/Readme
new file mode 100644
index 0000000..b54dc77
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Snippits/Readme
@@ -0,0 +1,11 @@
+Snippits - DTrace code snippits
+
+ This directory has useful snippits of D scripting in seperate files.
+
+ When coding in DTrace, I frequently refer to the same chunks of code
+ from the same scripts, when I need to do certain things that I have
+ solved in the past. I also refer other people to them when asked.
+ This directory is a library for such "snippits" of code.
+
+ This directory does not contain runnable DTrace scripts.
+
diff --git a/cddl/contrib/dtracetoolkit/Snippits/fd2pathname.txt b/cddl/contrib/dtracetoolkit/Snippits/fd2pathname.txt
new file mode 100644
index 0000000..b056e13
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Snippits/fd2pathname.txt
@@ -0,0 +1,32 @@
+You have a file descriptor (probably from a syscall), and you want the
+corresponding pathname.
+
+If you are on newer versions of DTrace, there is the fds[] array,
+
+# dtrace -n 'syscall::read:entry { @[fds[arg0].fi_pathname] = count(); }'
+dtrace: description 'syscall::read:entry ' matched 1 probe
+^C
+
+ /etc/minor_perm 2
+ /etc/mnttab 2
+ /etc/motd 2
+ /etc/magic 4
+ /usr/sbin/clri 5
+ /devices/pseudo/clone@0:ptm 6
+ /sbin/mount 6
+ /dev/pts/28 7
+ /devices/pseudo/consms@0:mouse 31
+ /devices/pseudo/conskbd@0:kbd 47
+ <unknown> 351
+
+easy.
+
+but if you are on an older version of DTrace, try this to convert from
+this->fd to self->vpath,
+
+ this->filep =
+ curthread->t_procp->p_user.u_finfo.fi_list[this->fd].uf_file;
+ this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
+ self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+
diff --git a/cddl/contrib/dtracetoolkit/System/Readme b/cddl/contrib/dtracetoolkit/System/Readme
new file mode 100644
index 0000000..3d739da
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/System/Readme
@@ -0,0 +1,3 @@
+System - System based analysis
+
+ This would include measuring system wide activity.
diff --git a/cddl/contrib/dtracetoolkit/System/sar-c.d b/cddl/contrib/dtracetoolkit/System/sar-c.d
new file mode 100755
index 0000000..ef63198
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/System/sar-c.d
@@ -0,0 +1,101 @@
+#!/usr/sbin/dtrace -s
+/*
+ * sar-c.d - sar -c demo in DTrace.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This has been written to demonstrate fetching similar data as sar -c
+ * from DTrace. This program is intended as a starting point for other
+ * DTrace scripts, by beginning with familiar statistics.
+ *
+ * $Id: sar-c.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: sar-c.d
+ *
+ * FIELDS:
+ * scall/s System calls
+ * sread/s reads
+ * swrit/s writes
+ * fork/s forks
+ * exec/s execs
+ * rchar/s read characters
+ * wchar/s write characters
+ *
+ * IDEA: David Rubio, who also wrote the original.
+ *
+ * NOTES:
+ * As this program does not use Kstat, there is no summary since boot line.
+ *
+ * SEE ALSO: sar(1)
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 12-Jun-2005 Brendan Gregg Created this.
+ * 12-Jun-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+inline int SCREEN = 21;
+
+/*
+ * Initialise variables
+ */
+dtrace:::BEGIN
+{
+ scall = 0; sread = 0; swrit = 0; fork = 0; exec = 0;
+ rchar = 0; wchar = 0;
+ lines = SCREEN + 1;
+}
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN,
+tick-1sec
+/lines++ > SCREEN/
+{
+ printf("%-20s %7s %7s %7s %7s %7s %8s %8s\n",
+ "Time", "scall/s", "sread/s", "swrit/s", "fork/s",
+ "exec/s", "rchar/s", "wchar/s");
+ lines = 0;
+}
+
+/*
+ * Probe events
+ */
+syscall:::entry { scall++; }
+sysinfo:::sysread { sread++; }
+sysinfo:::syswrite { swrit++; }
+sysinfo:::sysfork { fork++; }
+sysinfo:::sysvfork { fork++; }
+sysinfo:::sysexec { exec++; }
+sysinfo:::readch { rchar += arg0; }
+sysinfo:::writech { wchar += arg0; }
+
+/*
+ * Print output line
+ */
+profile:::tick-1sec
+{
+ /* print line */
+ printf("%20Y %7d %7d %7d %4d.00 %4d.00 %8d %8d\n",
+ walltimestamp, scall, sread, swrit, fork, exec, rchar, wchar);
+
+ /* clear counters */
+ scall = 0; sread = 0; swrit = 0; fork = 0; exec = 0;
+ rchar = 0; wchar = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/System/syscallbysysc.d b/cddl/contrib/dtracetoolkit/System/syscallbysysc.d
new file mode 100755
index 0000000..86b8ac3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/System/syscallbysysc.d
@@ -0,0 +1,10 @@
+#!/usr/sbin/dtrace -s
+/*
+ * syscallbysysc.d - report on syscalls by syscall. DTrace OneLiner.
+ *
+ * This is a DTrace OneLiner from the DTraceToolkit.
+ *
+ * $Id: syscallbysysc.d 3 2007-08-01 10:50:08Z brendan $
+ */
+
+syscall:::entry { @num[probefunc] = count(); }
diff --git a/cddl/contrib/dtracetoolkit/System/topsyscall b/cddl/contrib/dtracetoolkit/System/topsyscall
new file mode 100755
index 0000000..63ef8c6
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/System/topsyscall
@@ -0,0 +1,184 @@
+#!/usr/bin/ksh
+#
+# topsyscall - display top syscalls by syscall name.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program continually prints a report of the top system calls,
+# and refreshes the display every 1 second or as specified at the
+# command line.
+#
+# $Id: topsyscall 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: topsyscall [-Cs] [interval [count]]
+#
+# -C # don't clear the screen
+# -s # print per second values
+#
+# FIELDS:
+# load avg load averages, see uptime(1)
+# syscalls total syscalls in this interval
+# syscalls/s syscalls per second
+# SYSCALL system call name
+# COUNT total syscalls in this interval
+# COUNT/s syscalls per second
+#
+# INSPIRATION: top(1) by William LeFebvre
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# 13-Jun-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+count=-1; interval=1; opt_persec=0; opt_clear=1
+
+### Process options
+while getopts Chs name
+do
+ case $name in
+ C) opt_clear=0 ;;
+ s) opt_persec=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: topsyscall [-s] [interval [count]]
+ -C # don't clear the screen
+ -s # print per second values
+ eg,
+ topsyscall # default, 1 second updates
+ topsyscall 5 # 5 second updates
+ END
+ exit 1
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ #pragma D option destructive
+
+ /* constants */
+ inline int OPT_clear = '$opt_clear';
+ inline int OPT_persec = '$opt_persec';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int SCREEN = 20;
+ inline string CLEAR = "'$clearstr'";
+
+ /* variables */
+ dtrace:::BEGIN
+ {
+ secs = INTERVAL;
+ counts = COUNTER;
+ printf("Tracing... Please wait.\n");
+ }
+
+ /* record syscall event */
+ syscall:::entry
+ {
+ @Name[probefunc] = count();
+ @Total = count();
+ }
+
+ /* timer */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /* update screen */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch load averages */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load5a = `hp_avenrun[1] / 65536;
+ this->load15a = `hp_avenrun[2] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+ this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536;
+ this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
+
+ /* clear screen */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+
+ /* print load average */
+ printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
+ walltimestamp, this->load1a, this->load1b, this->load5a,
+ this->load5b, this->load15a, this->load15b);
+
+ /* calculate per second values if needed */
+ OPT_persec ? normalize(@Total, INTERVAL) : 1;
+ OPT_persec ? normalize(@Name, INTERVAL) : 1;
+
+ /* print syscall count */
+ printf(" %s: ", OPT_persec ? "syscalls/s" : "syscalls");
+ printa("%@d\n",@Total);
+
+ /* print report */
+ trunc(@Name, SCREEN);
+ printf("\n %-25s %12s\n", "SYSCALL",
+ OPT_persec ? "COUNT/s" : "COUNT");
+ printa(" %-25s %@12d\n", @Name);
+ printf("\n");
+
+ /* reset variables */
+ trunc(@Name);
+ clear(@Total);
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Cleanup for Ctrl-C
+ */
+ dtrace:::END
+ {
+ trunc(@Name);
+ trunc(@Total);
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/System/uname-a.d b/cddl/contrib/dtracetoolkit/System/uname-a.d
new file mode 100755
index 0000000..7775021
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/System/uname-a.d
@@ -0,0 +1,53 @@
+#!/usr/sbin/dtrace -s
+/*
+ * uname-a.d - "uname -a" demo in DTrace.
+ * Written using DTrace (Solaris 10 3/05).
+ *
+ * This has been written to demonstrate fetching the "uname -a" info
+ * from a DTrace script, which turns out to be all kernel variables.
+ * This is intended as a starting point for other DTrace scripts, by
+ * beginning with familiar statistics.
+ *
+ * $Id: uname-a.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: uname-a.d
+ *
+ * FIELDS: See uname(1) manpage for documentation.
+ *
+ * SEE ALSO: uname
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * 24-Jul-2005 Brendan Gregg Created this.
+ * 24-Jul-2005 " " Last update.
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=8k
+
+/* print system info */
+dtrace:::BEGIN
+{
+ printf("%s %s %s %s %s %s %s",
+ `utsname.sysname,
+ `utsname.nodename,
+ `utsname.release,
+ `utsname.version,
+ `utsname.machine,
+ `architecture,
+ `platform);
+
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/Readme b/cddl/contrib/dtracetoolkit/Tcl/Readme
new file mode 100644
index 0000000..68c7352
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/Readme
@@ -0,0 +1,39 @@
+Tcl - DTracing Tcl Programs
+
+ These scripts trace activity of the Tcl programming language, making use
+ of the Tcl DTrace provider which was integrated into the Tcl source in
+ version tcl8.4.16. See the Tcl DTrace wiki page for details:
+
+ http://wiki.tcl.tk/19923
+
+ This provider was written by Daniel Steffen and is currently available
+ by downloading and compiling the Tcl source with the --enable-dtrace
+ option to configure.
+
+ Since the DTrace Tcl provider could be developed a little further, there is
+ a chance that it has changed slightly by the time you are reading this,
+ causing these scripts to either break or behave oddly. Firstly, check for
+ newer versions of the DTraceToolkit; if it hasn't been updated and you need
+ to use these scripts immediately, then updating them shouldn't take
+ too long. The following was the state of the provider when these scripts
+ were written - check for changes and update the scripts accordingly,
+
+ provider tcl {
+ probe proc-entry(procname, argc, argv);
+ probe proc-return(procname, retcode);
+ probe proc-result(procname, retcode, retval, retobj);
+ probe proc-args(procname, args, ...);
+ probe cmd-entry(cmdname, argc, argv);
+ probe cmd-return(cmdname, retval);
+ probe cmd-args(procname, args, ...);
+ probe inst-start(instname, depth, stackobj);
+ probe inst-done(instname, depth, stackobj);
+ probe obj-create(object);
+ probe obj-free(object);
+ proobe tcl-probe(strings, ...);
+ };
+
+ Update: it looks like two new probes have recently been added to the
+ provider: proc-info and cmd-info. I'll need to update these scripts to
+ make use of these new probes.
+
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_calldist.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_calldist.d
new file mode 100755
index 0000000..47cbd4c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_calldist.d
@@ -0,0 +1,111 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * tcl_calldist.d - measure Tcl elapsed time for different types of operation.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_calldist.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * USAGE: tcl_calldist.d [top] # hit Ctrl-C to end
+ * eg,
+ * tcl_calldist.d # default, truncate to 10 lines
+ * tcl_calldist.d 25 # truncate each report section to 25 lines
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * FIELDS:
+ * 1 Process ID
+ * 2 Type of call (proc/cmd/total)
+ * 3 Name of call
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+tcl*:::proc-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->proc[self->depth] = timestamp;
+}
+
+tcl*:::proc-return
+/self->proc[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->proc[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->proc[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @types_incl[pid, "proc", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[pid, "proc", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+tcl*:::cmd-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->cmd[self->depth] = timestamp;
+}
+
+tcl*:::cmd-return
+/self->cmd[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->cmd[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->cmd[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @types_incl[pid, "cmd", this->name] =
+ quantize(this->elapsed_incl / 1000);
+ @types_excl[pid, "cmd", this->name] =
+ quantize(this->elapsed_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ trunc(@types_excl, top);
+ printf("\nTop %d exclusive elapsed times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ printf("\nTop %d inclusive elapsed times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_calls.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_calls.d
new file mode 100755
index 0000000..755efe7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_calls.d
@@ -0,0 +1,63 @@
+#!/usr/sbin/dtrace -ZCs
+/*
+ * tcl_calls.d - count Tcl calls (proc/cmd) using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_calls.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (see below)
+ * NAME Name of proc or cmd call
+ * COUNT Number of calls during sample
+ *
+ * TYPEs:
+ * proc procedure
+ * cmd command
+ *
+ * PORTIONS: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+tcl*:::proc-entry
+{
+ @calls[pid, "proc", copyinstr(arg0)] = count();
+}
+
+tcl*:::cmd-entry
+{
+ @calls[pid, "cmd", copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-8s %-52s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_calltime.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_calltime.d
new file mode 100755
index 0000000..bab2ade
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_calltime.d
@@ -0,0 +1,123 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * tcl_calltime.d - measure Tcl elapsed times for different types of operation.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_calltime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * USAGE: tcl_calltime.d [top] # hit Ctrl-C to end
+ * eg,
+ * tcl_calltime.d # default, truncate to 10 lines
+ * tcl_calltime.d 25 # truncate each report section to 25 lines
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (proc/cmd/total)
+ * NAME Name of call
+ * TOTAL Total elapsed time for calls (us)
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+tcl*:::proc-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->proc[self->depth] = timestamp;
+}
+
+tcl*:::proc-return
+/self->proc[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->proc[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->proc[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @num[pid, "proc", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "proc", this->name] = sum(this->elapsed_incl);
+ @types_excl[pid, "proc", this->name] = sum(this->elapsed_excl);
+ @types_excl[0, "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+tcl*:::cmd-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->cmd[self->depth] = timestamp;
+}
+
+tcl*:::cmd-return
+/self->cmd[self->depth]/
+{
+ this->elapsed_incl = timestamp - self->cmd[self->depth];
+ this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth];
+ self->cmd[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @num[pid, "cmd", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "cmd", this->name] = sum(this->elapsed_incl);
+ @types_excl[pid, "cmd", this->name] = sum(this->elapsed_excl);
+ @types_excl[0, "total", "-"] = sum(this->elapsed_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->elapsed_incl;
+}
+
+dtrace:::END
+{
+ trunc(@num, top);
+ printf("\nTop %d counts,\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-10s %-48s %@8d\n", @num);
+
+ trunc(@types_excl, top);
+ normalize(@types_excl, 1000);
+ printf("\nTop %d exclusive elapsed times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ normalize(@types_incl, 1000);
+ printf("\nTop %d inclusive elapsed times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_cpudist.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_cpudist.d
new file mode 100755
index 0000000..69f4ba2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_cpudist.d
@@ -0,0 +1,111 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * tcl_cpudist.d - measure Tcl on-CPU time for different types of operation.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_cpudist.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * USAGE: tcl_cpudist.d [top] # hit Ctrl-C to end
+ * eg,
+ * tcl_cpudist.d # default, truncate to 10 lines
+ * tcl_cpudist.d 25 # truncate each report section to 25 lines
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * FIELDS:
+ * 1 Process ID
+ * 2 Type of call (proc/cmd/total)
+ * 3 Name of call
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+tcl*:::proc-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->proc[self->depth] = vtimestamp;
+}
+
+tcl*:::proc-return
+/self->proc[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->proc[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->proc[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @types_incl[pid, "proc", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[pid, "proc", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+tcl*:::cmd-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->cmd[self->depth] = vtimestamp;
+}
+
+tcl*:::cmd-return
+/self->cmd[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->cmd[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->cmd[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @types_incl[pid, "cmd", this->name] =
+ quantize(this->oncpu_incl / 1000);
+ @types_excl[pid, "cmd", this->name] =
+ quantize(this->oncpu_excl / 1000);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ trunc(@types_excl, top);
+ printf("\nTop %d exclusive on-CPU times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ printf("\nTop %d inclusive on-CPU times (us),\n", top);
+ printa(" PID=%d, %s, %s %@d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_cputime.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_cputime.d
new file mode 100755
index 0000000..a29a541
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_cputime.d
@@ -0,0 +1,123 @@
+#!/usr/sbin/dtrace -CZs
+/*
+ * tcl_cputime.d - measure Tcl on-CPU times for different types of operation.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_cputime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * USAGE: tcl_cputime.d [top] # hit Ctrl-C to end
+ * eg,
+ * tcl_cputime.d # default, truncate to 10 lines
+ * tcl_cputime.d 25 # truncate each report section to 25 lines
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (proc/cmd/total)
+ * NAME Name of call
+ * TOTAL Total on-CPU time for calls (us)
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#define TOP 10 /* default output truncation */
+#define B_FALSE 0
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ top = $1 != 0 ? $1 : TOP;
+}
+
+tcl*:::proc-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->proc[self->depth] = vtimestamp;
+}
+
+tcl*:::proc-return
+/self->proc[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->proc[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->proc[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @num[pid, "proc", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "proc", this->name] = sum(this->oncpu_incl);
+ @types_excl[pid, "proc", this->name] = sum(this->oncpu_excl);
+ @types_excl[0, "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+tcl*:::cmd-entry
+{
+ self->depth++;
+ self->exclude[self->depth] = 0;
+ self->cmd[self->depth] = vtimestamp;
+}
+
+tcl*:::cmd-return
+/self->cmd[self->depth]/
+{
+ this->oncpu_incl = vtimestamp - self->cmd[self->depth];
+ this->oncpu_excl = this->oncpu_incl - self->exclude[self->depth];
+ self->cmd[self->depth] = 0;
+ self->exclude[self->depth] = 0;
+ this->name = copyinstr(arg0);
+
+ @num[pid, "cmd", this->name] = count();
+ @num[0, "total", "-"] = count();
+ @types_incl[pid, "cmd", this->name] = sum(this->oncpu_incl);
+ @types_excl[pid, "cmd", this->name] = sum(this->oncpu_excl);
+ @types_excl[0, "total", "-"] = sum(this->oncpu_excl);
+
+ self->depth--;
+ self->exclude[self->depth] += this->oncpu_incl;
+}
+
+dtrace:::END
+{
+ trunc(@num, top);
+ printf("\nTop %d counts,\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-10s %-48s %@8d\n", @num);
+
+ trunc(@types_excl, top);
+ normalize(@types_excl, 1000);
+ printf("\nTop %d exclusive on-CPU times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_excl);
+
+ trunc(@types_incl, top);
+ normalize(@types_incl, 1000);
+ printf("\nTop %d inclusive on-CPU times (us),\n", top);
+ printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL");
+ printa(" %6d %-10s %-48s %@8d\n", @types_incl);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_flow.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_flow.d
new file mode 100755
index 0000000..9146828
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_flow.d
@@ -0,0 +1,86 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_flow.d - snoop Tcl execution showing procedure flow using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_flow.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_flow.d # hit Ctrl-C to end
+ *
+ * This watches Tcl method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * PID Process ID
+ * CALL Tcl command or procedure name
+ *
+ * LEGEND:
+ * -> procedure entry
+ * <- procedure return
+ * > command entry
+ * < command return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "CALL");
+}
+
+tcl*:::proc-entry
+{
+ printf("%3d %6d %-16d %*s-> %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+}
+
+tcl*:::proc-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %*s<- %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+}
+
+tcl*:::cmd-entry
+{
+ printf("%3d %6d %-16d %*s > %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+}
+
+tcl*:::cmd-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %*s < %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_flowtime.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_flowtime.d
new file mode 100755
index 0000000..85f1b99
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_flowtime.d
@@ -0,0 +1,105 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_flowtime.d - snoop Tcl execution showing procedure flow and delta times.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_flowtime.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_flowtime.d # hit Ctrl-C to end
+ *
+ * This watches Tcl method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * TIME(us) Time since boot, us
+ * DELTA(us) Elapsed time from previous line to this line
+ * CALL Tcl command or procedure name
+ *
+ * LEGEND:
+ * -> procedure entry
+ * <- procedure return
+ * > command entry
+ * < command return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s %9s -- %s\n", "C", "PID", "TIME(us)",
+ "DELTA(us)", "CALL");
+}
+
+tcl*:::proc-entry,
+tcl*:::proc-return,
+tcl*:::cmd-entry,
+tcl*:::cmd-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+tcl*:::proc-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %-16d %9d %*s-> %s\n", cpu, pid, timestamp / 1000,
+ this->delta, self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+tcl*:::proc-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %9d %*s<- %s\n", cpu, pid, timestamp / 1000,
+ this->delta, self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
+
+tcl*:::cmd-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %-16d %9d %*s > %s\n", cpu, pid, timestamp / 1000,
+ this->delta, self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+tcl*:::cmd-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %9d %*s < %s\n", cpu, pid, timestamp / 1000,
+ this->delta, self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_ins.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_ins.d
new file mode 100755
index 0000000..39518f9
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_ins.d
@@ -0,0 +1,57 @@
+#!/usr/sbin/dtrace -ZCs
+/*
+ * tcl_ins.d - count Tcl instructions using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_ins.d 64 2007-10-04 08:35:29Z claire $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_calls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (see below)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * TYPEs:
+ * inst instruction
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+tcl*:::inst-start
+{
+ @calls[pid, "inst", copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-8s %-52s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_insflow.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_insflow.d
new file mode 100755
index 0000000..ba5e01c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_insflow.d
@@ -0,0 +1,123 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_insflow.d - snoop Tcl execution showing procedure flow and delta times.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_insflow.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_insflow.d # hit Ctrl-C to end
+ *
+ * This watches Tcl method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * TIME(us) Time since boot, us
+ * DELTA(us) Elapsed time from previous line to this line
+ * TYPE Type of call (proc/cmd/inst)
+ * CALL Tcl command or procedure name
+ *
+ * LEGEND:
+ * proc procedure
+ * cmd command
+ * inst instruction
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s %9s %5s -- %s\n", "C", "PID", "TIME(us)",
+ "DELTA(us)", "TYPE", "CALL");
+}
+
+tcl*:::proc-entry,
+tcl*:::proc-return,
+tcl*:::cmd-entry,
+tcl*:::cmd-return
+/self->last == 0/
+{
+ self->last = timestamp;
+}
+
+tcl*:::proc-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %-16d %9d %5s %*s-> %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "proc", self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+tcl*:::proc-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %9d %5s %*s<- %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "proc", self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
+
+tcl*:::cmd-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %-16d %9d %5s %*s-> %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "cmd", self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+tcl*:::cmd-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %9d %5s %*s<- %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "cmd", self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
+
+tcl*:::inst-start
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%3d %6d %-16d %9d %5s %*s-> %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "inst", self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+ self->last = timestamp;
+}
+
+tcl*:::inst-done
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %9d %5s %*s<- %s\n", cpu, pid, timestamp / 1000,
+ this->delta, "inst", self->depth * 2, "", copyinstr(arg0));
+ self->last = timestamp;
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_proccalls.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_proccalls.d
new file mode 100755
index 0000000..c874362
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_proccalls.d
@@ -0,0 +1,53 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_methodcalls.d - count Tcl method calls DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_proccalls.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_methodcalls.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * COUNT Number of calls during sample
+ * PROCEDURE Tcl procedure name
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+tcl*:::proc-entry
+{
+ @calls[pid, copyinstr(arg0)] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %8s %s\n", "PID", "COUNT", "PROCEDURE");
+ printa(" %6d %@8d %s\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_procflow.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_procflow.d
new file mode 100755
index 0000000..258c198
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_procflow.d
@@ -0,0 +1,70 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_procflow.d - snoop Tcl execution showing procedure flow using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_procflow.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_procflow.d # hit Ctrl-C to end
+ *
+ * This watches Tcl method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * TIME(us) Time since boot, us
+ * PID Process ID
+ * PROCEDURE Tcl procedure name
+ *
+ * LEGEND:
+ * -> proc entry
+ * <- proc return
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "PROCEDURE");
+}
+
+tcl*:::proc-entry
+{
+ printf("%3d %6d %-16d %*s-> %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+ self->depth++;
+}
+
+tcl*:::proc-return
+{
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%3d %6d %-16d %*s<- %s\n", cpu, pid, timestamp / 1000,
+ self->depth * 2, "", copyinstr(arg0));
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_stat.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_stat.d
new file mode 100755
index 0000000..a321d70
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_stat.d
@@ -0,0 +1,137 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_stat.d - Tcl operation stats using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_stat.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_stat.d [interval [count]]
+ *
+ * FIELDS:
+ * EXEC/s Tcl programs executed per second, including
+ * those without Tcl provider support
+ * PROC/s Procedures called, per second
+ * CMD/s Commands created, per second
+ * OBJNEW/s Objects created, per second
+ * OBJFRE/s Objects freed, per second
+ * OP/s Bytecode operations, per second
+ *
+ * The numbers are counts for the interval specified. The default interval
+ * is 1 second.
+ *
+ * If you see a count in "EXECS" but not in the other columns, then you
+ * may have older Tcl software that does not have the integrated DTrace
+ * provider (or newer software where the provider has changed).
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+
+inline int SCREEN = 21;
+
+dtrace:::BEGIN
+{
+ execs = procs = cmds = objnew = objfree = ops = 0;
+ lines = SCREEN + 1;
+ interval = $1 ? $1 : 1;
+ counts = $2 ? $2 : -1;
+ secs = interval;
+ first = 1;
+}
+
+profile:::tick-1sec
+{
+ secs--;
+}
+
+/*
+ * Print Header
+ */
+dtrace:::BEGIN,
+profile:::tick-1sec
+/first || (secs == 0 && lines > SCREEN)/
+{
+ printf("%-20s %6s %8s %8s %8s %8s %8s\n", "TIME", "EXEC/s",
+ "PROC/s", "CMD/s", "OBJNEW/s", "OBJFRE/s", "OP/s");
+ lines = 0;
+ first = 0;
+}
+
+/*
+ * Tally Data
+ */
+proc:::exec-success
+/execname == "tcl" || execname == "tclsh"/
+{
+ execs++;
+}
+
+tcl*:::proc-entry
+{
+ procs++;
+}
+
+tcl*:::cmd-entry
+{
+ cmds++;
+}
+
+tcl*:::obj-create
+{
+ objnew++;
+}
+
+tcl*:::obj-free
+{
+ objfree++;
+}
+
+tcl*:::inst-start
+{
+ ops++;
+}
+
+/*
+ * Print Output
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ printf("%-20Y %6d %8d %8d %8d %8d %8d\n", walltimestamp,
+ execs / interval, procs / interval, cmds / interval,
+ objnew / interval, objfree / interval, ops / interval);
+ execs = procs = cmds = objnew = objfree = ops = 0;
+ secs = interval;
+ lines++;
+ counts--;
+}
+
+/*
+ * End
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_syscalls.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_syscalls.d
new file mode 100755
index 0000000..239d7d0
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_syscalls.d
@@ -0,0 +1,66 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_syscalls.d - count Tcl calls and syscalls using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_syscalls.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_syscalls.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID
+ * TYPE Type of call (method/syscall)
+ * NAME Name of call
+ * COUNT Number of calls during sample
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+tcl$target:::proc-entry
+{
+ @calls[pid, "proc", copyinstr(arg0)] = count();
+}
+
+tcl$target:::cmd-entry
+{
+ @calls[pid, "cmd", copyinstr(arg0)] = count();
+}
+
+syscall:::entry
+/pid == $target/
+{
+ @calls[pid, "syscall", probefunc] = count();
+}
+
+
+dtrace:::END
+{
+ printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT");
+ printa(" %6d %-8s %-52s %@8d\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_syscolors.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_syscolors.d
new file mode 100755
index 0000000..f2529b5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_syscolors.d
@@ -0,0 +1,139 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_syscolors.d - trace Tcl program flow plus syscalls, in color.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_syscolors.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_syscolors.d { -p PID | -c cmd } # hit Ctrl-C to end
+ *
+ * This watches Tcl method entries and returns, and indents child
+ * method calls.
+ *
+ * FIELDS:
+ * C CPU-id
+ * PID Process ID
+ * TID Thread ID
+ * DELTA(us) Elapsed time from previous line to this line
+ * TYPE Type of call (proc/cmd/syscall)
+ * NAME Tcl proc/cmd or syscall name
+ *
+ * WARNING: Watch the first column carefully, it prints the CPU-id. If it
+ * changes, then it is very likely that the output has been shuffled.
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10
+
+self int depth;
+
+dtrace:::BEGIN
+{
+ color_tcl = "\033[2;35m"; /* violet, faint */
+ color_line = "\033[1;35m"; /* violet, bold */
+ color_syscall = "\033[2;32m"; /* green, faint */
+ color_off = "\033[0m"; /* default */
+
+ printf("%3s %6s %9s %-8s -- %s\n", "C", "PID", "DELTA(us)", "TYPE",
+ "NAME");
+}
+
+tcl$target:::method-entry,
+tcl$target:::method-return,
+syscall:::entry,
+syscall:::return
+/self->last == 0 && pid == $target/
+{
+ self->last = timestamp;
+}
+
+tcl$target:::proc-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d %9d %-8s %*s-> %s%s\n", color_tcl, cpu,
+ pid, this->delta, "proc", self->depth * 2, "", copyinstr(arg0),
+ color_off);
+ self->depth++;
+ self->depthlast = self->depth;
+ self->last = timestamp;
+}
+
+tcl$target:::proc-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%3d %6d %9d %-8s %*s<- %s%s\n", color_tcl, cpu,
+ pid, this->delta, "proc", self->depth * 2, "", copyinstr(arg0),
+ color_off);
+ self->depthlast = self->depth;
+ self->last = timestamp;
+}
+
+tcl$target:::cmd-entry
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d %9d %-8s %*s-> %s%s\n", color_tcl, cpu,
+ pid, this->delta, "cmd", self->depth * 2, "", copyinstr(arg0),
+ color_off);
+ self->depth++;
+ self->depthlast = self->depth;
+ self->last = timestamp;
+}
+
+tcl$target:::cmd-return
+{
+ this->delta = (timestamp - self->last) / 1000;
+ self->depth -= self->depth > 0 ? 1 : 0;
+ printf("%s%3d %6d %9d %-8s %*s<- %s%s\n", color_tcl, cpu,
+ pid, this->delta, "cmd", self->depth * 2, "", copyinstr(arg0),
+ color_off);
+ self->depthlast = self->depth;
+ self->last = timestamp;
+}
+
+syscall:::entry
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d %9d %-8s %*s-> %s%s\n", color_syscall,
+ cpu, pid, this->delta, "syscall", self->depthlast * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+syscall:::return
+/pid == $target/
+{
+ this->delta = (timestamp - self->last) / 1000;
+ printf("%s%3d %6d %9d %-8s %*s<- %s%s\n", color_syscall,
+ cpu, pid, this->delta, "syscall", self->depthlast * 2, "",
+ probefunc, color_off);
+ self->last = timestamp;
+}
+
+proc:::exit
+/pid == $target/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/dtracetoolkit/Tcl/tcl_who.d b/cddl/contrib/dtracetoolkit/Tcl/tcl_who.d
new file mode 100755
index 0000000..424ad31
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Tcl/tcl_who.d
@@ -0,0 +1,62 @@
+#!/usr/sbin/dtrace -Zs
+/*
+ * tcl_who.d - trace Tcl calls by process using DTrace.
+ * Written for the Tcl DTrace provider.
+ *
+ * $Id: tcl_who.d 63 2007-10-04 04:34:38Z brendan $
+ *
+ * This traces activity from all Tcl processes on the system with DTrace
+ * provider support (tcl8.4.16).
+ *
+ * USAGE: tcl_who.d # hit Ctrl-C to end
+ *
+ * FIELDS:
+ * PID Process ID of Tcl
+ * UID User ID of the owner
+ * CALLS Number of calls made (proc + cmd)
+ * ARGS Process name and arguments
+ *
+ * Calls is a measure of activity, and is a count of the procedures and
+ * commands that Tcl called.
+ *
+ * The argument list is truncated at 55 characters (up to 80 is easily
+ * available). To easily read the full argument list, use other system tools;
+ * on Solaris use "pargs PID".
+ *
+ * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-Sep-2007 Brendan Gregg Created this.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+tcl*:::proc-entry,
+tcl*:::cmd-entry
+{
+ @calls[pid, uid, curpsinfo->pr_psargs] = count();
+}
+
+dtrace:::END
+{
+ printf(" %6s %6s %6s %-55s\n", "PID", "UID", "CALLS", "ARGS");
+ printa(" %6d %6d %@6d %-55.55s\n", @calls);
+}
diff --git a/cddl/contrib/dtracetoolkit/User/Readme b/cddl/contrib/dtracetoolkit/User/Readme
new file mode 100644
index 0000000..d737125
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/User/Readme
@@ -0,0 +1,3 @@
+User - User based analysis
+
+ This would include activity by UID.
diff --git a/cddl/contrib/dtracetoolkit/User/setuids.d b/cddl/contrib/dtracetoolkit/User/setuids.d
new file mode 100755
index 0000000..f66d441
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/User/setuids.d
@@ -0,0 +1,82 @@
+#!/usr/sbin/dtrace -s
+/*
+ * setuids.d - snoop setuid calls. This can examine user logins.
+ * Written in DTrace (Solaris 10 3/05).
+ *
+ * $Id: setuids.d 3 2007-08-01 10:50:08Z brendan $
+ *
+ * USAGE: setuids.d
+ *
+ * FIELDS:
+ * UID user ID (from)
+ * SUID set user ID (to)
+ * PPID parent process ID
+ * PID process ID
+ * PCMD parent command
+ * CMD command (full arguments)
+ *
+ * SEE ALSO: BSM auditing
+ *
+ * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at Docs/cddl1.txt
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * CDDL HEADER END
+ *
+ * 09-May-2004 Brendan Gregg Created this.
+ * 08-May-2005 " " Used modern variable builtins.
+ * 28-Jul-2005 " " Last update.
+ */
+
+#pragma D option quiet
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ printf("%5s %5s %5s %5s %-12s %s\n",
+ "UID", "SUID", "PPID", "PID", "PCMD", "CMD");
+}
+
+/*
+ * Save values
+ */
+syscall::setuid:entry
+{
+ self->uid = uid;
+ self->suid = arg0;
+ self->ok = 1;
+}
+
+/*
+ * Print output on success
+ */
+syscall::setuid:return
+/arg0 == 0 && self->ok/
+{
+ printf("%5d %5d %5d %5d %-12s %S\n",
+ self->uid, self->suid, ppid, pid,
+ curthread->t_procp->p_parent->p_user.u_comm,
+ curpsinfo->pr_psargs);
+}
+
+/*
+ * Cleanup
+ */
+syscall::setuid:return
+{
+ self->uid = 0;
+ self->suid = 0;
+ self->ok = 0;
+}
diff --git a/cddl/contrib/dtracetoolkit/Version b/cddl/contrib/dtracetoolkit/Version
new file mode 100644
index 0000000..261c823
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Version
@@ -0,0 +1 @@
+DTraceToolkit version 0.99, 30-Sep-2007
diff --git a/cddl/contrib/dtracetoolkit/Zones/Readme b/cddl/contrib/dtracetoolkit/Zones/Readme
new file mode 100644
index 0000000..578e720
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Zones/Readme
@@ -0,0 +1,3 @@
+Zones - Zones based analysis
+
+ This would include activity by Zone.
diff --git a/cddl/contrib/dtracetoolkit/Zones/zvmstat b/cddl/contrib/dtracetoolkit/Zones/zvmstat
new file mode 100755
index 0000000..e49f89c
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/Zones/zvmstat
@@ -0,0 +1,277 @@
+#!/usr/bin/ksh
+#
+# zvmstat - print vmstat style info per Zone.
+# This uses DTrace (Solaris 10 3/05).
+#
+# This program must be run from the global zone as root.
+#
+# $Id: zvmstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: zvmstat [-ht] [interval [count]]
+#
+# zvmstat # default output
+# -t # print times
+# eg,
+# zvmstat 1 # print every 1 second
+# zvmstat 10 5 # print 5 x 10 second samples
+# zvmstat -t 5 # print every 5 seconds with time
+#
+#
+# FIELDS:
+# re page reclaims
+# mf minor faults
+# fr pages freed
+# sr scan rate
+# epi executable pages paged in
+# epo executable pages paged out
+# epf executable pages freed
+# api anonymous pages paged in
+# apo anonymous pages paged out
+# apf anonymous pages freed
+# fpi filesystem pages paged in
+# fpo filesystem pages paged out
+# fpf filesystem pages freed
+#
+# NOTES:
+# - Zone status should really be provided by Kstat, which currently
+# provides system wide values, per CPU and per processor set, but not per
+# zone. DTrace can fill this role in the meantime until Kstat supports zones.
+# - First output does not contain summary since boot.
+#
+# SEE ALSO: prstat -Z
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# BUGS:
+# - First output may not contain all zones due to how loops are achieved.
+# Check for newer versions.
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 11-May-2005 Brendan Gregg Created this.
+# 26-Jul-2005 " " Improved code.
+# 08-Jan-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_time=0; interval=1; counts=1
+
+### process options
+while getopts ht name
+do
+ case $name in
+ t) opt_time=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: zvmstat [-ht] [interval [count]]
+ zvmstat # default output
+ -t # print times
+ eg,
+ zvmstat 1 # print every 1 second
+ zvmstat 10 5 # print 5 x 10 second samples
+ zvmstat -t 5 # print every 5 seconds with time
+ END
+ exit 1
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+### option logic
+if (( "0$1" > 0 )); then
+ interval=$1; counts=-1; shift
+fi
+if (( "0$1" > 0 )); then
+ counts=$1; shift
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+dtrace -n '
+ #pragma D option quiet
+ #pragma D option destructive
+ #pragma D option switchrate=10
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_time = '$opt_time';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$counts';
+
+ /*
+ * Initialise variables
+ */
+ dtrace:::BEGIN
+ {
+ secs = INTERVAL;
+ counts = COUNTER;
+ zonemax = 0;
+ listing = 1;
+ re[""] = 0; pi[""] = 0; po[""] = 0;
+ mf[""] = 0; sr[""] = 0; fr[""] = 0;
+ epi[""] = 0; epo[""] = 0; epf[""] = 0;
+ api[""] = 0; apo[""] = 0; apf[""] = 0;
+ fpi[""] = 0; fpo[""] = 0; fpf[""] = 0;
+ }
+
+ /*
+ * Build zonelist array
+ *
+ * Here we want the output of a command to be saved into an array
+ * inside dtrace. This is done by running the command, sending the
+ * output to /dev/null, and by probing its write syscalls from dtrace.
+ *
+ * This is an example of a "scraper".
+ */
+
+ /*
+ * List zones
+ */
+ dtrace:::BEGIN
+ {
+ /* run zoneadm */
+ system("/usr/sbin/zoneadm list > /dev/null; echo END > /dev/null");
+ }
+
+ /*
+ * Scrape zone listing
+ */
+ syscall::write:entry
+ /listing && (execname == "zoneadm") &&
+ (curthread->t_procp->p_parent->p_ppid == $pid)/
+ {
+ /* read zoneadm output */
+ zonelist[zonemax] = stringof(copyin(arg1, arg2 - 1));
+
+ /* increment max number of zones */
+ zonemax++;
+ }
+
+ /*
+ * Finish scraping zones
+ */
+ syscall::write:entry
+ /listing && (execname == "sh") && (ppid == $pid)/
+ {
+ /*
+ * this end tag lets us know our zonelist has finished.
+ * thanks A. Packer.
+ */
+ listing = stringof(copyin(arg1, arg2 - 1)) == "END" ? 0 : 1;
+ }
+
+ /*
+ * Record vminfo counters
+ */
+ vminfo:::pgrec { re[zonename] += arg0; }
+ vminfo:::as_fault { mf[zonename] += arg0; }
+ vminfo:::scan { sr[zonename] += arg0; }
+ vminfo:::execpgin { epi[zonename] += arg0; }
+ vminfo:::execpgout { epo[zonename] += arg0; }
+ vminfo:::execfree { epf[zonename] += arg0; fr[zonename] += arg0; }
+ vminfo:::anonpgin { api[zonename] += arg0; }
+ vminfo:::anonpgout { apo[zonename] += arg0; }
+ vminfo:::anonfree { apf[zonename] += arg0; fr[zonename] += arg0; }
+ vminfo:::fspgin { fpi[zonename] += arg0; }
+ vminfo:::fspgout { fpo[zonename] += arg0; }
+ vminfo:::fsfree { fpf[zonename] += arg0; fr[zonename] += arg0; }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Check for exit
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Print header line
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* set counters */
+ secs = INTERVAL;
+ counts--;
+ zonei = 0;
+
+ /* print time */
+ OPT_time ? printf("\n%Y,\n",walltimestamp) : 1;
+
+ /* print output line */
+ printf("%10s %4s %5s %4s %5s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
+ "ZONE", "re", "mf", "fr", "sr", "epi", "epo", "epf", "api", "apo",
+ "apf", "fpi", "fpo", "fpf");
+
+ /* ensure zone writes are triggered */
+ printf(" \b");
+ }
+
+ /*
+ * Print zone status line
+ *
+ * This is a fairly interesting function in that it loops over the keys in
+ * an associative array and prints out the values. DTrace cant really do
+ * loops, and generally doesnt need to. We "cheat" by generating writes
+ * in the above probe which in turn trigger the probe below which
+ * contains the contents of each loop. Dont do this at home! We are
+ * supposed to use aggreagations instead, wherever possible.
+ *
+ * This is an example of a "feedback loop".
+ */
+ syscall::write:return
+ /pid == $pid && zonei < zonemax/
+ {
+ /* fetch zonename */
+ self->zone = zonelist[zonei];
+
+ /* print output */
+ printf("%10s %4d %5d %4d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
+ self->zone, re[self->zone], mf[self->zone], fr[self->zone],
+ sr[self->zone], epi[self->zone], epo[self->zone],
+ epf[self->zone], api[self->zone], apo[self->zone],
+ apf[self->zone], fpi[self->zone], fpo[self->zone],
+ fpf[self->zone]);
+
+ /* clear values */
+ re[self->zone] = 0; mf[self->zone] = 0; fr[self->zone] = 0;
+ sr[self->zone] = 0; epi[self->zone] = 0; epo[self->zone] = 0;
+ epf[self->zone] = 0; api[self->zone] = 0; apo[self->zone] = 0;
+ apf[self->zone] = 0; fpi[self->zone] = 0; fpo[self->zone] = 0;
+ fpf[self->zone] = 0;
+ self->zone = 0;
+
+ /* go to next zone */
+ zonei++;
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/dexplorer b/cddl/contrib/dtracetoolkit/dexplorer
new file mode 100755
index 0000000..002c803
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/dexplorer
@@ -0,0 +1,547 @@
+#!/usr/bin/ksh
+#
+# dexplorer - DTrace system explorer, runs a collection of scripts.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program automatically runs a collection of DTrace scripts to examine
+# many areas of the system, and places the output in a meaningful directory
+# structure that is tar'd and gzip'd.
+#
+# $Id: dexplorer 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: dexplorer [-yDT] [-d outputdir] [-i interval]
+#
+# -q # quiet mode
+# -y # "yes", don't prompt for confirmation
+# -D # don't delete output dir
+# -T # don't create output tar.gz
+# -d outputdir # output directory
+# -i interval # interval for each sample
+# eg,
+# dexplorer # default is 5 second samples
+# dexplorer -y -i30 # no prompting, with 30 second samples
+#
+# SEE ALSO: DTraceToolkit
+#
+# THANKS: David Visser, et all. for the idea and encouragement.
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# CODE:
+#
+# This is currently a monolithic script, and while it contains only
+# a few dozen straigftforward DTrace scripts I think it's desirable to
+# keep it that way. The scripts themselves have designed to be very
+# generic (eg, switching on all sdt:::), and are aggregations to keep a
+# limit on the size of the output.
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 23-Jun-2005 Brendan Gregg Created this.
+# 28-Jun-2005 " " Last update.
+
+#
+# Default variables
+#
+interval=5 # time of each sample
+verbose=1 # print screen output
+prompt=1 # prompt before run
+tar=1 # create tar file
+delete=1 # delete output dirs
+dtrace=/usr/sbin/dtrace # path to dtrace
+root=. # default output dir
+PATH=/usr/bin:/usr/sbin # safe path
+dir=de_`uname -n`_`date +%Y%m%d%H%M` # OUTPUT FILENAME
+samples=20 # max number of tests
+current=0 # current sample
+
+#
+# Process options
+#
+while getopts d:hi:qyDT name
+do
+ case $name in
+ d) root=$OPTARG ;;
+ i) interval=$OPTARG ;;
+ q) verbose=0 ;;
+ y) prompt=0 ;;
+ D) delete=0 ;;
+ T) tar=0 ;;
+ h|?) cat <<-END >&2
+ USAGE: dexplorer [-qyDT] [-d outputdir] [-i interval]
+
+ -q # quiet mode
+ -y # "yes", don't prompt for confirmation
+ -D # don't delete output dir
+ -T # don't create output tar.gz
+ -d outputdir # output directory
+ -i interval # interval for each sample
+ eg,
+ dexplorer # default is 5 second samples
+ dexplorer -y -i30 # no prompting, with 30 second samples
+ END
+ exit 1
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+#
+# Confirm path
+#
+if [[ "$prompt" == "1" ]] ; then
+ if [[ "$root" == "." ]]; then
+ print "Output dir will be the current dir ($PWD)."
+ else
+ print "Output dir will be $root"
+ fi
+ print -n "Hit enter for yes, or type path: "
+ read ans junk
+ if [[ "$ans" == [yY] || "$ans" == [yY]es ]]; then
+ print "WARNING: I didn't ask for \"$ans\"!"
+ print "\tI was asking for the path or just enter."
+ print "\tignoring \"$ans\"..."
+ fi
+ if [[ "$ans" != "" ]]; then
+ root=$ans
+ print "Output is now $root."
+ fi
+fi
+
+#
+# Sanity checks
+#
+if [[ "$interval" == *[a-zA-Z]* ]]; then
+ print "ERROR2: Invalid interval $interval.\n"
+ print "Please use a number of seconds."
+ exit 2
+fi
+if (( ${#interval} < 1 )); then
+ print "ERROR3: Length of interval $interval too short.\n"
+ print "Minimum 1 second."
+ exit 3
+fi
+if [[ ! -d "$root" ]]; then
+ print "ERROR4: Output directory \"$root\" does not exist.\n"
+ print "Perhaps try a mkdir first?"
+ print "or use an existing dir, eg \"/tmp\""
+ exit 4
+fi
+if [[ ! -w "$root" ]]; then
+ print "ERROR5: Can't write to output directory \"$root\".\n"
+ print "Are you logged in as root?"
+ print "Perhaps try another directory, eg \"/tmp\""
+ exit 5
+fi
+if [[ `$dtrace -b1k -qn 'BEGIN { trace(pid); exit(0); }'` == "" ]]; then
+ print "ERROR6: Unable to run dtrace!\n"
+ print "Perhaps this is a permission problem? Try running as root."
+ exit 6
+fi
+
+# calculate total time
+(( total = interval * samples ))
+if (( total > 180 )); then
+ (( total = total / 60 ))
+ total="$total minutes"
+else
+ total="$total seconds"
+fi
+
+#
+# Common Functions
+#
+function decho {
+ if (( verbose )); then print "$*"; fi
+}
+clean="sed /^\$/d"
+header='dtrace:::BEGIN {
+ printf("%Y, ", walltimestamp);
+ printf("%s %s %s %s %s, ", `utsname.sysname, `utsname.nodename,
+ `utsname.release, `utsname.version, `utsname.machine);
+ printf("%d secs\n",'$interval');
+ }
+ profile:::tick-'$interval'sec { exit(0); }
+ '
+function dstatus {
+ if (( verbose )); then
+ (( percent = current * 100 / samples ))
+ printf "%3d%% $*\n" $percent
+ (( current = current + 1 ))
+ fi
+}
+
+########################################
+# START #
+########################################
+
+#
+# Make dirs
+#
+err=0
+cd $root
+(( err = err + $? ))
+mkdir $dir
+(( err = err + $? ))
+cd $dir
+(( err = err + $? ))
+base1=${PWD##*/}
+base2=${dir##*/}
+if [[ "$base1" != "$base2" || "$err" != "0" ]]; then
+ print "ERROR7: tried to mkdir $dir from $root, but something failed.\n"
+ print "Check directories before rerunning."
+ exit 7
+fi
+mkdir Cpu
+mkdir Disk
+mkdir Mem
+mkdir Net
+mkdir Proc
+mkdir Info
+
+#
+# Create Log
+#
+decho "Starting dexplorer ver 0.76."
+decho "Sample interval is $interval seconds. Total run is > $total."
+( print "dexplorer ver 0.76\n------------------"
+print -n "System: "
+uname -a
+print -n "Start: "
+date ) > log
+
+#
+# Capture Standard Info
+#
+args='pid,ppid,uid,gid,projid,zoneid,pset,pri,nice,'
+args=$args'class,vsz,rss,time,pcpu,pmem,args'
+uname -a > Info/uname-a # System
+psrinfo -v > Info/psrinfo-v # CPU
+prtconf > Info/prtconf # Memory (+ devices)
+df -k > Info/df-k # Disk
+ifconfig -a > Info/ifconfig-a # Network
+ps -eo $args > Info/ps-o # Processes
+uptime > Info/uptime # Load
+
+#
+# Cpu Tests, DTrace
+#
+
+dstatus "Interrupts by CPU..."
+$dtrace -qn "$header"'
+ sdt:::interrupt-start { @num[cpu] = count(); }
+ dtrace:::END
+ {
+ printf("%-16s %16s\n", "CPU", "INTERRUPTS");
+ printa("%-16d %@16d\n", @num);
+ }
+' | $clean > Cpu/interrupt_by_cpu
+
+dstatus "Interrupt times..."
+$dtrace -qn "$header"'
+ sdt:::interrupt-start { self->ts = vtimestamp; }
+ sdt:::interrupt-complete
+ /self->ts && arg0 != 0/
+ {
+ this->devi = (struct dev_info *)arg0;
+ self->name = this->devi != 0 ?
+ stringof(`devnamesp[this->devi->devi_major].dn_name) : "?";
+ this->inst = this->devi != 0 ? this->devi->devi_instance : 0;
+ @num[self->name, this->inst] = sum(vtimestamp - self->ts);
+ self->name = 0;
+ }
+ sdt:::interrupt-complete { self->ts = 0; }
+ dtrace:::END
+ {
+ printf("%11s %16s\n", "DEVICE", "TIME (ns)");
+ printa("%10s%-3d %@16d\n", @num);
+ }
+' | $clean > Cpu/interrupt_time
+
+dstatus "Dispatcher queue length by CPU..."
+$dtrace -qn "$header"'
+ profile:::profile-1000
+ {
+ this->num = curthread->t_cpu->cpu_disp->disp_nrunnable;
+ @length[cpu] = lquantize(this->num, 0, 100, 1);
+ }
+ dtrace:::END { printa(" CPU %d%@d\n", @length); }
+' | $clean > Cpu/dispqlen_by_cpu
+
+dstatus "Sdt counts..."
+$dtrace -qn "$header"'
+ sdt:::{ @num[probefunc, probename] = count(); }
+ dtrace:::END
+ {
+ printf("%-32s %-32s %10s\n", "FUNC", "NAME", "COUNT");
+ printa("%-32s %-32s %@10d\n", @num);
+ }
+' | $clean > Cpu/sdt_count
+
+#
+# Disk Tests, DTrace
+#
+
+dstatus "Pages paged in by process..."
+$dtrace -qn "$header"'
+ vminfo:::pgpgin { @pg[pid, execname] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %16s\n", "PID", "CMD", "PAGES");
+ printa("%6d %-16s %@16d\n", @pg);
+ }
+' | $clean > Disk/pgpgin_by_process
+
+dstatus "Files opened successfully count..."
+$dtrace -qn "$header"'
+ syscall::open*:entry { self->file = copyinstr(arg0); self->ok = 1; }
+ syscall::open*:return /self->ok && arg0 != -1/
+ {
+ @num[self->file] = count();
+ }
+ syscall::open*:return /self->ok/ { self->file = 0; self->ok = 0; }
+ dtrace:::END
+ {
+ printf("%-64s %8s\n", "FILE", "COUNT");
+ printa("%-64s %@8d\n", @num);
+ }
+' | $clean > Disk/fileopen_count
+
+dstatus "Disk I/O size distribution by process..."
+$dtrace -qn "$header"'
+ io:::start { @size[pid, execname] = quantize(args[0]->b_bcount); }
+' | $clean > Disk/sizedist_by_process
+
+#
+# Mem Tests, DTrace
+#
+
+dstatus "Minor faults by process..."
+$dtrace -qn "$header"'
+ vminfo:::as_fault { @mem[pid, execname] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %16s\n", "PID", "CMD", "MINFAULTS");
+ printa("%6d %-16s %@16d\n", @mem);
+ }
+' | $clean > Mem/minf_by_process
+
+
+dstatus "Vminfo data by process..."
+$dtrace -qn "$header"'
+ vminfo::: { @data[pid, execname, probename] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %-16s %16s\n",
+ "PID", "CMD", "STATISTIC", "VALUE");
+ printa("%6d %-16s %-16s %@16d\n", @data);
+ }
+' | $clean > Mem/vminfo_by_process
+
+#
+# Net Tests, DTrace
+#
+
+dstatus "Mib data by mib statistic..."
+$dtrace -qn "$header"'
+ mib::: { @data[probename] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%-32s %16s\n", "STATISTIC", "VALUE");
+ printa("%-32s %@16d\n", @data);
+ }
+' | $clean > Net/mib_data
+
+dstatus "TCP write bytes by process..."
+$dtrace -qn "$header"'
+ fbt:ip:tcp_output:entry
+ {
+ this->size = msgdsize(args[1]);
+ @size[pid, execname] = sum(this->size);
+ }
+ dtrace:::END
+ {
+ printf("%6s %-16s %12s\n", "PID", "CMD", "BYTES");
+ printa("%6d %-16s %@12d\n", @size);
+ }
+' | $clean > Net/tcpw_by_process
+
+#
+# Proc Tests, DTrace
+#
+
+dstatus "Sample process @ 1000 Hz..."
+$dtrace -qn "$header"'
+ profile:::profile-1000
+ {
+ @num[pid, curpsinfo->pr_psargs] = count();
+ }
+ dtrace:::END
+ {
+ printf("%6s %12s %s\n", "PID", "SAMPLES", "ARGS");
+ printa("%6d %@12d %S\n", @num);
+ }
+' | $clean > Proc/sample_process
+
+dstatus "Syscall count by process..."
+$dtrace -qn "$header"'
+ syscall:::entry { @num[pid, execname, probefunc] = count(); }
+ dtrace:::END
+ {
+ printf("%6s %-24s %-24s %8s\n",
+ "PID", "CMD", "SYSCALL", "COUNT");
+ printa("%6d %-24s %-24s %@8d\n", @num);
+ }
+' | $clean > Proc/syscall_by_process
+
+dstatus "Syscall count by syscall..."
+$dtrace -qn "$header"'
+ syscall:::entry { @num[probefunc] = count(); }
+ dtrace:::END
+ {
+ printf("%-32s %16s\n", "SYSCALL", "COUNT");
+ printa("%-32s %@16d\n", @num);
+ }
+' | $clean > Proc/syscall_count
+
+dstatus "Read bytes by process..."
+$dtrace -qn "$header"'
+ sysinfo:::readch { @bytes[pid, execname] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %16s\n", "PID", "CMD", "BYTES");
+ printa("%6d %-16s %@16d\n", @bytes);
+ }
+' | $clean > Proc/readb_by_process
+
+dstatus "Write bytes by process..."
+$dtrace -qn "$header"'
+ sysinfo:::writech { @bytes[pid, execname] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %16s\n", "PID", "CMD", "BYTES");
+ printa("%6d %-16s %@16d\n", @bytes);
+ }
+' | $clean > Proc/writeb_by_process
+
+dstatus "Sysinfo counts by process..."
+$dtrace -qn "$header"'
+ sysinfo::: { @num[pid, execname, probename] = sum(arg0); }
+ dtrace:::END
+ {
+ printf("%6s %-16s %-16s %16s\n",
+ "PID", "CMD", "STATISTIC", "COUNT");
+ printa("%6d %-16s %-16s %@16d\n", @num);
+ }
+' | $clean > Proc/sysinfo_by_process
+
+dstatus "New process counts with arguments..."
+$dtrace -qn "$header"'
+ proc:::exec-success
+ {
+ @num[pid, ppid, curpsinfo->pr_psargs] = count();
+ }
+ dtrace:::END
+ {
+ printf("%6s %6s %8s %s\n", "PID", "PPID", "COUNT", "ARGS");
+ printa("%6d %6d %@8d %S\n", @num);
+ }
+' | $clean > Proc/newprocess_count
+
+dstatus "Signal counts..."
+$dtrace -qn "$header"'
+ proc:::signal-send {
+ @num[execname,args[2],stringof(args[1]->pr_fname)] = count();
+ }
+ dtrace:::END
+ {
+ printf("%-16s %-8s %-16s %8s\n",
+ "FROM", "SIG", "TO", "COUNT");
+ printa("%-16s %-8d %-16s %@8d\n", @num);
+ }
+' | $clean > Proc/signal_count
+
+dstatus "Syscall error counts..."
+$dtrace -qn "$header"'
+ syscall:::return /(int)arg0 == -1/
+ {
+ @num[pid, execname, probefunc, errno] = count();
+ }
+ dtrace:::END
+ {
+ printf("%6s %-16s %-32s %-6s %8s\n",
+ "PID", "CMD", "SYSCALL", "ERRNO", "COUNT");
+ printa("%6d %-16s %-32s %-6d %@8d\n", @num);
+ }
+' | $clean > Proc/syscall_errors
+
+
+###########
+# Done
+#
+( print -n "End: "
+date ) >> log
+decho "100% Done."
+if (( tar )); then
+ cd ..
+ tar cf $dir.tar $dir
+ gzip $dir.tar
+ decho "File is $dir.tar.gz"
+fi
+if (( delete && tar )); then
+ cd $dir
+ # this could be all an "rm -r $dir", but since it will be run
+ # as root on production servers - lets be analy cautious,
+ rm Cpu/interrupt_by_cpu
+ rm Cpu/interrupt_time
+ rm Cpu/dispqlen_by_cpu
+ rm Cpu/sdt_count
+ rm Disk/pgpgin_by_process
+ rm Disk/fileopen_count
+ rm Disk/sizedist_by_process
+ rm Mem/minf_by_process
+ rm Mem/vminfo_by_process
+ rm Net/mib_data
+ rm Net/tcpw_by_process
+ rm Proc/sample_process
+ rm Proc/syscall_by_process
+ rm Proc/syscall_count
+ rm Proc/readb_by_process
+ rm Proc/writeb_by_process
+ rm Proc/sysinfo_by_process
+ rm Proc/newprocess_count
+ rm Proc/signal_count
+ rm Proc/syscall_errors
+ rmdir Cpu
+ rmdir Disk
+ rmdir Mem
+ rmdir Net
+ rmdir Proc
+ rm Info/uname-a
+ rm Info/psrinfo-v
+ rm Info/prtconf
+ rm Info/df-k
+ rm Info/ifconfig-a
+ rm Info/ps-o
+ rm Info/uptime
+ rmdir Info
+ rm log
+ cd ..
+ rmdir $dir
+else
+ decho "Directory is $dir"
+fi
+
diff --git a/cddl/contrib/dtracetoolkit/dtruss b/cddl/contrib/dtracetoolkit/dtruss
new file mode 100755
index 0000000..93b12d3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/dtruss
@@ -0,0 +1,464 @@
+#!/bin/sh
+#
+# dtruss - print process system call time details.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: dtruss 9 2007-08-07 10:21:07Z brendan $
+#
+# USAGE: dtruss [-acdeflhoLs] [-t syscall] { -p PID | -n name | command }
+#
+# -p PID # examine this PID
+# -n name # examine this process name
+# -t syscall # examine this syscall only
+# -a # print all details
+# -c # print system call counts
+# -d # print relative timestamps (us)
+# -e # print elapsed times (us)
+# -f # follow children as they are forked
+# -l # force printing of pid/lwpid per line
+# -o # print on cpu times (us)
+# -s # print stack backtraces
+# -L # don't print pid/lwpid per line
+# -b bufsize # dynamic variable buf size (default is "4m")
+# eg,
+# dtruss df -h # run and examine the "df -h" command
+# dtruss -p 1871 # examine PID 1871
+# dtruss -n tar # examine all processes called "tar"
+# dtruss -f test.sh # run test.sh and follow children
+#
+# See the man page dtruss(1M) for further details.
+#
+# SEE ALSO: procsystime # DTraceToolkit
+# dapptrace # DTraceToolkit
+# truss
+#
+# COPYRIGHT: Copyright (c) 2005, 2006, 2007 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# TODO: Track signals, more output formatting.
+#
+# 29-Apr-2005 Brendan Gregg Created this.
+# 09-May-2005 " " Fixed evaltime (thanks Adam L.)
+# 16-May-2005 " " Added -t syscall tracing.
+# 17-Jun-2005 " " Added -s stack backtraces.
+# 17-Jun-2005 " " Last update.
+# 29-Jun-2007 " " Used progenyof() (thanks Aaron Gutman).
+# 06-Aug-2007 " " Various updates.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_pid=0; opt_name=0; pid=0; pname="."; opt_elapsed=0; opt_cpu=0
+opt_counts=0; opt_relative=0; opt_printid=0; opt_follow=0; opt_command=0
+command=""; opt_buf=0; buf="4m"; opt_trace=0; trace="."; opt_stack=0
+
+### Process options
+while getopts ab:cdefhln:op:st:L name
+do
+ case $name in
+ b) opt_buf=1; buf=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ t) opt_trace=1; trace=$OPTARG ;;
+ a) opt_counts=1; opt_relative=1; opt_elapsed=1; opt_follow=1
+ opt_printid=1; opt_cpu=1 ;;
+ c) opt_counts=1 ;;
+ d) opt_relative=1 ;;
+ e) opt_elapsed=1 ;;
+ f) opt_follow=1 ;;
+ l) opt_printid=1 ;;
+ o) opt_cpu=1 ;;
+ L) opt_printid=-1 ;;
+ s) opt_stack=-1 ;;
+ h|?) cat <<-END >&2
+ USAGE: dtruss [-acdefholLs] [-t syscall] { -p PID | -n name | command }
+
+ -p PID # examine this PID
+ -n name # examine this process name
+ -t syscall # examine this syscall only
+ -a # print all details
+ -c # print syscall counts
+ -d # print relative times (us)
+ -e # print elapsed times (us)
+ -f # follow children (-p or cmd only)
+ -l # force printing pid/lwpid
+ -o # print on cpu times
+ -s # print stack backtraces
+ -L # don't print pid/lwpid
+ -b bufsize # dynamic variable buf size
+ eg,
+ dtruss df -h # run and examine "df -h"
+ dtruss -p 1871 # examine PID 1871
+ dtruss -n tar # examine all processes called "tar"
+ dtruss -f test.sh # run test.sh and follow children
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+### Option logic
+if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then
+ opt_command=1
+ if [ "$*" = "" ]; then
+ $0 -h
+ exit
+ fi
+ command="$*" # yes, I meant $*!
+fi
+if [ $opt_follow -eq 1 -o $opt_name -eq 1 ]; then
+ if [ $opt_printid -ne -1 ]; then
+ opt_printid=1
+ else
+ opt_printid=0
+ fi
+fi
+if [ $opt_follow -eq 1 -a $opt_name -eq 1 ]; then
+ echo "ERROR: -f option cannot be used with -n (use -p or cmd instead)."
+ exit 1
+fi
+
+### Option translation
+if [ "$trace" = "exec" ]; then trace="exece"; fi
+if [ "$trace" = "time" ]; then trace="gtime"; fi
+if [ "$trace" = "exit" ]; then trace="rexit"; fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+
+### Define D Script
+dtrace='
+#pragma D option quiet
+#pragma D option switchrate=10
+
+/*
+ * Command line arguments
+ */
+inline int OPT_command = '$opt_command';
+inline int OPT_follow = '$opt_follow';
+inline int OPT_printid = '$opt_printid';
+inline int OPT_relative = '$opt_relative';
+inline int OPT_elapsed = '$opt_elapsed';
+inline int OPT_cpu = '$opt_cpu';
+inline int OPT_counts = '$opt_counts';
+inline int OPT_pid = '$opt_pid';
+inline int OPT_name = '$opt_name';
+inline int OPT_trace = '$opt_trace';
+inline int OPT_stack = '$opt_stack';
+inline string NAME = "'$pname'";
+inline string TRACE = "'$trace'";
+
+dtrace:::BEGIN
+{
+ /* print header */
+ OPT_printid ? printf("%-9s ", "PID/LWP") : 1;
+ OPT_relative ? printf("%8s ", "RELATIVE") : 1;
+ OPT_elapsed ? printf("%7s ", "ELAPSD") : 1;
+ OPT_cpu ? printf("%6s ", "CPU") : 1;
+ printf("SYSCALL(args) \t\t = return\n");
+}
+
+/*
+ * Save syscall entry info
+ */
+syscall:::entry
+/((OPT_command || OPT_pid) && pid == $target) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_follow && progenyof($target))/
+{
+ /* set start details */
+ self->start = timestamp;
+ self->vstart = vtimestamp;
+ self->arg0 = arg0;
+ self->arg1 = arg1;
+ self->arg2 = arg2;
+
+ /* count occurances */
+ OPT_counts == 1 ? @Counts[probefunc] = count() : 1;
+}
+
+/*
+ * Follow children
+ */
+syscall::fork*:return
+/(OPT_follow && progenyof($target)) && (!OPT_trace || (TRACE == probefunc))/
+{
+ /* print output */
+ self->code = errno == 0 ? "" : "Err#";
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d: ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d: ", 0) : 1;
+ OPT_cpu ? printf("%6d ", 0) : 1;
+ printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc,
+ self->arg0, self->arg1, self->arg2, (int)arg0, self->code,
+ (int)errno);
+}
+
+/*
+ * Check for syscall tracing
+ */
+syscall:::entry
+/OPT_trace && probefunc != TRACE/
+{
+ /* drop info */
+ self->start = 0;
+ self->vstart = 0;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/*
+ * Print return data
+ */
+
+/*
+ * The following code is written in an intentionally repetative way.
+ * The first versions had no code redundancies, but performed badly during
+ * benchmarking. The priority here is speed, not cleverness. I know there
+ * are many obvious shortcuts to this code, I have tried them. This style has
+ * shown in benchmarks to be the fastest (fewest probes fired, fewest actions).
+ */
+
+/* print 3 args, return as hex */
+syscall::sigprocmask:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(0x%X, 0x%X, 0x%X)\t\t = 0x%X %s%d\n", probefunc,
+ (int)self->arg0, self->arg1, self->arg2, (int)arg0,
+ self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 3 args, arg0 as a string */
+syscall::access*:return,
+syscall::stat*:return,
+syscall::lstat*:return,
+syscall::readlink*:return,
+syscall::open*:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(\"%S\", 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc,
+ copyinstr(self->arg0), self->arg1, self->arg2, (int)arg0,
+ self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 3 args, arg1 as a string */
+syscall::write:return,
+syscall::pwrite:return,
+syscall::*read*:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(0x%X, \"%S\", 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0,
+ stringof(copyin(self->arg1, self->arg2)), self->arg2, (int)arg0,
+ self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 0 arg output */
+syscall::*fork*:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s()\t\t = %d %s%d\n", probefunc,
+ (int)arg0, self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 1 arg output */
+syscall::close:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(0x%X)\t\t = %d %s%d\n", probefunc, self->arg0,
+ (int)arg0, self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 2 arg output */
+syscall::utimes:return,
+syscall::munmap:return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0,
+ self->arg1, (int)arg0, self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* print 3 arg output - default */
+syscall:::return
+/self->start/
+{
+ /* calculate elapsed time */
+ this->elapsed = timestamp - self->start;
+ self->start = 0;
+ this->cpu = vtimestamp - self->vstart;
+ self->vstart = 0;
+ self->code = errno == 0 ? "" : "Err#";
+
+ /* print optional fields */
+ OPT_printid ? printf("%6d/%d: ", pid, tid) : 1;
+ OPT_relative ? printf("%8d ", vtimestamp/1000) : 1;
+ OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1;
+ OPT_cpu ? printf("%6d ", this->cpu/1000) : 1;
+
+ /* print main data */
+ printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0,
+ self->arg1, self->arg2, (int)arg0, self->code, (int)errno);
+ OPT_stack ? ustack() : 1;
+ OPT_stack ? trace("\n") : 1;
+ self->arg0 = 0;
+ self->arg1 = 0;
+ self->arg2 = 0;
+}
+
+/* program exited */
+proc:::exit
+/(OPT_command || OPT_pid) && pid == $target/
+{
+ exit(0);
+}
+
+/* print counts */
+dtrace:::END
+{
+ OPT_counts == 1 ? printf("\n%-32s %16s\n", "CALL", "COUNT") : 1;
+ OPT_counts == 1 ? printa("%-32s %@16d\n", @Counts) : 1;
+}
+'
+
+### Run DTrace
+if [ $opt_command -eq 1 ]; then
+ /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \
+ -c "$command" >&2
+elif [ $opt_pid -eq 1 ]; then
+ /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2
+else
+ /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" >&2
+fi
diff --git a/cddl/contrib/dtracetoolkit/dvmstat b/cddl/contrib/dtracetoolkit/dvmstat
new file mode 100755
index 0000000..41f40e3
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/dvmstat
@@ -0,0 +1,250 @@
+#!/usr/bin/sh
+#
+# dvmstat - vmstat by PID/name/command.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This program provides vmstat like data for one particular PID, a
+# process name, or when running a command. It prints statistics
+# every second.
+#
+# $Id: dvmstat 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: dvmstat { -p PID | -n name | command }
+# eg,
+# dvmstat -p 1871 # examine PID 1871
+# dvmstat -n tar # examine processes called "tar"
+# dvmstat df -h # run and examine "df -h"
+#
+# FIELDS:
+# re page reclaims Kbytes
+# maj major faults Kbytes
+# mf minor faults Kbytes
+# fr page frees Kbytes
+# epi executable page ins Kbytes
+# epo executable page out Kbytes
+# api anonymous page ins Kbytes
+# apo anonymous page outs Kbytes
+# fpi filesystem page ins Kbytes
+# fpo filesystem page outs Kbytes
+# sy system calls number
+#
+# SEE ALSO: vmstat(1M)
+#
+# NOTES:
+#
+# When using dvmstat to run a command - if the command takes some time
+# to execute, dvmstat will print output every second. If the command runs
+# in less than a second, then the only one line of output will be printed.
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 12-Jun-2005 Brendan Gregg Created this.
+# 08-Jan-2006 " " Last update.
+#
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_pid=0; opt_name=0; pid=0; pname="."; opt_command=0; command=""
+
+### Process options
+while getopts hn:p: name
+do
+ case $name in
+ p) opt_pid=1; pid=$OPTARG ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ h|?) cat <<-END >&2
+ USAGE: dvmstat [-h] { -p PID | -n name | command }
+ -p PID # examine this PID
+ -n name # examine this process name
+ eg,
+ dvmstat -p 1871 # examine PID 1871
+ dvmstat -n tar # examine processes called "tar"
+ dvmstat df -h # run and examine "df -h"
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+
+### Option logic
+if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then
+ opt_command=1
+ if [ "$*" = "" ]; then
+ $0 -h
+ exit
+ fi
+ command="$*"
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+dtrace='
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_command = '$opt_command';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+ inline string COMMAND = "'$command'";
+ inline int SCREEN = 21;
+
+ /*
+ * Initialise variables
+ */
+ dtrace:::BEGIN
+ {
+ epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
+ re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
+ lines = SCREEN + 1;
+ header = 0;
+ }
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN,
+ dtrace:::END,
+ profile:::tick-1sec
+ /(OPT_command && probename == "END") ||
+ (!(OPT_command && probename == "BEGIN") && lines++ > SCREEN)/
+ {
+ printf("%6s %5s %5s %4s %4s %4s %4s %4s %4s %4s %6s\n",
+ "re", "maj", "mf", "fr", "epi", "epo", "api", "apo",
+ "fpi", "fpo", "sy");
+ lines = 0;
+ }
+
+ /*
+ * Probe events
+ *
+ * this intentionally does not use an associative array for storing data,
+ * for reasons of performance.
+ */
+
+ vminfo:::execpgin
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { epi += arg0; }
+
+ vminfo:::execpgout
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { epo += arg0; }
+
+ vminfo:::anonpgin
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { api += arg0; }
+
+ vminfo:::anonpgout
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { apo += arg0; }
+
+ vminfo:::fspgin
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { fpi += arg0; }
+
+ vminfo:::fspgout
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { fpo += arg0; }
+
+ vminfo:::pgrec
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { re += arg0; }
+
+ vminfo:::as_fault
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { mf += arg0; }
+
+ vminfo:::maj_fault
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { maj += arg0; }
+
+ vminfo:::dfree
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { fr += arg0; }
+
+ syscall:::entry
+ /(OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ { sy++; }
+
+ /*
+ * Print output line
+ */
+ profile:::tick-1sec,
+ dtrace:::END
+ {
+ /* convert to Kbytes */
+ re *= `_pagesize / 1024;
+ maj *= `_pagesize / 1024;
+ mf *= `_pagesize / 1024;
+ fr *= `_pagesize / 1024;
+ epi *= `_pagesize / 1024;
+ epo *= `_pagesize / 1024;
+ api *= `_pagesize / 1024;
+ apo *= `_pagesize / 1024;
+ fpi *= `_pagesize / 1024;
+ fpo *= `_pagesize / 1024;
+
+ /* print line */
+ printf("%6d %5d %5d %4d %4d %4d %4d %4d %4d %4d %6d\n",
+ re, maj, mf, fr, epi, epo, api, apo, fpi, fpo, sy);
+
+ /* clear counters */
+ epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
+ re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
+ }
+'
+
+### Run DTrace
+if [ $opt_command -eq 1 ]; then
+ /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2
+else
+ /usr/sbin/dtrace -n "$dtrace" >&2
+fi
+
diff --git a/cddl/contrib/dtracetoolkit/errinfo b/cddl/contrib/dtracetoolkit/errinfo
new file mode 100755
index 0000000..79160b1
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/errinfo
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+#
+# errinfo - report on syscall failures and print errno error messages.
+# Written using Perl and DTrace (Solaris 10 03/05)
+#
+# When system calls fail, an errno variable is set to convay a meaningful
+# message to the end user - so long as the program does something with it
+# (eg, "ls" printing "No such file or directory"). This program fetches
+# and prints details for all syscall failures along with their message,
+# whether the failing program is already printing this info or not.
+#
+# $Id: errinfo 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: errinfo [-ch] [-p PID] [-n name]
+#
+# -c # counts - aggregate style
+# -p PID # examine this PID only
+# -n name # examine processes with this name only
+# eg,
+# errinfo # default output - snoop event style
+# errinfo -n ssh # examine "ssh" processes only
+# errinfo -cn ssh # examine "ssh" using counts
+#
+# FIELDS:
+# EXEC Program name (truncated)
+# SYSCALL System call name
+# ERR Value of errno
+# DESC Description of errno message
+#
+# SEE ALSO: /usr/include/sys/errno.h
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 18-Apr-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+use Getopt::Std;
+
+#
+# Defaults
+#
+$FILTER = "";
+$COUNT = 0;
+
+#
+# Command line arguments
+#
+&Usage() if $ARGV[0] eq "--help";
+getopts('ch:n:p:') || &Usage();
+&Usage() if $opt_h;
+$COUNT = 1 if $opt_c;
+$FILTER = "&& execname == \"$opt_n\"" if defined $opt_n;
+$FILTER = "&& pid == $opt_p" if defined $opt_p;
+
+#
+# Load errno descriptions
+#
+open(ERRNO,"/usr/include/sys/errno.h") || die "ERROR1: reading errno.h: $!\n";
+while (chomp($line = <ERRNO>)) {
+ next unless $line =~ /^#define/;
+ ($errno,$desc) = $line =~ /^#define\s+\S+\s+(\d+)\s+\/\*(.*)\*\//;
+ $Errno{$errno} = $desc;
+}
+close ERRNO;
+
+#
+# Declare DTrace script
+#
+ if ($COUNT) { # aggregate style
+$dtrace = <<END;
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ syscall:::return
+ /errno != 0 && pid != \$pid $FILTER/
+ {
+ \@Errs[execname, probefunc, errno] = count();
+ }
+ dtrace:::END {
+ printa("%s %s %d %\@d\\n", \@Errs);
+ }'
+END
+ } else { # snoop style
+$dtrace = <<END;
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ #pragma D option switchrate=5hz
+ syscall:::return
+ /errno != 0 && pid != \$pid $FILTER/
+ {
+ printf("%s %s %d\\n", execname, probefunc, errno);
+ }'
+END
+ }
+
+#
+# Cleanup on signals
+#
+$SIG{INT} = \&Cleanup_Signal; # Ctrl-C
+$SIG{QUIT} = \&Cleanup_Signal; # Ctrl-\
+$SIG{TERM} = \&Cleanup_Signal; # TERM
+
+#
+# Run DTrace, process output
+#
+
+if ($COUNT) {
+ print STDERR "Tracing... Hit Ctrl-C to end.\n";
+ $header = 1;
+} else {
+ printf("%16s %16s %4s %s\n","EXEC","SYSCALL","ERR","DESC");
+}
+
+### Open DTrace
+open(DTRACE,"$dtrace |") || die "ERROR2: Can't start dtrace (perms?): $!\n";
+
+### Process DTrace output
+while (chomp($line = <DTRACE>)) {
+
+ ### Print count header
+ if ($COUNT && $header) {
+ printf("\n%16s %16s %4s %6s %s\n",
+ "EXEC","SYSCALL","ERR","COUNT","DESC");
+ $header = 0;
+ }
+
+ ### Split data
+ ($execname,$syscall,$errno,$counts) = split(' ',$line);
+ next if $errno eq "";
+
+ ### Fetch errno description
+ $desc = $Errno{$errno};
+
+ ### Print output line
+ if ($COUNT) {
+ printf("%16s %16s %4d %6d %s\n",
+ $execname,$syscall,$errno,$counts,$desc);
+ } else {
+ printf("%16s %16s %4d %s\n",$execname,$syscall,$errno,$desc);
+ }
+}
+close(DTRACE);
+
+#
+# Triggered by signals
+#
+sub Cleanup_Signal {
+}
+
+#
+# Usage message
+#
+sub Usage {
+ print STDERR "USAGE: errinfo [-ch] [-p PID] [-n name]\n";
+ print STDERR <<ENDUSAGE;
+ eg,
+ errinfo # default output - snoop event style
+ -c # counts - aggregate style
+ -p 871 # examine PID 871 only
+ -n ssh # examine processes with the name "ssh" only
+ -cn ssh # examine "ssh" using counts
+ENDUSAGE
+ exit(1);
+}
diff --git a/cddl/contrib/dtracetoolkit/execsnoop b/cddl/contrib/dtracetoolkit/execsnoop
new file mode 100755
index 0000000..a4b4f04
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/execsnoop
@@ -0,0 +1,167 @@
+#!/bin/sh
+#
+# execsnoop - snoop process execution as it occurs.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: execsnoop 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: execsnoop [-a|-A|-ehsvJ] [-c command]
+#
+# execsnoop # default output
+#
+# -a # print all data
+# -A # dump all data, space delimited
+# -e # safe output - parseable
+# -s # print start time, us
+# -v # print start time, string
+# -J # print jail ID
+# -c command # command name to snoop
+# eg,
+# execsnoop -v # human readable timestamps
+# execsnoop -J # print jail ID
+# execsnoop -c ls # snoop ls commands only
+#
+# The parseable output ensures that the ARGS field doesn't contain
+# any "\n"s, which normally sometimes can - and would wreck postprocessing.
+#
+# FIELDS:
+# UID User ID
+# PID Process ID
+# PPID Parent Process ID
+# COMM command name for the process
+# ARGS argument listing for the process
+# JAIL ID Jail ID
+# TIME timestamp for the command, us
+# STRTIME timestamp for the command, string
+#
+# SEE ALSO: BSM auditing.
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 27-Mar-2004 Brendan Gregg Created this.
+# 21-Jan-2005 " " Wrapped in sh to provide options.
+# 08-May-2005 " " Rewritten for performance.
+# 14-May-2005 " " Added zonename.
+# 02-Jul-2005 " " Added projid, safe printing.
+# 11-Sep-2005 " " Increased switchrate.
+# 11-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_dump=0; opt_cmd=0; opt_time=0; opt_timestr=0; filter=0; command=.
+opt_jailid=0; opt_safe=0
+
+### process options
+while getopts aAc:ehsvJ name
+do
+ case $name in
+ a) opt_time=1; opt_timestr=1; opt_jailid=1 ;;
+ A) opt_dump=1 ;;
+ c) opt_cmd=1; command=$OPTARG ;;
+ e) opt_safe=1 ;;
+ s) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ J) opt_jailid=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: execsnoop [-a|-A|-ehjsvJ] [-c command]
+ execsnoop # default output
+ -a # print all data
+ -A # dump all data, space delimited
+ -e # safe output, parseable
+ -s # print start time, us
+ -v # print start time, string
+ -J # print jail ID
+ -c command # command name to snoop
+ eg,
+ execsnoop -v # human readable timestamps
+ execsnoop -J # print jail ID
+ execsnoop -c ls # snoop ls commands only
+ END
+ exit 1
+ esac
+done
+
+### option logic
+if [ $opt_dump -eq 1 ]; then
+ opt_time=0; opt_timestr=0; opt_jailid=0
+fi
+if [ $opt_cmd -eq 1 ]; then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_dump = '$opt_dump';
+ inline int OPT_cmd = '$opt_cmd';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_jailid = '$opt_jailid';
+ inline int OPT_safe = '$opt_safe';
+ inline int FILTER = '$filter';
+ inline string COMMAND = "'$command'";
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
+ OPT_jailid ? printf("%-10s ", "JAIL ID") : 1;
+
+ /* print main headers */
+ OPT_dump ? printf("%s %s %s %s %s %s %s\n",
+ "TIME", "JAIL ID", "UID", "PID", "PPID", "COMM", "ARGS") :
+ printf("%5s %6s %6s %s\n", "UID", "PID", "PPID", "ARGS");
+ }
+
+ /*
+ * Print exec event
+ */
+ syscall::execve:return
+ /(FILTER == 0) || (OPT_cmd == 1 && COMMAND == execname)/
+ {
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_jailid ? printf("%-10d ", curpsinfo->pr_jailid) : 1;
+
+ /* print main data */
+ OPT_dump ? printf("%d %d %d %d %d %s ", timestamp/1000,
+ curpsinfo->pr_jailid, uid, pid, ppid, execname) :
+ printf("%5d %6d %6d ", uid, pid, ppid);
+ OPT_safe ? printf("%S\n", curpsinfo->pr_psargs) :
+ printf("%s\n", curpsinfo->pr_psargs);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/hotkernel b/cddl/contrib/dtracetoolkit/hotkernel
new file mode 100755
index 0000000..84d3362
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/hotkernel
@@ -0,0 +1,125 @@
+#!/usr/bin/perl -w
+#
+# hotkernel - sample on-CPU kernel-level functions and modules.
+# Written using Perl and DTrace (Solaris 10 03/05)
+#
+# This samples the on-CPU function at 1001 Hertz, for a simple yet
+# effective kernel-level profiling tool for sampling exclusive function time.
+# The output will identify which function is on the CPU the most - which is
+# the hottest. See Notes/ALLexclusive_notes.txt for an explanation of
+# exclusive time.
+#
+# $Id: hotkernel 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: hotkernel [-hm]
+#
+# -h # help
+# -m # match modules, not functions
+# eg,
+# hotkernel # sample kernel functions
+# hotkernel -m # sample kernel modules
+#
+# FIELDS:
+# FUNCTION Function name
+# MODULE Module name
+# COUNT Number of samples
+# PCNT Percentage of total samples
+#
+# COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 29-Jun-2006 Brendan Gregg Created this.
+# 29-Jun-2006 " " Last update.
+#
+
+use strict;
+use Getopt::Std;
+
+#
+# Command Line Arguments
+#
+my $args;
+usage() if defined $ARGV[0] and $ARGV[0] eq "--help";
+getopts('hm') or usage();
+usage() if defined $main::opt_h and $main::opt_h;
+my $mods = defined $main::opt_m and $main::opt_m ? 1 : 0;
+
+#
+# Cleanup on signals
+#
+$SIG{INT} = \&cleanupsig; # Ctrl-C
+$SIG{QUIT} = \&cleanupsig; # Ctrl-\
+$SIG{TERM} = \&cleanupsig; # TERM
+
+#
+# Declare DTrace script
+#
+my $dtrace = <<END;
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ profile:::profile-1001hz
+ /arg0/
+ {
+ \@pc[arg0] = count();
+ }
+ dtrace:::END
+ {
+ printa("%a %\@d\\n", \@pc);
+ }
+'
+END
+
+#
+# Run DTrace, process output
+#
+my %Count;
+my $total;
+open DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n";
+print "Sampling... Hit Ctrl-C to end.\n";
+while (my $line = <DTRACE>) {
+ next if $line =~ /^\s*$/;
+ my ($addr, $count) = split ' ', $line;
+ my ($name, $offset) = split /\+/, $addr;
+ next if $name eq "0x0";
+ $name =~ s/\`.*// if $mods;
+ $Count{$name} += $count;
+ $total += $count;
+}
+close DTRACE;
+
+#
+# Print final report
+#
+printf "\n%-52s %8s %6s\n", $mods ? "MODULE" : "FUNCTION", "COUNT", "PCNT";
+foreach my $name (sort { $Count{$a} <=> $Count{$b} } keys %Count) {
+ printf "%-52s %8d %5.1f%%\n", $name, $Count{$name},
+ 100 * $Count{$name} / ($total ? $total : 1);
+}
+
+#
+# Subroutines
+#
+sub cleanupsig {
+}
+sub usage {
+ print STDERR "USAGE: hotkernel [-hm]\n";
+ print STDERR " eg,\n";
+ print STDERR " hotkernel # sample kernel functions\n";
+ print STDERR " hotkernel -m # sample kernel modules\n";
+ exit 1;
+}
diff --git a/cddl/contrib/dtracetoolkit/hotuser b/cddl/contrib/dtracetoolkit/hotuser
new file mode 100755
index 0000000..2377487
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/hotuser
@@ -0,0 +1,139 @@
+#!/usr/bin/perl -w
+#
+# hotuser - sample on-CPU user-level functions and libraries.
+# Written using Perl and DTrace (Solaris 10 03/05)
+#
+# This samples the on-CPU function at 1001 Hertz, for a simple yet
+# effective user-level profiling tool for sampling exclusive function time.
+# The output will identify which function is on the CPU the most - which
+# is the hottest. See Notes/ALLexclusive_notes.txt for an explanation of
+# exclusive time.
+#
+# $Id: hotuser 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: hotuser [-hl] { -c command | -p PID }
+#
+# -h # help
+# -l # match libraries, not functions
+# -p PID # examine this PID
+# -c command # run and examine this command
+# eg,
+# hotuser -p 81 # sample user functions from PID 81
+# hotuser -lp 81 # sample user libraries from PID 81
+# hotuser -p `pgrep -n Xorg` # sample Xorg
+#
+# FIELDS:
+# FUNCTION Function name
+# LIBRARY Library name
+# COUNT Number of samples
+# PCNT Percentage of total samples
+#
+# COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 29-Jun-2006 Brendan Gregg Created this.
+# 29-Jun-2006 " " Last update.
+#
+
+use strict;
+use Getopt::Std;
+
+#
+# Command Line Arguments
+#
+my $args;
+usage() if defined $ARGV[0] and $ARGV[0] eq "--help";
+getopts('c:hlp:') or usage();
+usage() if defined $main::opt_h and $main::opt_h;
+my $libs = defined $main::opt_l and $main::opt_l ? 1 : 0;
+if (defined $main::opt_c) {
+ $args = "-c $main::opt_c";
+}
+elsif (defined $main::opt_p) {
+ $args = "-p $main::opt_p";
+}
+else {
+ usage();
+}
+
+#
+# Cleanup on signals
+#
+$SIG{INT} = \&cleanupsig; # Ctrl-C
+$SIG{QUIT} = \&cleanupsig; # Ctrl-\
+$SIG{TERM} = \&cleanupsig; # TERM
+
+#
+# Declare DTrace script
+#
+my $dtrace = <<END;
+/usr/sbin/dtrace -n '
+ #pragma D option quiet
+ profile:::profile-1001hz
+ /pid == \$target/
+ {
+ \@pc[arg1] = count();
+ }
+ dtrace:::END
+ {
+ printa("OUT: %A %\@d\\n", \@pc);
+ }
+' '$args'
+END
+
+#
+# Run DTrace, process output
+#
+my %Count;
+my $total;
+open DTRACE, "$dtrace |" or die "ERROR1: Can't run dtrace (perms?): $!\n";
+print "Sampling... Hit Ctrl-C to end.\n";
+while (my $line = <DTRACE>) {
+ next if $line =~ /^\s*$/;
+ next if $line !~ /^OUT: /;
+ my ($tag, $addr, $count) = split ' ', $line;
+ my ($name, $offset) = split /\+/, $addr;
+ next if $name eq "0x0";
+ $name =~ s/\`.*// if $libs;
+ $Count{$name} += $count;
+ $total += $count;
+}
+close DTRACE;
+
+#
+# Print final report
+#
+printf "\n%-52s %8s %6s\n", $libs ? "LIBRARY" : "FUNCTION", "COUNT", "PCNT";
+foreach my $name (sort { $Count{$a} <=> $Count{$b} } keys %Count) {
+ printf "%-52s %8d %5.1f%%\n", $name, $Count{$name},
+ 100 * $Count{$name} / ($total ? $total : 1);
+}
+
+#
+# Subroutines
+#
+sub cleanupsig {
+}
+sub usage {
+ print STDERR "USAGE: hotuser [-hl] { -c command | -p PID }\n";
+ print STDERR " eg,\n";
+ print STDERR " hotuser -p 81 # sample user funcs for PID 81\n";
+ print STDERR " hotuser -lp 81 # sample user libs for PID 81\n";
+ print STDERR " hotuser -p `pgrep -n Xorg` # sample Xorg\n";
+ exit 1;
+}
diff --git a/cddl/contrib/dtracetoolkit/install b/cddl/contrib/dtracetoolkit/install
new file mode 100755
index 0000000..1962c46
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/install
@@ -0,0 +1,151 @@
+#!/usr/bin/ksh
+#
+# install - installer for the DTraceToolkit
+#
+# This is a fairly simple script, most of it is error checking.
+# All the script does is copy the DTraceToolkit files to another directory,
+# with various checks. The user could have copied the files themselves, this
+# script doesn't do anything special to them. It's really here in case
+# people extrace the toolkit and go looking for an installer.
+#
+# 15-May-2005 Brendan Gregg Created this.
+
+DEBUG=0 # print debug data
+TEETH=1 # does this script have teeth
+SLEEP=1 # pause on messages
+PATH=/usr/bin
+
+### Ensure we know where we are,
+dir=${0%/*}
+cd $dir
+(( DEBUG )) && print "DEBUG: dir $dir"
+
+### Print welcome,
+print "DTraceToolkit Installation\n---------------------------"
+cat Version
+print "\nhit Ctrl-C any time you wish to quit.\n\n"
+
+### Fetch location,
+print -n "Enter target directory for installation [/opt/DTT]: "
+read loc junk
+if [[ "$loc" == "" ]]; then loc="/opt/DTT"; fi
+print ""
+(( DEBUG )) && print "DEBUG: loc $loc"
+
+### Sanity check,
+if print "$loc" | grep '^[./]*$' > /dev/null; then
+ print "ERROR1: Location \"$loc\" is ambiguous.\n."
+ (( SLEEP )) && sleep 1
+ print ".\tTry a full path, like \"/opt/DTT\"\n."
+ print ".\tSorry!\n"
+ exit 1
+fi
+
+### Evilness check,
+if print "$loc" | grep '[^a-zA-Z0-9_.-/]' > /dev/null; then
+ print "ERROR2: Sorry, location \"$loc\" contains bad characters.\n."
+ (( SLEEP )) && sleep 1
+ print ".\tTry a path like \"/opt/DTT\"\n."
+ print ".\tSorry!\n"
+ exit 2
+fi
+
+### Process location,
+basename=${loc%/*}
+nodename=${loc##*/}
+if [[ "$basename" == "" ]]; then basename="/"; fi
+(( DEBUG )) && print "DEBUG: basename $basename"
+(( DEBUG )) && print "DEBUG: nodename $nodename"
+
+### Check parent dir exists,
+if [[ ! -d "$basename" ]]; then
+ print "ERROR3: Parent directory \"$basename\" does not exist!\n."
+ (( SLEEP )) && sleep 1
+ print ".\tI'm not sure what you want me to do here, if you were"
+ print ".\tserious about the above parent directory - then run"
+ print ".\ta \"mkdir -p $basename\" first, then rerun this script.\n."
+ print ".\tSorry!\n"
+ exit 3
+fi
+
+### Check parent dir perms,
+if [[ ! -w "$basename" ]]; then
+ print "ERROR4: Can't write to parent directory \"$basename\"!\n."
+ (( SLEEP )) && sleep 1
+ print ".\tSince I can't write to this directory, I can't install the"
+ print ".\tDTraceToolkit. You are currently logged in as,\n."
+ id | sed 's/^/. /'
+ print ".\n.\tand the directory has permissions,\n."
+ ls -ld "$basename" | awk '{ print ".\t\t",$1,$2,$3,$4,"..." }'
+ owner=`ls -ld "$basename" | awk '{ print $3 }'`
+ print ".\n.\tMaybe you need to run \"su - $owner\" first?\n."
+ print ".\tSorry!\n"
+ exit 4
+fi
+
+### Check if toolkit is already installed,
+if [[ -d "$loc" ]]; then
+ print "Warning: Possible old version of the DTraceToolkit found."
+ print "\tThis will DELETE the files in $loc, then install the toolkit."
+ (( SLEEP )) && sleep 1
+ if [[ ! -f "$loc/Version" ]]; then
+ print "\nWARNING: $loc doesn't look like an old DTraceToolkit!"
+ (( SLEEP )) && sleep 1
+ fi
+ print -n "\nContinue (will run \"rm -rf $loc\"). Are you sure (y/N)?: "
+ read ans junk
+ if [[ "$ans" != "y" ]]; then
+ print "\nExiting..."
+ exit 5
+ fi
+ if (( TEETH )); then
+ rm -rf "$loc"
+ else
+ print COMMAND: rm -rf \"$loc\"
+ fi
+fi
+
+### Make new toolkit dir,
+print "\nMaking directory \"$loc\"...\n"
+if (( TEETH )); then
+ mkdir -p "$loc"
+else
+ print COMMAND: mkdir -p \"$loc\"
+fi
+if [[ ! -d "$loc" || ! -w "$loc" ]]; then
+ print "ERROR6: Creation of \"$loc\" failed.\n."
+ (( SLEEP )) && sleep 1
+ print ".\tCheck directory location and try again.\n."
+ print ".\tSorry!\n"
+ exit 6
+fi
+
+### Copy files across,
+print "\nCopying DTraceToolkit files...\n"
+if (( TEETH )); then
+ tar cf - . | (cd "$loc"; tar xvf -)
+else
+ print COMMAND: "tar cf - . | (cd \"$loc\"; tar xvf -)"
+fi
+error=$?
+if [[ ! -f "$loc/install" ]]; then error=1; fi
+if (( error )); then
+ print "ERROR7: Failure during copy.\n."
+ (( SLEEP )) && sleep 1
+ print ".\tCheck source \"$dir\" and destination \"$loc\", then"
+ print ".\ttry again.\n."
+ print ".\tSorry!\n"
+ exit 7
+fi
+
+### Delete installer,
+if (( TEETH )); then
+ rm "$loc/install"
+else
+ print COMMAND: rm \"$loc/install\"
+fi
+
+### Finished,
+print "\nFinished.\n"
+print "Installed to \"$loc\". See $loc/Guide for how to get started.\n"
+
diff --git a/cddl/contrib/dtracetoolkit/iopattern b/cddl/contrib/dtracetoolkit/iopattern
new file mode 100755
index 0000000..e825f9f
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/iopattern
@@ -0,0 +1,277 @@
+#!/usr/bin/ksh
+#
+# iopattern - print disk I/O pattern.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This prints details on the I/O access pattern for the disks, such as
+# percentage of events that were of a random or sequential nature.
+# By default totals for all disks are printed.
+#
+# $Id: iopattern 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
+# [interval [count]]
+#
+# -v # print timestamp, string
+# -d device # instance name to snoop (eg, dad0)
+# -f filename # full pathname of file to snoop
+# -m mount_point # this FS only (will skip raw events)
+# eg,
+# iopattern # default output, 1 second intervals
+# iopattern 10 # 10 second samples
+# iopattern 5 12 # print 12 x 5 second samples
+# iopattern -m / # snoop events on filesystem / only
+#
+# FIELDS:
+# %RAN percentage of events of a random nature
+# %SEQ percentage of events of a sequential nature
+# COUNT number of I/O events
+# MIN minimum I/O event size
+# MAX maximum I/O event size
+# AVG average I/O event size
+# KR total kilobytes read during sample
+# KW total kilobytes written during sample
+# DEVICE device name
+# MOUNT mount point
+# FILE filename
+# TIME timestamp, string
+#
+# NOTES:
+#
+# An event is considered random when the heads seek. This program prints
+# the percentage of events that are random. The size of the seek is not
+# measured - it's either random or not.
+#
+# SEE ALSO: iosnoop, iotop
+#
+# IDEA: Ryan Matteson
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 25-Jul-2005 Brendan Gregg Created this.
+# 25-Jul-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_device=0; opt_file=0; opt_mount=0; opt_time=0
+filter=0; device=.; filename=.; mount=.; interval=1; count=-1
+
+### process options
+while getopts d:f:hm:v name
+do
+ case $name in
+ d) opt_device=1; device=$OPTARG ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ v) opt_time=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: iopattern [-v] [-d device] [-f filename] [-m mount_point]
+ [interval [count]]
+
+ -v # print timestamp
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ eg,
+ iopattern # default output, 1 second samples
+ iopattern 10 # 10 second samples
+ iopattern 5 12 # print 12 x 5 second samples
+ iopattern -m / # snoop events on filesystem / only
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_device || opt_mount || opt_file )); then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_time = '$opt_time';
+ inline int OPT_device = '$opt_device';
+ inline int OPT_mount = '$opt_mount';
+ inline int OPT_file = '$opt_file';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int FILTER = '$filter';
+ inline string DEVICE = "'$device'";
+ inline string FILENAME = "'$filename'";
+ inline string MOUNT = "'$mount'";
+
+ #pragma D option quiet
+
+ int last_loc[string];
+
+ /*
+ * Program start
+ */
+ dtrace:::BEGIN
+ {
+ /* starting values */
+ diskcnt = 0;
+ diskmin = 0;
+ diskmax = 0;
+ diskran = 0;
+ diskr = 0;
+ diskw = 0;
+ counts = COUNTER;
+ secs = INTERVAL;
+ LINES = 20;
+ line = 0;
+ last_event[""] = 0;
+ }
+
+ /*
+ * Print header
+ */
+ profile:::tick-1sec
+ /line <= 0 /
+ {
+ /* print optional headers */
+ OPT_time ? printf("%-20s ", "TIME") : 1;
+ OPT_device ? printf("%-9s ", "DEVICE") : 1;
+ OPT_mount ? printf("%-12s ", "MOUNT") : 1;
+ OPT_file ? printf("%-12s ", "FILE") : 1;
+
+ /* print header */
+ printf("%4s %4s %6s %6s %6s %6s %6s %6s\n",
+ "%RAN", "%SEQ", "COUNT", "MIN", "MAX", "AVG", "KR", "KW");
+
+ line = LINES;
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::done
+ {
+ /* default is to trace unless filtering */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? self->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? self->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? self->ok = 1 : 1;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /self->ok/
+ {
+ /*
+ * Save details
+ */
+ this->loc = args[0]->b_blkno * 512;
+ this->pre = last_loc[args[1]->dev_statname];
+ diskr += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
+ diskw += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
+ diskran += this->pre == this->loc ? 0 : 1;
+ diskcnt++;
+ diskmin = diskmin == 0 ? args[0]->b_bcount :
+ (diskmin > args[0]->b_bcount ? args[0]->b_bcount : diskmin);
+ diskmax = diskmax < args[0]->b_bcount ? args[0]->b_bcount : diskmax;
+
+ /* save disk location */
+ last_loc[args[1]->dev_statname] = this->loc + args[0]->b_bcount;
+
+ /* cleanup */
+ self->ok = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Print Output
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* calculate diskavg */
+ diskavg = diskcnt > 0 ? (diskr + diskw) / diskcnt : 0;
+
+ /* convert counters to Kbytes */
+ diskr /= 1024;
+ diskw /= 1024;
+
+ /* convert to percentages */
+ diskran = diskcnt == 0 ? 0 : (diskran * 100) / diskcnt;
+ diskseq = diskcnt == 0 ? 0 : 100 - diskran;
+
+ /* print optional fields */
+ OPT_time ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_device ? printf("%-9s ", DEVICE) : 1;
+ OPT_mount ? printf("%-12s ", MOUNT) : 1;
+ OPT_file ? printf("%-12s ", FILENAME) : 1;
+
+ /* print data */
+ printf("%4d %4d %6d %6d %6d %6d %6d %6d\n",
+ diskran, diskseq, diskcnt, diskmin, diskmax, diskavg,
+ diskr, diskw);
+
+ /* clear data */
+ diskmin = 0;
+ diskmax = 0;
+ diskcnt = 0;
+ diskran = 0;
+ diskr = 0;
+ diskw = 0;
+
+ secs = INTERVAL;
+ counts--;
+ line--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/iosnoop b/cddl/contrib/dtracetoolkit/iosnoop
new file mode 100755
index 0000000..00931d2
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/iosnoop
@@ -0,0 +1,367 @@
+#!/usr/bin/sh
+#
+# iosnoop - A program to print disk I/O events as they happen, with useful
+# details such as UID, PID, filename, command, etc.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring disk events that have made it past system caches.
+#
+# $Id: iosnoop 8 2007-08-06 05:55:26Z brendan $
+#
+# USAGE: iosnoop [-a|-A|-DeghiNostv] [-d device] [-f filename]
+# [-m mount_point] [-n name] [-p PID]
+#
+# iosnoop # default output
+#
+# -a # print all data (mostly)
+# -A # dump all data, space delimited
+# -D # print time delta, us (elapsed)
+# -e # print device name
+# -g # print command arguments
+# -i # print device instance
+# -N # print major and minor numbers
+# -o # print disk delta time, us
+# -s # print start time, us
+# -t # print completion time, us
+# -v # print completion time, string
+# -d device # instance name to snoop (eg, dad0)
+# -f filename # full pathname of file to snoop
+# -m mount_point # this FS only (will skip raw events)
+# -n name # this process name only
+# -p PID # this PID only
+# eg,
+# iosnoop -v # human readable timestamps
+# iosnoop -N # print major and minor numbers
+# iosnoop -m / # snoop events on the root filesystem only
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# PPID parennt process ID
+# COMM command name for the process
+# ARGS argument listing for the process
+# SIZE size of operation, bytes
+# BLOCK disk block for the operation (location)
+# STIME timestamp for the disk request, us
+# TIME timestamp for the disk completion, us
+# DELTA elapsed time from request to completion, us
+# DTIME time for disk to complete request, us
+# STRTIME timestamp for the disk completion, string
+# DEVICE device name
+# INS device instance number
+# D direction, Read or Write
+# MOUNT mount point
+# FILE filename (basename) for io operation
+#
+# NOTE:
+# - There are two different delta times reported. -D prints the
+# elapsed time from the disk request (strategy) to the disk completion
+# (iodone); -o prints the time for the disk to complete that event
+# since it's last event (time between iodones), or, the time to the
+# strategy if the disk had been idle.
+# - When filtering on PID or process name, be aware that poor disk event
+# times may be due to events that have been filtered away, for example
+# another process that may be seeking the disk heads elsewhere.
+#
+# SEE ALSO: BigAdmin: DTrace, http://www.sun.com/bigadmin/content/dtrace
+# Solaris Dynamic Tracing Guide, http://docs.sun.com
+# DTrace Tools, http://www.brendangregg.com/dtrace.html
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 12-Mar-2004 Brendan Gregg Created this, build 51.
+# 23-May-2004 " " Fixed mntpt bug.
+# 10-Oct-2004 " " Rewritten to use the io provider, build 63.
+# 04-Jan-2005 " " Wrapped in sh to provide options.
+# 08-May-2005 " " Rewritten for perfromance.
+# 15-Jul-2005 " " Improved DTIME calculation.
+# 25-Jul-2005 " " Added -p, -n. Improved code.
+# 17-Sep-2005 " " Increased switchrate.
+# 17-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_dump=0; opt_device=0; opt_delta=0; opt_devname=0; opt_file=0; opt_args=0;
+opt_mount=0; opt_start=0 opt_end=0; opt_endstr=0; opt_ins=0; opt_nums=0
+opt_dtime=0; filter=0; device=.; filename=.; mount=.; pname=.; pid=0
+opt_name=0; opt_pid=0
+
+### process options
+while getopts aAd:Def:ghim:Nn:op:stv name
+do
+ case $name in
+ a) opt_devname=1; opt_args=1; opt_endstr=1; opt_nums=1 ;;
+ A) opt_dump=1 ;;
+ d) opt_device=1; device=$OPTARG ;;
+ D) opt_delta=1 ;;
+ e) opt_devname=1 ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ g) opt_args=1 ;;
+ i) opt_ins=1 ;;
+ N) opt_nums=1 ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ o) opt_dtime=1 ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ s) opt_start=1 ;;
+ t) opt_end=1 ;;
+ v) opt_endstr=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: iosnoop [-a|-A|-DeghiNostv] [-d device] [-f filename]
+ [-m mount_point] [-n name] [-p PID]
+ iosnoop # default output
+ -a # print all data (mostly)
+ -A # dump all data, space delimited
+ -D # print time delta, us (elapsed)
+ -e # print device name
+ -g # print command arguments
+ -i # print device instance
+ -N # print major and minor numbers
+ -o # print disk delta time, us
+ -s # print start time, us
+ -t # print completion time, us
+ -v # print completion time, string
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ -n name # this process name only
+ -p PID # this PID only
+ eg,
+ iosnoop -v # human readable timestamps
+ iosnoop -N # print major and minor numbers
+ iosnoop -m / # snoop events on filesystem / only
+ END
+ exit 1
+ esac
+done
+
+### option logic
+if [ $opt_dump -eq 1 ]; then
+ opt_delta=0; opt_devname=0; opt_args=2; opt_start=0;
+ opt_end=0; opt_endstr=0; opt_nums=0; opt_ins=0; opt_dtime=0
+fi
+if [ $opt_device -eq 1 -o $opt_file -eq 1 -o $opt_mount -eq 1 -o \
+ $opt_name -eq 1 -o $opt_pid -eq 1 ]; then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_dump = '$opt_dump';
+ inline int OPT_device = '$opt_device';
+ inline int OPT_delta = '$opt_delta';
+ inline int OPT_devname = '$opt_devname';
+ inline int OPT_file = '$opt_file';
+ inline int OPT_args = '$opt_args';
+ inline int OPT_ins = '$opt_ins';
+ inline int OPT_nums = '$opt_nums';
+ inline int OPT_dtime = '$opt_dtime';
+ inline int OPT_mount = '$opt_mount';
+ inline int OPT_start = '$opt_start';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_end = '$opt_end';
+ inline int OPT_endstr = '$opt_endstr';
+ inline int FILTER = '$filter';
+ inline int PID = '$pid';
+ inline string DEVICE = "'$device'";
+ inline string FILENAME = "'$filename'";
+ inline string MOUNT = "'$mount'";
+ inline string NAME = "'$pname'";
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ last_event[""] = 0;
+
+ /* print optional headers */
+ OPT_start ? printf("%-14s ","STIME") : 1;
+ OPT_end ? printf("%-14s ","TIME") : 1;
+ OPT_endstr ? printf("%-20s ","STRTIME") : 1;
+ OPT_devname ? printf("%-7s ","DEVICE") : 1;
+ OPT_ins ? printf("%-3s ","INS") : 1;
+ OPT_nums ? printf("%-3s %-3s ","MAJ","MIN") : 1;
+ OPT_delta ? printf("%-10s ","DELTA") : 1;
+ OPT_dtime ? printf("%-10s ","DTIME") : 1;
+
+ /* print main headers */
+ OPT_dump ?
+ printf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
+ "TIME", "STIME", "DELTA", "DEVICE", "INS", "MAJ", "MIN", "UID",
+ "PID", "PPID", "D", "BLOCK", "SIZE", "MOUNT", "FILE", "PATH",
+ "COMM","ARGS") :
+ printf("%5s %5s %1s %8s %6s ", "UID", "PID", "D", "BLOCK", "SIZE");
+ OPT_args == 0 ? printf("%10s %s\n", "COMM", "PATHNAME") : 1;
+ OPT_args == 1 ? printf("%28s %s\n", "PATHNAME", "ARGS") : 1;
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::start
+ {
+ /* default is to trace unless filtering, */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? self->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? self->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? self->ok = 1 : 1;
+ (OPT_name == 1 && NAME == execname) ? self->ok = 1 : 1;
+ (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1;
+ }
+
+ /*
+ * Reset last_event for disk idle -> start
+ * this prevents idle time being counted as disk time.
+ */
+ io:genunix::start
+ /! pending[args[1]->dev_statname]/
+ {
+ /* save last disk event */
+ last_event[args[1]->dev_statname] = timestamp;
+ }
+
+ /*
+ * Store entry details
+ */
+ io:genunix::start
+ /self->ok/
+ {
+ /* these are used as a unique disk event key, */
+ this->dev = args[0]->b_edev;
+ this->blk = args[0]->b_blkno;
+
+ /* save disk event details, */
+ start_uid[this->dev, this->blk] = uid;
+ start_pid[this->dev, this->blk] = pid;
+ start_ppid[this->dev, this->blk] = ppid;
+ start_args[this->dev, this->blk] = (char *)curpsinfo->pr_psargs;
+ start_comm[this->dev, this->blk] = execname;
+ start_time[this->dev, this->blk] = timestamp;
+
+ /* increase disk event pending count */
+ pending[args[1]->dev_statname]++;
+
+ self->ok = 0;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /start_time[args[0]->b_edev, args[0]->b_blkno]/
+ {
+ /* decrease disk event pending count */
+ pending[args[1]->dev_statname]--;
+
+ /*
+ * Process details
+ */
+
+ /* fetch entry values */
+ this->dev = args[0]->b_edev;
+ this->blk = args[0]->b_blkno;
+ this->suid = start_uid[this->dev, this->blk];
+ this->spid = start_pid[this->dev, this->blk];
+ this->sppid = start_ppid[this->dev, this->blk];
+ self->sargs = (int)start_args[this->dev, this->blk] == 0 ?
+ "" : start_args[this->dev, this->blk];
+ self->scomm = start_comm[this->dev, this->blk];
+ this->stime = start_time[this->dev, this->blk];
+ this->etime = timestamp; /* endtime */
+ this->delta = this->etime - this->stime;
+ this->dtime = last_event[args[1]->dev_statname] == 0 ? 0 :
+ timestamp - last_event[args[1]->dev_statname];
+
+ /* memory cleanup */
+ start_uid[this->dev, this->blk] = 0;
+ start_pid[this->dev, this->blk] = 0;
+ start_ppid[this->dev, this->blk] = 0;
+ start_args[this->dev, this->blk] = 0;
+ start_time[this->dev, this->blk] = 0;
+ start_comm[this->dev, this->blk] = 0;
+ start_rw[this->dev, this->blk] = 0;
+
+ /*
+ * Print details
+ */
+
+ /* print optional fields */
+ OPT_start ? printf("%-14d ", this->stime/1000) : 1;
+ OPT_end ? printf("%-14d ", this->etime/1000) : 1;
+ OPT_endstr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_devname ? printf("%-7s ", args[1]->dev_statname) : 1;
+ OPT_ins ? printf("%3d ", args[1]->dev_instance) : 1;
+ OPT_nums ? printf("%3d %3d ",
+ args[1]->dev_major, args[1]->dev_minor) : 1;
+ OPT_delta ? printf("%-10d ", this->delta/1000) : 1;
+ OPT_dtime ? printf("%-10d ", this->dtime/1000) : 1;
+
+ /* print main fields */
+ OPT_dump ?
+ printf("%d %d %d %s %d %d %d %d %d %d %s %d %d %s %s %s %s %S\n",
+ this->etime/1000, this->stime/1000, this->delta/1000,
+ args[1]->dev_statname, args[1]->dev_instance, args[1]->dev_major,
+ args[1]->dev_minor, this->suid, this->spid, this->sppid,
+ args[0]->b_flags & B_READ ? "R" : "W",
+ args[0]->b_blkno, args[0]->b_bcount, args[2]->fi_mount,
+ args[2]->fi_name, args[2]->fi_pathname, self->scomm, self->sargs) :
+ printf("%5d %5d %1s %8d %6d ",
+ this->suid, this->spid, args[0]->b_flags & B_READ ? "R" : "W",
+ args[0]->b_blkno, args[0]->b_bcount);
+ OPT_args == 0 ? printf("%10s %s\n", self->scomm, args[2]->fi_pathname)
+ : 1;
+ OPT_args == 1 ? printf("%28s %S\n",
+ args[2]->fi_pathname, self->sargs) : 1;
+
+ /* save last disk event */
+ last_event[args[1]->dev_statname] = timestamp;
+
+ /* cleanup */
+ self->scomm = 0;
+ self->sargs = 0;
+ }
+
+ /*
+ * Prevent pending from underflowing
+ * this can happen if this program is started during disk events.
+ */
+ io:genunix::done
+ /pending[args[1]->dev_statname] < 0/
+ {
+ pending[args[1]->dev_statname] = 0;
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/iotop b/cddl/contrib/dtracetoolkit/iotop
new file mode 100755
index 0000000..788c492
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/iotop
@@ -0,0 +1,422 @@
+#!/usr/bin/ksh
+#
+# iotop - display top disk I/O events by process.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring disk events that have made it past system caches.
+#
+# $Id: iotop 8 2007-08-06 05:55:26Z brendan $
+#
+# USAGE: iotop [-C] [-D|-o|-P] [-j|-Z] [-d device] [-f filename]
+# [-m mount_point] [-t top] [interval [count]]
+#
+# iotop # default output, 5 second intervals
+#
+# -C # don't clear the screen
+# -D # print delta times, elapsed, us
+# -j # print project ID
+# -o # print disk delta times, us
+# -P # print %I/O (disk delta times)
+# -Z # print zone ID
+# -d device # instance name to snoop (eg, dad0)
+# -f filename # full pathname of file to snoop
+# -m mount_point # this FS only (will skip raw events)
+# -t top # print top number only
+# eg,
+# iotop 1 # 1 second samples
+# iotop -C # don't clear the screen
+# iotop -P # print %I/O (time based)
+# iotop -j # print project IDs
+# iotop -Z # print zone IDs
+# iotop -t 20 # print top 20 lines only
+# iotop -C 5 12 # print 12 x 5 second samples
+#
+# FIELDS:
+# UID user ID
+# PID process ID
+# PPID parent process ID
+# PROJ project ID
+# ZONE zone ID
+# CMD process command name
+# DEVICE device name
+# MAJ device major number
+# MIN device minor number
+# D direction, Read or Write
+# BYTES total size of operations, bytes
+# ELAPSED total elapsed from request to completion, us
+# DISKTIME total time for disk to complete request, us
+# %I/O percent disk I/O, based on time (DISKTIME)
+# load 1 min load average
+# disk_r total disk read Kbytes for sample
+# disk_w total disk write Kbytes for sample
+#
+# NOTE:
+# * There are two different delta times reported. -D prints the
+# elapsed time from the disk request (strategy) to the disk completion
+# (iodone); -o prints the time for the disk to complete that event
+# since it's last event (time between iodones), or, the time to the
+# strategy if the disk had been idle.
+# * The %I/O value can exceed 100%. It represents how busy a process is
+# making the disks, in terms of a single disk. A value of 200% could
+# mean 2 disks are busy at 100%, or 4 disks at 50%...
+#
+# SEE ALSO: iosnoop
+# BigAdmin: DTrace, http://www.sun.com/bigadmin/content/dtrace
+# Solaris Dynamic Tracing Guide, http://docs.sun.com
+# DTrace Tools, http://www.brendangregg.com/dtrace.html
+#
+# INSPIRATION: top(1) by William LeFebvre
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# KNOWN BUGS:
+# - This can print errors while running on servers with Veritas volumes.
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 15-Jul-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_device=0; opt_file=0; opt_mount=0; opt_clear=1; opt_proj=0; opt_zone=0
+opt_percent=0; opt_def=1; opt_bytes=1; filter=0; device=.; filename=.; mount=.
+opt_top=0; opt_elapsed=0; opt_dtime=0; interval=5; count=-1; top=0
+
+### process options
+while getopts CDd:f:hjm:oPt:Z name
+do
+ case $name in
+ C) opt_clear=0 ;;
+ D) opt_elapsed=1; opt_bytes=0 ;;
+ d) opt_device=1; device=$OPTARG ;;
+ f) opt_file=1; filename=$OPTARG ;;
+ j) opt_proj=1; opt_def=0 ;;
+ m) opt_mount=1; mount=$OPTARG ;;
+ o) opt_dtime=1; opt_bytes=0 ;;
+ P) opt_percent=1; opt_dtime=1; opt_bytes=0 ;;
+ t) opt_top=1; top=$OPTARG ;;
+ Z) opt_zone=1; opt_def=0 ;;
+ h|?) cat <<-END >&2
+ USAGE: iotop [-C] [-D|-o|-P] [-j|-Z] [-d device] [-f filename]
+ [-m mount_point] [-t top] [interval [count]]
+
+ -C # don't clear the screen
+ -D # print delta times, elapsed, us
+ -j # print project ID
+ -o # print disk delta times, us
+ -P # print %I/O (disk delta times)
+ -Z # print zone ID
+ -d device # instance name to snoop
+ -f filename # snoop this file only
+ -m mount_point # this FS only
+ -t top # print top number only
+ eg,
+ iotop # default output, 5 second samples
+ iotop 1 # 1 second samples
+ iotop -P # print %I/O (time based)
+ iotop -m / # snoop events on filesystem / only
+ iotop -t 20 # print top 20 lines only
+ iotop -C 5 12 # print 12 x 5 second samples
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_proj && opt_zone )); then
+ opt_proj=0
+fi
+if (( opt_elapsed && opt_dtime )); then
+ opt_elapsed=0
+fi
+if (( opt_device || opt_mount || opt_file )); then
+ filter=1
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_proj = '$opt_proj';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_clear = '$opt_clear';
+ inline int OPT_bytes = '$opt_bytes';
+ inline int OPT_elapsed = '$opt_elapsed';
+ inline int OPT_dtime = '$opt_dtime';
+ inline int OPT_percent = '$opt_percent';
+ inline int OPT_device = '$opt_device';
+ inline int OPT_mount = '$opt_mount';
+ inline int OPT_file = '$opt_file';
+ inline int OPT_top = '$opt_top';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int FILTER = '$filter';
+ inline int TOP = '$top';
+ inline string DEVICE = "'$device'";
+ inline string FILENAME = "'$filename'";
+ inline string MOUNT = "'$mount'";
+ inline string CLEAR = "'$clearstr'";
+
+ #pragma D option quiet
+
+ /* boost the following if you get "dynamic variable drops" */
+ #pragma D option dynvarsize=8m
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ last_event[""] = 0;
+
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ disk_r = 0;
+ disk_w = 0;
+
+ printf("Tracing... Please wait.\n");
+ }
+
+ /*
+ * Check event is being traced
+ */
+ io:genunix::start,
+ io:genunix::done
+ {
+ /* default is to trace unless filtering, */
+ this->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_device == 1 && DEVICE == args[1]->dev_statname)? this->ok = 1 : 1;
+ (OPT_file == 1 && FILENAME == args[2]->fi_pathname) ? this->ok = 1 : 1;
+ (OPT_mount == 1 && MOUNT == args[2]->fi_mount) ? this->ok = 1 : 1;
+ }
+
+ /*
+ * Reset last_event for disk idle -> start
+ * this prevents idle time being counted as disk time.
+ */
+ io:genunix::start
+ /! pending[args[1]->dev_statname]/
+ {
+ /* save last disk event */
+ last_event[args[1]->dev_statname] = timestamp;
+ }
+
+ /*
+ * Store entry details
+ */
+ io:genunix::start
+ /this->ok/
+ {
+ /* these are used as a unique disk event key, */
+ this->dev = args[0]->b_edev;
+ this->blk = args[0]->b_blkno;
+
+ /* save disk event details, */
+ start_uid[this->dev, this->blk] = uid;
+ start_pid[this->dev, this->blk] = pid;
+ start_ppid[this->dev, this->blk] = ppid;
+ start_comm[this->dev, this->blk] = execname;
+ start_time[this->dev, this->blk] = timestamp;
+ start_proj[this->dev, this->blk] = curpsinfo->pr_projid;
+ start_zone[this->dev, this->blk] = curpsinfo->pr_zoneid;
+ start_rw[this->dev, this->blk] = args[0]->b_flags & B_READ ? "R" : "W";
+ disk_r += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
+ disk_w += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
+
+ /* increase disk event pending count */
+ pending[args[1]->dev_statname]++;
+ }
+
+ /*
+ * Process and Print completion
+ */
+ io:genunix::done
+ /this->ok/
+ {
+ /* decrease disk event pending count */
+ pending[args[1]->dev_statname]--;
+
+ /*
+ * Process details
+ */
+
+ /* fetch entry values */
+ this->dev = args[0]->b_edev;
+ this->blk = args[0]->b_blkno;
+ this->suid = start_uid[this->dev, this->blk];
+ this->spid = start_pid[this->dev, this->blk];
+ this->sppid = start_ppid[this->dev, this->blk];
+ this->sproj = start_proj[this->dev, this->blk];
+ this->szone = start_zone[this->dev, this->blk];
+ self->scomm = start_comm[this->dev, this->blk];
+ this->stime = start_time[this->dev, this->blk];
+ this->etime = timestamp; /* endtime */
+ this->elapsed = this->etime - this->stime;
+ self->rw = start_rw[this->dev, this->blk];
+ this->dtime = last_event[args[1]->dev_statname] == 0 ? 0 :
+ timestamp - last_event[args[1]->dev_statname];
+
+ /* memory cleanup */
+ start_uid[this->dev, this->blk] = 0;
+ start_pid[this->dev, this->blk] = 0;
+ start_ppid[this->dev, this->blk] = 0;
+ start_time[this->dev, this->blk] = 0;
+ start_comm[this->dev, this->blk] = 0;
+ start_zone[this->dev, this->blk] = 0;
+ start_proj[this->dev, this->blk] = 0;
+ start_rw[this->dev, this->blk] = 0;
+
+ /*
+ * Choose statistic to track
+ */
+ OPT_bytes ? this->value = args[0]->b_bcount : 1;
+ OPT_elapsed ? this->value = this->elapsed / 1000 : 1;
+ OPT_dtime ? this->value = this->dtime / 1000 : 1;
+
+ /*
+ * Save details
+ */
+ OPT_def ? @out[this->suid, this->spid, this->sppid, self->scomm,
+ args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
+ self->rw] = sum(this->value) : 1;
+ OPT_proj ? @out[this->sproj, this->spid, this->sppid, self->scomm,
+ args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
+ self->rw] = sum(this->value) : 1;
+ OPT_zone ? @out[this->szone, this->spid, this->sppid, self->scomm,
+ args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
+ self->rw] = sum(this->value) : 1;
+
+ /* save last disk event */
+ last_event[args[1]->dev_statname] = timestamp;
+
+ self->scomm = 0;
+ self->rw = 0;
+ }
+
+ /*
+ * Prevent pending from underflowing
+ * this can happen if this program is started during disk events.
+ */
+ io:genunix::done
+ /pending[args[1]->dev_statname] < 0/
+ {
+ pending[args[1]->dev_statname] = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Print Report
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert counters to Kbytes */
+ disk_r /= 1024;
+ disk_w /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, disk_r: %6d KB, disk_w: %6d KB\n\n",
+ walltimestamp, this->load1a, this->load1b, disk_r, disk_w);
+
+ /* print headers */
+ OPT_def ? printf(" UID ") : 1;
+ OPT_proj ? printf(" PROJ ") : 1;
+ OPT_zone ? printf(" ZONE ") : 1;
+ printf("%6s %6s %-16s %-7s %3s %3s %1s",
+ "PID", "PPID", "CMD", "DEVICE", "MAJ", "MIN", "D");
+ OPT_bytes ? printf(" %16s\n", "BYTES") : 1;
+ OPT_elapsed ? printf(" %16s\n", "ELAPSED") : 1;
+ OPT_dtime && ! OPT_percent ? printf(" %16s\n", "DISKTIME") : 1;
+ OPT_dtime && OPT_percent ? printf(" %6s\n", "%I/O") : 1;
+
+ /* truncate to top lines if needed */
+ OPT_top ? trunc(@out, TOP) : 1;
+
+ /* normalise to percentage if needed */
+ OPT_percent ? normalize(@out, INTERVAL * 10000) : 1;
+
+ /* print data */
+ ! OPT_percent ?
+ printa("%5d %6d %6d %-16s %-7s %3d %3d %1s %16@d\n", @out) :
+ printa("%5d %6d %6d %-16s %-7s %3d %3d %1s %6@d\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ disk_r = 0;
+ disk_w = 0;
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Cleanup for Ctrl-C
+ */
+ dtrace:::END
+ {
+ trunc(@out);
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/opensnoop b/cddl/contrib/dtracetoolkit/opensnoop
new file mode 100755
index 0000000..b8fca3e
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/opensnoop
@@ -0,0 +1,244 @@
+#!/bin/sh
+#
+# opensnoop - snoop file opens as they occur.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: opensnoop 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname] [-n name] [-p PID]
+#
+# opensnoop # default output
+#
+# -a # print most data
+# -A # dump all data, space delimited
+# -c # print cwd of process
+# -e # print errno value
+# -g # print command arguments
+# -s # print start time, us
+# -v # print start time, string
+# -x # only print failed opens
+# -Z # print zonename
+# -f pathname # file pathname to snoop
+# -n name # command name to snoop
+# -p PID # process ID to snoop
+# eg,
+# opensnoop -v # human readable timestamps
+# opensnoop -e # see error codes
+# opensnoop -f /etc/passwd # snoop this file only
+#
+# FIELDS:
+# ZONE Zone name
+# UID User ID
+# PID Process ID
+# PPID Parent Process ID
+# FD file descriptor (-1 for error)
+# ERR errno value (see /usr/include/sys/errno.h)
+# CWD print current working directory of process
+# PATH pathname for file open
+# COMM command name for the process
+# ARGS argument listing for the process
+# TIME timestamp for the open event, us
+# STRTIME timestamp for the open event, string
+#
+# SEE ALSO: truss, BSM auditing.
+#
+# COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 09-May-2004 Brendan Gregg Created this.
+# 21-Jan-2005 " " Wrapped in sh to provide options.
+# 08-May-2005 " " Rewritten for performance.
+# 14-May-2005 " " Added errno.
+# 28-Jun-2005 " " Added cwd, zonename.
+# 17-Sep-2005 " " Increased switchrate, fixed page fault bug.
+# 16-Jan-2006 " " Added -n, -p.
+# 16-Jan-2006 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_dump=0; opt_file=0; opt_time=0; opt_timestr=0; opt_args=0
+opt_zone=0; opt_cwd=0; opt_failonly=0; opt_err=0; filter=0; pathname=.
+opt_name=0; opt_pid=0; pname=.; pid=0
+
+### Process options
+while getopts aAcef:ghn:p:svxZ name
+do
+ case $name in
+ a) opt_time=1; opt_timestr=1; opt_args=1; opt_err=1 ;;
+ A) opt_dump=1 ;;
+ c) opt_cwd=1 ;;
+ e) opt_err=1 ;;
+ g) opt_args=1 ;;
+ f) opt_file=1; pathname=$OPTARG ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ s) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ x) opt_failonly=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname]
+ [-n name] [-p PID]
+ opensnoop # default output
+ -a # print most data
+ -A # dump all data, space delimited
+ -c # print cwd of process
+ -e # print errno value
+ -g # print command arguments
+ -s # print start time, us
+ -v # print start time, string
+ -x # only print failed opens
+ -Z # print zonename
+ -f pathname # pathname name to snoop
+ -n name # process name to snoop
+ -p PID # process ID to snoop
+ eg,
+ opensnoop -v # human readable timestamps
+ opensnoop -e # see error codes
+ opensnoop -f /etc/motd # snoop this file only
+ END
+ exit 1
+ esac
+done
+
+### Option logic
+if [ $opt_dump -eq 1 ]; then
+ opt_zone=0; opt_cwd=0; opt_time=0; opt_timestr=0; opt_args=2
+fi
+if [ $opt_name -eq 1 -o $opt_pid -eq 1 ]; then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_dump = '$opt_dump';
+ inline int OPT_file = '$opt_file';
+ inline int OPT_args = '$opt_args';
+ inline int OPT_cwd = '$opt_cwd';
+ inline int OPT_err = '$opt_err';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_failonly = '$opt_failonly';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_name = '$opt_name';
+ inline int FILTER = '$filter';
+ inline int PID = '$pid';
+ inline string PATHNAME = "'$pathname'";
+ inline string NAME = "'$pname'";
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /*
+ * ternary operators are used to improve performance.
+ * OPT_args is unusual in that it can have one of three values.
+ */
+
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
+ OPT_zone ? printf("%-10s ", "ZONE") : 1;
+
+ /* print dump headers */
+ OPT_dump ? printf("%s %s %s %s %s %s %s %s %s %s %s", "ZONE",
+ "TIME", "UID", "PID", "PPID", "COMM", "FD", "ERR", "CWD",
+ "PATH", "ARGS") : printf("%5s %6s ","UID","PID");
+
+ /* print main headers */
+ OPT_args == 0 ? printf("%-12s ", "COMM") : 1;
+ OPT_dump == 0 ? printf("%3s ", "FD") : 1;
+ OPT_err ? printf("%3s ", "ERR") : 1;
+ OPT_cwd ? printf("%-20s ", "CWD") : 1;
+ OPT_dump == 0 ? printf("%-20s ", "PATH") : 1;
+ OPT_args == 1 ? printf("%s", "ARGS") : 1;
+ printf("\n");
+ }
+
+ /*
+ * Print open event
+ */
+ syscall::open:entry
+ {
+ /* save pathname */
+ self->pathp = arg0;
+
+ /* default is to trace unless filtering */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter */
+ (OPT_name == 1 && NAME == execname) ? self->ok = 1 : 1;
+ (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1;
+ /* OPT_file is checked on return to ensure pathp is mapped */
+ }
+
+ syscall::open:return
+ /self->ok && (! OPT_failonly || (int)arg0 < 0) &&
+ ((OPT_file == 0) || (OPT_file == 1 && PATHNAME == copyinstr(self->pathp)))/
+ {
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%-10s ", zonename) : 1;
+
+ /* print dump fields */
+ OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename,
+ timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno,
+ cwd, copyinstr(self->pathp), curpsinfo->pr_psargs) :
+ printf("%5d %6d ", uid, pid);
+
+ /* print main fields */
+ OPT_args == 0 ? printf("%-12s ", execname) : 1;
+ OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1;
+ OPT_err ? printf("%3d ", errno) : 1;
+ OPT_cwd ? printf("%-20s ", cwd) : 1;
+ OPT_dump == 0 ? printf("%-20s ", copyinstr(self->pathp)) : 1;
+ OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1;
+ printf("\n");
+
+ /* cleanup */
+ self->pathp = 0;
+ self->ok = 0;
+ }
+
+ /*
+ * Cleanup
+ */
+ syscall::open:return
+ /self->ok/
+ {
+ self->pathp = 0;
+ self->ok = 0;
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/procsystime b/cddl/contrib/dtracetoolkit/procsystime
new file mode 100755
index 0000000..3b4bae7
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/procsystime
@@ -0,0 +1,233 @@
+#!/bin/sh
+#
+# procsystime - print process system call time details.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: procsystime 4 2007-08-01 11:01:38Z brendan $
+#
+# USAGE: procsystime [-acehoT] [ -p PID | -n name | command ]
+#
+# -p PID # examine this PID
+# -n name # examine this process name
+# -a # print all details
+# -c # print syscall counts
+# -e # print elapsed times
+# -o # print CPU times
+# -T # print totals
+# eg,
+# procsystime -p 1871 # examine PID 1871
+# procsystime -n tar # examine processes called "tar"
+# procsystime -aTn bash # print all details for bash shells
+# procsystime df -h # run and examine "df -h"
+#
+# The elapsed times are interesting, to help identify syscalls that take
+# some time to complete (during which the process may have slept). CPU time
+# helps us identify syscalls that are consuming CPU cycles to run.
+#
+# FIELDS:
+# SYSCALL System call name
+# TIME (ns) Total time, nanoseconds
+# COUNT Number of occurrences
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 27-Apr-2005 Brendan Gregg Created this.
+# 08-Jun-2005 " " Added command option.
+# 22-Sep-2005 " " Allowed systemwide tracing.
+# 22-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_filter=0; opt_pid=0; opt_name=0; pid=0; pname=".";
+opt_elapsed=0; opt_cpu=0; opt_counts=0; opt_totals=0
+opt_command=0; command="";
+
+### Process options
+while getopts acehn:op:T name
+do
+ case $name in
+ p) opt_filter=1; opt_pid=1; pid=$OPTARG ;;
+ n) opt_filter=1; opt_name=1; pname=$OPTARG ;;
+ a) opt_totals=1; opt_elapsed=1; opt_cpu=1; opt_counts=1 ;;
+ e) opt_elapsed=1 ;;
+ c) opt_counts=1 ;;
+ o) opt_cpu=1 ;;
+ T) opt_totals=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: procsystime [-aceho] [ -p PID | -n name | command ]
+ -p PID # examine this PID
+ -n name # examine this process name
+ -a # print all details
+ -e # print elapsed times
+ -c # print syscall counts
+ -o # print CPU times
+ -T # print totals
+ eg,
+ procsystime -p 1871 # examine PID 1871
+ procsystime -n tar # examine processes called "tar"
+ procsystime -aTn bash # print all details for bash
+ procsystime df -h # run and examine "df -h"
+ END
+ exit 1
+ esac
+done
+shift `expr $OPTIND - 1`
+
+### Option logic
+if [ $opt_pid -eq 0 -a $opt_name -eq 0 -a "$*" != "" ]; then
+ opt_filter=1
+ opt_command=1
+ command="$*"
+fi
+if [ $opt_elapsed -eq 0 -a $opt_cpu -eq 0 -a $opt_counts -eq 0 ]; then
+ opt_elapsed=1;
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+dtrace='
+ #pragma D option quiet
+
+ /*
+ * Command line arguments
+ */
+ inline int OPT_elapsed = '$opt_elapsed';
+ inline int OPT_cpu = '$opt_cpu';
+ inline int OPT_counts = '$opt_counts';
+ inline int OPT_filter = '$opt_filter';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_totals = '$opt_totals';
+ inline int OPT_command = '$opt_command';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+ inline string COMMAND = "'$command'";
+
+ dtrace:::BEGIN
+ {
+ self->start = 0;
+ self->vstart = 0;
+ }
+ dtrace:::BEGIN
+ /! OPT_command/
+ {
+ printf("Tracing... Hit Ctrl-C to end...\n");
+ }
+
+ /*
+ * Set start timestamp and counts
+ */
+ syscall:::entry
+ /(! OPT_filter) ||
+ (OPT_pid && pid == PID) ||
+ (OPT_name && execname == NAME) ||
+ (OPT_command && pid == $target)/
+ {
+ self->ok = 1;
+ }
+ syscall:::entry
+ /self->ok/
+ {
+ OPT_counts ? @Counts[probefunc] = count() : 1;
+ (OPT_counts && OPT_totals) ? @Counts["TOTAL:"] = count() : 1;
+ OPT_elapsed ? self->start = timestamp : 1;
+ OPT_cpu ? self->vstart = vtimestamp : 1;
+ self->ok = 0;
+ }
+
+ /*
+ * Calculate time deltas
+ */
+ syscall:::return
+ /self->start/
+ {
+ this->elapsed = timestamp - self->start;
+ @Elapsed[probefunc] = sum(this->elapsed);
+ OPT_totals ? @Elapsed["TOTAL:"] = sum(this->elapsed) : 1;
+ self->start = 0;
+ }
+ syscall:::return
+ /self->vstart/
+ {
+ this->cpu = vtimestamp - self->vstart;
+ @CPU[probefunc] = sum(this->cpu);
+ OPT_totals ? @CPU["TOTAL:"] = sum(this->cpu) : 1;
+ self->vstart = 0;
+ }
+
+ /*
+ * Elapsed time report
+ */
+ dtrace:::END
+ /OPT_elapsed/
+ {
+ printf("\nElapsed Times for ");
+ OPT_pid ? printf("PID %d,\n\n",PID) : 1;
+ OPT_name ? printf("processes %s,\n\n",NAME) : 1;
+ OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
+ (! OPT_filter) ? printf("all processes,\n\n") : 1;
+ printf("%16s %18s\n","SYSCALL","TIME (ns)");
+ printa("%16s %@18d\n",@Elapsed);
+ }
+
+ /*
+ * CPU time report
+ */
+ dtrace:::END
+ /OPT_cpu/
+ {
+ printf("\nCPU Times for ");
+ OPT_pid ? printf("PID %d,\n\n",PID) : 1;
+ OPT_name ? printf("processes %s,\n\n",NAME) : 1;
+ OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
+ (! OPT_filter) ? printf("all processes,\n\n") : 1;
+ printf("%16s %18s\n","SYSCALL","TIME (ns)");
+ printa("%16s %@18d\n",@CPU);
+ }
+
+ /*
+ * Syscall count report
+ */
+ dtrace:::END
+ /OPT_counts/
+ {
+ printf("\nSyscall Counts for ");
+ OPT_pid ? printf("PID %d,\n\n",PID) : 1;
+ OPT_name ? printf("processes %s,\n\n",NAME) : 1;
+ OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
+ (! OPT_filter) ? printf("all processes,\n\n") : 1;
+ printf("%16s %18s\n","SYSCALL","COUNT");
+ OPT_counts ? printa("%16s %@18d\n",@Counts) : 1;
+ }
+'
+
+### Run DTrace
+if [ $opt_command -eq 1 ]; then
+ /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2
+else
+ /usr/sbin/dtrace -n "$dtrace" >&2
+fi
+
diff --git a/cddl/contrib/dtracetoolkit/rwsnoop b/cddl/contrib/dtracetoolkit/rwsnoop
new file mode 100755
index 0000000..9d49324
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/rwsnoop
@@ -0,0 +1,234 @@
+#!/usr/bin/ksh
+#
+# rwsnoop - snoop read/write events.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring reads and writes at the application level. This matches
+# the syscalls read, write, pread and pwrite.
+#
+# $Id: rwsnoop 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: rwsnoop [-jPtvZ] [-n name] [-p pid]
+#
+# rwsnoop # default output
+#
+# -j # print project ID
+# -P # print parent process ID
+# -t # print timestamp, us
+# -v # print time, string
+# -Z # print zone ID
+# -n name # this process name only
+# -p PID # this PID only
+# eg,
+# rwsnoop -Z # print zone ID
+# rwsnoop -n bash # monitor processes named "bash"
+# rwsnoop > out.txt # recommended
+#
+# NOTE:
+# rwsnoop usually prints plenty of output, which itself will cause
+# more output. It can be better to redirect the output of rwsnoop
+# to a file to prevent this.
+#
+# FIELDS:
+# TIME Timestamp, us
+# TIMESTR Time, string
+# ZONE Zone ID
+# PROJ Project ID
+# UID User ID
+# PID Process ID
+# PPID Parent Process ID
+# CMD Process name
+# D Direction, Read or Write
+# BYTES Total bytes during sample, -1 for error
+# FILE Filename, if file based
+#
+# Reads and writes that are not file based, for example with sockets, will
+# print "<unknown>" as the filename.
+#
+# SEE ALSO: rwtop
+#
+# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# TODO:
+# Track readv and writev.
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 24-Jul-2005 Brendan Gregg Created this.
+# 17-Sep-2005 " " Increased switchrate.
+# 17-Sep-2005 " " Last update.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_name=0; opt_pid=0; opt_proj=0; opt_zone=0; opt_time=0; opt_timestr=0
+opt_bytes=1; filter=0; pname=.; pid=0; opt_ppid=0
+
+### process options
+while getopts n:Pp:jtvZ name
+do
+ case $name in
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ P) opt_ppid=1 ;;
+ j) opt_proj=1 ;;
+ t) opt_time=1 ;;
+ v) opt_timestr=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: rwsnoop [-jPtvZ] [-n name] [-p pid]
+
+ -j # print project ID
+ -P # print parent process ID
+ -t # print timestamp, us
+ -v # print time, string
+ -Z # print zone ID
+ -n name # this process name only
+ -p PID # this PID only
+ eg,
+ rwsnoop # default output
+ rwsnoop -Z # print zone ID
+ rwsnoop -n bash # monitor processes named "bash"
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if (( opt_name || opt_pid )); then
+ filter=1
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_proj = '$opt_proj';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_bytes = '$opt_bytes';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_ppid = '$opt_ppid';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int FILTER = '$filter';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* print header */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "TIMESTR") : 1;
+ OPT_proj ? printf("%5s ", "PROJ") : 1;
+ OPT_zone ? printf("%5s ", "ZONE") : 1;
+ OPT_ppid ? printf("%6s ", "PPID") : 1;
+ printf("%5s %6s %-12s %1s %7s %s\n",
+ "UID", "PID", "CMD", "D", "BYTES", "FILE");
+ }
+
+ /*
+ * Check event is being traced
+ */
+ syscall::*read:entry,
+ syscall::*write:entry
+ /pid != $pid/
+ {
+ /* default is to trace unless filtering, */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_name == 1 && NAME == execname)? self->ok = 1 : 1;
+ (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1;
+
+ /* save file descriptor */
+ self->fd = self->ok ? arg0 : 0;
+ }
+
+ /*
+ * Save read details
+ */
+ syscall::*read:return
+ /self->ok/
+ {
+ self->rw = "R";
+ self->size = arg0;
+ }
+
+ /*
+ * Save write details
+ */
+ syscall::*write:entry
+ /self->ok/
+ {
+ self->rw = "W";
+ self->size = arg2;
+ }
+
+ /*
+ * Process event
+ */
+ syscall::*read:return,
+ syscall::*write:entry
+ /self->ok/
+ {
+ /*
+ * Fetch filename
+ */
+ this->filistp = curthread->t_procp->p_user.u_finfo.fi_list;
+ this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp +
+ (uint64_t)self->fd * (uint64_t)sizeof(uf_entry_t));
+ this->filep = this->ufentryp->uf_file;
+ this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
+ self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+
+ /*
+ * Print details
+ */
+ OPT_time ? printf("%-14d ", timestamp / 1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_proj ? printf("%5d ", curpsinfo->pr_projid) : 1;
+ OPT_zone ? printf("%5d ", curpsinfo->pr_zoneid) : 1;
+ OPT_ppid ? printf("%6d ", ppid) : 1;
+ printf("%5d %6d %-12.12s %1s %7d %s\n",
+ uid, pid, execname, self->rw, (int)self->size, self->vpath);
+
+ self->ok = 0;
+ self->fd = 0;
+ self->rw = 0;
+ self->size = 0;
+ self->vpath = 0;
+ }
+'
diff --git a/cddl/contrib/dtracetoolkit/rwtop b/cddl/contrib/dtracetoolkit/rwtop
new file mode 100755
index 0000000..ed0a6fa
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/rwtop
@@ -0,0 +1,292 @@
+#!/usr/bin/ksh
+#
+# rwtop - display top read/write bytes by process.
+# Written using DTrace (Solaris 10 3/05).
+#
+# This is measuring reads and writes at the application level. This matches
+# read and write system calls.
+#
+# $Id: rwtop 3 2007-08-01 10:50:08Z brendan $
+#
+# USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid]
+# [-t top] [interval [count]]
+#
+# rwtop # default output, 5 second samples
+#
+# -C # don't clear the screen
+# -c # print counts
+# -j # print project ID
+# -Z # print zone ID
+# -n name # this process name only
+# -p PID # this PID only
+# -t top # print top number only
+# eg,
+# rwtop 1 # 1 second samples
+# rwtop -t 10 # print top 10 only
+# rwtop -n bash # monitor processes named "bash"
+# rwtop -C 5 12 # print 12 x 5 second samples
+#
+# FIELDS:
+# ZONE Zone ID
+# PROJ Project ID
+# UID User ID
+# PID Process ID
+# PPID Parent Process ID
+# CMD Process name
+# D Direction, Read or Write
+# BYTES Total bytes during sample
+# app_r total reads during sample, Kbytes
+# app_w total writes during sample, Kbytes
+#
+# SEE ALSO: iotop
+#
+# INSPIRATION: top(1) by William LeFebvre
+#
+# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 24-Jul-2005 Brendan Gregg Created this.
+# 20-Apr-2006 " " Last update.
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### default variables
+opt_name=0; opt_pid=0; opt_clear=1; opt_proj=0; opt_zone=0
+opt_def=1; opt_bytes=1; filter=0; pname=.; pid=0
+opt_top=0; opt_count=0; interval=5; count=-1; top=0
+
+### process options
+while getopts Cchn:p:jt:Z name
+do
+ case $name in
+ C) opt_clear=0 ;;
+ c) opt_count=1; opt_bytes=0 ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ j) opt_proj=1; opt_def=0 ;;
+ t) opt_top=1; top=$OPTARG ;;
+ Z) opt_zone=1; opt_def=0 ;;
+ h|?) cat <<-END >&2
+ USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid]
+ [-t top] [interval [count]]
+
+ -C # don't clear the screen
+ -c # print counts
+ -j # print project ID
+ -Z # print zone ID
+ -n name # this process name only
+ -p PID # this PID only
+ -t top # print top number only
+ eg,
+ rwtop # default output, 5 second samples
+ rwtop 1 # 1 second samples
+ rwtop -t 10 # print top 10 only
+ rwtop -n bash # monitor processes named "bash"
+ rwtop -C 5 12 # print 12 x 5 second samples
+ END
+ exit 1
+ esac
+done
+
+shift $(( $OPTIND - 1 ))
+
+### option logic
+if [[ "$1" > 0 ]]; then
+ interval=$1; shift
+fi
+if [[ "$1" > 0 ]]; then
+ count=$1; shift
+fi
+if (( opt_proj && opt_zone )); then
+ opt_proj=0
+fi
+if (( opt_name || opt_pid )); then
+ filter=1
+fi
+if (( opt_clear )); then
+ clearstr=`clear`
+else
+ clearstr=.
+fi
+
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_def = '$opt_def';
+ inline int OPT_proj = '$opt_proj';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_clear = '$opt_clear';
+ inline int OPT_bytes = '$opt_bytes';
+ inline int OPT_count = '$opt_count';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_top = '$opt_top';
+ inline int INTERVAL = '$interval';
+ inline int COUNTER = '$count';
+ inline int FILTER = '$filter';
+ inline int TOP = '$top';
+ inline int PID = '$pid';
+ inline string NAME = "'$pname'";
+ inline string CLEAR = "'$clearstr'";
+
+ #pragma D option quiet
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* starting values */
+ counts = COUNTER;
+ secs = INTERVAL;
+ app_r = 0;
+ app_w = 0;
+
+ printf("Tracing... Please wait.\n");
+ }
+
+ /*
+ * Check event is being traced
+ */
+ sysinfo:::readch,
+ sysinfo:::writech
+ /pid != $pid/
+ {
+ /* default is to trace unless filtering, */
+ this->ok = FILTER ? 0 : 1;
+
+ /* check each filter, */
+ (OPT_name == 1 && NAME == execname)? this->ok = 1 : 1;
+ (OPT_pid == 1 && PID == pid) ? this->ok = 1 : 1;
+ }
+
+ /*
+ * Increment tallys
+ */
+ sysinfo:::readch
+ /this->ok/
+ {
+ app_r += arg0;
+ }
+ sysinfo:::writech
+ /this->ok/
+ {
+ app_w += arg0;
+ }
+
+ /*
+ * Process event
+ */
+ sysinfo:::readch,
+ sysinfo:::writech
+ /this->ok/
+ {
+ /* choose statistic to track */
+ this->value = OPT_bytes ? arg0 : 1;
+
+ /*
+ * Save details
+ */
+ OPT_def ? @out[uid, pid, ppid, execname,
+ probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
+ OPT_proj ? @out[curpsinfo->pr_projid, pid, ppid, execname,
+ probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
+ OPT_zone ? @out[curpsinfo->pr_zoneid, pid, ppid, execname,
+ probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
+
+ this->ok = 0;
+ }
+
+ /*
+ * Timer
+ */
+ profile:::tick-1sec
+ {
+ secs--;
+ }
+
+ /*
+ * Print Report
+ */
+ profile:::tick-1sec
+ /secs == 0/
+ {
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert counters to Kbytes */
+ app_r /= 1024;
+ app_w /= 1024;
+
+ /* print status */
+ OPT_clear ? printf("%s", CLEAR) : 1;
+ printf("%Y, load: %d.%02d, app_r: %6d KB, app_w: %6d KB\n\n",
+ walltimestamp, this->load1a, this->load1b, app_r, app_w);
+
+ /* print headers */
+ OPT_def ? printf(" UID ") : 1;
+ OPT_proj ? printf(" PROJ ") : 1;
+ OPT_zone ? printf(" ZONE ") : 1;
+ printf("%6s %6s %-16s %1s",
+ "PID", "PPID", "CMD", "D");
+ OPT_bytes ? printf(" %16s\n", "BYTES") : 1;
+ OPT_count ? printf(" %16s\n", "COUNT") : 1;
+
+ /* truncate to top lines if needed */
+ OPT_top ? trunc(@out, TOP) : 1;
+
+ /* print data */
+ printa("%5d %6d %6d %-16s %1s %16@d\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ app_r = 0;
+ app_w = 0;
+ secs = INTERVAL;
+ counts--;
+ }
+
+ /*
+ * End of program
+ */
+ profile:::tick-1sec
+ /counts == 0/
+ {
+ exit(0);
+ }
+
+ /*
+ * Cleanup for Ctrl-C
+ */
+ dtrace:::END
+ {
+ trunc(@out);
+ }
+'
+
diff --git a/cddl/contrib/dtracetoolkit/statsnoop b/cddl/contrib/dtracetoolkit/statsnoop
new file mode 100755
index 0000000..6284fb5
--- /dev/null
+++ b/cddl/contrib/dtracetoolkit/statsnoop
@@ -0,0 +1,286 @@
+#!/usr/bin/sh
+#
+# statsnoop - snoop file stats as they occur.
+# Written using DTrace (Solaris 10 3/05).
+#
+# $Id: statsnoop 65 2007-10-04 11:09:40Z brendan $
+#
+# USAGE: statsnoop [-a|-A|-ceghlsvxZ] [-f pathname] [-t syscall]
+# [-n name] [-p PID]
+#
+# statsnoop # default output
+#
+# -a # print most data
+# -A # dump all data, space delimited
+# -c # print cwd of process
+# -e # print errno value
+# -g # print command arguments
+# -l # print syscall type
+# -s # print start time, us
+# -v # print start time, string
+# -x # only print failed stats
+# -Z # print zonename
+# -f pathname # file pathname to snoop
+# -n name # command name to snoop
+# -p PID # process ID to snoop
+# -t syscall # stat syscall to trace
+# eg,
+# statsnoop -v # human readable timestamps
+# statsnoop -S # syscall type
+# statsnoop -e # see error codes
+# statsnoop -f /etc/passwd # snoop this file only
+#
+# FIELDS:
+# ZONE Zone name
+# UID User ID
+# PID Process ID
+# PPID Parent Process ID
+# FD file descriptor (-1 for error)
+# ERR errno value (see /usr/include/sys/errno.h)
+# TYPE syscall type
+# CWD current working directory of process
+# PATH pathname for file stat
+# COMM command name for the process
+# ARGS argument listing for the process
+# TIME timestamp for the stat event, us
+# STRTIME timestamp for the stat event, string
+#
+# SEE ALSO: truss, BSM auditing.
+#
+# COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at Docs/cddl1.txt
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# CDDL HEADER END
+#
+# Author: Brendan Gregg [Sydney, Australia]
+#
+# 09-Sep-2007 Brendan Gregg Created this.
+#
+
+
+##############################
+# --- Process Arguments ---
+#
+
+### Default variables
+opt_dump=0; opt_file=0; opt_time=0; opt_timestr=0; opt_args=0
+opt_zone=0; opt_cwd=0; opt_failonly=0; opt_err=0; filter=0; pathname=.
+opt_name=0; opt_pid=0; opt_type=0; opt_trace=0; pname=.; pid=0; trace=.
+
+### Process options
+while getopts aAcef:ghln:p:st:vxZ name
+do
+ case $name in
+ a) opt_time=1; opt_timestr=1; opt_args=1; opt_err=1 ;;
+ A) opt_dump=1 ;;
+ c) opt_cwd=1 ;;
+ e) opt_err=1 ;;
+ g) opt_args=1 ;;
+ f) opt_file=1; pathname=$OPTARG ;;
+ l) opt_type=1 ;;
+ n) opt_name=1; pname=$OPTARG ;;
+ p) opt_pid=1; pid=$OPTARG ;;
+ s) opt_time=1 ;;
+ t) opt_trace=1; trace=$OPTARG ;;
+ v) opt_timestr=1 ;;
+ x) opt_failonly=1 ;;
+ Z) opt_zone=1 ;;
+ h|?) cat <<-END >&2
+ USAGE: statsnoop [-a|-A|-ceghlsvxZ] [-f pathname] [-t syscall]
+ [-n execname] [-p PID]
+ statsnoop # default output
+ -a # print most data
+ -A # dump all data, space delimited
+ -c # print cwd of process
+ -e # print errno value
+ -g # print command arguments
+ -l # print syscall type
+ -s # print start time, us
+ -v # print start time, string
+ -x # only print failed stats
+ -Z # print zonename
+ -f pathname # pathname name to snoop
+ -n name # process name to snoop
+ -p PID # process ID to snoop
+ -t syscall # stat syscall to trace
+ eg,
+ statsnoop -v # human readable timestamps
+ statsnoop -e # see error codes
+ statsnoop -f /etc/motd # snoop this file only
+ END
+ exit 1
+ esac
+done
+
+### Option logic
+if [ $opt_dump -eq 1 ]; then
+ opt_zone=0; opt_cwd=0; opt_time=0; opt_timestr=0; opt_type=0
+ opt_args=2
+fi
+if [ $opt_name -eq 1 -o $opt_pid -eq 1 -o $opt_trace -eq 1 ]; then
+ filter=1
+fi
+
+
+#################################
+# --- Main Program, DTrace ---
+#
+/usr/sbin/dtrace -n '
+ /*
+ * Command line arguments
+ */
+ inline int OPT_dump = '$opt_dump';
+ inline int OPT_file = '$opt_file';
+ inline int OPT_args = '$opt_args';
+ inline int OPT_cwd = '$opt_cwd';
+ inline int OPT_err = '$opt_err';
+ inline int OPT_zone = '$opt_zone';
+ inline int OPT_time = '$opt_time';
+ inline int OPT_timestr = '$opt_timestr';
+ inline int OPT_type = '$opt_type';
+ inline int OPT_failonly = '$opt_failonly';
+ inline int OPT_pid = '$opt_pid';
+ inline int OPT_name = '$opt_name';
+ inline int OPT_trace = '$opt_trace';
+ inline int FILTER = '$filter';
+ inline int PID = '$pid';
+ inline string PATHNAME = "'$pathname'";
+ inline string NAME = "'$pname'";
+ inline string TRACE = "'$trace'";
+
+ #pragma D option quiet
+ #pragma D option switchrate=10hz
+
+ /*
+ * Print header
+ */
+ dtrace:::BEGIN
+ {
+ /* print optional headers */
+ OPT_time ? printf("%-14s ", "TIME") : 1;
+ OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
+ OPT_zone ? printf("%-10s ", "ZONE") : 1;
+
+ /* print dump headers */
+ OPT_dump ? printf("%s %s %s %s %s %s %s %s %s %s %s", "ZONE",
+ "TIME", "UID", "PID", "PPID", "COMM", "FD", "ERR", "CWD",
+ "PATH", "ARGS") : printf("%5s %6s ","UID","PID");
+
+ /* print main headers */
+ OPT_args == 0 ? printf("%-12s ", "COMM") : 1;
+ OPT_dump == 0 ? printf("%3s ", "FD") : 1;
+ OPT_err ? printf("%3s ", "ERR") : 1;
+ OPT_cwd ? printf("%-20s ", "CWD") : 1;
+ OPT_type ? printf("%-8s ", "TYPE") : 1;
+ OPT_dump == 0 ? printf("%-20s ", "PATH") : 1;
+ OPT_args == 1 ? printf("%s", "ARGS") : 1;
+ printf("\n");
+ }
+
+ /*
+ * Print stat event
+ */
+ syscall::stat:entry, syscall::stat64:entry, syscall::xstat:entry,
+ syscall::lstat:entry, syscall::lstat64:entry, syscall::lxstat:entry,
+ syscall::fstat:entry, syscall::fstat64:entry, syscall::fxstat:entry
+ {
+ /* default is to trace unless filtering */
+ self->ok = FILTER ? 0 : 1;
+
+ /* check each filter */
+ (OPT_name == 1 && NAME == execname) ? self->ok = 1 : 1;
+ (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1;
+ (OPT_trace == 1 && TRACE == probefunc) ? self->ok = 1 : 1;
+ }
+
+ syscall::stat:entry, syscall::stat64:entry,
+ syscall::lstat:entry, syscall::lstat64:entry, syscall::lxstat:entry
+ /self->ok/
+ {
+ self->pathp = arg0;
+ }
+
+ syscall::xstat:entry
+ /self->ok/
+ {
+ self->pathp = arg1;
+ }
+
+ syscall::stat:return, syscall::stat64:return, syscall::xstat:return,
+ syscall::lstat:return, syscall::lstat64:return, syscall::lxstat:return
+ /self->ok/
+ {
+ self->path = copyinstr(self->pathp);
+ self->pathp = 0;
+ }
+
+ syscall::fstat:return, syscall::fstat64:entry, syscall::fxstat:entry
+ /self->ok/
+ {
+ self->filep = curthread->t_procp->p_user.u_finfo.fi_list[arg0].uf_file;
+ }
+
+ syscall::fstat:return, syscall::fstat64:return, syscall::fxstat:return
+ /self->ok/
+ {
+ this->vnodep = self->filep != 0 ? self->filep->f_vnode : 0;
+ self->path = this->vnodep ? (this->vnodep->v_path != 0 ?
+ cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
+ self->filep = 0;
+ }
+
+ syscall::stat:return, syscall::stat64:return, syscall::xstat:return,
+ syscall::lstat:return, syscall::lstat64:return, syscall::lxstat:return,
+ syscall::fstat:return, syscall::fstat64:return, syscall::fxstat:return
+ /self->ok && (! OPT_failonly || (int)arg0 < 0) &&
+ ((OPT_file == 0) || (OPT_file == 1 && PATHNAME == copyinstr(self->pathp)))/
+ {
+ /* print optional fields */
+ OPT_time ? printf("%-14d ", timestamp/1000) : 1;
+ OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
+ OPT_zone ? printf("%-10s ", zonename) : 1;
+
+ /* print dump fields */
+ OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename,
+ timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno,
+ cwd, self->path, curpsinfo->pr_psargs) :
+ printf("%5d %6d ", uid, pid);
+
+ /* print main fields */
+ OPT_args == 0 ? printf("%-12.12s ", execname) : 1;
+ OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1;
+ OPT_err ? printf("%3d ", errno) : 1;
+ OPT_cwd ? printf("%-20s ", cwd) : 1;
+ OPT_type ? printf("%-8s ", probefunc) : 1;
+ OPT_dump == 0 ? printf("%-20s ", self->path) : 1;
+ OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1;
+ printf("\n");
+
+ /* cleanup */
+ self->path = 0;
+ self->ok = 0;
+ }
+
+ /*
+ * Cleanup
+ */
+ syscall::stat:return, syscall::stat64:return, syscall::xstat:return,
+ syscall::lstat:return, syscall::lstat64:return, syscall::lxstat:return,
+ syscall::fstat:return, syscall::fstat64:return, syscall::fxstat:return
+ /self->ok/
+ {
+ self->path = 0;
+ self->ok = 0;
+ }
+'
diff --git a/cddl/contrib/opensolaris/OPENSOLARIS.LICENSE b/cddl/contrib/opensolaris/OPENSOLARIS.LICENSE
new file mode 100644
index 0000000..da23621
--- /dev/null
+++ b/cddl/contrib/opensolaris/OPENSOLARIS.LICENSE
@@ -0,0 +1,384 @@
+Unless otherwise noted, all files in this distribution are released
+under the Common Development and Distribution License (CDDL).
+Exceptions are noted within the associated source files.
+
+--------------------------------------------------------------------
+
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
+
+1. Definitions.
+
+ 1.1. "Contributor" means each individual or entity that creates
+ or contributes to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Software, prior Modifications used by a Contributor (if any),
+ and the Modifications made by that particular Contributor.
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b)
+ Modifications, or (c) the combination of files containing
+ Original Software with files containing Modifications, in
+ each case including portions thereof.
+
+ 1.4. "Executable" means the Covered Software in any form other
+ than Source Code.
+
+ 1.5. "Initial Developer" means the individual or entity that first
+ makes Original Software available under this License.
+
+ 1.6. "Larger Work" means a work which combines Covered Software or
+ portions thereof with code not governed by the terms of this
+ License.
+
+ 1.7. "License" means this document.
+
+ 1.8. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed
+ herein.
+
+ 1.9. "Modifications" means the Source Code and Executable form of
+ any of the following:
+
+ A. Any file that results from an addition to, deletion from or
+ modification of the contents of a file containing Original
+ Software or previous Modifications;
+
+ B. Any new file that contains any part of the Original
+ Software or previous Modifications; or
+
+ C. Any new file that is contributed or otherwise made
+ available under the terms of this License.
+
+ 1.10. "Original Software" means the Source Code and Executable
+ form of computer software code that is originally released
+ under this License.
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by
+ grantor.
+
+ 1.12. "Source Code" means (a) the common form of computer software
+ code in which modifications are made and (b) associated
+ documentation included in or with such code.
+
+ 1.13. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms
+ of, this License. For legal entities, "You" includes any
+ entity which controls, is controlled by, or is under common
+ control with You. For purposes of this definition,
+ "control" means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty
+ percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, the Initial
+ Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer, to use,
+ reproduce, modify, display, perform, sublicense and
+ distribute the Original Software (or portions thereof),
+ with or without Modifications, and/or as part of a Larger
+ Work; and
+
+ (b) under Patent Claims infringed by the making, using or
+ selling of Original Software, to make, have made, use,
+ practice, sell, and offer for sale, and/or otherwise
+ dispose of the Original Software (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ or otherwise makes the Original Software available to a
+ third party under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: (1) for code that You delete from the Original
+ Software, or (2) for infringements caused by: (i) the
+ modification of the Original Software, or (ii) the
+ combination of the Original Software with other software
+ or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, each
+ Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor to use, reproduce,
+ modify, display, perform, sublicense and distribute the
+ Modifications created by such Contributor (or portions
+ thereof), either on an unmodified basis, with other
+ Modifications, as Covered Software and/or as part of a
+ Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either
+ alone and/or in combination with its Contributor Version
+ (or portions of such combination), to make, use, sell,
+ offer for sale, have made, and/or otherwise dispose of:
+ (1) Modifications made by that Contributor (or portions
+ thereof); and (2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions
+ of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first distributes or
+ otherwise makes the Modifications available to a third
+ party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: (1) for any code that Contributor has deleted
+ from the Contributor Version; (2) for infringements caused
+ by: (i) third party modifications of Contributor Version,
+ or (ii) the combination of Modifications made by that
+ Contributor with other software (except as part of the
+ Contributor Version) or other devices; or (3) under Patent
+ Claims infringed by Covered Software in the absence of
+ Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make
+ available in Executable form must also be made available in Source
+ Code form and that Source Code form must be distributed only under
+ the terms of this License. You must include a copy of this
+ License with every copy of the Source Code form of the Covered
+ Software You distribute or otherwise make available. You must
+ inform recipients of any such Covered Software in Executable form
+ as to how they can obtain such Covered Software in Source Code
+ form in a reasonable manner on or through a medium customarily
+ used for software exchange.
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are
+ governed by the terms of this License. You represent that You
+ believe Your Modifications are Your original creation(s) and/or
+ You have sufficient rights to grant the rights conveyed by this
+ License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that
+ identifies You as the Contributor of the Modification. You may
+ not remove or alter any copyright, patent or trademark notices
+ contained within the Covered Software, or any notices of licensing
+ or any descriptive text giving attribution to any Contributor or
+ the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in
+ Source Code form that alters or restricts the applicable version
+ of this License or the recipients' rights hereunder. You may
+ choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of
+ Covered Software. However, you may do so only on Your own behalf,
+ and not on behalf of the Initial Developer or any Contributor.
+ You must make it absolutely clear that any such warranty, support,
+ indemnity or liability obligation is offered by You alone, and You
+ hereby agree to indemnify the Initial Developer and every
+ Contributor for any liability incurred by the Initial Developer or
+ such Contributor as a result of warranty, support, indemnity or
+ liability terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software
+ under the terms of this License or under the terms of a license of
+ Your choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License
+ and that the license for the Executable form does not attempt to
+ limit or alter the recipient's rights in the Source Code form from
+ the rights set forth in this License. If You distribute the
+ Covered Software in Executable form under a different license, You
+ must make it absolutely clear that any terms which differ from
+ this License are offered by You alone, not by the Initial
+ Developer or Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred
+ by the Initial Developer or such Contributor as a result of any
+ such terms You offer.
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with
+ other code not governed by the terms of this License and
+ distribute the Larger Work as a single product. In such a case,
+ You must make sure the requirements of this License are fulfilled
+ for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Sun Microsystems, Inc. is the initial license steward and may
+ publish revised and/or new versions of this License from time to
+ time. Each version will be given a distinguishing version number.
+ Except as provided in Section 4.3, no one other than the license
+ steward has the right to modify this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the
+ Covered Software available under the terms of the version of the
+ License under which You originally received the Covered Software.
+ If the Initial Developer includes a notice in the Original
+ Software prohibiting it from being distributed or otherwise made
+ available under any subsequent version of the License, You must
+ distribute and make the Covered Software available under the terms
+ of the version of the License under which You originally received
+ the Covered Software. Otherwise, You may also choose to use,
+ distribute or otherwise make the Covered Software available under
+ the terms of any subsequent version of the License published by
+ the license steward.
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new
+ license for Your Original Software, You may create and use a
+ modified version of this License if You: (a) rename the license
+ and remove any references to the name of the license steward
+ (except to note that the license differs from this License); and
+ (b) otherwise make it clear that the license contains terms which
+ differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+ SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+ PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+ COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+ WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+ DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to
+ cure such breach within 30 days of becoming aware of the breach.
+ Provisions which, by their nature, must remain in effect beyond
+ the termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding
+ declaratory judgment actions) against Initial Developer or a
+ Contributor (the Initial Developer or Contributor against whom You
+ assert such claim is referred to as "Participant") alleging that
+ the Participant Software (meaning the Contributor Version where
+ the Participant is a Contributor or the Original Software where
+ the Participant is the Initial Developer) directly or indirectly
+ infringes any patent, then any and all rights granted directly or
+ indirectly to You by such Participant, the Initial Developer (if
+ the Initial Developer is not the Participant) and all Contributors
+ under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
+ notice from Participant terminate prospectively and automatically
+ at the expiration of such 60 day notice period, unless if within
+ such 60 day period You withdraw Your claim with respect to the
+ Participant Software against such Participant either unilaterally
+ or pursuant to a written agreement with Participant.
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2 above,
+ all end user licenses that have been validly granted by You or any
+ distributor hereunder prior to termination (excluding licenses
+ granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+ LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+ INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+ NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+ APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is
+ defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
+ computer software" (as that term is defined at 48
+ C.F.R. 252.227-7014(a)(1)) and "commercial computer software
+ documentation" as such terms are used in 48 C.F.R. 12.212
+ (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+ C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Software with only those
+ rights set forth herein. This U.S. Government Rights clause is in
+ lieu of, and supersedes, any other FAR, DFAR, or other clause or
+ provision that addresses Government rights in computer software
+ under this License.
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed
+ by the law of the jurisdiction specified in a notice contained
+ within the Original Software (except to the extent applicable law,
+ if any, provides otherwise), excluding such jurisdiction's
+ conflict-of-law provisions. Any litigation relating to this
+ License shall be subject to the jurisdiction of the courts located
+ in the jurisdiction and venue specified in a notice contained
+ within the Original Software, with the losing party responsible
+ for costs, including, without limitation, court costs and
+ reasonable attorneys' fees and expenses. The application of the
+ United Nations Convention on Contracts for the International Sale
+ of Goods is expressly excluded. Any law or regulation which
+ provides that the language of a contract shall be construed
+ against the drafter shall not apply to this License. You agree
+ that You alone are responsible for compliance with the United
+ States export administration regulations (and the export control
+ laws and regulation of any other countries) when You use,
+ distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or
+ indirectly, out of its utilization of rights under this License
+ and You agree to work with Initial Developer and Contributors to
+ distribute such responsibility on an equitable basis. Nothing
+ herein is intended or shall be deemed to constitute any admission
+ of liability.
+
+--------------------------------------------------------------------
+
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
+DISTRIBUTION LICENSE (CDDL)
+
+For Covered Software in this distribution, this License shall
+be governed by the laws of the State of California (excluding
+conflict-of-law provisions).
+
+Any litigation relating to this License shall be subject to the
+jurisdiction of the Federal Courts of the Northern District of
+California and the state courts of the State of California, with
+venue lying in Santa Clara County, California.
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
new file mode 100644
index 0000000..e20ed9f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
@@ -0,0 +1,670 @@
+'\" te
+.\" CDDL HEADER START
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" CDDL HEADER END
+.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved.
+.TH dtrace 1M "5 Sep 2006" "SunOS 5.11" "System Administration Commands"
+.SH NAME
+dtrace \- DTrace dynamic tracing compiler and tracing utility
+.SH SYNOPSIS
+.LP
+.nf
+\fBdtrace\fR [\fB-32\fR | \fB-64\fR] [\fB-aACeFGHhlqSvVwZ\fR] [\fB-b\fR \fIbufsz\fR] [\fB-c\fR \fIcmd\fR]
+ [\fB-D\fR \fIname\fR [\fI=value\fR]] [\fB-I\fR \fIpath\fR] [\fB-L\fR \fIpath\fR] [\fB-o\fR \fIoutput\fR]
+ [\fB-s\fR \fIscript\fR] [\fB-U\fR \fIname\fR] [\fB-x\fR \fIarg\fR [\fI=val\fR]]
+ [\fB-X\fR a | c | s | t] [\fB-p\fR \fIpid\fR]
+ [\fB-P\fR \fIprovider\fR [[\fIpredicate\fR] \fIaction\fR]]
+ [\fB-m\fR [\fIprovider:\fR] \fImodule\fR [[\fIpredicate\fR] \fIaction\fR]]
+ [\fB-f\fR [[\fIprovider:\fR] \fImodule:\fR] \fIfunction\fR [[\fIpredicate\fR] \fIaction\fR]]
+ [\fB-n\fR [[[\fIprovider:\fR] \fImodule:\fR] \fIfunction:\fR] \fIname\fR [[\fIpredicate\fR] \fIaction\fR]]
+ [\fB-i\fR \fIprobe-id\fR [[\fIpredicate\fR] \fIaction\fR]]
+.fi
+
+.SH DESCRIPTION
+.sp
+.LP
+DTrace is a comprehensive dynamic tracing framework for the Solaris Operating System. DTrace provides a powerful infrastructure that permits administrators, developers, and service personnel to concisely answer arbitrary questions about the behavior of the operating system and user programs.
+.sp
+.LP
+The \fISolaris Dynamic Tracing Guide\fR describes how to use DTrace to observe, debug, and tune system behavior. Refer to this book for a detailed description of DTrace features, including the bundled DTrace observability
+tools, instrumentation providers, and the D programming language.
+.sp
+.LP
+The \fBdtrace\fR command provides a generic interface to the essential services provided by the DTrace facility, including:
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that list the set of probes and providers currently published by DTrace
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that enable probes directly using any of the probe description specifiers (provider, module, function, name)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that run the D compiler and compile one or more D program files or programs written directly on the command line
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that generate anonymous tracing programs
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that generate program stability reports
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+Options that modify DTrace tracing and buffering behavior and enable additional D compiler features
+.RE
+.sp
+.LP
+You can use \fBdtrace\fR to create D scripts by using it in a \fB#!\fR declaration to create an interpreter file. You can also use \fBdtrace\fR to attempt to compile D programs and determine their properties without actually enabling tracing using the \fB-e\fR option. See \fBOPTIONS\fR. See the \fISolaris Dynamic Tracing Guide\fR for detailed examples of how to use the \fBdtrace\fR utility to perform these tasks.
+.SH OPTIONS
+.sp
+.LP
+The arguments accepted by the \fB-P\fR, \fB-m\fR, \fB-f\fR, \fB-n\fR, and \fB-i\fR options can include an optional D language \fIpredicate\fR enclosed in slashes \fB//\fR and optional D language \fIaction\fR statement list enclosed in braces \fB{}\fR. D program code specified on the command line must be appropriately quoted to avoid intepretation of meta-characters by the shell.
+.sp
+.LP
+The following options are supported:
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-32\fR | \fB-64\fR\fR
+.ad
+.sp .6
+.RS 4n
+The D compiler produces programs using the native data model of the operating system kernel. You can use the \fBisainfo\fR \fB-b\fR command to determine the current operating system data model. If the \fB-32\fR option is specified, \fBdtrace\fR forces
+the D compiler to compile a D program using the 32-bit data model. If the \fB-64\fR option is specified, \fBdtrace\fR forces the D compiler to compile a D program using the 64-bit data model. These options are typically not required as \fBdtrace\fR selects the
+native data model as the default. The data model affects the sizes of integer types and other language properties. D programs compiled for either data model can be executed on both 32-bit and 64-bit kernels. The \fB-32\fR and \fB-64\fR options also determine the ELF file format
+(ELF32 or ELF64) produced by the \fB-G\fR option.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-a\fR\fR
+.ad
+.sp .6
+.RS 4n
+Claim anonymous tracing state and display the traced data. You can combine the \fB-a\fR option with the \fB-e\fR option to force \fBdtrace\fR to exit immediately after consuming the anonymous tracing state rather than continuing to wait for new
+data. See the \fISolaris Dynamic Tracing Guide\fR for more information about anonymous tracing.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-A\fR\fR
+.ad
+.sp .6
+.RS 4n
+Generate \fBdriver.conf\fR(4) directives for anonymous tracing. This option constructs a set of \fBdtrace\fR(7D) configuration file directives to enable the specified probes for anonymous tracing and then exits. By default, \fBdtrace\fR attempts to store the directives to the file \fB/kernel/drv/dtrace.conf\fR. You can modify this behavior if you use the \fB-o\fR option to specify an alternate output file.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-b\fR \fIbufsz\fR\fR
+.ad
+.sp .6
+.RS 4n
+Set principal trace buffer size (\fIbufsz\fR). The trace buffer size can include any of the size suffixes \fBk\fR, \fBm\fR, \fBg\fR, or \fBt\fR. If the buffer space cannot be allocated, \fBdtrace\fR attempts
+to reduce the buffer size or exit depending on the setting of the \fBbufresize\fR property.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-c\fR \fIcmd\fR\fR
+.ad
+.sp .6
+.RS 4n
+Run the specified command \fIcmd\fR and exit upon its completion. If more than one \fB-c\fR option is present on the command line, \fBdtrace\fR exits when all commands have exited, reporting the exit status for each child process as it
+terminates. The process-ID of the first command is made available to any D programs specified on the command line or using the \fB-s\fR option through the \fB$target\fR macro variable. Refer to the \fISolaris Dynamic Tracing Guide\fR for more information
+on macro variables.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-C\fR\fR
+.ad
+.sp .6
+.RS 4n
+Run the C preprocessor \fBcpp\fR(1) over D programs before compiling them. You can pass options to the C preprocessor using the \fB-D\fR, \fB-U\fR, \fB-I\fR, and \fB-H\fR options. You can select the degree of C standard conformance if you use the \fB-X\fR option. For a description of the set of tokens defined by the D compiler when invoking the C preprocessor, see \fB-X\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-D\fR \fIname\fR \fB[=\fR\fIvalue\fR\fB]\fR\fR
+.ad
+.sp .6
+.RS 4n
+Define \fIname\fR when invoking \fBcpp\fR(1) (enabled using the \fB-C\fR option). If you specify the equals sign (\fB=\fR)
+and additional \fIvalue\fR, the name is assigned the corresponding value. This option passes the \fB-D\fR option to each \fBcpp\fR invocation.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-e\fR\fR
+.ad
+.sp .6
+.RS 4n
+Exit after compiling any requests and consuming anonymous tracing state (\fB-a\fR option) but prior to enabling any probes. You can combine this option with the \fB-a\fR option to print anonymous tracing data and exit. You can also combine this option with D
+compiler options. This combination verifies that the programs compile without actually executing them and enabling the corresponding instrumentation.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-f\fR\fB[[\fR\fIprovider\fR\fB:]\fR\fImodule\fR\fB:]\fR\fIfunction\fR\fB[[\fR\fIpredicate\fR\fB]\fR\fIaction\fR\fB]]\fR\fR
+.ad
+.sp .6
+.RS 4n
+Specify function name to trace or list (\fB-l\fR option). The corresponding argument can include any of the probe description forms \fIprovider:module:function\fR, \fImodule:function\fR, or \fIfunction\fR.
+Unspecified probe description fields are left blank and match any probes regardless of the values in those fields. If no qualifiers other than \fIfunction\fR are specified in the description, all probes with the corresponding \fIfunction\fR are matched.
+The \fB-f\fR argument can be suffixed with an optional D probe clause. You can specify more than one \fB-f\fR option on the command line at a time.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-F\fR\fR
+.ad
+.sp .6
+.RS 4n
+Coalesce trace output by identifying function entry and return. Function entry probe reports are indented and their output is prefixed with \fB->\fR. Function return probe reports are unindented and their output is prefixed with \fB<-\fR\&. System call
+entry probe reports are indented and their output is prefixed with \fB=>\fR. System call return probe reports are unindented and their output is prefixed with \fB<=\fR\&.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-G\fR\fR
+.ad
+.sp .6
+.RS 4n
+Generate an ELF file containing an embedded DTrace program. The DTrace probes specified in the program are saved inside of a relocatable ELF object which can be linked into another program. If the \fB-o\fR option is present, the ELF file is saved using the pathname specified
+as the argument for this operand. If the \fB-o\fR option is not present and the DTrace program is contained with a file whose name is \fB\fIfilename\fR.d\fR, then the ELF file is saved using the name \fB\fIfilename\fR.o\fR.
+Otherwise the ELF file is saved using the name \fBd.out\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-H\fR\fR
+.ad
+.sp .6
+.RS 4n
+Print the pathnames of included files when invoking \fBcpp\fR(1) (enabled using the \fB-C\fR option). This option passes the \fB-H\fR option
+to each \fBcpp\fR invocation, causing it to display the list of pathnames, one for each line, to \fBstderr\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-h\fR\fR
+.ad
+.sp .6
+.RS 4n
+Generate a header file containing macros that correspond to probes in the specified provider definitions. This option should be used to generate a header file that is included by other source files for later use with the \fB-G\fR option. If the \fB-o\fR option
+is present, the header file is saved using the pathname specified as the argument for that option. If the \fB-o\fR option is not present and the DTrace program is contained with a file whose name is \fIfilename\fR\fB\&.d\fR, then the header file is saved
+using the name \fIfilename\fR\fB\&.h\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-i\fR \fIprobe-id\fR\fB[[\fR\fIpredicate\fR] \fIaction\fR\fB]\fR\fR
+.ad
+.sp .6
+.RS 4n
+Specify probe identifier (\fIprobe-id\fR) to trace or list (\fB-l\fR option). You can specify probe IDs using decimal integers as shown by \fBdtrace\fR \fB-l\fR. The \fB-i\fR argument can be suffixed with an optional
+D probe clause. You can specify more than one \fB-i\fR option at a time.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-I\fR \fIpath\fR\fR
+.ad
+.sp .6
+.RS 4n
+Add the specified directory \fIpath\fR to the search path for \fB#include\fR files when invoking \fBcpp\fR(1) (enabled
+using the \fB-C\fR option). This option passes the \fB-I\fR option to each \fBcpp\fR invocation. The specified \fIpath\fR is inserted into the search path ahead of the default directory list.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-L\fR \fIpath\fR\fR
+.ad
+.sp .6
+.RS 4n
+Add the specified directory \fIpath\fR to the search path for DTrace libraries. DTrace libraries are used to contain common definitions that can be used when writing D programs. The specified \fIpath\fR is added after the default library
+search path.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-l\fR\fR
+.ad
+.sp .6
+.RS 4n
+List probes instead of enabling them. If the \fB-l\fR option is specified, \fBdtrace\fR produces a report of the probes matching the descriptions given using the \fB-P\fR, \fB-m\fR, \fB-f\fR, \fB-n\fR, \fB-i\fR,
+and \fB-s\fR options. If none of these options are specified, this option lists all probes.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-m\fR [[\fIprovider:\fR] \fImodule:\fR [[\fIpredicate\fR] \fIaction\fR]]\fR
+.ad
+.sp .6
+.RS 4n
+Specify module name to trace or list (\fB-l\fR option). The corresponding argument can include any of the probe description forms \fIprovider:module\fR or \fImodule\fR. Unspecified probe description fields are left blank and match
+any probes regardless of the values in those fields. If no qualifiers other than \fImodule\fR are specified in the description, all probes with a corresponding \fImodule\fR are matched. The \fB-m\fR argument can be suffixed with an optional D
+probe clause. More than one \fB-m\fR option can be specified on the command line at a time.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-n\fR [[[\fIprovider:\fR] \fImodule:\fR] \fIfunction:\fR] \fIname\fR [[\fIpredicate\fR] \fIaction\fR]\fR
+.ad
+.sp .6
+.RS 4n
+Specify probe name to trace or list (\fB-l\fR option). The corresponding argument can include any of the probe description forms \fIprovider:module:function:name\fR, \fImodule:function:name\fR, \fIfunction:name\fR,
+or \fIname\fR. Unspecified probe description fields are left blank and match any probes regardless of the values in those fields. If no qualifiers other than \fIname\fR are specified in the description, all probes with a corresponding \fIname\fR are
+matched. The \fB-n\fR argument can be suffixed with an optional D probe clause. More than one \fB-n\fR option can be specified on the command line at a time.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-o\fR \fIoutput\fR\fR
+.ad
+.sp .6
+.RS 4n
+Specify the \fIoutput\fR file for the \fB-A\fR , \fB-G\fR, and \fB-l\fR options, or for the traced data itself. If the \fB-A\fR option is present and \fB-o\fR is not present, the default output file is \fB/kernel/drv/dtrace.conf\fR. If the \fB-G\fR option is present and the \fB-s\fR option's argument is of the form \fB\fIfilename\fR.d\fR and \fB-o\fR is not present, the default output file is \fB\fIfilename\fR.o\fR.
+Otherwise the default output file is \fBd.out\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-p\fR \fIpid\fR\fR
+.ad
+.sp .6
+.RS 4n
+Grab the specified process-ID \fIpid\fR, cache its symbol tables, and exit upon its completion. If more than one \fB-p\fR option is present on the command line, \fBdtrace\fR exits when all commands have exited, reporting the exit status
+for each process as it terminates. The first process-ID is made available to any D programs specified on the command line or using the \fB-s\fR option through the \fB$target\fR macro variable. Refer to the \fISolaris Dynamic Tracing Guide\fR for
+more information on macro variables.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-P\fR \fIprovider\fR \fB[[\fR\fIpredicate\fR\fB]\fR \fIaction\fR]\fR
+.ad
+.sp .6
+.RS 4n
+Specify provider name to trace or list (\fB-l\fR option). The remaining probe description fields module, function, and name are left blank and match any probes regardless of the values in those fields. The \fB-P\fR argument can be suffixed with an optional D
+probe clause. You can specify more than one \fB-P\fR option on the command line at a time.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-q\fR\fR
+.ad
+.sp .6
+.RS 4n
+Set quiet mode. \fBdtrace\fR suppresses messages such as the number of probes matched by the specified options and D programs and does not print column headers, the CPU ID, the probe ID, or insert newlines into the output. Only data traced and formatted by D program
+statements such as \fBtrace()\fR and \fBprintf()\fR is displayed to \fBstdout\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-s\fR\fR
+.ad
+.sp .6
+.RS 4n
+Compile the specified D program source file. If the \fB-e\fR option is present, the program is compiled but instrumentation is not enabled. If the \fB-l\fR option is present, the program is compiled and the set of probes matched by it is listed, but instrumentation
+is not enabled. If none of \fB-e\fR, \fB-l\fR, \fB-G\fR, or \fB-A\fR are present, the instrumentation specified by the D program is enabled and tracing begins.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-S\fR\fR
+.ad
+.sp .6
+.RS 4n
+Show D compiler intermediate code. The D compiler produces a report of the intermediate code generated for each D program to \fBstderr\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-U\fR \fIname\fR\fR
+.ad
+.sp .6
+.RS 4n
+Undefine the specified \fIname\fR when invoking \fBcpp\fR(1) (enabled using the \fB-C\fR option). This option passes the \fB-U\fR option to each \fBcpp\fR invocation.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-v\fR\fR
+.ad
+.sp .6
+.RS 4n
+Set verbose mode. If the \fB-v\fR option is specified, \fBdtrace\fR produces a program stability report showing the minimum interface stability and dependency level for the specified D programs. DTrace stability levels are explained in further detail in the \fISolaris Dynamic Tracing Guide\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-V\fR\fR
+.ad
+.sp .6
+.RS 4n
+Report the highest D programming interface version supported by \fBdtrace\fR. The version information is printed to \fBstdout\fR and the \fBdtrace\fR command exits. Refer to the \fISolaris Dynamic Tracing Guide\fR for
+more information about DTrace versioning features.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-w\fR\fR
+.ad
+.sp .6
+.RS 4n
+Permit destructive actions in D programs specified using the \fB-s\fR, \fB-P\fR, \fB-m\fR, \fB-f\fR, \fB-n\fR, or \fB-i\fR options. If the \fB-w\fR option is not specified, \fBdtrace\fR does not
+permit the compilation or enabling of a D program that contains destructive actions.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-x\fR \fIarg\fR [\fI=val\fR]\fR
+.ad
+.sp .6
+.RS 4n
+Enable or modify a DTrace runtime option or D compiler option. The list of options is found in the \fISolaris Dynamic Tracing Guide\fR. Boolean options are enabled by specifying their name. Options with values are set by separating the option name and
+value with an equals sign (\fB=\fR).
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-X\fR \fBa | c | s | t\fR\fR
+.ad
+.sp .6
+.RS 4n
+Specify the degree of conformance to the ISO C standard that should be selected when invoking \fBcpp\fR(1) (enabled using the \fB-C\fR option).
+The \fB-X\fR option argument affects the value and presence of the \fB__STDC__\fR macro depending upon the value of the argument letter.
+.sp
+The \fB-X\fR option supports the following arguments:
+.sp
+.ne 2
+.mk
+.na
+\fB\fBa\fR\fR
+.ad
+.RS 5n
+.rt
+Default. ISO C plus K&R compatibility extensions, with semantic changes required by ISO C. This is the default mode if \fB-X\fR is not specified. The predefined macro \fB__STDC__\fR has a value of 0 when \fBcpp\fR is invoked in conjunction
+with the \fB-Xa\fR option.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBc\fR\fR
+.ad
+.RS 5n
+.rt
+Conformance. Strictly conformant ISO C, without K&R C compatibility extensions. The predefined macro \fB__STDC__\fR has a value of 1 when \fBcpp\fR is invoked in conjunction with the \fB-Xc\fR option.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBs\fR\fR
+.ad
+.RS 5n
+.rt
+K&R C only. The macro \fB__STDC__\fR is not defined when \fBcpp\fR is invoked in conjunction with the \fB-Xs\fR option.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBt\fR\fR
+.ad
+.RS 5n
+.rt
+Transition. ISO C plus K&R C compatibility extensions, without semantic changes required by ISO C. The predefined macro \fB__STDC__\fR has a value of 0 when \fBcpp\fR is invoked in conjunction with the \fB-Xt\fR option.
+.RE
+
+As the \fB-X\fR option only affects how the D compiler invokes the C preprocessor, the \fB-Xa\fR and \fB-Xt\fR options are equivalent from the perspective of D and both are provided only to ease re-use of settings from a C build environment.
+.sp
+Regardless of the \fB-X\fR mode, the following additional C preprocessor definitions are always specified and valid in all modes:
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__sun\fR
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__unix\fR
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__SVR4\fR
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__sparc\fR (on SPARC systems only)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__sparcv9\fR (on SPARC systems only when 64-bit programs are compiled)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__i386\fR (on x86 systems only when 32-bit programs are compiled)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__amd64\fR (on x86 systems only when 64-bit programs are compiled)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__\fI`uname -s`\fR_\fI`uname -r`\fR\fR (for example, \fB__SunOS_5_10\fR)
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__SUNW_D=1\fR
+.RE
+.RS +4
+.TP
+.ie t \(bu
+.el o
+\fB__SUNW_D_VERSION=0x\fIMMmmmuuu\fR\fR
+.sp
+Where \fIMM\fR is the major release value in hexadecimal, \fImmm\fR is the minor release value in hexadecimal, and \fIuuu\fR is the
+micro release value in hexadecimal. Refer to the \fISolaris Dynamic Tracing Guide\fR for more information about DTrace versioning.
+.RE
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-Z\fR\fR
+.ad
+.sp .6
+.RS 4n
+Permit probe descriptions that match zero probes. If the \fB-Z\fR option is not specified, \fBdtrace\fR reports an error and exits if any probe descriptions specified in D program files (\fB-s\fR option) or on the command line (\fB-P\fR, \fB-m\fR, \fB-f\fR, \fB-n\fR, or \fB-i\fR options) contain descriptions that do not match any known probes.
+.RE
+
+.SH OPERANDS
+.sp
+.LP
+You can specify zero or more additional arguments on the \fBdtrace\fR command line to define a set of macro variables (\fB$1\fR, \fB$2\fR, and so forth). The additional arguments can be used in D programs specified using the \fB-s\fR option
+or on the command line. The use of macro variables is described further in the \fISolaris Dynamic Tracing Guide\fR.
+.SH EXIT STATUS
+.sp
+.LP
+The following exit values are returned:
+.sp
+.ne 2
+.mk
+.na
+\fB0\fR
+.ad
+.RS 5n
+.rt
+Successful completion.
+.sp
+For D program requests, an exit status of \fB0\fR indicates that programs were successfully compiled, probes were successfully enabled, or anonymous state was successfully retrieved. \fBdtrace\fR returns \fB0\fR even if the specified tracing requests
+encountered errors or drops.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB1\fR\fR
+.ad
+.RS 5n
+.rt
+An error occurred.
+.sp
+For D program requests, an exit status of \fB1\fR indicates that program compilation failed or that the specified request could not be satisfied.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB2\fR\fR
+.ad
+.RS 5n
+.rt
+Invalid command line options or arguments were specified.
+.RE
+
+.SH ATTRIBUTES
+.sp
+.LP
+See \fBattributes\fR(5) for descriptions of the following attributes:
+.sp
+
+.sp
+.TS
+tab() box;
+cw(2.75i) |cw(2.75i)
+lw(2.75i) |lw(2.75i)
+.
+ATTRIBUTE TYPEATTRIBUTE VALUE
+_
+AvailabilitySUNWdtrc
+_
+Interface StabilitySee below.
+.TE
+
+.sp
+.LP
+The command-line syntax is Committed. The human-readable output is Uncommitted.
+.SH SEE ALSO
+.sp
+.LP
+\fBcpp\fR(1), \fBisainfo\fR(1), \fBlibdtrace\fR(3LIB), \fBdriver.conf\fR(4), \fBattributes\fR(5), \fBdtrace\fR(7D)
+.sp
+.LP
+\fISolaris Dynamic Tracing Guide\fR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
new file mode 100644
index 0000000..cc7959f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
@@ -0,0 +1,1926 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <dtrace.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <libgen.h>
+#if defined(sun)
+#include <libproc.h>
+#endif
+
+typedef struct dtrace_cmd {
+ void (*dc_func)(struct dtrace_cmd *); /* function to compile arg */
+ dtrace_probespec_t dc_spec; /* probe specifier context */
+ char *dc_arg; /* argument from main argv */
+ const char *dc_name; /* name for error messages */
+ const char *dc_desc; /* desc for error messages */
+ dtrace_prog_t *dc_prog; /* program compiled from arg */
+ char dc_ofile[PATH_MAX]; /* derived output file name */
+} dtrace_cmd_t;
+
+#define DMODE_VERS 0 /* display version information and exit (-V) */
+#define DMODE_EXEC 1 /* compile program for enabling (-a/e/E) */
+#define DMODE_ANON 2 /* compile program for anonymous tracing (-A) */
+#define DMODE_LINK 3 /* compile program for linking with ELF (-G) */
+#define DMODE_LIST 4 /* compile program and list probes (-l) */
+#define DMODE_HEADER 5 /* compile program for headergen (-h) */
+
+#define E_SUCCESS 0
+#define E_ERROR 1
+#define E_USAGE 2
+
+static const char DTRACE_OPTSTR[] =
+ "3:6:aAb:Bc:CD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
+
+static char **g_argv;
+static int g_argc;
+static char **g_objv;
+static int g_objc;
+static dtrace_cmd_t *g_cmdv;
+static int g_cmdc;
+static struct ps_prochandle **g_psv;
+static int g_psc;
+static int g_pslive;
+static char *g_pname;
+static int g_quiet;
+static int g_flowindent;
+static int g_intr;
+static int g_impatient;
+static int g_newline;
+static int g_total;
+static int g_cflags;
+static int g_oflags;
+static int g_verbose;
+static int g_exec = 1;
+static int g_mode = DMODE_EXEC;
+static int g_status = E_SUCCESS;
+static int g_grabanon = 0;
+static const char *g_ofile = NULL;
+static FILE *g_ofp;
+static dtrace_hdl_t *g_dtp;
+#if defined(sun)
+static char *g_etcfile = "/etc/system";
+static const char *g_etcbegin = "* vvvv Added by DTrace";
+static const char *g_etcend = "* ^^^^ Added by DTrace";
+
+static const char *g_etc[] = {
+"*",
+"* The following forceload directives were added by dtrace(1M) to allow for",
+"* tracing during boot. If these directives are removed, the system will",
+"* continue to function, but tracing will not occur during boot as desired.",
+"* To remove these directives (and this block comment) automatically, run",
+"* \"dtrace -A\" without additional arguments. See the \"Anonymous Tracing\"",
+"* chapter of the Solaris Dynamic Tracing Guide for details.",
+"*",
+NULL };
+#endif
+
+static int
+usage(FILE *fp)
+{
+ static const char predact[] = "[[ predicate ] action ]";
+
+ (void) fprintf(fp, "Usage: %s [-32|-64] [-aACeFGhHlqSvVwZ] "
+ "[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] "
+ "[-o output] [-p pid] [-s script] [-U name]\n\t"
+ "[-x opt[=val]] [-X a|c|s|t]\n\n"
+ "\t[-P provider %s]\n"
+ "\t[-m [ provider: ] module %s]\n"
+ "\t[-f [[ provider: ] module: ] func %s]\n"
+ "\t[-n [[[ provider: ] module: ] func: ] name %s]\n"
+ "\t[-i probe-id %s] [ args ... ]\n\n", g_pname,
+ predact, predact, predact, predact, predact);
+
+ (void) fprintf(fp, "\tpredicate -> '/' D-expression '/'\n");
+ (void) fprintf(fp, "\t action -> '{' D-statements '}'\n");
+
+ (void) fprintf(fp, "\n"
+ "\t-32 generate 32-bit D programs and ELF files\n"
+ "\t-64 generate 64-bit D programs and ELF files\n\n"
+ "\t-a claim anonymous tracing state\n"
+ "\t-A generate driver.conf(4) directives for anonymous tracing\n"
+ "\t-b set trace buffer size\n"
+ "\t-c run specified command and exit upon its completion\n"
+ "\t-C run cpp(1) preprocessor on script files\n"
+ "\t-D define symbol when invoking preprocessor\n"
+ "\t-e exit after compiling request but prior to enabling probes\n"
+ "\t-f enable or list probes matching the specified function name\n"
+ "\t-F coalesce trace output by function\n"
+ "\t-G generate an ELF file containing embedded dtrace program\n"
+ "\t-h generate a header file with definitions for static probes\n"
+ "\t-H print included files when invoking preprocessor\n"
+ "\t-i enable or list probes matching the specified probe id\n"
+ "\t-I add include directory to preprocessor search path\n"
+ "\t-l list probes matching specified criteria\n"
+ "\t-L add library directory to library search path\n"
+ "\t-m enable or list probes matching the specified module name\n"
+ "\t-n enable or list probes matching the specified probe name\n"
+ "\t-o set output file\n"
+ "\t-p grab specified process-ID and cache its symbol tables\n"
+ "\t-P enable or list probes matching the specified provider name\n"
+ "\t-q set quiet mode (only output explicitly traced data)\n"
+ "\t-s enable or list probes according to the specified D script\n"
+ "\t-S print D compiler intermediate code\n"
+ "\t-U undefine symbol when invoking preprocessor\n"
+ "\t-v set verbose mode (report stability attributes, arguments)\n"
+ "\t-V report DTrace API version\n"
+ "\t-w permit destructive actions\n"
+ "\t-x enable or modify compiler and tracing options\n"
+ "\t-X specify ISO C conformance settings for preprocessor\n"
+ "\t-Z permit probe descriptions that match zero probes\n");
+
+ return (E_USAGE);
+}
+
+static void
+verror(const char *fmt, va_list ap)
+{
+ int error = errno;
+
+ (void) fprintf(stderr, "%s: ", g_pname);
+ (void) vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", strerror(error));
+}
+
+/*PRINTFLIKE1*/
+static void
+fatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verror(fmt, ap);
+ va_end(ap);
+
+ /*
+ * Close the DTrace handle to ensure that any controlled processes are
+ * correctly restored and continued.
+ */
+ if (g_dtp)
+ dtrace_close(g_dtp);
+
+ exit(E_ERROR);
+}
+
+/*PRINTFLIKE1*/
+static void
+dfatal(const char *fmt, ...)
+{
+#if !defined(sun) && defined(NEED_ERRLOC)
+ char *p_errfile = NULL;
+ int errline = 0;
+#endif
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ (void) fprintf(stderr, "%s: ", g_pname);
+ if (fmt != NULL)
+ (void) vfprintf(stderr, fmt, ap);
+
+ va_end(ap);
+
+ if (fmt != NULL && fmt[strlen(fmt) - 1] != '\n') {
+ (void) fprintf(stderr, ": %s\n",
+ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
+ } else if (fmt == NULL) {
+ (void) fprintf(stderr, "%s\n",
+ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
+ }
+#if !defined(sun) && defined(NEED_ERRLOC)
+ dt_get_errloc(g_dtp, &p_errfile, &errline);
+ if (p_errfile != NULL)
+ printf("File '%s', line %d\n", p_errfile, errline);
+#endif
+
+ /*
+ * Close the DTrace handle to ensure that any controlled processes are
+ * correctly restored and continued.
+ */
+ dtrace_close(g_dtp);
+
+ exit(E_ERROR);
+}
+
+/*PRINTFLIKE1*/
+static void
+error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verror(fmt, ap);
+ va_end(ap);
+}
+
+/*PRINTFLIKE1*/
+static void
+notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (g_quiet)
+ return; /* -q or quiet pragma suppresses notice()s */
+
+ va_start(ap, fmt);
+ verror(fmt, ap);
+ va_end(ap);
+}
+
+/*PRINTFLIKE1*/
+static void
+oprintf(const char *fmt, ...)
+{
+ va_list ap;
+ int n;
+
+ if (g_ofp == NULL)
+ return;
+
+ va_start(ap, fmt);
+ n = vfprintf(g_ofp, fmt, ap);
+ va_end(ap);
+
+ if (n < 0) {
+ if (errno != EINTR) {
+ fatal("failed to write to %s",
+ g_ofile ? g_ofile : "<stdout>");
+ }
+ clearerr(g_ofp);
+ }
+}
+
+static char **
+make_argv(char *s)
+{
+ const char *ws = "\f\n\r\t\v ";
+ char **argv = malloc(sizeof (char *) * (strlen(s) / 2 + 1));
+ int argc = 0;
+ char *p = s;
+
+ if (argv == NULL)
+ return (NULL);
+
+ for (p = strtok(s, ws); p != NULL; p = strtok(NULL, ws))
+ argv[argc++] = p;
+
+ if (argc == 0)
+ argv[argc++] = s;
+
+ argv[argc] = NULL;
+ return (argv);
+}
+
+static void
+dof_prune(const char *fname)
+{
+ struct stat sbuf;
+ size_t sz, i, j, mark, len;
+ char *buf;
+ int msg = 0, fd;
+
+ if ((fd = open(fname, O_RDONLY)) == -1) {
+ /*
+ * This is okay only if the file doesn't exist at all.
+ */
+ if (errno != ENOENT)
+ fatal("failed to open %s", fname);
+ return;
+ }
+
+ if (fstat(fd, &sbuf) == -1)
+ fatal("failed to fstat %s", fname);
+
+ if ((buf = malloc((sz = sbuf.st_size) + 1)) == NULL)
+ fatal("failed to allocate memory for %s", fname);
+
+ if (read(fd, buf, sz) != sz)
+ fatal("failed to read %s", fname);
+
+ buf[sz] = '\0';
+ (void) close(fd);
+
+ if ((fd = open(fname, O_WRONLY | O_TRUNC)) == -1)
+ fatal("failed to open %s for writing", fname);
+
+ len = strlen("dof-data-");
+
+ for (mark = 0, i = 0; i < sz; i++) {
+ if (strncmp(&buf[i], "dof-data-", len) != 0)
+ continue;
+
+ /*
+ * This is only a match if it's in the 0th column.
+ */
+ if (i != 0 && buf[i - 1] != '\n')
+ continue;
+
+ if (msg++ == 0) {
+ error("cleaned up old anonymous "
+ "enabling in %s\n", fname);
+ }
+
+ /*
+ * We have a match. First write out our data up until now.
+ */
+ if (i != mark) {
+ if (write(fd, &buf[mark], i - mark) != i - mark)
+ fatal("failed to write to %s", fname);
+ }
+
+ /*
+ * Now scan forward until we scan past a newline.
+ */
+ for (j = i; j < sz && buf[j] != '\n'; j++)
+ continue;
+
+ /*
+ * Reset our mark.
+ */
+ if ((mark = j + 1) >= sz)
+ break;
+
+ i = j;
+ }
+
+ if (mark < sz) {
+ if (write(fd, &buf[mark], sz - mark) != sz - mark)
+ fatal("failed to write to %s", fname);
+ }
+
+ (void) close(fd);
+ free(buf);
+}
+
+#if defined(sun)
+static void
+etcsystem_prune(void)
+{
+ struct stat sbuf;
+ size_t sz;
+ char *buf, *start, *end;
+ int fd;
+ char *fname = g_etcfile, *tmpname;
+
+ if ((fd = open(fname, O_RDONLY)) == -1)
+ fatal("failed to open %s", fname);
+
+ if (fstat(fd, &sbuf) == -1)
+ fatal("failed to fstat %s", fname);
+
+ if ((buf = malloc((sz = sbuf.st_size) + 1)) == NULL)
+ fatal("failed to allocate memory for %s", fname);
+
+ if (read(fd, buf, sz) != sz)
+ fatal("failed to read %s", fname);
+
+ buf[sz] = '\0';
+ (void) close(fd);
+
+ if ((start = strstr(buf, g_etcbegin)) == NULL)
+ goto out;
+
+ if (strlen(buf) != sz) {
+ fatal("embedded nul byte in %s; manual repair of %s "
+ "required\n", fname, fname);
+ }
+
+ if (strstr(start + 1, g_etcbegin) != NULL) {
+ fatal("multiple start sentinels in %s; manual repair of %s "
+ "required\n", fname, fname);
+ }
+
+ if ((end = strstr(buf, g_etcend)) == NULL) {
+ fatal("missing end sentinel in %s; manual repair of %s "
+ "required\n", fname, fname);
+ }
+
+ if (start > end) {
+ fatal("end sentinel preceeds start sentinel in %s; manual "
+ "repair of %s required\n", fname, fname);
+ }
+
+ end += strlen(g_etcend) + 1;
+ bcopy(end, start, strlen(end) + 1);
+
+ tmpname = alloca(sz = strlen(fname) + 80);
+ (void) snprintf(tmpname, sz, "%s.dtrace.%d", fname, getpid());
+
+ if ((fd = open(tmpname,
+ O_WRONLY | O_CREAT | O_EXCL, sbuf.st_mode)) == -1)
+ fatal("failed to create %s", tmpname);
+
+ if (write(fd, buf, strlen(buf)) < strlen(buf)) {
+ (void) unlink(tmpname);
+ fatal("failed to write to %s", tmpname);
+ }
+
+ (void) close(fd);
+
+ if (chown(tmpname, sbuf.st_uid, sbuf.st_gid) != 0) {
+ (void) unlink(tmpname);
+ fatal("failed to chown(2) %s to uid %d, gid %d", tmpname,
+ (int)sbuf.st_uid, (int)sbuf.st_gid);
+ }
+
+ if (rename(tmpname, fname) == -1)
+ fatal("rename of %s to %s failed", tmpname, fname);
+
+ error("cleaned up forceload directives in %s\n", fname);
+out:
+ free(buf);
+}
+
+static void
+etcsystem_add(void)
+{
+ const char *mods[20];
+ int nmods, line;
+
+ if ((g_ofp = fopen(g_ofile = g_etcfile, "a")) == NULL)
+ fatal("failed to open output file '%s'", g_ofile);
+
+ oprintf("%s\n", g_etcbegin);
+
+ for (line = 0; g_etc[line] != NULL; line++)
+ oprintf("%s\n", g_etc[line]);
+
+ nmods = dtrace_provider_modules(g_dtp, mods,
+ sizeof (mods) / sizeof (char *) - 1);
+
+ if (nmods >= sizeof (mods) / sizeof (char *))
+ fatal("unexpectedly large number of modules!");
+
+ mods[nmods++] = "dtrace";
+
+ for (line = 0; line < nmods; line++)
+ oprintf("forceload: drv/%s\n", mods[line]);
+
+ oprintf("%s\n", g_etcend);
+
+ if (fclose(g_ofp) == EOF)
+ fatal("failed to close output file '%s'", g_ofile);
+
+ error("added forceload directives to %s\n", g_ofile);
+}
+#endif
+
+static void
+print_probe_info(const dtrace_probeinfo_t *p)
+{
+ char buf[BUFSIZ];
+ int i;
+
+ oprintf("\n\tProbe Description Attributes\n");
+
+ oprintf("\t\tIdentifier Names: %s\n",
+ dtrace_stability_name(p->dtp_attr.dtat_name));
+ oprintf("\t\tData Semantics: %s\n",
+ dtrace_stability_name(p->dtp_attr.dtat_data));
+ oprintf("\t\tDependency Class: %s\n",
+ dtrace_class_name(p->dtp_attr.dtat_class));
+
+ oprintf("\n\tArgument Attributes\n");
+
+ oprintf("\t\tIdentifier Names: %s\n",
+ dtrace_stability_name(p->dtp_arga.dtat_name));
+ oprintf("\t\tData Semantics: %s\n",
+ dtrace_stability_name(p->dtp_arga.dtat_data));
+ oprintf("\t\tDependency Class: %s\n",
+ dtrace_class_name(p->dtp_arga.dtat_class));
+
+ oprintf("\n\tArgument Types\n");
+
+ for (i = 0; i < p->dtp_argc; i++) {
+ if (ctf_type_name(p->dtp_argv[i].dtt_ctfp,
+ p->dtp_argv[i].dtt_type, buf, sizeof (buf)) == NULL)
+ (void) strlcpy(buf, "(unknown)", sizeof (buf));
+ oprintf("\t\targs[%d]: %s\n", i, buf);
+ }
+
+ if (p->dtp_argc == 0)
+ oprintf("\t\tNone\n");
+
+ oprintf("\n");
+}
+
+/*ARGSUSED*/
+static int
+info_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
+ dtrace_stmtdesc_t *stp, dtrace_ecbdesc_t **last)
+{
+ dtrace_ecbdesc_t *edp = stp->dtsd_ecbdesc;
+ dtrace_probedesc_t *pdp = &edp->dted_probe;
+ dtrace_probeinfo_t p;
+
+ if (edp == *last)
+ return (0);
+
+ oprintf("\n%s:%s:%s:%s\n",
+ pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
+
+ if (dtrace_probe_info(dtp, pdp, &p) == 0)
+ print_probe_info(&p);
+
+ *last = edp;
+ return (0);
+}
+
+/*
+ * Execute the specified program by enabling the corresponding instrumentation.
+ * If -e has been specified, we get the program info but do not enable it. If
+ * -v has been specified, we print a stability report for the program.
+ */
+static void
+exec_prog(const dtrace_cmd_t *dcp)
+{
+ dtrace_ecbdesc_t *last = NULL;
+ dtrace_proginfo_t dpi;
+
+ if (!g_exec) {
+ dtrace_program_info(g_dtp, dcp->dc_prog, &dpi);
+ } else if (dtrace_program_exec(g_dtp, dcp->dc_prog, &dpi) == -1) {
+ dfatal("failed to enable '%s'", dcp->dc_name);
+ } else {
+ notice("%s '%s' matched %u probe%s\n",
+ dcp->dc_desc, dcp->dc_name,
+ dpi.dpi_matches, dpi.dpi_matches == 1 ? "" : "s");
+ }
+
+ if (g_verbose) {
+ oprintf("\nStability attributes for %s %s:\n",
+ dcp->dc_desc, dcp->dc_name);
+
+ oprintf("\n\tMinimum Probe Description Attributes\n");
+ oprintf("\t\tIdentifier Names: %s\n",
+ dtrace_stability_name(dpi.dpi_descattr.dtat_name));
+ oprintf("\t\tData Semantics: %s\n",
+ dtrace_stability_name(dpi.dpi_descattr.dtat_data));
+ oprintf("\t\tDependency Class: %s\n",
+ dtrace_class_name(dpi.dpi_descattr.dtat_class));
+
+ oprintf("\n\tMinimum Statement Attributes\n");
+
+ oprintf("\t\tIdentifier Names: %s\n",
+ dtrace_stability_name(dpi.dpi_stmtattr.dtat_name));
+ oprintf("\t\tData Semantics: %s\n",
+ dtrace_stability_name(dpi.dpi_stmtattr.dtat_data));
+ oprintf("\t\tDependency Class: %s\n",
+ dtrace_class_name(dpi.dpi_stmtattr.dtat_class));
+
+ if (!g_exec) {
+ (void) dtrace_stmt_iter(g_dtp, dcp->dc_prog,
+ (dtrace_stmt_f *)info_stmt, &last);
+ } else
+ oprintf("\n");
+ }
+
+ g_total += dpi.dpi_matches;
+}
+
+/*
+ * Print out the specified DOF buffer as a set of ASCII bytes appropriate for
+ * storing in a driver.conf(4) file associated with the dtrace driver.
+ */
+static void
+anon_prog(const dtrace_cmd_t *dcp, dof_hdr_t *dof, int n)
+{
+ const uchar_t *p, *q;
+
+ if (dof == NULL)
+ dfatal("failed to create DOF image for '%s'", dcp->dc_name);
+
+ p = (uchar_t *)dof;
+ q = p + dof->dofh_loadsz;
+
+#if defined(sun)
+ oprintf("dof-data-%d=0x%x", n, *p++);
+
+ while (p < q)
+ oprintf(",0x%x", *p++);
+
+ oprintf(";\n");
+#else
+ /*
+ * On FreeBSD, the DOF data is handled as a kernel environment (kenv)
+ * string. We use two hex characters per DOF byte.
+ */
+ oprintf("dof-data-%d=%02x", n, *p++);
+
+ while (p < q)
+ oprintf("%02x", *p++);
+
+ oprintf("\n");
+#endif
+
+ dtrace_dof_destroy(g_dtp, dof);
+}
+
+/*
+ * Link the specified D program in DOF form into an ELF file for use in either
+ * helpers, userland provider definitions, or both. If -o was specified, that
+ * path is used as the output file name. If -o wasn't specified and the input
+ * program is from a script whose name is %.d, use basename(%.o) as the output
+ * file name. Otherwise we use "d.out" as the default output file name.
+ */
+static void
+link_prog(dtrace_cmd_t *dcp)
+{
+ char *p;
+
+ if (g_cmdc == 1 && g_ofile != NULL) {
+ (void) strlcpy(dcp->dc_ofile, g_ofile, sizeof (dcp->dc_ofile));
+ } else if ((p = strrchr(dcp->dc_arg, '.')) != NULL &&
+ strcmp(p, ".d") == 0) {
+ p[0] = '\0'; /* strip .d suffix */
+ (void) snprintf(dcp->dc_ofile, sizeof (dcp->dc_ofile),
+ "%s.o", basename(dcp->dc_arg));
+ } else if (g_cmdc > 1) {
+ (void) snprintf(dcp->dc_ofile, sizeof (dcp->dc_ofile),
+ "d.out.%td", dcp - g_cmdv);
+ } else {
+ (void) snprintf(dcp->dc_ofile, sizeof (dcp->dc_ofile),
+ "d.out");
+ }
+
+ if (dtrace_program_link(g_dtp, dcp->dc_prog, DTRACE_D_PROBES,
+ dcp->dc_ofile, g_objc, g_objv) != 0)
+ dfatal("failed to link %s %s", dcp->dc_desc, dcp->dc_name);
+}
+
+/*ARGSUSED*/
+static int
+list_probe(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
+{
+ dtrace_probeinfo_t p;
+
+ oprintf("%5d %10s %17s %33s %s\n", pdp->dtpd_id,
+ pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
+
+ if (g_verbose && dtrace_probe_info(dtp, pdp, &p) == 0)
+ print_probe_info(&p);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+list_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
+ dtrace_stmtdesc_t *stp, dtrace_ecbdesc_t **last)
+{
+ dtrace_ecbdesc_t *edp = stp->dtsd_ecbdesc;
+
+ if (edp == *last)
+ return (0);
+
+ if (dtrace_probe_iter(g_dtp, &edp->dted_probe, list_probe, NULL) != 0) {
+ error("failed to match %s:%s:%s:%s: %s\n",
+ edp->dted_probe.dtpd_provider, edp->dted_probe.dtpd_mod,
+ edp->dted_probe.dtpd_func, edp->dted_probe.dtpd_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ *last = edp;
+ return (0);
+}
+
+/*
+ * List the probes corresponding to the specified program by iterating over
+ * each statement and then matching probes to the statement probe descriptions.
+ */
+static void
+list_prog(const dtrace_cmd_t *dcp)
+{
+ dtrace_ecbdesc_t *last = NULL;
+
+ (void) dtrace_stmt_iter(g_dtp, dcp->dc_prog,
+ (dtrace_stmt_f *)list_stmt, &last);
+}
+
+static void
+compile_file(dtrace_cmd_t *dcp)
+{
+ char *arg0;
+ FILE *fp;
+
+ if ((fp = fopen(dcp->dc_arg, "r")) == NULL)
+ fatal("failed to open %s", dcp->dc_arg);
+
+ arg0 = g_argv[0];
+ g_argv[0] = dcp->dc_arg;
+
+ if ((dcp->dc_prog = dtrace_program_fcompile(g_dtp, fp,
+ g_cflags, g_argc, g_argv)) == NULL)
+ dfatal("failed to compile script %s", dcp->dc_arg);
+
+ g_argv[0] = arg0;
+ (void) fclose(fp);
+
+ dcp->dc_desc = "script";
+ dcp->dc_name = dcp->dc_arg;
+}
+
+static void
+compile_str(dtrace_cmd_t *dcp)
+{
+ char *p;
+
+ if ((dcp->dc_prog = dtrace_program_strcompile(g_dtp, dcp->dc_arg,
+ dcp->dc_spec, g_cflags | DTRACE_C_PSPEC, g_argc, g_argv)) == NULL)
+ dfatal("invalid probe specifier %s", dcp->dc_arg);
+
+ if ((p = strpbrk(dcp->dc_arg, "{/;")) != NULL)
+ *p = '\0'; /* crop name for reporting */
+
+ dcp->dc_desc = "description";
+ dcp->dc_name = dcp->dc_arg;
+}
+
+/*ARGSUSED*/
+static void
+prochandler(struct ps_prochandle *P, const char *msg, void *arg)
+{
+#if defined(sun)
+ const psinfo_t *prp = Ppsinfo(P);
+ int pid = Pstatus(P)->pr_pid;
+ char name[SIG2STR_MAX];
+#else
+ int wstatus = proc_getwstat(P);
+ int pid = proc_getpid(P);
+#endif
+
+ if (msg != NULL) {
+ notice("pid %d: %s\n", pid, msg);
+ return;
+ }
+
+#if defined(sun)
+ switch (Pstate(P)) {
+#else
+ switch (proc_state(P)) {
+#endif
+ case PS_UNDEAD:
+#if defined(sun)
+ /*
+ * Ideally we would like to always report pr_wstat here, but it
+ * isn't possible given current /proc semantics. If we grabbed
+ * the process, Ppsinfo() will either fail or return a zeroed
+ * psinfo_t depending on how far the parent is in reaping it.
+ * When /proc provides a stable pr_wstat in the status file,
+ * this code can be improved by examining this new pr_wstat.
+ */
+ if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) {
+ notice("pid %d terminated by %s\n", pid,
+ proc_signame(WTERMSIG(prp->pr_wstat),
+ name, sizeof (name)));
+#else
+ if (WIFSIGNALED(wstatus)) {
+ notice("pid %d terminated by %d\n", pid,
+ WTERMSIG(wstatus));
+#endif
+#if defined(sun)
+ } else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {
+ notice("pid %d exited with status %d\n",
+ pid, WEXITSTATUS(prp->pr_wstat));
+#else
+ } else if (WEXITSTATUS(wstatus) != 0) {
+ notice("pid %d exited with status %d\n",
+ pid, WEXITSTATUS(wstatus));
+#endif
+ } else {
+ notice("pid %d has exited\n", pid);
+ }
+ g_pslive--;
+ break;
+
+ case PS_LOST:
+ notice("pid %d exec'd a set-id or unobservable program\n", pid);
+ g_pslive--;
+ break;
+ }
+}
+
+/*ARGSUSED*/
+static int
+errhandler(const dtrace_errdata_t *data, void *arg)
+{
+ error(data->dteda_msg);
+ return (DTRACE_HANDLE_OK);
+}
+
+/*ARGSUSED*/
+static int
+drophandler(const dtrace_dropdata_t *data, void *arg)
+{
+ error(data->dtdda_msg);
+ return (DTRACE_HANDLE_OK);
+}
+
+/*ARGSUSED*/
+static int
+setopthandler(const dtrace_setoptdata_t *data, void *arg)
+{
+ if (strcmp(data->dtsda_option, "quiet") == 0)
+ g_quiet = data->dtsda_newval != DTRACEOPT_UNSET;
+
+ if (strcmp(data->dtsda_option, "flowindent") == 0)
+ g_flowindent = data->dtsda_newval != DTRACEOPT_UNSET;
+
+ return (DTRACE_HANDLE_OK);
+}
+
+#define BUFDUMPHDR(hdr) \
+ (void) printf("%s: %s%s\n", g_pname, hdr, strlen(hdr) > 0 ? ":" : "");
+
+#define BUFDUMPSTR(ptr, field) \
+ (void) printf("%s: %20s => ", g_pname, #field); \
+ if ((ptr)->field != NULL) { \
+ const char *c = (ptr)->field; \
+ (void) printf("\""); \
+ do { \
+ if (*c == '\n') { \
+ (void) printf("\\n"); \
+ continue; \
+ } \
+ \
+ (void) printf("%c", *c); \
+ } while (*c++ != '\0'); \
+ (void) printf("\"\n"); \
+ } else { \
+ (void) printf("<NULL>\n"); \
+ }
+
+#define BUFDUMPASSTR(ptr, field, str) \
+ (void) printf("%s: %20s => %s\n", g_pname, #field, str);
+
+#define BUFDUMP(ptr, field) \
+ (void) printf("%s: %20s => %lld\n", g_pname, #field, \
+ (long long)(ptr)->field);
+
+#define BUFDUMPPTR(ptr, field) \
+ (void) printf("%s: %20s => %s\n", g_pname, #field, \
+ (ptr)->field != NULL ? "<non-NULL>" : "<NULL>");
+
+/*ARGSUSED*/
+static int
+bufhandler(const dtrace_bufdata_t *bufdata, void *arg)
+{
+ const dtrace_aggdata_t *agg = bufdata->dtbda_aggdata;
+ const dtrace_recdesc_t *rec = bufdata->dtbda_recdesc;
+ const dtrace_probedesc_t *pd;
+ uint32_t flags = bufdata->dtbda_flags;
+ char buf[512], *c = buf, *end = c + sizeof (buf);
+ int i, printed;
+
+ struct {
+ const char *name;
+ uint32_t value;
+ } flagnames[] = {
+ { "AGGVAL", DTRACE_BUFDATA_AGGVAL },
+ { "AGGKEY", DTRACE_BUFDATA_AGGKEY },
+ { "AGGFORMAT", DTRACE_BUFDATA_AGGFORMAT },
+ { "AGGLAST", DTRACE_BUFDATA_AGGLAST },
+ { "???", UINT32_MAX },
+ { NULL }
+ };
+
+ if (bufdata->dtbda_probe != NULL) {
+ pd = bufdata->dtbda_probe->dtpda_pdesc;
+ } else if (agg != NULL) {
+ pd = agg->dtada_pdesc;
+ } else {
+ pd = NULL;
+ }
+
+ BUFDUMPHDR(">>> Called buffer handler");
+ BUFDUMPHDR("");
+
+ BUFDUMPHDR(" dtrace_bufdata");
+ BUFDUMPSTR(bufdata, dtbda_buffered);
+ BUFDUMPPTR(bufdata, dtbda_probe);
+ BUFDUMPPTR(bufdata, dtbda_aggdata);
+ BUFDUMPPTR(bufdata, dtbda_recdesc);
+
+ (void) snprintf(c, end - c, "0x%x ", bufdata->dtbda_flags);
+ c += strlen(c);
+
+ for (i = 0, printed = 0; flagnames[i].name != NULL; i++) {
+ if (!(flags & flagnames[i].value))
+ continue;
+
+ (void) snprintf(c, end - c,
+ "%s%s", printed++ ? " | " : "(", flagnames[i].name);
+ c += strlen(c);
+ flags &= ~flagnames[i].value;
+ }
+
+ if (printed)
+ (void) snprintf(c, end - c, ")");
+
+ BUFDUMPASSTR(bufdata, dtbda_flags, buf);
+ BUFDUMPHDR("");
+
+ if (pd != NULL) {
+ BUFDUMPHDR(" dtrace_probedesc");
+ BUFDUMPSTR(pd, dtpd_provider);
+ BUFDUMPSTR(pd, dtpd_mod);
+ BUFDUMPSTR(pd, dtpd_func);
+ BUFDUMPSTR(pd, dtpd_name);
+ BUFDUMPHDR("");
+ }
+
+ if (rec != NULL) {
+ BUFDUMPHDR(" dtrace_recdesc");
+ BUFDUMP(rec, dtrd_action);
+ BUFDUMP(rec, dtrd_size);
+
+ if (agg != NULL) {
+ uint8_t *data;
+ int lim = rec->dtrd_size;
+
+ (void) sprintf(buf, "%d (data: ", rec->dtrd_offset);
+ c = buf + strlen(buf);
+
+ if (lim > sizeof (uint64_t))
+ lim = sizeof (uint64_t);
+
+ data = (uint8_t *)agg->dtada_data + rec->dtrd_offset;
+
+ for (i = 0; i < lim; i++) {
+ (void) snprintf(c, end - c, "%s%02x",
+ i == 0 ? "" : " ", *data++);
+ c += strlen(c);
+ }
+
+ (void) snprintf(c, end - c,
+ "%s)", lim < rec->dtrd_size ? " ..." : "");
+ BUFDUMPASSTR(rec, dtrd_offset, buf);
+ } else {
+ BUFDUMP(rec, dtrd_offset);
+ }
+
+ BUFDUMPHDR("");
+ }
+
+ if (agg != NULL) {
+ dtrace_aggdesc_t *desc = agg->dtada_desc;
+
+ BUFDUMPHDR(" dtrace_aggdesc");
+ BUFDUMPSTR(desc, dtagd_name);
+ BUFDUMP(desc, dtagd_varid);
+ BUFDUMP(desc, dtagd_id);
+ BUFDUMP(desc, dtagd_nrecs);
+ BUFDUMPHDR("");
+ }
+
+ return (DTRACE_HANDLE_OK);
+}
+
+/*ARGSUSED*/
+static int
+chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg)
+{
+ dtrace_actkind_t act;
+ uintptr_t addr;
+
+ if (rec == NULL) {
+ /*
+ * We have processed the final record; output the newline if
+ * we're not in quiet mode.
+ */
+ if (!g_quiet)
+ oprintf("\n");
+
+ return (DTRACE_CONSUME_NEXT);
+ }
+
+ act = rec->dtrd_action;
+ addr = (uintptr_t)data->dtpda_data;
+
+ if (act == DTRACEACT_EXIT) {
+ g_status = *((uint32_t *)addr);
+ return (DTRACE_CONSUME_NEXT);
+ }
+
+ return (DTRACE_CONSUME_THIS);
+}
+
+/*ARGSUSED*/
+static int
+chew(const dtrace_probedata_t *data, void *arg)
+{
+ dtrace_probedesc_t *pd = data->dtpda_pdesc;
+ processorid_t cpu = data->dtpda_cpu;
+ static int heading;
+
+ if (g_impatient) {
+ g_newline = 0;
+ return (DTRACE_CONSUME_ABORT);
+ }
+
+ if (heading == 0) {
+ if (!g_flowindent) {
+ if (!g_quiet) {
+ oprintf("%3s %6s %32s\n",
+ "CPU", "ID", "FUNCTION:NAME");
+ }
+ } else {
+ oprintf("%3s %-41s\n", "CPU", "FUNCTION");
+ }
+ heading = 1;
+ }
+
+ if (!g_flowindent) {
+ if (!g_quiet) {
+ char name[DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 2];
+
+ (void) snprintf(name, sizeof (name), "%s:%s",
+ pd->dtpd_func, pd->dtpd_name);
+
+ oprintf("%3d %6d %32s ", cpu, pd->dtpd_id, name);
+ }
+ } else {
+ int indent = data->dtpda_indent;
+ char *name;
+ size_t len;
+
+ if (data->dtpda_flow == DTRACEFLOW_NONE) {
+ len = indent + DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 5;
+ name = alloca(len);
+ (void) snprintf(name, len, "%*s%s%s:%s", indent, "",
+ data->dtpda_prefix, pd->dtpd_func,
+ pd->dtpd_name);
+ } else {
+ len = indent + DTRACE_FUNCNAMELEN + 5;
+ name = alloca(len);
+ (void) snprintf(name, len, "%*s%s%s", indent, "",
+ data->dtpda_prefix, pd->dtpd_func);
+ }
+
+ oprintf("%3d %-41s ", cpu, name);
+ }
+
+ return (DTRACE_CONSUME_THIS);
+}
+
+static void
+go(void)
+{
+ int i;
+
+ struct {
+ char *name;
+ char *optname;
+ dtrace_optval_t val;
+ } bufs[] = {
+ { "buffer size", "bufsize" },
+ { "aggregation size", "aggsize" },
+ { "speculation size", "specsize" },
+ { "dynamic variable size", "dynvarsize" },
+ { NULL }
+ }, rates[] = {
+ { "cleaning rate", "cleanrate" },
+ { "status rate", "statusrate" },
+ { NULL }
+ };
+
+ for (i = 0; bufs[i].name != NULL; i++) {
+ if (dtrace_getopt(g_dtp, bufs[i].optname, &bufs[i].val) == -1)
+ fatal("couldn't get option %s", bufs[i].optname);
+ }
+
+ for (i = 0; rates[i].name != NULL; i++) {
+ if (dtrace_getopt(g_dtp, rates[i].optname, &rates[i].val) == -1)
+ fatal("couldn't get option %s", rates[i].optname);
+ }
+
+ if (dtrace_go(g_dtp) == -1)
+ dfatal("could not enable tracing");
+
+ for (i = 0; bufs[i].name != NULL; i++) {
+ dtrace_optval_t j = 0, mul = 10;
+ dtrace_optval_t nsize;
+
+ if (bufs[i].val == DTRACEOPT_UNSET)
+ continue;
+
+ (void) dtrace_getopt(g_dtp, bufs[i].optname, &nsize);
+
+ if (nsize == DTRACEOPT_UNSET || nsize == 0)
+ continue;
+
+ if (nsize >= bufs[i].val - sizeof (uint64_t))
+ continue;
+
+ for (; (INT64_C(1) << mul) <= nsize; j++, mul += 10)
+ continue;
+
+ if (!(nsize & ((INT64_C(1) << (mul - 10)) - 1))) {
+ error("%s lowered to %lld%c\n", bufs[i].name,
+ (long long)nsize >> (mul - 10), " kmgtpe"[j]);
+ } else {
+ error("%s lowered to %lld bytes\n", bufs[i].name,
+ (long long)nsize);
+ }
+ }
+
+ for (i = 0; rates[i].name != NULL; i++) {
+ dtrace_optval_t nval;
+ char *dir;
+
+ if (rates[i].val == DTRACEOPT_UNSET)
+ continue;
+
+ (void) dtrace_getopt(g_dtp, rates[i].optname, &nval);
+
+ if (nval == DTRACEOPT_UNSET || nval == 0)
+ continue;
+
+ if (rates[i].val == nval)
+ continue;
+
+ dir = nval > rates[i].val ? "reduced" : "increased";
+
+ if (nval <= NANOSEC && (NANOSEC % nval) == 0) {
+ error("%s %s to %lld hz\n", rates[i].name, dir,
+ (long long)NANOSEC / (long long)nval);
+ continue;
+ }
+
+ if ((nval % NANOSEC) == 0) {
+ error("%s %s to once every %lld seconds\n",
+ rates[i].name, dir,
+ (long long)nval / (long long)NANOSEC);
+ continue;
+ }
+
+ error("%s %s to once every %lld nanoseconds\n",
+ rates[i].name, dir, (long long)nval);
+ }
+}
+
+/*ARGSUSED*/
+static void
+intr(int signo)
+{
+ if (!g_intr)
+ g_newline = 1;
+
+ if (g_intr++)
+ g_impatient = 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ dtrace_bufdesc_t buf;
+ struct sigaction act, oact;
+ dtrace_status_t status[2];
+ dtrace_optval_t opt;
+ dtrace_cmd_t *dcp;
+
+ g_ofp = stdout;
+ int done = 0, mode = 0;
+ int err, i, c;
+ char *p, **v;
+ struct ps_prochandle *P;
+ pid_t pid;
+
+ g_pname = basename(argv[0]);
+
+ if (argc == 1)
+ return (usage(stderr));
+
+ if ((g_argv = malloc(sizeof (char *) * argc)) == NULL ||
+ (g_cmdv = malloc(sizeof (dtrace_cmd_t) * argc)) == NULL ||
+ (g_psv = malloc(sizeof (struct ps_prochandle *) * argc)) == NULL)
+ fatal("failed to allocate memory for arguments");
+
+ g_argv[g_argc++] = argv[0]; /* propagate argv[0] to D as $0/$$0 */
+ argv[0] = g_pname; /* rewrite argv[0] for getopt errors */
+
+ bzero(status, sizeof (status));
+ bzero(&buf, sizeof (buf));
+
+ /*
+ * Make an initial pass through argv[] processing any arguments that
+ * affect our behavior mode (g_mode) and flags used for dtrace_open().
+ * We also accumulate arguments that are not affiliated with getopt
+ * options into g_argv[], and abort if any invalid options are found.
+ */
+ for (optind = 1; optind < argc; optind++) {
+ while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != -1) {
+ switch (c) {
+ case '3':
+ if (strcmp(optarg, "2") != 0) {
+ (void) fprintf(stderr,
+ "%s: illegal option -- 3%s\n",
+ argv[0], optarg);
+ return (usage(stderr));
+ }
+ g_oflags &= ~DTRACE_O_LP64;
+ g_oflags |= DTRACE_O_ILP32;
+ break;
+
+ case '6':
+ if (strcmp(optarg, "4") != 0) {
+ (void) fprintf(stderr,
+ "%s: illegal option -- 6%s\n",
+ argv[0], optarg);
+ return (usage(stderr));
+ }
+ g_oflags &= ~DTRACE_O_ILP32;
+ g_oflags |= DTRACE_O_LP64;
+ break;
+
+ case 'a':
+ g_grabanon++; /* also checked in pass 2 below */
+ break;
+
+ case 'A':
+ g_mode = DMODE_ANON;
+ g_exec = 0;
+ mode++;
+ break;
+
+ case 'e':
+ g_exec = 0;
+ done = 1;
+ break;
+
+ case 'h':
+ g_mode = DMODE_HEADER;
+ g_oflags |= DTRACE_O_NODEV;
+ g_cflags |= DTRACE_C_ZDEFS; /* -h implies -Z */
+ g_exec = 0;
+ mode++;
+ break;
+
+ case 'G':
+ g_mode = DMODE_LINK;
+ g_oflags |= DTRACE_O_NODEV;
+ g_cflags |= DTRACE_C_ZDEFS; /* -G implies -Z */
+ g_exec = 0;
+ mode++;
+ break;
+
+ case 'l':
+ g_mode = DMODE_LIST;
+ g_cflags |= DTRACE_C_ZDEFS; /* -l implies -Z */
+ mode++;
+ break;
+
+ case 'V':
+ g_mode = DMODE_VERS;
+ mode++;
+ break;
+
+ default:
+ if (strchr(DTRACE_OPTSTR, c) == NULL)
+ return (usage(stderr));
+ }
+ }
+
+ if (optind < argc)
+ g_argv[g_argc++] = argv[optind];
+ }
+
+ if (mode > 1) {
+ (void) fprintf(stderr, "%s: only one of the [-AGhlV] options "
+ "can be specified at a time\n", g_pname);
+ return (E_USAGE);
+ }
+
+ if (g_mode == DMODE_VERS)
+ return (printf("%s: %s\n", g_pname, _dtrace_version) <= 0);
+
+ /*
+ * If we're in linker mode and the data model hasn't been specified,
+ * we try to guess the appropriate setting by examining the object
+ * files. We ignore certain errors since we'll catch them later when
+ * we actually process the object files.
+ */
+ if (g_mode == DMODE_LINK &&
+ (g_oflags & (DTRACE_O_ILP32 | DTRACE_O_LP64)) == 0 &&
+ elf_version(EV_CURRENT) != EV_NONE) {
+ int fd;
+ Elf *elf;
+ GElf_Ehdr ehdr;
+
+ for (i = 1; i < g_argc; i++) {
+ if ((fd = open64(g_argv[i], O_RDONLY)) == -1)
+ break;
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ (void) close(fd);
+ break;
+ }
+
+ if (elf_kind(elf) != ELF_K_ELF ||
+ gelf_getehdr(elf, &ehdr) == NULL) {
+ (void) close(fd);
+ (void) elf_end(elf);
+ break;
+ }
+
+ (void) close(fd);
+ (void) elf_end(elf);
+
+ if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ if (g_oflags & DTRACE_O_ILP32) {
+ fatal("can't mix 32-bit and 64-bit "
+ "object files\n");
+ }
+ g_oflags |= DTRACE_O_LP64;
+ } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
+ if (g_oflags & DTRACE_O_LP64) {
+ fatal("can't mix 32-bit and 64-bit "
+ "object files\n");
+ }
+ g_oflags |= DTRACE_O_ILP32;
+ } else {
+ break;
+ }
+ }
+ }
+
+ /*
+ * Open libdtrace. If we are not actually going to be enabling any
+ * instrumentation attempt to reopen libdtrace using DTRACE_O_NODEV.
+ */
+ while ((g_dtp = dtrace_open(DTRACE_VERSION, g_oflags, &err)) == NULL) {
+ if (!(g_oflags & DTRACE_O_NODEV) && !g_exec && !g_grabanon) {
+ g_oflags |= DTRACE_O_NODEV;
+ continue;
+ }
+
+ fatal("failed to initialize dtrace: %s\n",
+ dtrace_errmsg(NULL, err));
+ }
+
+#if defined(__i386__)
+ /* XXX The 32-bit seems to need more buffer space by default -sson */
+ (void) dtrace_setopt(g_dtp, "bufsize", "12m");
+ (void) dtrace_setopt(g_dtp, "aggsize", "12m");
+#else
+ (void) dtrace_setopt(g_dtp, "bufsize", "4m");
+ (void) dtrace_setopt(g_dtp, "aggsize", "4m");
+#endif
+
+ /*
+ * If -G is specified, enable -xlink=dynamic and -xunodefs to permit
+ * references to undefined symbols to remain as unresolved relocations.
+ * If -A is specified, enable -xlink=primary to permit static linking
+ * only to kernel symbols that are defined in a primary kernel module.
+ */
+ if (g_mode == DMODE_LINK) {
+ (void) dtrace_setopt(g_dtp, "linkmode", "dynamic");
+ (void) dtrace_setopt(g_dtp, "unodefs", NULL);
+
+ /*
+ * Use the remaining arguments as the list of object files
+ * when in linker mode.
+ */
+ g_objc = g_argc - 1;
+ g_objv = g_argv + 1;
+
+ /*
+ * We still use g_argv[0], the name of the executable.
+ */
+ g_argc = 1;
+ } else if (g_mode == DMODE_ANON)
+ (void) dtrace_setopt(g_dtp, "linkmode", "primary");
+
+ /*
+ * Now that we have libdtrace open, make a second pass through argv[]
+ * to perform any dtrace_setopt() calls and change any compiler flags.
+ * We also accumulate any program specifications into our g_cmdv[] at
+ * this time; these will compiled as part of the fourth processing pass.
+ */
+ for (optind = 1; optind < argc; optind++) {
+ while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != -1) {
+ switch (c) {
+ case 'a':
+ if (dtrace_setopt(g_dtp, "grabanon", 0) != 0)
+ dfatal("failed to set -a");
+ break;
+
+ case 'b':
+ if (dtrace_setopt(g_dtp,
+ "bufsize", optarg) != 0)
+ dfatal("failed to set -b %s", optarg);
+ break;
+
+ case 'B':
+ g_ofp = NULL;
+ break;
+
+ case 'C':
+ g_cflags |= DTRACE_C_CPP;
+ break;
+
+ case 'D':
+ if (dtrace_setopt(g_dtp, "define", optarg) != 0)
+ dfatal("failed to set -D %s", optarg);
+ break;
+
+ case 'f':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_str;
+ dcp->dc_spec = DTRACE_PROBESPEC_FUNC;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'F':
+ if (dtrace_setopt(g_dtp, "flowindent", 0) != 0)
+ dfatal("failed to set -F");
+ break;
+
+ case 'H':
+ if (dtrace_setopt(g_dtp, "cpphdrs", 0) != 0)
+ dfatal("failed to set -H");
+ break;
+
+ case 'i':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_str;
+ dcp->dc_spec = DTRACE_PROBESPEC_NAME;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'I':
+ if (dtrace_setopt(g_dtp, "incdir", optarg) != 0)
+ dfatal("failed to set -I %s", optarg);
+ break;
+
+ case 'L':
+ if (dtrace_setopt(g_dtp, "libdir", optarg) != 0)
+ dfatal("failed to set -L %s", optarg);
+ break;
+
+ case 'm':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_str;
+ dcp->dc_spec = DTRACE_PROBESPEC_MOD;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'n':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_str;
+ dcp->dc_spec = DTRACE_PROBESPEC_NAME;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'P':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_str;
+ dcp->dc_spec = DTRACE_PROBESPEC_PROVIDER;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'q':
+ if (dtrace_setopt(g_dtp, "quiet", 0) != 0)
+ dfatal("failed to set -q");
+ break;
+
+ case 'o':
+ g_ofile = optarg;
+ break;
+
+ case 's':
+ dcp = &g_cmdv[g_cmdc++];
+ dcp->dc_func = compile_file;
+ dcp->dc_spec = DTRACE_PROBESPEC_NONE;
+ dcp->dc_arg = optarg;
+ break;
+
+ case 'S':
+ g_cflags |= DTRACE_C_DIFV;
+ break;
+
+ case 'U':
+ if (dtrace_setopt(g_dtp, "undef", optarg) != 0)
+ dfatal("failed to set -U %s", optarg);
+ break;
+
+ case 'v':
+ g_verbose++;
+ break;
+
+ case 'w':
+ if (dtrace_setopt(g_dtp, "destructive", 0) != 0)
+ dfatal("failed to set -w");
+ break;
+
+ case 'x':
+ if ((p = strchr(optarg, '=')) != NULL)
+ *p++ = '\0';
+
+ if (dtrace_setopt(g_dtp, optarg, p) != 0)
+ dfatal("failed to set -x %s", optarg);
+ break;
+
+ case 'X':
+ if (dtrace_setopt(g_dtp, "stdc", optarg) != 0)
+ dfatal("failed to set -X %s", optarg);
+ break;
+
+ case 'Z':
+ g_cflags |= DTRACE_C_ZDEFS;
+ break;
+
+ default:
+ if (strchr(DTRACE_OPTSTR, c) == NULL)
+ return (usage(stderr));
+ }
+ }
+ }
+
+ if (g_ofp == NULL && g_mode != DMODE_EXEC) {
+ (void) fprintf(stderr, "%s: -B not valid in combination"
+ " with [-AGl] options\n", g_pname);
+ return (E_USAGE);
+ }
+
+ if (g_ofp == NULL && g_ofile != NULL) {
+ (void) fprintf(stderr, "%s: -B not valid in combination"
+ " with -o option\n", g_pname);
+ return (E_USAGE);
+ }
+
+ /*
+ * In our third pass we handle any command-line options related to
+ * grabbing or creating victim processes. The behavior of these calls
+ * may been affected by any library options set by the second pass.
+ */
+ for (optind = 1; optind < argc; optind++) {
+ while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != -1) {
+ switch (c) {
+ case 'c':
+ if ((v = make_argv(optarg)) == NULL)
+ fatal("failed to allocate memory");
+
+ P = dtrace_proc_create(g_dtp, v[0], v, NULL, NULL);
+ if (P == NULL)
+ dfatal(NULL); /* dtrace_errmsg() only */
+
+ g_psv[g_psc++] = P;
+ free(v);
+ break;
+
+ case 'p':
+ errno = 0;
+ pid = strtol(optarg, &p, 10);
+
+ if (errno != 0 || p == optarg || p[0] != '\0')
+ fatal("invalid pid: %s\n", optarg);
+
+ P = dtrace_proc_grab(g_dtp, pid, 0);
+ if (P == NULL)
+ dfatal(NULL); /* dtrace_errmsg() only */
+
+ g_psv[g_psc++] = P;
+ break;
+ }
+ }
+ }
+
+ /*
+ * In our fourth pass we finish g_cmdv[] by calling dc_func to convert
+ * each string or file specification into a compiled program structure.
+ */
+ for (i = 0; i < g_cmdc; i++)
+ g_cmdv[i].dc_func(&g_cmdv[i]);
+
+ if (g_mode != DMODE_LIST) {
+ if (dtrace_handle_err(g_dtp, &errhandler, NULL) == -1)
+ dfatal("failed to establish error handler");
+
+ if (dtrace_handle_drop(g_dtp, &drophandler, NULL) == -1)
+ dfatal("failed to establish drop handler");
+
+ if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1)
+ dfatal("failed to establish proc handler");
+
+ if (dtrace_handle_setopt(g_dtp, &setopthandler, NULL) == -1)
+ dfatal("failed to establish setopt handler");
+
+ if (g_ofp == NULL &&
+ dtrace_handle_buffered(g_dtp, &bufhandler, NULL) == -1)
+ dfatal("failed to establish buffered handler");
+ }
+
+ (void) dtrace_getopt(g_dtp, "flowindent", &opt);
+ g_flowindent = opt != DTRACEOPT_UNSET;
+
+ (void) dtrace_getopt(g_dtp, "grabanon", &opt);
+ g_grabanon = opt != DTRACEOPT_UNSET;
+
+ (void) dtrace_getopt(g_dtp, "quiet", &opt);
+ g_quiet = opt != DTRACEOPT_UNSET;
+
+ /*
+ * Now make a fifth and final pass over the options that have been
+ * turned into programs and saved in g_cmdv[], performing any mode-
+ * specific processing. If g_mode is DMODE_EXEC, we will break out
+ * of the switch() and continue on to the data processing loop. For
+ * other modes, we will exit dtrace once mode-specific work is done.
+ */
+ switch (g_mode) {
+ case DMODE_EXEC:
+ if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)
+ fatal("failed to open output file '%s'", g_ofile);
+
+ for (i = 0; i < g_cmdc; i++)
+ exec_prog(&g_cmdv[i]);
+
+ if (done && !g_grabanon) {
+ dtrace_close(g_dtp);
+ return (g_status);
+ }
+ break;
+
+ case DMODE_ANON:
+ if (g_ofile == NULL)
+#if defined(sun)
+ g_ofile = "/kernel/drv/dtrace.conf";
+#else
+ /*
+ * On FreeBSD, anonymous DOF data is written to
+ * the DTrace DOF file that the boot loader will
+ * read if booting with the DTrace option.
+ */
+ g_ofile = "/boot/dtrace.dof";
+#endif
+
+ dof_prune(g_ofile); /* strip out any old DOF directives */
+#if defined(sun)
+ etcsystem_prune(); /* string out any forceload directives */
+#endif
+
+ if (g_cmdc == 0) {
+ dtrace_close(g_dtp);
+ return (g_status);
+ }
+
+ if ((g_ofp = fopen(g_ofile, "a")) == NULL)
+ fatal("failed to open output file '%s'", g_ofile);
+
+ for (i = 0; i < g_cmdc; i++) {
+ anon_prog(&g_cmdv[i],
+ dtrace_dof_create(g_dtp, g_cmdv[i].dc_prog, 0), i);
+ }
+
+ /*
+ * Dump out the DOF corresponding to the error handler and the
+ * current options as the final DOF property in the .conf file.
+ */
+ anon_prog(NULL, dtrace_geterr_dof(g_dtp), i++);
+ anon_prog(NULL, dtrace_getopt_dof(g_dtp), i++);
+
+ if (fclose(g_ofp) == EOF)
+ fatal("failed to close output file '%s'", g_ofile);
+
+ /*
+ * These messages would use notice() rather than error(), but
+ * we don't want them suppressed when -A is run on a D program
+ * that itself contains a #pragma D option quiet.
+ */
+ error("saved anonymous enabling in %s\n", g_ofile);
+#if defined(sun)
+ etcsystem_add();
+ error("run update_drv(1M) or reboot to enable changes\n");
+#endif
+
+ dtrace_close(g_dtp);
+ return (g_status);
+
+ case DMODE_LINK:
+ if (g_cmdc == 0) {
+ (void) fprintf(stderr, "%s: -G requires one or more "
+ "scripts or enabling options\n", g_pname);
+ dtrace_close(g_dtp);
+ return (E_USAGE);
+ }
+
+ for (i = 0; i < g_cmdc; i++)
+ link_prog(&g_cmdv[i]);
+
+ if (g_cmdc > 1 && g_ofile != NULL) {
+ char **objv = alloca(g_cmdc * sizeof (char *));
+
+ for (i = 0; i < g_cmdc; i++)
+ objv[i] = g_cmdv[i].dc_ofile;
+
+ if (dtrace_program_link(g_dtp, NULL, DTRACE_D_PROBES,
+ g_ofile, g_cmdc, objv) != 0)
+ dfatal(NULL); /* dtrace_errmsg() only */
+ }
+
+ dtrace_close(g_dtp);
+ return (g_status);
+
+ case DMODE_LIST:
+ if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)
+ fatal("failed to open output file '%s'", g_ofile);
+
+ oprintf("%5s %10s %17s %33s %s\n",
+ "ID", "PROVIDER", "MODULE", "FUNCTION", "NAME");
+
+ for (i = 0; i < g_cmdc; i++)
+ list_prog(&g_cmdv[i]);
+
+ if (g_cmdc == 0)
+ (void) dtrace_probe_iter(g_dtp, NULL, list_probe, NULL);
+
+ dtrace_close(g_dtp);
+ return (g_status);
+
+ case DMODE_HEADER:
+ if (g_cmdc == 0) {
+ (void) fprintf(stderr, "%s: -h requires one or more "
+ "scripts or enabling options\n", g_pname);
+ dtrace_close(g_dtp);
+ return (E_USAGE);
+ }
+
+ if (g_ofile == NULL) {
+ char *p;
+
+ if (g_cmdc > 1) {
+ (void) fprintf(stderr, "%s: -h requires an "
+ "output file if multiple scripts are "
+ "specified\n", g_pname);
+ dtrace_close(g_dtp);
+ return (E_USAGE);
+ }
+
+ if ((p = strrchr(g_cmdv[0].dc_arg, '.')) == NULL ||
+ strcmp(p, ".d") != 0) {
+ (void) fprintf(stderr, "%s: -h requires an "
+ "output file if no scripts are "
+ "specified\n", g_pname);
+ dtrace_close(g_dtp);
+ return (E_USAGE);
+ }
+
+ p[0] = '\0'; /* strip .d suffix */
+ g_ofile = p = g_cmdv[0].dc_ofile;
+ (void) snprintf(p, sizeof (g_cmdv[0].dc_ofile),
+ "%s.h", basename(g_cmdv[0].dc_arg));
+ }
+
+ if ((g_ofp = fopen(g_ofile, "w")) == NULL)
+ fatal("failed to open header file '%s'", g_ofile);
+
+ oprintf("/*\n * Generated by dtrace(1M).\n */\n\n");
+
+ if (dtrace_program_header(g_dtp, g_ofp, g_ofile) != 0 ||
+ fclose(g_ofp) == EOF)
+ dfatal("failed to create header file %s", g_ofile);
+
+ dtrace_close(g_dtp);
+ return (g_status);
+ }
+
+ /*
+ * If -a and -Z were not specified and no probes have been matched, no
+ * probe criteria was specified on the command line and we abort.
+ */
+ if (g_total == 0 && !g_grabanon && !(g_cflags & DTRACE_C_ZDEFS))
+ dfatal("no probes %s\n", g_cmdc ? "matched" : "specified");
+
+ /*
+ * Start tracing. Once we dtrace_go(), reload any options that affect
+ * our globals in case consuming anonymous state has changed them.
+ */
+ go();
+
+ (void) dtrace_getopt(g_dtp, "flowindent", &opt);
+ g_flowindent = opt != DTRACEOPT_UNSET;
+
+ (void) dtrace_getopt(g_dtp, "grabanon", &opt);
+ g_grabanon = opt != DTRACEOPT_UNSET;
+
+ (void) dtrace_getopt(g_dtp, "quiet", &opt);
+ g_quiet = opt != DTRACEOPT_UNSET;
+
+ (void) dtrace_getopt(g_dtp, "destructive", &opt);
+ if (opt != DTRACEOPT_UNSET)
+ notice("allowing destructive actions\n");
+
+ (void) sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = intr;
+
+ if (sigaction(SIGINT, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
+ (void) sigaction(SIGINT, &act, NULL);
+
+ if (sigaction(SIGTERM, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
+ (void) sigaction(SIGTERM, &act, NULL);
+
+#if !defined(sun)
+ if (sigaction(SIGUSR1, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
+ (void) sigaction(SIGUSR1, &act, NULL);
+#endif
+
+ /*
+ * Now that tracing is active and we are ready to consume trace data,
+ * continue any grabbed or created processes, setting them running
+ * using the /proc control mechanism inside of libdtrace.
+ */
+ for (i = 0; i < g_psc; i++)
+ dtrace_proc_continue(g_dtp, g_psv[i]);
+
+ g_pslive = g_psc; /* count for prochandler() */
+
+ do {
+ if (!g_intr && !done)
+ dtrace_sleep(g_dtp);
+
+ if (g_newline) {
+ /*
+ * Output a newline just to make the output look
+ * slightly cleaner. Note that we do this even in
+ * "quiet" mode...
+ */
+ oprintf("\n");
+ g_newline = 0;
+ }
+
+ if (done || g_intr || (g_psc != 0 && g_pslive == 0)) {
+ done = 1;
+ if (dtrace_stop(g_dtp) == -1)
+ dfatal("couldn't stop tracing");
+ }
+
+ switch (dtrace_work(g_dtp, g_ofp, chew, chewrec, NULL)) {
+ case DTRACE_WORKSTATUS_DONE:
+ done = 1;
+ break;
+ case DTRACE_WORKSTATUS_OKAY:
+ break;
+ default:
+ if (!g_impatient && dtrace_errno(g_dtp) != EINTR)
+ dfatal("processing aborted");
+ }
+
+ if (g_ofp != NULL && fflush(g_ofp) == EOF)
+ clearerr(g_ofp);
+ } while (!done);
+
+ oprintf("\n");
+
+ if (!g_impatient) {
+ if (dtrace_aggregate_print(g_dtp, g_ofp, NULL) == -1 &&
+ dtrace_errno(g_dtp) != EINTR)
+ dfatal("failed to print aggregations");
+ }
+
+ dtrace_close(g_dtp);
+ return (g_status);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/README b/cddl/contrib/opensolaris/cmd/dtrace/test/README
new file mode 100644
index 0000000..51ab650
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/README
@@ -0,0 +1,32 @@
+
+CDDL HEADER START
+
+The contents of this file are subject to the terms of the
+Common Development and Distribution License (the "License").
+You may not use this file except in compliance with the License.
+
+You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+or http://www.opensolaris.org/os/licensing.
+See the License for the specific language governing permissions
+and limitations under the License.
+
+When distributing Covered Code, include this CDDL HEADER in each
+file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+If applicable, add the following below this CDDL HEADER, with the
+fields enclosed by brackets "[]" replaced with your own identifying
+information: Portions Copyright [yyyy] [name of copyright owner]
+
+CDDL HEADER END
+
+Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+Use is subject to license terms.
+
+ident "%Z%%M% %I% %E% SMI"
+
+DTrace Testing Suite
+
+The SUNWdtrt package delivers a set of test programs and D source
+files into the directory /opt/SUNWdtrt. For more information see
+the following web site:
+
+ http://www.opensolaris.org/os/community/dtrace/dtest
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c
new file mode 100644
index 0000000..1c14c65
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c
@@ -0,0 +1,207 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/varargs.h>
+#include <errno.h>
+#include <math.h>
+#include <dtrace.h>
+
+void
+fatal(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ fprintf(stderr, "%s: ", "baddof");
+ vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ fprintf(stderr, ": %s\n", strerror(errno));
+
+ exit(1);
+}
+
+#define LEAP_DISTANCE 20
+
+void
+corrupt(int fd, unsigned char *buf, int len)
+{
+ static int ttl, valid;
+ int bit, i;
+ unsigned char saved;
+ int val[LEAP_DISTANCE], pos[LEAP_DISTANCE];
+ int new, rv;
+
+again:
+ printf("valid DOF #%d\n", valid++);
+
+ /*
+ * We are going iterate through, flipping one bit and attempting
+ * to enable.
+ */
+ for (bit = 0; bit < len * 8; bit++) {
+ saved = buf[bit / 8];
+ buf[bit / 8] ^= (1 << (bit % 8));
+
+ if ((bit % 100) == 0)
+ printf("%d\n", bit);
+
+ if ((rv = ioctl(fd, DTRACEIOC_ENABLE, buf)) == -1) {
+ /*
+ * That failed -- restore the bit and drive on.
+ */
+ buf[bit / 8] = saved;
+ continue;
+ }
+
+ /*
+ * That worked -- and it may have enabled probes. To keep
+ * enabled probes down to a reasonable level, we'll close
+ * and reopen pseudodevice if we have more than 10,000
+ * probes enabled.
+ */
+ ttl += rv;
+
+ if (ttl < 10000) {
+ buf[bit / 8] = saved;
+ continue;
+ }
+
+ printf("enabled %d probes; resetting device.\n", ttl);
+ close(fd);
+
+ new = open("/devices/pseudo/dtrace@0:dtrace", O_RDWR);
+
+ if (new == -1)
+ fatal("couldn't open DTrace pseudo device");
+
+ if (new != fd) {
+ dup2(new, fd);
+ close(new);
+ }
+
+ ttl = 0;
+ buf[bit / 8] = saved;
+ }
+
+ for (;;) {
+ /*
+ * Now we want to get as many bits away as possible. We flip
+ * bits randomly -- getting as far away as we can until we don't
+ * seem to be making any progress.
+ */
+ for (i = 0; i < LEAP_DISTANCE; i++) {
+ /*
+ * Pick a random bit and corrupt it.
+ */
+ bit = lrand48() % (len * 8);
+
+ val[i] = buf[bit / 8];
+ pos[i] = bit / 8;
+ buf[bit / 8] ^= (1 << (bit % 8));
+ }
+
+ /*
+ * Let's see if that managed to get us valid DOF...
+ */
+ if ((rv = ioctl(fd, DTRACEIOC_ENABLE, buf)) > 0) {
+ /*
+ * Success! This will be our new base for valid DOF.
+ */
+ ttl += rv;
+ goto again;
+ }
+
+ /*
+ * No luck -- we'll restore those bits and try flipping a
+ * different set. Note that this must be done in reverse
+ * order...
+ */
+ for (i = LEAP_DISTANCE - 1; i >= 0; i--)
+ buf[pos[i]] = val[i];
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char *filename = argv[1];
+ dtrace_hdl_t *dtp;
+ dtrace_prog_t *pgp;
+ int err, fd, len;
+ FILE *fp;
+ unsigned char *dof, *copy;
+
+ if (argc < 2)
+ fatal("expected D script as argument\n");
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ fatal("couldn't open %s", filename);
+
+ /*
+ * First, we need to compile our provided D into DOF.
+ */
+ if ((dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
+ fatal("cannot open dtrace library: %s\n",
+ dtrace_errmsg(NULL, err));
+ }
+
+ pgp = dtrace_program_fcompile(dtp, fp, 0, 0, NULL);
+ fclose(fp);
+
+ if (pgp == NULL) {
+ fatal("failed to compile script %s: %s\n", filename,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ dof = dtrace_dof_create(dtp, pgp, 0);
+ len = ((dof_hdr_t *)dof)->dofh_loadsz;
+
+ if ((copy = malloc(len)) == NULL)
+ fatal("could not allocate copy of %d bytes", len);
+
+ for (;;) {
+ bcopy(dof, copy, len);
+ /*
+ * Open another instance of the dtrace device.
+ */
+ fd = open("/devices/pseudo/dtrace@0:dtrace", O_RDWR);
+
+ if (fd == -1)
+ fatal("couldn't open DTrace pseudo device");
+
+ corrupt(fd, copy, len);
+ close(fd);
+ }
+
+ /* NOTREACHED */
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/badioctl/badioctl.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/badioctl/badioctl.c
new file mode 100644
index 0000000..8d6833d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/badioctl/badioctl.c
@@ -0,0 +1,145 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/varargs.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8))
+#define DTRACEIOC_MAX 17
+
+void
+fatal(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ fprintf(stderr, "%s: ", "badioctl");
+ vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ fprintf(stderr, ": %s\n", strerror(errno));
+
+ exit(1);
+}
+
+void
+badioctl(pid_t parent)
+{
+ int fd = -1, random, ps = sysconf(_SC_PAGESIZE);
+ int i = 0, seconds;
+ caddr_t addr;
+ hrtime_t now, last = 0, end;
+
+ if ((random = open("/dev/random", O_RDONLY)) == -1)
+ fatal("couldn't open /dev/random");
+
+ if ((addr = mmap(0, ps, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0)) == (caddr_t)-1)
+ fatal("mmap");
+
+ for (;;) {
+ unsigned int ioc;
+
+ if ((now = gethrtime()) - last > NANOSEC) {
+ if (kill(parent, 0) == -1 && errno == ESRCH) {
+ /*
+ * Our parent died. We will kill ourselves in
+ * sympathy.
+ */
+ exit(0);
+ }
+
+ /*
+ * Once a second, we'll reopen the device.
+ */
+ if (fd != -1)
+ close(fd);
+
+ fd = open("/devices/pseudo/dtrace@0:dtrace", O_RDONLY);
+
+ if (fd == -1)
+ fatal("couldn't open DTrace pseudo device");
+
+ last = now;
+ }
+
+
+ if ((i++ % 1000) == 0) {
+ /*
+ * Every thousand iterations, change our random gunk.
+ */
+ read(random, addr, ps);
+ }
+
+ read(random, &ioc, sizeof (ioc));
+ ioc %= DTRACEIOC_MAX;
+ ioc++;
+ ioctl(fd, DTRACEIOC | ioc, addr);
+ }
+}
+
+int
+main()
+{
+ pid_t child, parent = getpid();
+ int status;
+
+ for (;;) {
+ if ((child = fork()) == 0)
+ badioctl(parent);
+
+ while (waitpid(child, &status, WEXITED) != child)
+ continue;
+
+ if (WIFEXITED(status)) {
+ /*
+ * Our child exited by design -- we'll exit with
+ * the same status code.
+ */
+ exit(WEXITSTATUS(status));
+ }
+
+ /*
+ * Our child died on a signal. Respawn it.
+ */
+ printf("badioctl: child died on signal %d; respawning.\n",
+ WTERMSIG(status));
+ fflush(stdout);
+ }
+
+ /* NOTREACHED */
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c
new file mode 100644
index 0000000..a7e0222
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c
@@ -0,0 +1,149 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <strings.h>
+#include <unistd.h>
+#include <dtrace.h>
+
+static int g_count;
+static int g_errs;
+static int g_fd;
+static int g_verbose;
+static int g_errexit;
+static char *g_progname;
+
+static int
+probe(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *data)
+{
+ dtrace_probeinfo_t p;
+ dtrace_argdesc_t arg;
+ char buf[BUFSIZ];
+ int i;
+
+ (void) printf("\r%6d", ++g_count);
+ (void) fflush(stdout);
+
+ if (dtrace_probe_info(dtp, pdp, &p) != 0) {
+ (void) printf(" failed to get probe info for "
+ "%s:%s:%s:%s [%d]\n", pdp->dtpd_provider, pdp->dtpd_mod,
+ pdp->dtpd_func, pdp->dtpd_name, pdp->dtpd_id);
+ g_errs++;
+ return (0);
+ }
+
+ for (i = 0; i < p.dtp_argc; i++) {
+ if (p.dtp_argv[i].dtt_type == CTF_ERR) {
+ bzero(&arg, sizeof (dtrace_argdesc_t));
+ arg.dtargd_id = pdp->dtpd_id;
+ arg.dtargd_ndx = i;
+ (void) ioctl(g_fd, DTRACEIOC_PROBEARG, &arg);
+
+ (void) printf(" failed to get types for args[%d] "
+ "of %s:%s:%s:%s [%d]: <%s> -> <%s>\n", i,
+ pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func,
+ pdp->dtpd_name, pdp->dtpd_id,
+ arg.dtargd_native, arg.dtargd_xlate);
+
+ g_errs++;
+
+ if (g_errexit)
+ return (-1);
+
+ } else if (g_verbose) {
+ (void) printf("%d args[%d] : %s\n", pdp->dtpd_id, i,
+ ctf_type_name(p.dtp_argv[i].dtt_ctfp,
+ p.dtp_argv[i].dtt_type, buf, sizeof (buf)));
+ }
+ }
+
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ dtrace_probedesc_t pd, *pdp = NULL;
+ dtrace_hdl_t *dtp;
+ int err, c;
+ char *p;
+
+ g_progname = argv[0];
+
+ if ((dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
+ (void) fprintf(stderr, "%s: failed to open dtrace: %s\n",
+ g_progname, dtrace_errmsg(dtp, err));
+ return (1);
+ }
+
+ while ((c = getopt(argc, argv, "evx:")) != -1) {
+ switch (c) {
+ case 'e':
+ g_errexit++;
+ break;
+ case 'v':
+ g_verbose++;
+ break;
+ case 'x':
+ if ((p = strchr(optarg, '=')) != NULL)
+ *p++ = '\0';
+
+ if (dtrace_setopt(dtp, optarg, p) != 0) {
+ (void) fprintf(stderr, "%s: failed to set "
+ "option -x %s: %s\n", g_progname, optarg,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ return (2);
+ }
+ break;
+
+ default:
+ (void) fprintf(stderr, "Usage: %s [-ev] "
+ "[-x opt[=arg]] [probedesc]\n", g_progname);
+ return (2);
+ }
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ if (argc > 0) {
+ if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, argv[0], &pd)) {
+ (void) fprintf(stderr, "%s: invalid probe description "
+ "%s: %s\n", g_progname, argv[0],
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ return (2);
+ }
+ pdp = &pd;
+ }
+
+ g_fd = dtrace_ctlfd(dtp);
+ (void) dtrace_probe_iter(dtp, pdp, probe, NULL);
+ dtrace_close(dtp);
+
+ (void) printf("\nTotal probes: %d\n", g_count);
+ (void) printf("Total errors: %d\n\n", g_errs);
+
+ return (g_errs != 0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/Getopt.java b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/Getopt.java
new file mode 100644
index 0000000..e06a170
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/Getopt.java
@@ -0,0 +1,453 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+/**
+ * A Java port of Solaris {@code lib/libc/port/gen/getopt.c}, which is a
+ * port of System V UNIX getopt. See <b>getopt(3C)</b> and SUS/XPG
+ * getopt() for function definition and requirements. Unlike that
+ * definition, this implementation moves non-options to the end of the
+ * argv array rather than quitting at the first non-option.
+ */
+public class Getopt {
+ static final int EOF = -1;
+
+ private String progname;
+ private String[] args;
+ private int argc;
+ private String optstring;
+ private int optind = 0; // args index
+ private int optopt = 0;
+ private String optarg = null;
+ private boolean opterr = true;
+
+ /*
+ * _sp is required to keep state between successive calls to
+ * getopt() while extracting aggregated short-options (ie: -abcd).
+ */
+ private int _sp = 1;
+
+ /**
+ * Creates a {Code Getopt} instance to parse the given command-line
+ * arguments. Modifies the given args array by swapping the
+ * positions of non-options and options so that non-options appear
+ * at the end of the array.
+ */
+ public Getopt(String programName, String[] args,
+ String optionString)
+ {
+ progname = programName;
+ // No defensive copy; Getopt is expected to modify the given
+ // args array
+ this.args = args;
+ argc = this.args.length;
+ optstring = optionString;
+ validate();
+ }
+
+ private void
+ validate()
+ {
+ if (progname == null) {
+ throw new NullPointerException("program name is null");
+ }
+ int i = 0;
+ for (String s : args) {
+ if (s == null) {
+ throw new NullPointerException("null arg at index " + i);
+ }
+ ++i;
+ }
+ if (optstring == null) {
+ throw new NullPointerException("option string is null");
+ }
+ }
+
+ private static class StringRef {
+ private String s;
+
+ public String
+ get()
+ {
+ return s;
+ }
+
+ public StringRef
+ set(String value)
+ {
+ s = value;
+ return this;
+ }
+ }
+
+ /*
+ * Generalized error processing method. If the optstr parameter is
+ * null, the character c is converted to a string and displayed
+ * instead.
+ */
+ void
+ err(String format, char c, String optstr)
+ {
+ if (opterr && optstring.charAt(0) != ':') {
+ StringWriter w = new StringWriter();
+ PrintWriter p = new PrintWriter(w);
+ p.printf(format, progname, (optstr == null ?
+ Character.toString(c) : optstr.substring(2)));
+ System.err.println(w.toString());
+ }
+ }
+
+ /*
+ * Determine if the specified character (c) is present in the string
+ * (optstring) as a regular, single character option. If the option
+ * is found, return an index into optstring where the short-option
+ * character is found, otherwise return -1. The characters ':' and
+ * '(' are not allowed.
+ */
+ static int
+ parseshort(String optstring, char c)
+ {
+ if (c == ':' || c == '(') {
+ return -1;
+ }
+
+ int ch;
+ int len = optstring.length();
+ for (int i = 0; i < len; ++i) {
+ ch = optstring.charAt(i);
+ if (ch == c) {
+ return i;
+ }
+
+ while (i < len && ch == '(') {
+ for (++i; i < len && (ch = optstring.charAt(i)) != ')'; ++i);
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Determine if the specified string (opt) is present in the string
+ * (optstring) as a long-option contained within parenthesis. If the
+ * long-option specifies option-argument, return a reference to it
+ * in longoptarg. Otherwise set the longoptarg reference to null.
+ * If the option is found, return an index into optstring at the
+ * position of the short-option character associated with the
+ * long-option; otherwise return -1.
+ *
+ * @param optstring the entire optstring passed to the {@code
+ * Getopt} constructor
+ * @param opt the long option read from the command line
+ * @param longoptarg the value of the option is returned in this
+ * parameter, if an option exists. Possible return values in
+ * longoptarg are:
+ * <ul>
+ * <li><b>NULL:</b> No argument was found</li>
+ * <li><b>empty string (""):</b> Argument was explicitly left empty
+ * by the user (e.g., --option= )</li>
+ * <li><b>valid string:</b> Argument found on the command line</li>
+ * </ul>
+ * @return index to equivalent short-option in optstring, or -1 if
+ * option not found in optstring.
+ */
+ static int
+ parselong(String optstring, String opt, StringRef longoptarg)
+ {
+ int cp; // index into optstring, beginning of one option spec
+ int ip; // index into optstring, traverses every char
+ char ic; // optstring char
+ int il; // optstring length
+ int op; // index into opt
+ char oc; // opt char
+ int ol; // opt length
+ boolean match; // true if opt is matching part of optstring
+
+ longoptarg.set(null);
+ cp = ip = 0;
+ il = optstring.length();
+ ol = opt.length();
+ do {
+ ic = optstring.charAt(ip);
+ if (ic != '(' && ++ip == il)
+ break;
+ ic = optstring.charAt(ip);
+ if (ic == ':' && ++ip == il)
+ break;
+ ic = optstring.charAt(ip);
+ while (ic == '(') {
+ if (++ip == il)
+ break;
+ op = 0;
+ match = true;
+ while (ip < il && (ic = optstring.charAt(ip)) != ')' &&
+ op < ol) {
+ oc = opt.charAt(op++);
+ match = (ic == oc && match);
+ ++ip;
+ }
+
+ if (match && ip < il && ic == ')' && (op >= ol ||
+ opt.charAt(op) == '=')) {
+ if (op < ol && opt.charAt(op) == '=') {
+ /* may be an empty string - OK */
+ longoptarg.set(opt.substring(op + 1));
+ } else {
+ longoptarg.set(null);
+ }
+ return cp;
+ }
+ if (ip < il && ic == ')' && ++ip == il)
+ break;
+ ic = optstring.charAt(ip);
+ }
+ cp = ip;
+ /*
+ * Handle double-colon in optstring ("a::(longa)") The old
+ * getopt() accepts it and treats it as a required argument.
+ */
+ while ((cp > 0) && (cp < il) && (optstring.charAt(cp) == ':')) {
+ --cp;
+ }
+ } while (cp < il);
+ return -1;
+ }
+
+ /**
+ * Get the current option value.
+ */
+ public String
+ getOptarg()
+ {
+ return optarg;
+ }
+
+ /**
+ * Get the index of the next option to be parsed.
+ */
+ public int
+ getOptind()
+ {
+ return optind;
+ }
+
+ /**
+ * Gets the command-line arguments.
+ */
+ public String[]
+ getArgv()
+ {
+ // No defensive copy: Getopt is expected to modify the given
+ // args array.
+ return args;
+ }
+
+ /**
+ * Gets the aggregated short option that just failed. Since long
+ * options can't be aggregated, a failed long option can be obtained
+ * by {@code getArgv()[getOptind() - 1]}.
+ */
+ public int
+ getOptopt()
+ {
+ return optopt;
+ }
+
+ /**
+ * Set to {@code false} to suppress diagnostic messages to stderr.
+ */
+ public void
+ setOpterr(boolean err)
+ {
+ opterr = err;
+ }
+
+ /**
+ * Gets the next option character, or -1 if there are no more
+ * options. If getopt() encounters a short-option character or a
+ * long-option string not described in the {@code optionString}
+ * argument to the constructor, it returns the question-mark (?)
+ * character. If it detects a missing option-argument, it also
+ * returns the question-mark (?) character, unless the first
+ * character of the {@code optionString} argument was a colon (:),
+ * in which case getopt() returns the colon (:) character.
+ * <p>
+ * This implementation swaps the positions of options and
+ * non-options in the given argv array.
+ */
+ public int
+ getopt()
+ {
+ char c;
+ int cp;
+ boolean longopt;
+ StringRef longoptarg = new StringRef();
+
+ /*
+ * Has the end of the options been encountered? The following
+ * implements the SUS requirements:
+ *
+ * If, when getopt() is called:
+ * - the first character of argv[optind] is not '-'
+ * - argv[optind] is the string "-"
+ * getopt() returns -1 without changing optind if
+ * - argv[optind] is the string "--"
+ * getopt() returns -1 after incrementing optind
+ */
+ if (_sp == 1) {
+ boolean nonOption;
+ do {
+ nonOption = false;
+ if (optind >= argc || args[optind].equals("-")) {
+ return EOF;
+ } else if (args[optind].equals("--")) {
+ ++optind;
+ return EOF;
+ } else if (args[optind].charAt(0) != '-') {
+ // non-option: here we deviate from the SUS requirements
+ // by not quitting, and instead move non-options to the
+ // end of the args array
+ nonOption = true;
+ String tmp = args[optind];
+ if (optind + 1 < args.length) {
+ System.arraycopy(args, optind + 1, args, optind,
+ args.length - (optind + 1));
+ args[args.length - 1] = tmp;
+ }
+ --argc;
+ }
+ } while (nonOption);
+ }
+
+ /*
+ * Getting this far indicates that an option has been encountered.
+ * Note that the syntax of optstring applies special meanings to
+ * the characters ':' and '(', so they are not permissible as
+ * option letters. A special meaning is also applied to the ')'
+ * character, but its meaning can be determined from context.
+ * Note that the specification only requires that the alnum
+ * characters be accepted.
+ *
+ * If the second character of the argument is a '-' this must be
+ * a long-option, otherwise it must be a short option. Scan for
+ * the option in optstring by the appropriate algorithm. Either
+ * scan will return an index to the short-option character in
+ * optstring if the option is found and -1 otherwise.
+ *
+ * For an unrecognized long-option, optopt will equal 0, but
+ * since long-options can't aggregate the failing option can be
+ * identified by argv[optind-1].
+ */
+ optopt = c = args[optind].charAt(_sp);
+ optarg = null;
+ longopt = (_sp == 1 && c == '-');
+ if (!(longopt
+ ? ((cp = parselong(optstring, args[optind].substring(2),
+ longoptarg)) != -1)
+ : ((cp = parseshort(optstring, c)) != -1))) {
+ err("%s: illegal option -- %s", c,
+ (longopt ? args[optind] : null));
+ /*
+ * Note: When the long option is unrecognized, optopt will
+ * be '-' here, which matches the specification.
+ */
+ if (args[optind].length() == ++_sp || longopt) {
+ ++optind;
+ _sp = 1;
+ }
+ return '?';
+ }
+ optopt = c = optstring.charAt(cp);
+
+ /*
+ * A valid option has been identified. If it should have an
+ * option-argument, process that now. SUS defines the setting
+ * of optarg as follows:
+ *
+ * 1. If the option was the last character in an element of
+ * argv, then optarg contains the next element of argv, and
+ * optind is incremented by 2. If the resulting value of
+ * optind is not less than argc, this indicates a missing
+ * option-argument, and getopt() returns an error indication.
+ *
+ * 2. Otherwise, optarg points to the string following the
+ * option character in that element of argv, and optind is
+ * incremented by 1.
+ *
+ * The second clause allows -abcd (where b requires an
+ * option-argument) to be interpreted as "-a -b cd".
+ *
+ * Note that the option-argument can legally be an empty string,
+ * such as:
+ * command --option= operand
+ * which explicitly sets the value of --option to nil
+ */
+ if (cp + 1 < optstring.length() && optstring.charAt(cp + 1) == ':') {
+ // The option takes an argument
+ if (!longopt && ((_sp + 1) < args[optind].length())) {
+ optarg = args[optind++].substring(_sp + 1);
+ } else if (longopt && (longoptarg.get() != null)) {
+ /*
+ * The option argument was explicitly set to the empty
+ * string on the command line (--option=)
+ */
+ optind++;
+ optarg = longoptarg.get();
+ } else if (++optind >= argc) {
+ err("%s: option requires an argument -- %s", c,
+ (longopt ? args[optind - 1] : null));
+ _sp = 1;
+ optarg = null;
+ return (optstring.charAt(0) == ':' ? ':' : '?');
+ } else
+ optarg = args[optind++];
+ _sp = 1;
+ } else {
+ // The option does NOT take an argument
+ if (longopt && (longoptarg.get() != null)) {
+ // User supplied an arg to an option that takes none
+ err("%s: option doesn't take an argument -- %s", (char)0,
+ (longopt ? args[optind] : null));
+ optarg = longoptarg.set(null).get();
+ c = '?';
+ }
+
+ if (longopt || args[optind].length() == ++_sp) {
+ _sp = 1;
+ ++optind;
+ }
+ optarg = null;
+ }
+ return (c);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java
new file mode 100644
index 0000000..3c5654d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java
@@ -0,0 +1,1042 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+import org.opensolaris.os.dtrace.*;
+import java.io.*;
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Emulates {@code dtrace(1M)} using the Java DTrace API.
+ */
+public class JDTrace {
+ static Logger logger = Logger.getLogger(JDTrace.class.getName());
+
+ static Consumer dtrace;
+
+ static {
+ Handler handler = new ConsoleHandler();
+ handler.setLevel(Level.ALL);
+ logger.addHandler(handler);
+ }
+
+ static final String CLASSNAME = "JDTrace";
+ static final String OPTSTR =
+ "3:6:b:c:CD:ef:Fi:I:lL:m:n:o:p:P:qs:U:vVwx:X:Z";
+ static boolean heading = false;
+ static boolean quiet = false;
+ static boolean flow = false;
+ static int stackindent = 14;
+ static int exitStatus = 0;
+ static boolean started;
+ static boolean stopped;
+ static PrintStream out = System.out;
+ static final String ATS = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
+ static final String SPACES = " ";
+ static final int QUANTIZE_ZERO_BUCKET = 63;
+
+ enum Mode {
+ EXEC,
+ INFO,
+ LIST,
+ VERSION
+ }
+
+ enum ProgramType {
+ STRING,
+ FILE
+ }
+
+ static class CompileRequest {
+ String s;
+ ProgramType type;
+ ProbeDescription.Spec probespec;
+ }
+
+ // Modify program string by expanding an incomplete probe
+ // description according to the requested probespec.
+ static void
+ applyProbespec(CompileRequest req)
+ {
+ ProbeDescription.Spec spec = ((req.probespec == null)
+ ? ProbeDescription.Spec.NAME
+ : req.probespec);
+
+ int colons = 0;
+ switch (req.probespec) {
+ case PROVIDER:
+ colons = 3;
+ break;
+ case MODULE:
+ colons = 2;
+ break;
+ case FUNCTION:
+ colons = 1;
+ break;
+ }
+
+ StringBuffer buf = new StringBuffer();
+ if (colons > 0) {
+ char ch;
+ int len = req.s.length();
+
+ int i = 0;
+ // Find first whitespace character not including leading
+ // whitespace (end of first token). Ignore whitespace
+ // inside a block if the block is concatenated with the
+ // probe description.
+ for (; (i < len) && Character.isWhitespace(req.s.charAt(i)); ++i);
+ int npos = i;
+ boolean inBlock = false;
+ for (; (npos < len) &&
+ (!Character.isWhitespace(ch = req.s.charAt(npos)) ||
+ inBlock); ++npos) {
+ if (ch == '{') {
+ inBlock = true;
+ } else if (ch == '}') {
+ inBlock = false;
+ }
+ }
+
+ // libdtrace lets you concatenate multiple probe
+ // descriptions separated by code blocks in curly braces,
+ // for example genunix::'{printf("FOUND");}'::entry, as long
+ // as the concatenated probe descriptions begin with ':' and
+ // not a specific field such as 'syscall'. So to expand the
+ // possibly multiple probe descriptions, we need to insert
+ // colons before each open curly brace, and again at the end
+ // only if there is at least one non-whitespace (probe
+ // specifying) character after the last closing curly brace.
+
+ int prev_i = 0;
+ while (i < npos) {
+ for (; (i < npos) && (req.s.charAt(i) != '{'); ++i);
+ buf.append(req.s.substring(prev_i, i));
+ if ((i < npos) || ((i > 0) && (req.s.charAt(i - 1) != '}'))) {
+ for (int c = 0; c < colons; ++c) {
+ buf.append(':');
+ }
+ }
+ if (i < npos) {
+ buf.append(req.s.charAt(i++));
+ }
+ prev_i = i;
+ }
+
+ // append remainder of program text
+ buf.append(req.s.substring(i));
+
+ req.s = buf.toString();
+ }
+ }
+
+ static void
+ printValue(Object value, int bytes, String stringFormat)
+ {
+ if (value instanceof Integer) {
+ if (bytes == 1) {
+ out.printf(" %3d", (Integer)value);
+ } else if (bytes == 2) {
+ out.printf(" %5d", (Integer)value);
+ } else {
+ out.printf(" %8d", (Integer)value);
+ }
+ } else if (value instanceof Long) {
+ out.printf(" %16d", (Long)value);
+ } else {
+ out.printf(stringFormat, value.toString());
+ }
+ }
+
+ static void
+ consumeProbeData(ProbeData data)
+ {
+ if (logger.isLoggable(Level.FINER)) {
+ logger.finer(data.toString());
+ }
+
+ if (!heading) {
+ if (flow) {
+ out.printf("%3s %-41s\n", "CPU", "FUNCTION");
+ } else {
+ if (!quiet) {
+ out.printf("%3s %6s %32s\n",
+ "CPU", "ID", "FUNCTION:NAME");
+ }
+ }
+ heading = true;
+ }
+ ProbeDescription probe = data.getEnabledProbeDescription();
+ if (flow) {
+ Flow flow = data.getFlow();
+ int indent = (flow.getDepth() * 2);
+ StringBuffer buf = new StringBuffer();
+ // indent
+ buf.append(' ');
+ for (int i = 0; i < indent; ++i) {
+ buf.append(' ');
+ }
+ // prefix
+ switch (flow.getKind()) {
+ case ENTRY:
+ if (indent == 0) {
+ buf.append("=> ");
+ } else {
+ buf.append("-> ");
+ }
+ break;
+ case RETURN:
+ if (indent == 0) {
+ buf.append("<= ");
+ } else {
+ buf.append("<- ");
+ }
+ break;
+ }
+
+ switch (flow.getKind()) {
+ case NONE:
+ buf.append(probe.getFunction());
+ buf.append(':');
+ buf.append(probe.getName());
+ break;
+ default:
+ buf.append(probe.getFunction());
+ }
+
+ out.printf("%3s %-41s ", data.getCPU(),
+ buf.toString());
+ } else {
+ if (!quiet) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(probe.getFunction());
+ buf.append(':');
+ buf.append(probe.getName());
+ out.printf("%3s %6s %32s ",
+ data.getCPU(), probe.getID(),
+ buf.toString());
+ }
+ }
+ Record record = null;
+ Object value;
+ List <Record> records = data.getRecords();
+ Iterator <Record> itr = records.iterator();
+ while (itr.hasNext()) {
+ record = itr.next();
+
+ if (record instanceof ExitRecord) {
+ exitStatus = ((ExitRecord)record).getStatus();
+ } else if (record instanceof ScalarRecord) {
+ ScalarRecord scalar = (ScalarRecord)record;
+ value = scalar.getValue();
+ if (value instanceof byte[]) {
+ out.print(record.toString());
+ } else {
+ if (quiet) {
+ out.print(value);
+ } else {
+ printValue(value, scalar.getNumberOfBytes(),
+ " %-33s");
+ }
+ }
+ } else if (record instanceof PrintfRecord) {
+ out.print(record);
+ } else if (record instanceof PrintaRecord) {
+ PrintaRecord printa = (PrintaRecord)record;
+ List <Tuple> tuples = printa.getTuples();
+ if (tuples.isEmpty()) {
+ out.print(printa.getOutput());
+ } else {
+ for (Tuple t : tuples) {
+ out.print(printa.getFormattedString(t));
+ }
+ }
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine(printa.toString());
+ }
+ } else if (record instanceof StackValueRecord) {
+ printStack((StackValueRecord)record);
+ }
+ }
+ if (!quiet) {
+ out.println();
+ }
+ }
+
+ static void
+ printDistribution(Distribution d)
+ {
+ out.printf("\n%16s %41s %-9s\n", "value",
+ "------------- Distribution -------------",
+ "count");
+ long v; // bucket frequency (value)
+ long b; // lower bound of bucket range
+ double total = 0;
+ boolean positives = false;
+ boolean negatives = false;
+
+ Distribution.Bucket bucket;
+ int b1 = 0; // first displayed bucket
+ int b2 = d.size() - 1; // last displayed bucket
+ for (; (b1 <= b2) && (d.get(b1).getFrequency() == 0); ++b1);
+ // If possible, get one bucket before the first non-zero
+ // bucket and one bucket after the last.
+ if (b1 > b2) {
+ // There isn't any data. This is possible if (and only if)
+ // negative increment values have been used. In this case,
+ // print the buckets around the base.
+ if (d instanceof LinearDistribution) {
+ b1 = 0;
+ b2 = 2;
+ } else {
+ b1 = QUANTIZE_ZERO_BUCKET - 1;
+ b2 = QUANTIZE_ZERO_BUCKET + 1;
+ }
+ } else {
+ if (b1 > 0) --b1;
+ for (; (b2 > 0) && (d.get(b2).getFrequency() == 0); --b2);
+ if (b2 < (d.size() - 1)) ++b2;
+ }
+ for (int i = b1; i <= b2; ++i) {
+ v = d.get(i).getFrequency();
+ if (v > 0) {
+ positives = true;
+ }
+ if (v < 0) {
+ negatives = true;
+ }
+ total += Math.abs((double)v);
+ }
+ for (int i = b1; i <= b2; ++i) {
+ bucket = d.get(i);
+ v = bucket.getFrequency();
+ b = bucket.getMin();
+
+ if (d instanceof LinearDistribution) {
+ if (b == Long.MIN_VALUE) {
+ String lt = "< " + ((LinearDistribution)d).getBase();
+ out.printf("%16s ", lt);
+ } else if (bucket.getMax() == Long.MAX_VALUE) {
+ String ge = ">= " + b;
+ out.printf("%16s ", ge);
+ } else {
+ out.printf("%16d ", b);
+ }
+ } else {
+ out.printf("%16d ", b);
+ }
+
+ printDistributionLine(v, total, positives, negatives);
+ }
+ }
+
+ static void
+ printDistributionLine(long val, double total, boolean positives,
+ boolean negatives)
+ {
+ double f;
+ int depth, len = 40;
+
+ assert (ATS.length() == len && SPACES.length() == len);
+ assert (!(total == 0 && (positives || negatives)));
+ assert (!(val < 0 && !negatives));
+ assert (!(val > 0 && !positives));
+ assert (!(val != 0 && total == 0));
+
+ if (!negatives) {
+ if (positives) {
+ f = (Math.abs((double)val) * (double)len) / total;
+ depth = (int)(f + 0.5);
+ } else {
+ depth = 0;
+ }
+
+ out.printf("|%s%s %-9d\n", ATS.substring(len - depth),
+ SPACES.substring(depth), val);
+ return;
+ }
+
+ if (!positives) {
+ f = (Math.abs((double)val) * (double)len) / total;
+ depth = (int)(f + 0.5);
+
+ out.printf("%s%s| %-9d\n", SPACES.substring(depth),
+ ATS.substring(len - depth), val);
+ return;
+ }
+
+ /*
+ * If we're here, we have both positive and negative bucket values.
+ * To express this graphically, we're going to generate both positive
+ * and negative bars separated by a centerline. These bars are half
+ * the size of normal quantize()/lquantize() bars, so we divide the
+ * length in half before calculating the bar length.
+ */
+ len /= 2;
+ String ats = ATS.substring(len);
+ String spaces = SPACES.substring(len);
+
+ f = (Math.abs((double)val) * (double)len) / total;
+ depth = (int)(f + 0.5);
+
+ if (val <= 0) {
+ out.printf("%s%s|%s %-9d\n", spaces.substring(depth),
+ ats.substring(len - depth), repeat(" ", len), val);
+ return;
+ } else {
+ out.printf("%20s|%s%s %-9d\n", "", ats.substring(len - depth),
+ spaces.substring(depth), val);
+ }
+ }
+
+ public static String
+ repeat(String s, int n)
+ {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < n; ++i) {
+ buf.append(s);
+ }
+ return buf.toString();
+ }
+
+ static void
+ printStack(StackValueRecord rec)
+ {
+ StackFrame[] frames = rec.getStackFrames();
+ int i;
+ out.println();
+ String s;
+ for (StackFrame f : frames) {
+ for (i = 0; i < stackindent; ++i) {
+ out.print(' ');
+ }
+ s = f.getFrame();
+ if (s.indexOf('[') == 0) {
+ out.print(" ");
+ }
+ out.println(s);
+ }
+ }
+
+ static void
+ printAggregate(Aggregate aggregate)
+ {
+ printAggregationRecords(aggregate.getOrderedRecords());
+ }
+
+ static void
+ printAggregationRecords(List <AggregationRecord> list)
+ {
+ Tuple tuple;
+ AggregationValue value;
+ ValueRecord tupleRecord;
+ int i;
+ int len;
+ for (AggregationRecord r : list) {
+ tuple = r.getTuple();
+ value = r.getValue();
+ len = tuple.size();
+ for (i = 0; i < len; ++i) {
+ tupleRecord = tuple.get(i);
+ if (tupleRecord instanceof StackValueRecord) {
+ printStack((StackValueRecord)tupleRecord);
+ } else if (tupleRecord instanceof SymbolValueRecord) {
+ printValue(tupleRecord.toString(), -1, " %-50s");
+ } else {
+ printValue(tupleRecord.getValue(),
+ ((ScalarRecord)tupleRecord).getNumberOfBytes(),
+ " %-50s");
+ }
+ }
+ if (value instanceof Distribution) {
+ Distribution d = (Distribution)value;
+ printDistribution(d);
+ } else {
+ Number v = value.getValue();
+ printValue(v, -1, " %-50s");
+ }
+ out.println();
+ }
+ }
+
+ static void
+ exit(int status)
+ {
+ out.flush();
+ System.err.flush();
+ if (status == 0) {
+ status = exitStatus;
+ }
+ System.exit(status);
+ }
+
+ static void
+ usage()
+ {
+ String predact = "[[ predicate ] action ]";
+ System.err.printf("Usage: java %s [-32|-64] [-CeFlqvVwZ] " +
+ "[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] " +
+ "[-o output] [-p pid] [-s script] [-U name]\n\t" +
+ "[-x opt[=val]] [-X a|c|s|t]\n\n" +
+ "\t[-P provider %s]\n" +
+ "\t[-m [ provider: ] module %s]\n" +
+ "\t[-f [[ provider: ] module: ] func %s]\n" +
+ "\t[-n [[[ provider: ] module: ] func: ] name %s]\n" +
+ "\t[-i probe-id %s] [ args ... ]\n\n", CLASSNAME,
+ predact, predact, predact, predact, predact);
+ System.err.printf("\tpredicate -> '/' D-expression '/'\n");
+ System.err.printf("\t action -> '{' D-statements '}'\n");
+ System.err.printf("\n" +
+ "\t-32 generate 32-bit D programs\n" +
+ "\t-64 generate 64-bit D programs\n\n" +
+ "\t-b set trace buffer size\n" +
+ "\t-c run specified command and exit upon its completion\n" +
+ "\t-C run cpp(1) preprocessor on script files\n" +
+ "\t-D define symbol when invoking preprocessor\n" +
+ "\t-e exit after compiling request but prior to enabling " +
+ "probes\n" +
+ "\t-f enable or list probes matching the specified " +
+ "function name\n" +
+ "\t-F coalesce trace output by function\n" +
+ "\t-i enable or list probes matching the specified probe id\n" +
+ "\t-I add include directory to preprocessor search path\n" +
+ "\t-l list probes matching specified criteria\n" +
+ "\t-L add library directory to library search path\n" +
+ "\t-m enable or list probes matching the specified " +
+ "module name\n" +
+ "\t-n enable or list probes matching the specified probe name\n" +
+ "\t-o set output file\n" +
+ "\t-p grab specified process-ID and cache its symbol tables\n" +
+ "\t-P enable or list probes matching the specified " +
+ "provider name\n" +
+ "\t-q set quiet mode (only output explicitly traced data)\n" +
+ "\t-s enable or list probes according to the specified " +
+ "D script\n" +
+ "\t-U undefine symbol when invoking preprocessor\n" +
+ "\t-v set verbose mode (report stability attributes, " +
+ "arguments)\n" +
+ "\t-V report DTrace API version\n" +
+ "\t-w permit destructive actions\n" +
+ "\t-x enable or modify compiler and tracing options\n" +
+ "\t-X specify ISO C conformance settings for preprocessor\n" +
+ "\t-Z permit probe descriptions that match zero probes\n" +
+ "\n" +
+ "\tTo log PrintaRecord, set this environment variable:\n" +
+ "\t\tJDTRACE_LOGGING_LEVEL=FINE\n" +
+ "\tTo log ProbeData, set JDTRACE_LOGGING_LEVEL=FINER\n");
+ exit(2);
+ }
+
+ static void
+ printProgramStability(String programType, String programDescription,
+ ProgramInfo info)
+ {
+ out.println();
+ out.printf("Stability data for %s %s:\n\n",
+ programType, programDescription);
+ InterfaceAttributes a;
+ out.println("\tMinimum probe description " +
+ "attributes");
+ a = info.getMinimumProbeAttributes();
+ out.printf("\t\tIdentifier Names: %s\n",
+ a.getNameStability());
+ out.printf("\t\tData Semantics: %s\n",
+ a.getDataStability());
+ out.printf("\t\tDependency Class: %s\n",
+ a.getDependencyClass());
+ out.println("\tMinimum probe statement attributes");
+ a = info.getMinimumStatementAttributes();
+ out.printf("\t\tIdentifier Names: %s\n",
+ a.getNameStability());
+ out.printf("\t\tData Semantics: %s\n",
+ a.getDataStability());
+ out.printf("\t\tDependency Class: %s\n",
+ a.getDependencyClass());
+ }
+
+ static void
+ printProbeDescription(ProbeDescription p)
+ {
+ out.printf("%5d %10s %17s %33s %s\n", p.getID(),
+ p.getProvider(), p.getModule(),
+ p.getFunction(), p.getName());
+ }
+
+ static void
+ printProbeInfo(ProbeInfo p)
+ {
+ InterfaceAttributes a;
+ out.println("\n\tProbe Description Attributes");
+
+ a = p.getProbeAttributes();
+ out.printf("\t\tIdentifier Names: %s\n",
+ a.getNameStability());
+ out.printf("\t\tData Semantics: %s\n",
+ a.getDataStability());
+ out.printf("\t\tDependency Class: %s\n",
+ a.getDependencyClass());
+
+ out.println("\n\tArgument Attributes");
+
+ a = p.getArgumentAttributes();
+ out.printf("\t\tIdentifier Names: %s\n",
+ a.getNameStability());
+ out.printf("\t\tData Semantics: %s\n",
+ a.getDataStability());
+ out.printf("\t\tDependency Class: %s\n",
+ a.getDependencyClass());
+
+ // Argument types unsupported for now.
+
+ out.println();
+ }
+
+ public static void
+ main(String[] args)
+ {
+ String loggingLevel = System.getenv().get("JDTRACE_LOGGING_LEVEL");
+ try {
+ logger.setLevel(Level.parse(loggingLevel));
+ } catch (Exception e) {
+ logger.setLevel(Level.OFF);
+ }
+
+ if (args.length == 0) {
+ usage();
+ }
+
+ List <CompileRequest> compileRequests = new LinkedList
+ <CompileRequest> ();
+ List <Program> programList = new LinkedList <Program> ();
+ boolean verbose = false;
+ Mode mode = Mode.EXEC;
+
+ final ExceptionHandler exceptionHandler = new ExceptionHandler() {
+ public void handleException(Throwable e) {
+ if (e instanceof DTraceException) {
+ DTraceException de = (DTraceException)e;
+ System.err.printf("dtrace: %s\n", de.getMessage());
+ } else if (e instanceof ConsumerException) {
+ ConsumerException ce = (ConsumerException)e;
+ Object msg = ce.getNotificationObject();
+ if ((msg instanceof org.opensolaris.os.dtrace.Error) ||
+ (msg instanceof Drop)) {
+ System.err.printf("dtrace: %s\n", ce.getMessage());
+ } else {
+ ce.printStackTrace();
+ }
+ } else {
+ e.printStackTrace();
+ }
+ exit(1);
+ }
+ };
+
+ Getopt g = new Getopt(CLASSNAME, args, OPTSTR);
+ int c = 0;
+
+ List <Consumer.OpenFlag> openFlags =
+ new ArrayList <Consumer.OpenFlag> ();
+
+ while ((c = g.getopt()) != -1) {
+ switch (c) {
+ case '3': {
+ String s = g.getOptarg();
+ if (!s.equals("2")) {
+ System.err.println("dtrace: illegal option -- 3" + s);
+ usage();
+ }
+ openFlags.add(Consumer.OpenFlag.ILP32);
+ break;
+ }
+ case '6': {
+ String s = g.getOptarg();
+ if (!s.equals("4")) {
+ System.err.println("dtrace: illegal option -- 6" + s);
+ usage();
+ }
+ openFlags.add(Consumer.OpenFlag.LP64);
+ break;
+ }
+ }
+ }
+
+ Consumer.OpenFlag[] oflags = new Consumer.OpenFlag[openFlags.size()];
+ oflags = openFlags.toArray(oflags);
+
+ dtrace = new LocalConsumer() {
+ protected Thread createThread() {
+ Thread t = super.createThread();
+ t.setDaemon(false);
+ t.setPriority(Thread.MIN_PRIORITY);
+ return t;
+ }
+ };
+
+ g = new Getopt(CLASSNAME, args, OPTSTR);
+ c = 0;
+
+ try {
+ dtrace.open(oflags);
+
+ // Set default options that may be overriden by options or #pragma
+ dtrace.setOption(Option.bufsize, Option.mb(4));
+ dtrace.setOption(Option.aggsize, Option.mb(4));
+
+ CompileRequest r;
+ while ((c = g.getopt()) != -1) {
+ switch (c) {
+ case 'b':
+ dtrace.setOption(Option.bufsize, g.getOptarg());
+ break;
+ case 'c':
+ dtrace.createProcess(g.getOptarg());
+ break;
+ case 'C':
+ dtrace.setOption(Option.cpp);
+ break;
+ case 'D':
+ dtrace.setOption(Option.define, g.getOptarg());
+ break;
+ case 'e':
+ mode = Mode.INFO;
+ break;
+ case 'f':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.STRING;
+ r.probespec = ProbeDescription.Spec.FUNCTION;
+ compileRequests.add(r);
+ break;
+ case 'F':
+ dtrace.setOption(Option.flowindent);
+ break;
+ case 'i':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.STRING;
+ r.probespec = ProbeDescription.Spec.NAME;
+ compileRequests.add(r);
+ break;
+ case 'I':
+ dtrace.setOption(Option.incdir, g.getOptarg());
+ break;
+ case 'l':
+ mode = Mode.LIST;
+ dtrace.setOption(Option.zdefs); // -l implies -Z
+ break;
+ case 'L':
+ dtrace.setOption(Option.libdir, g.getOptarg());
+ break;
+ case 'm':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.STRING;
+ r.probespec = ProbeDescription.Spec.MODULE;
+ compileRequests.add(r);
+ break;
+ case 'n':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.STRING;
+ r.probespec = ProbeDescription.Spec.NAME;
+ compileRequests.add(r);
+ break;
+ case 'o':
+ String outFileName = g.getOptarg();
+ File outFile = new File(outFileName);
+ try {
+ FileOutputStream fos = new FileOutputStream(
+ outFile, true);
+ out = new PrintStream(fos);
+ } catch (FileNotFoundException e) {
+ System.err.println("failed to open " +
+ outFileName + " in write mode");
+ exit(1);
+ } catch (SecurityException e) {
+ System.err.println("failed to open " +
+ outFileName);
+ exit(1);
+ }
+ break;
+ case 'p':
+ String pidstr = g.getOptarg();
+ int pid = -1;
+ try {
+ pid = Integer.parseInt(pidstr);
+ } catch (NumberFormatException e) {
+ System.err.println("invalid pid: " + pidstr);
+ exit(1);
+ }
+ dtrace.grabProcess(pid);
+ break;
+ case 'P':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.STRING;
+ r.probespec = ProbeDescription.Spec.PROVIDER;
+ compileRequests.add(r);
+ break;
+ case 'q':
+ dtrace.setOption(Option.quiet);
+ break;
+ case 's':
+ r = new CompileRequest();
+ r.s = g.getOptarg();
+ r.type = ProgramType.FILE;
+ compileRequests.add(r);
+ break;
+ case 'U':
+ dtrace.setOption(Option.undef, g.getOptarg());
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case 'V':
+ mode = Mode.VERSION;
+ break;
+ case 'w':
+ dtrace.setOption(Option.destructive);
+ break;
+ case 'x':
+ String[] xarg = g.getOptarg().split("=", 2);
+ if (xarg.length > 1) {
+ dtrace.setOption(xarg[0], xarg[1]);
+ } else if (xarg.length == 1) {
+ dtrace.setOption(xarg[0]);
+ }
+ break;
+ case 'X':
+ dtrace.setOption(Option.stdc, g.getOptarg());
+ break;
+ case 'Z':
+ dtrace.setOption(Option.zdefs);
+ break;
+ case '?':
+ usage(); // getopt() already printed an error
+ break;
+ default:
+ System.err.print("getopt() returned " + c + "\n");
+ c = 0;
+ }
+ }
+ c = 0;
+ List <String> argList = new LinkedList <String> ();
+ for (int i = g.getOptind(); i < args.length; ++i) {
+ argList.add(args[i]);
+ }
+
+ if (mode == Mode.VERSION) {
+ out.printf("dtrace: %s\n", dtrace.getVersion());
+ dtrace.close();
+ exit(0);
+ }
+
+ String[] compileArgs = new String[argList.size()];
+ compileArgs = argList.toArray(compileArgs);
+
+ Program program;
+ for (CompileRequest req : compileRequests) {
+ switch (req.type) {
+ case STRING:
+ applyProbespec(req);
+ program = dtrace.compile(req.s, compileArgs);
+ break;
+ case FILE:
+ File file = new File(req.s);
+ program = dtrace.compile(file, compileArgs);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unexpected program type: " + req.type);
+ }
+
+ programList.add(program);
+ }
+
+ // Get options set by #pragmas in compiled program
+ long optval;
+ quiet = (dtrace.getOption(Option.quiet) != Option.UNSET);
+ flow = (dtrace.getOption(Option.flowindent) != Option.UNSET);
+ optval = dtrace.getOption("stackindent");
+ if (optval != Option.UNSET) {
+ stackindent = (int)optval;
+ }
+
+ if (mode == Mode.LIST) {
+ out.printf("%5s %10s %17s %33s %s\n",
+ "ID", "PROVIDER", "MODULE", "FUNCTION", "NAME");
+
+ if (verbose) {
+ List <List <Probe>> lists =
+ new LinkedList <List <Probe>> ();
+ for (Program p : programList) {
+ lists.add(dtrace.listProgramProbeDetail(p));
+ }
+ ProbeDescription p;
+ ProbeInfo pinfo;
+ for (List <Probe> list : lists) {
+ for (Probe probe : list) {
+ p = probe.getDescription();
+ pinfo = probe.getInfo();
+ printProbeDescription(p);
+ printProbeInfo(pinfo);
+ }
+ }
+ } else {
+ List <List <ProbeDescription>> lists =
+ new LinkedList <List <ProbeDescription>> ();
+ for (Program p : programList) {
+ lists.add(dtrace.listProgramProbes(p));
+ }
+ for (List <ProbeDescription> list : lists) {
+ for (ProbeDescription p : list) {
+ printProbeDescription(p);
+ }
+ }
+ }
+ exit(0);
+ }
+
+ String programType;
+ String programDescription;
+ ProgramInfo info;
+ for (Program p : programList) {
+ if (p instanceof Program.File) {
+ Program.File pf = (Program.File)p;
+ programType = "script";
+ programDescription = pf.getFile().getPath();
+ } else {
+ programType = "description";
+ programDescription =
+ p.getContents().split("[/{;]", 2)[0];
+ }
+
+ if (mode == Mode.EXEC) {
+ dtrace.enable(p);
+ } else {
+ dtrace.getProgramInfo(p);
+ }
+ info = p.getInfo();
+ if ((mode == Mode.EXEC) && !quiet) {
+ System.err.printf("dtrace: %s '%s' matched %d probe%s\n",
+ programType, programDescription,
+ info.getMatchingProbeCount(),
+ info.getMatchingProbeCount() == 1 ? "" : "s");
+ }
+ if (verbose) {
+ printProgramStability(programType,
+ programDescription, info);
+ }
+ }
+ if (mode != Mode.EXEC) {
+ exit(0);
+ }
+ dtrace.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStarted(ConsumerEvent e) {
+ started = true;
+ }
+ public void consumerStopped(ConsumerEvent e) {
+ stopped = true;
+ out.println();
+ try {
+ Aggregate aggregate = dtrace.getAggregate();
+ if (aggregate != null) {
+ printAggregate(aggregate);
+ }
+ dtrace.close();
+ } catch (Throwable x) {
+ exceptionHandler.handleException(x);
+ }
+ exit(0);
+ }
+ public void dataDropped(DropEvent e) {
+ System.err.printf("dtrace: %s",
+ e.getDrop().getDefaultMessage());
+ }
+ public void errorEncountered(ErrorEvent e)
+ throws ConsumerException {
+ org.opensolaris.os.dtrace.Error error = e.getError();
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine(error.toString());
+ }
+ System.err.printf("dtrace: %s",
+ error.getDefaultMessage());
+ }
+ public void dataReceived(DataEvent e)
+ throws ConsumerException {
+ consumeProbeData(e.getProbeData());
+ }
+ public void processStateChanged(ProcessEvent e)
+ throws ConsumerException {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine(e.getProcessState().toString());
+ }
+ }
+ });
+ // Print unprinted aggregations after Ctrl-C
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ if (stopped || !started) {
+ return;
+ }
+
+ try {
+ Aggregate aggregate = dtrace.getAggregate();
+ if (aggregate != null) {
+ out.println();
+ out.println();
+ printAggregate(aggregate);
+ }
+ } catch (Throwable x) {
+ exceptionHandler.handleException(x);
+ }
+ }
+ });
+ dtrace.go(exceptionHandler);
+ } catch (DTraceException e) {
+ if (c > 0) {
+ // set option error
+ if (g.getOptarg() == null) {
+ System.err.printf("dtrace: failed to set -%c: %s\n",
+ c, e.getMessage());
+ } else {
+ System.err.printf("dtrace: failed to set -%c %s: %s\n",
+ c, g.getOptarg(), e.getMessage());
+ }
+ } else {
+ // any other error
+ System.err.printf("dtrace: %s\n", e.getMessage());
+ }
+ exit(1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
new file mode 100644
index 0000000..261f870
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
@@ -0,0 +1,77 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+# Exception list: names tests that are bypassed when running in Java
+# mode (relative to /opt/SUNWdtrt/tst)
+
+# double precision (64-bit floating point) not same in java
+common/aggs/tst.neglquant.d
+common/aggs/tst.negquant.d
+
+# freopen() (to suppress output) not supported by Java DTrace API
+common/printa/tst.walltimestamp.ksh
+
+# -G option not supported by jdtrace
+common/dtraceUtil/tst.ELFGenerationOut.d.ksh
+common/dtraceUtil/tst.ELFGenerationWithO.d.ksh
+
+# -H option not supported by jdtrace
+common/dtraceUtil/tst.PreprocessorStatement.d.ksh
+
+# -G and -h options not supported by jdtrace
+common/usdt/tst.badguess.ksh
+common/usdt/tst.dlclose1.ksh
+common/usdt/tst.dlclose2.ksh
+common/usdt/tst.dlclose3.ksh
+common/usdt/tst.eliminate.ksh
+common/usdt/tst.enabled.ksh
+common/usdt/tst.enabled2.ksh
+common/usdt/tst.entryreturn.ksh
+common/usdt/tst.fork.ksh
+common/usdt/tst.header.ksh
+common/usdt/tst.guess32.ksh
+common/usdt/tst.guess64.ksh
+common/usdt/tst.linkpriv.ksh
+common/usdt/tst.linkunpriv.ksh
+common/usdt/tst.multiple.ksh
+common/usdt/tst.nodtrace.ksh
+common/usdt/tst.onlyenabled.ksh
+common/usdt/tst.reeval.ksh
+common/usdt/tst.static.ksh
+common/usdt/tst.static2.ksh
+common/usdt/tst.user.ksh
+sparc/usdt/tst.tailcall.ksh
+common/pid/tst.provregex3.ksh
+common/pid/tst.provregex4.ksh
+
+# freopen() and ftruncate() not supported by Java DTrace API
+common/funcs/tst.badfreopen.ksh
+common/funcs/tst.freopen.ksh
+common/funcs/tst.ftruncate.ksh
+
+# jdtrace doesn't pull in library files?
+common/pragma/tst.libdepfullyconnected.ksh
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/jdtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/jdtrace.c
new file mode 100644
index 0000000..0951265
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/jdtrace.c
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <alloca.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/systeminfo.h>
+
+int
+main(int argc, char **argv)
+{
+ int i, ac, has64;
+ char **av, **p;
+
+ ac = argc + 3;
+ av = p = alloca(sizeof (char *) * ac);
+
+ *p++ = "java";
+ *p++ = "-jar";
+ *p++ = "/opt/SUNWdtrt/lib/java/jdtrace.jar";
+
+ argc--;
+ argv++;
+
+ for (i = 0; i < argc; i++) {
+ p[i] = argv[i];
+ }
+ p[i] = NULL;
+
+ (void) execvp(av[0], av);
+
+ perror("exec failed");
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/manifest/jdtrace.jar-manifest b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/manifest/jdtrace.jar-manifest
new file mode 100644
index 0000000..add47eb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/manifest/jdtrace.jar-manifest
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: JDTrace
+Class-Path: /usr/share/lib/java/dtrace.jar
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl
new file mode 100755
index 0000000..3c3e180
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl
@@ -0,0 +1,235 @@
+#!/usr/local/bin/perl
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+require 5.8.4;
+
+$PNAME = $0;
+$PNAME =~ s:.*/::;
+$USAGE = "Usage: $PNAME [file ...]\n";
+$errs = 0;
+
+sub err
+{
+ my($msg) = @_;
+
+ print "$file: $lineno: $msg\n";
+ $errs++;
+}
+
+sub dstyle
+{
+ open(FILE, "$file");
+ $lineno = 0;
+ $inclause = 0;
+ $skipnext = 0;
+
+ while (<FILE>) {
+ $lineno++;
+
+ chop;
+
+ if ($skipnext) {
+ $skipnext = 0;
+ next;
+ }
+
+ #
+ # Amazingly, some ident strings are longer than 80 characters!
+ #
+ if (/^#pragma ident/) {
+ next;
+ }
+
+ #
+ # The algorithm to calculate line length from cstyle.
+ #
+ $line = $_;
+ if ($line =~ tr/\t/\t/ * 7 + length($line) > 80) {
+ # yes, there is a chance.
+ # replace tabs with spaces and check again.
+ $eline = $line;
+ 1 while $eline =~
+ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
+
+ if (length($eline) > 80) {
+ err "line > 80 characters";
+ }
+ }
+
+ if (/\/\*DSTYLED\*\//) {
+ $skipnext = 1;
+ next;
+ }
+
+ if (/^#pragma/) {
+ next;
+ }
+
+ if (/^#include/) {
+ next;
+ }
+
+ #
+ # Before we do any more analysis, we want to prune out any
+ # quoted strings. This is a bit tricky because we need
+ # to be careful of backslashed quotes within quoted strings.
+ # I'm sure there is a very crafty way to do this with a
+ # single regular expression, but that will have to wait for
+ # somone with better regex juju that I; we do this by first
+ # eliminating the backslashed quotes, and then eliminating
+ # whatever quoted strings are left. Note that we eliminate
+ # the string by replacing it with "quotedstr"; this is to
+ # allow lines to end with a quoted string. (If we simply
+ # eliminated the quoted string, dstyle might complain about
+ # the line ending in a space or tab.)
+ #
+ s/\\\"//g;
+ s/\"[^\"]*\"/quotedstr/g;
+
+ if (/[ \t]$/) {
+ err "space or tab at end of line";
+ }
+
+ if (/^[\t]+[ ]+[\t]+/) {
+ err "spaces between tabs";
+ }
+
+ if (/^[\t]* \*/) {
+ next;
+ }
+
+ if (/^ /) {
+ err "indented by spaces not tabs";
+ }
+
+ if (/^{}$/) {
+ next;
+ }
+
+ if (!/^enum/ && !/^\t*struct/ && !/^\t*union/ && !/^typedef/ &&
+ !/^translator/ && !/^provider/) {
+ if (/[\w\s]+{/) {
+ err "left brace not on its own line";
+ }
+
+ if (/{[\w\s]+/) {
+ err "left brace not on its own line";
+ }
+ }
+
+ if (!/;$/) {
+ if (/[\w\s]+}/) {
+ err "right brace not on its own line";
+ }
+
+ if (/}[\w\s]+/) {
+ err "right brace not on its own line";
+ }
+ }
+
+ if (/^}/) {
+ $inclause = 0;
+ }
+
+ if (!$inclause && /^[\w ]+\//) {
+ err "predicate not at beginning of line";
+ }
+
+ if (!$inclause && /^\/[ \t]+\w/) {
+ err "space between '/' and expression in predicate";
+ }
+
+ if (!$inclause && /\w[ \t]+\/$/) {
+ err "space between expression and '/' in predicate";
+ }
+
+ if (!$inclause && /\s,/) {
+ err "space before comma in probe description";
+ }
+
+ if (!$inclause && /\w,[\w\s]/ && !/;$/) {
+ if (!/extern/ && !/\(/ && !/inline/) {
+ err "multiple probe descriptions on same line";
+ }
+ }
+
+ if ($inclause && /sizeof\(/) {
+ err "missing space after sizeof";
+ }
+
+ if ($inclause && /^[\w ]/) {
+ err "line doesn't begin with a tab";
+ }
+
+ if ($inclause && /,[\w]/) {
+ err "comma without trailing space";
+ }
+
+ if (/\w&&/ || /&&\w/ || /\w\|\|/ || /\|\|\w/) {
+ err "logical operator not set off with spaces";
+ }
+
+ #
+ # We want to catch "i<0" variants, but we don't want to
+ # erroneously flag translators.
+ #
+ if (!/\w<\w+>\(/) {
+ if (/\w>/ || / >\w/ || /\w</ || /<\w/) {
+ err "comparison operator not set " .
+ "off with spaces";
+ }
+ }
+
+ if (/\w==/ || /==\w/ || /\w<=/ || />=\w/ || /\w!=/ || /!=\w/) {
+ err "comparison operator not set off with spaces";
+ }
+
+ if (/\w=/ || /=\w/) {
+ err "assignment operator not set off with spaces";
+ }
+
+ if (/^{/) {
+ $inclause = 1;
+ }
+ }
+}
+
+foreach $arg (@ARGV) {
+ if (-f $arg) {
+ push(@files, $arg);
+ } else {
+ die "$PNAME: $arg is not a valid file\n";
+ }
+}
+
+die $USAGE if (scalar(@files) == 0);
+
+foreach $file (@files) {
+ dstyle($file);
+}
+
+exit($errs != 0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl
new file mode 100755
index 0000000..7b47580
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl
@@ -0,0 +1,704 @@
+#!/usr/local/bin/perl
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+require 5.8.4;
+
+use File::Find;
+use File::Basename;
+use Getopt::Std;
+use Cwd;
+use Cwd 'abs_path';
+
+$PNAME = $0;
+$PNAME =~ s:.*/::;
+$OPTSTR = 'abd:fghi:jlnqsx:';
+$USAGE = "Usage: $PNAME [-abfghjlnqs] [-d dir] [-i isa] "
+ . "[-x opt[=arg]] [file | dir ...]\n";
+($MACH = `uname -p`) =~ s/\W*\n//;
+($PLATFORM = `uname -i`) =~ s/\W*\n//;
+
+@dtrace_argv = ();
+
+$ksh_path = '/usr/local/bin/ksh';
+
+@files = ();
+%exceptions = ();
+%results = ();
+$errs = 0;
+
+#
+# If no test files are specified on the command-line, execute a find on "."
+# and append any tst.*.d, tst.*.ksh, err.*.d or drp.*.d files found within
+# the directory tree.
+#
+sub wanted
+{
+ push(@files, $File::Find::name)
+ if ($_ =~ /^(tst|err|drp)\..+\.(d|ksh)$/ && -f "$_");
+}
+
+sub dirname {
+ my($s) = @_;
+ my($i);
+
+ $s = substr($s, 0, $i) if (($i = rindex($s, '/')) != -1);
+ return $i == -1 ? '.' : $i == 0 ? '/' : $s;
+}
+
+sub usage
+{
+ print $USAGE;
+ print "\t -a execute test suite using anonymous enablings\n";
+ print "\t -b execute bad ioctl test program\n";
+ print "\t -d specify directory for test results files and cores\n";
+ print "\t -g enable libumem debugging when running tests\n";
+ print "\t -f force bypassed tests to run\n";
+ print "\t -h display verbose usage message\n";
+ print "\t -i specify ISA to test instead of isaexec(3C) default\n";
+ print "\t -j execute test suite using jdtrace (Java API) only\n";
+ print "\t -l save log file of results and PIDs used by tests\n";
+ print "\t -n execute test suite using dtrace(1m) only\n";
+ print "\t -q set quiet mode (only report errors and summary)\n";
+ print "\t -s save results files even for tests that pass\n";
+ print "\t -x pass corresponding -x argument to dtrace(1M)\n";
+ exit(2);
+}
+
+sub errmsg
+{
+ my($msg) = @_;
+
+ print STDERR $msg;
+ print LOG $msg if ($opt_l);
+ $errs++;
+}
+
+sub fail
+{
+ my(@parms) = @_;
+ my($msg) = $parms[0];
+ my($errfile) = $parms[1];
+ my($n) = 0;
+ my($dest) = basename($file);
+
+ while (-d "$opt_d/failure.$n") {
+ $n++;
+ }
+
+ unless (mkdir "$opt_d/failure.$n") {
+ warn "ERROR: failed to make directory $opt_d/failure.$n: $!\n";
+ exit(125);
+ }
+
+ open(README, ">$opt_d/failure.$n/README");
+ print README "ERROR: " . $file . " " . $msg;
+
+ if (scalar @parms > 1) {
+ print README "; see $errfile\n";
+ } else {
+ if (-f "$opt_d/$pid.core") {
+ print README "; see $pid.core\n";
+ } else {
+ print README "\n";
+ }
+ }
+
+ close(README);
+
+ if (-f "$opt_d/$pid.out") {
+ rename("$opt_d/$pid.out", "$opt_d/failure.$n/$pid.out");
+ link("$file.out", "$opt_d/failure.$n/$dest.out");
+ }
+
+ if (-f "$opt_d/$pid.err") {
+ rename("$opt_d/$pid.err", "$opt_d/failure.$n/$pid.err");
+ link("$file.err", "$opt_d/failure.$n/$dest.err");
+ }
+
+ if (-f "$opt_d/$pid.core") {
+ rename("$opt_d/$pid.core", "$opt_d/failure.$n/$pid.core");
+ }
+
+ link("$file", "$opt_d/failure.$n/$dest");
+
+ $msg = "ERROR: " . $dest . " " . $msg;
+
+ if (scalar @parms > 1) {
+ $msg = $msg . "; see $errfile in failure.$n\n";
+ } else {
+ $msg = $msg . "; details in failure.$n\n";
+ }
+
+ errmsg($msg);
+}
+
+sub logmsg
+{
+ my($msg) = @_;
+
+ print STDOUT $msg unless ($opt_q);
+ print LOG $msg if ($opt_l);
+}
+
+# Trim leading and trailing whitespace
+sub trim {
+ my($s) = @_;
+
+ $s =~ s/^\s*//;
+ $s =~ s/\s*$//;
+ return $s;
+}
+
+# Load exception set of skipped tests from the file at the given
+# pathname. The test names are assumed to be paths relative to $dt_tst,
+# for example: common/aggs/tst.neglquant.d, and specify tests to be
+# skipped.
+sub load_exceptions {
+ my($listfile) = @_;
+ my($line) = "";
+
+ %exceptions = ();
+ if (length($listfile) > 0) {
+ exit(123) unless open(STDIN, "<$listfile");
+ while (<STDIN>) {
+ chomp;
+ $line = $_;
+ # line is non-empty and not a comment
+ if ((length($line) > 0) && ($line =~ /^\s*[^\s#]/ )) {
+ $exceptions{trim($line)} = 1;
+ }
+ }
+ }
+}
+
+# Return 1 if the test is found in the exception set, 0 otherwise.
+sub is_exception {
+ my($file) = @_;
+ my($i) = -1;
+
+ if (scalar(keys(%exceptions)) == 0) {
+ return 0;
+ }
+
+ # hash absolute pathname after $dt_tst/
+ $file = abs_path($file);
+ $i = index($file, $dt_tst);
+ if ($i == 0) {
+ $file = substr($file, length($dt_tst) + 1);
+ return $exceptions{$file};
+ }
+ return 0;
+}
+
+#
+# Iterate over the set of test files specified on the command-line or by a find
+# on "$defdir/common", "$defdir/$MACH" and "$defdir/$PLATFORM" and execute each
+# one. If the test file is executable, we fork and exec it. If the test is a
+# .ksh file, we run it with $ksh_path. Otherwise we run dtrace -s on it. If
+# the file is named tst.* we assume it should return exit status 0. If the
+# file is named err.* we assume it should return exit status 1. If the file is
+# named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and examine stderr to
+# ensure that a matching error tag was produced. If the file is named
+# drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and examine stderr to ensure
+# that a matching drop tag was produced. If any *.out or *.err files are found
+# we perform output comparisons.
+#
+# run_tests takes two arguments: The first is the pathname of the dtrace
+# command to invoke when running the tests. The second is the pathname
+# of a file (may be the empty string) listing tests that ought to be
+# skipped (skipped tests are listed as paths relative to $dt_tst, for
+# example: common/aggs/tst.neglquant.d).
+#
+sub run_tests {
+ my($dtrace, $exceptions_path) = @_;
+ my($passed) = 0;
+ my($bypassed) = 0;
+ my($failed) = $errs;
+ my($total) = 0;
+
+ die "$PNAME: $dtrace not found\n" unless (-x "$dtrace");
+ logmsg($dtrace . "\n");
+
+ load_exceptions($exceptions_path);
+
+ foreach $file (sort @files) {
+ $file =~ m:.*/((.*)\.(\w+)):;
+ $name = $1;
+ $base = $2;
+ $ext = $3;
+
+ $dir = dirname($file);
+ $isksh = 0;
+ $tag = 0;
+ $droptag = 0;
+
+ if ($name =~ /^tst\./) {
+ $isksh = ($ext eq 'ksh');
+ $status = 0;
+ } elsif ($name =~ /^err\.(D_[A-Z0-9_]+)\./) {
+ $status = 1;
+ $tag = $1;
+ } elsif ($name =~ /^err\./) {
+ $status = 1;
+ } elsif ($name =~ /^drp\.([A-Z0-9_]+)\./) {
+ $status = 0;
+ $droptag = $1;
+ } else {
+ errmsg("ERROR: $file is not a valid test file name\n");
+ next;
+ }
+
+ $fullname = "$dir/$name";
+ $exe = "./$base.exe";
+ $exe_pid = -1;
+
+ if ($opt_a && ($status != 0 || $tag != 0 || $droptag != 0 ||
+ -x $exe || $isksh || -x $fullname)) {
+ $bypassed++;
+ next;
+ }
+
+ if (!$opt_f && is_exception("$dir/$name")) {
+ $bypassed++;
+ next;
+ }
+
+ if (!$isksh && -x $exe) {
+ if (($exe_pid = fork()) == -1) {
+ errmsg(
+ "ERROR: failed to fork to run $exe: $!\n");
+ next;
+ }
+
+ if ($exe_pid == 0) {
+ open(STDIN, '</dev/null');
+
+ exec($exe);
+
+ warn "ERROR: failed to exec $exe: $!\n";
+ }
+ }
+
+ logmsg("testing $file ... ");
+
+ if (($pid = fork()) == -1) {
+ errmsg("ERROR: failed to fork to run test $file: $!\n");
+ next;
+ }
+
+ if ($pid == 0) {
+ open(STDIN, '</dev/null');
+ exit(125) unless open(STDOUT, ">$opt_d/$$.out");
+ exit(125) unless open(STDERR, ">$opt_d/$$.err");
+
+ unless (chdir($dir)) {
+ warn "ERROR: failed to chdir for $file: $!\n";
+ exit(126);
+ }
+
+ push(@dtrace_argv, '-xerrtags') if ($tag);
+ push(@dtrace_argv, '-xdroptags') if ($droptag);
+ push(@dtrace_argv, $exe_pid) if ($exe_pid != -1);
+
+ if ($isksh) {
+ exit(123) unless open(STDIN, "<$name");
+ exec("$ksh_path /dev/stdin $dtrace");
+ } elsif (-x $name) {
+ warn "ERROR: $name is executable\n";
+ exit(1);
+ } else {
+ if ($tag == 0 && $status == $0 && $opt_a) {
+ push(@dtrace_argv, '-A');
+ }
+
+ push(@dtrace_argv, '-C');
+ push(@dtrace_argv, '-s');
+ push(@dtrace_argv, $name);
+ exec($dtrace, @dtrace_argv);
+ }
+
+ warn "ERROR: failed to exec for $file: $!\n";
+ exit(127);
+ }
+
+ if (waitpid($pid, 0) == -1) {
+ errmsg("ERROR: timed out waiting for $file\n");
+ kill(9, $exe_pid) if ($exe_pid != -1);
+ kill(9, $pid);
+ next;
+ }
+
+ kill(9, $exe_pid) if ($exe_pid != -1);
+
+ if ($tag == 0 && $status == $0 && $opt_a) {
+ #
+ # We can chuck the earler output.
+ #
+ unlink($pid . '.out');
+ unlink($pid . '.err');
+
+ #
+ # This is an anonymous enabling. We need to get
+ # the module unloaded.
+ #
+ system("dtrace -ae 1> /dev/null 2> /dev/null");
+ system("svcadm disable -s " .
+ "svc:/network/nfs/mapid:default");
+ system("modunload -i 0 ; modunload -i 0 ; " .
+ "modunload -i 0");
+ if (!system("modinfo | grep dtrace")) {
+ warn "ERROR: couldn't unload dtrace\n";
+ system("svcadm enable " .
+ "-s svc:/network/nfs/mapid:default");
+ exit(124);
+ }
+
+ #
+ # DTrace is gone. Now update_drv(1M), and rip
+ # everything out again.
+ #
+ system("update_drv dtrace");
+ system("dtrace -ae 1> /dev/null 2> /dev/null");
+ system("modunload -i 0 ; modunload -i 0 ; " .
+ "modunload -i 0");
+ if (!system("modinfo | grep dtrace")) {
+ warn "ERROR: couldn't unload dtrace\n";
+ system("svcadm enable " .
+ "-s svc:/network/nfs/mapid:default");
+ exit(124);
+ }
+
+ #
+ # Now bring DTrace back in.
+ #
+ system("sync ; sync");
+ system("dtrace -l -n bogusprobe 1> /dev/null " .
+ "2> /dev/null");
+ system("svcadm enable -s " .
+ "svc:/network/nfs/mapid:default");
+
+ #
+ # That should have caused DTrace to reload with
+ # the new configuration file. Now we can try to
+ # snag our anonymous state.
+ #
+ if (($pid = fork()) == -1) {
+ errmsg("ERROR: failed to fork to run " .
+ "test $file: $!\n");
+ next;
+ }
+
+ if ($pid == 0) {
+ open(STDIN, '</dev/null');
+ exit(125) unless open(STDOUT, ">$opt_d/$$.out");
+ exit(125) unless open(STDERR, ">$opt_d/$$.err");
+
+ push(@dtrace_argv, '-a');
+
+ unless (chdir($dir)) {
+ warn "ERROR: failed to chdir " .
+ "for $file: $!\n";
+ exit(126);
+ }
+
+ exec($dtrace, @dtrace_argv);
+ warn "ERROR: failed to exec for $file: $!\n";
+ exit(127);
+ }
+
+ if (waitpid($pid, 0) == -1) {
+ errmsg("ERROR: timed out waiting for $file\n");
+ kill(9, $pid);
+ next;
+ }
+ }
+
+ logmsg("[$pid]\n");
+ $wstat = $?;
+ $wifexited = ($wstat & 0xFF) == 0;
+ $wexitstat = ($wstat >> 8) & 0xFF;
+ $wtermsig = ($wstat & 0x7F);
+
+ if (!$wifexited) {
+ fail("died from signal $wtermsig");
+ next;
+ }
+
+ if ($wexitstat == 125) {
+ die "$PNAME: failed to create output file in $opt_d " .
+ "(cd elsewhere or use -d)\n";
+ }
+
+ if ($wexitstat != $status) {
+ fail("returned $wexitstat instead of $status");
+ next;
+ }
+
+ if (-f "$file.out" &&
+ system("cmp -s $file.out $opt_d/$pid.out") != 0) {
+ fail("stdout mismatch", "$pid.out");
+ next;
+ }
+
+ if (-f "$file.err" &&
+ system("cmp -s $file.err $opt_d/$pid.err") != 0) {
+ fail("stderr mismatch: see $pid.err");
+ next;
+ }
+
+ if ($tag) {
+ open(TSTERR, "<$opt_d/$pid.err");
+ $tsterr = <TSTERR>;
+ close(TSTERR);
+
+ unless ($tsterr =~ /: \[$tag\] line \d+:/) {
+ fail("errtag mismatch: see $pid.err");
+ next;
+ }
+ }
+
+ if ($droptag) {
+ $found = 0;
+ open(TSTERR, "<$opt_d/$pid.err");
+
+ while (<TSTERR>) {
+ if (/\[$droptag\] /) {
+ $found = 1;
+ last;
+ }
+ }
+
+ close (TSTERR);
+
+ unless ($found) {
+ fail("droptag mismatch: see $pid.err");
+ next;
+ }
+ }
+
+ unless ($opt_s) {
+ unlink($pid . '.out');
+ unlink($pid . '.err');
+ }
+ }
+
+ if ($opt_a) {
+ #
+ # If we're running with anonymous enablings, we need to
+ # restore the .conf file.
+ #
+ system("dtrace -A 1> /dev/null 2> /dev/null");
+ system("dtrace -ae 1> /dev/null 2> /dev/null");
+ system("modunload -i 0 ; modunload -i 0 ; modunload -i 0");
+ system("update_drv dtrace");
+ }
+
+ $total = scalar(@files);
+ $failed = $errs - $failed;
+ $passed = ($total - $failed - $bypassed);
+ $results{$dtrace} = {
+ "passed" => $passed,
+ "bypassed" => $bypassed,
+ "failed" => $failed,
+ "total" => $total
+ };
+}
+
+die $USAGE unless (getopts($OPTSTR));
+usage() if ($opt_h);
+
+foreach $arg (@ARGV) {
+ if (-f $arg) {
+ push(@files, $arg);
+ } elsif (-d $arg) {
+ find(\&wanted, $arg);
+ } else {
+ die "$PNAME: $arg is not a valid file or directory\n";
+ }
+}
+
+$dt_tst = '/opt/SUNWdtrt/tst';
+$dt_bin = '/opt/SUNWdtrt/bin';
+$defdir = -d $dt_tst ? $dt_tst : '.';
+$bindir = -d $dt_bin ? $dt_bin : '.';
+
+find(\&wanted, "$defdir/common") if (scalar(@ARGV) == 0);
+find(\&wanted, "$defdir/$MACH") if (scalar(@ARGV) == 0);
+find(\&wanted, "$defdir/$PLATFORM") if (scalar(@ARGV) == 0);
+die $USAGE if (scalar(@files) == 0);
+
+$dtrace_path = '/usr/sbin/dtrace';
+$jdtrace_path = "$bindir/jdtrace";
+
+%exception_lists = ("$jdtrace_path" => "$bindir/exception.lst");
+
+if ($opt_j || $opt_n || $opt_i) {
+ @dtrace_cmds = ();
+ push(@dtrace_cmds, $dtrace_path) if ($opt_n);
+ push(@dtrace_cmds, $jdtrace_path) if ($opt_j);
+ push(@dtrace_cmds, "/usr/sbin/$opt_i/dtrace") if ($opt_i);
+} else {
+ @dtrace_cmds = ($dtrace_path, $jdtrace_path);
+}
+
+if ($opt_d) {
+ die "$PNAME: -d arg must be absolute path\n" unless ($opt_d =~ /^\//);
+ die "$PNAME: -d arg $opt_d is not a directory\n" unless (-d "$opt_d");
+ system("coreadm -p $opt_d/%p.core");
+} else {
+ my $dir = getcwd;
+ system("coreadm -p $dir/%p.core");
+ $opt_d = '.';
+}
+
+if ($opt_x) {
+ push(@dtrace_argv, '-x');
+ push(@dtrace_argv, $opt_x);
+}
+
+die "$PNAME: failed to open $PNAME.$$.log: $!\n"
+ unless (!$opt_l || open(LOG, ">$PNAME.$$.log"));
+
+if ($opt_g) {
+ $ENV{'UMEM_DEBUG'} = 'default,verbose';
+ $ENV{'UMEM_LOGGING'} = 'fail,contents';
+ $ENV{'LD_PRELOAD'} = 'libumem.so';
+}
+
+#
+# Ensure that $PATH contains a cc(1) so that we can execute the
+# test programs that require compilation of C code.
+#
+#$ENV{'PATH'} = $ENV{'PATH'} . ':/ws/onnv-tools/SUNWspro/SS11/bin';
+
+if ($opt_b) {
+ logmsg("badioctl'ing ... ");
+
+ if (($badioctl = fork()) == -1) {
+ errmsg("ERROR: failed to fork to run badioctl: $!\n");
+ next;
+ }
+
+ if ($badioctl == 0) {
+ open(STDIN, '</dev/null');
+ exit(125) unless open(STDOUT, ">$opt_d/$$.out");
+ exit(125) unless open(STDERR, ">$opt_d/$$.err");
+
+ exec($bindir . "/badioctl");
+ warn "ERROR: failed to exec badioctl: $!\n";
+ exit(127);
+ }
+
+
+ logmsg("[$badioctl]\n");
+
+ #
+ # If we're going to be bad, we're just going to iterate over each
+ # test file.
+ #
+ foreach $file (sort @files) {
+ ($name = $file) =~ s:.*/::;
+ $dir = dirname($file);
+
+ if (!($name =~ /^tst\./ && $name =~ /\.d$/)) {
+ next;
+ }
+
+ logmsg("baddof'ing $file ... ");
+
+ if (($pid = fork()) == -1) {
+ errmsg("ERROR: failed to fork to run baddof: $!\n");
+ next;
+ }
+
+ if ($pid == 0) {
+ open(STDIN, '</dev/null');
+ exit(125) unless open(STDOUT, ">$opt_d/$$.out");
+ exit(125) unless open(STDERR, ">$opt_d/$$.err");
+
+ unless (chdir($dir)) {
+ warn "ERROR: failed to chdir for $file: $!\n";
+ exit(126);
+ }
+
+ exec($bindir . "/baddof", $name);
+
+ warn "ERROR: failed to exec for $file: $!\n";
+ exit(127);
+ }
+
+ sleep 60;
+ kill(9, $pid);
+ waitpid($pid, 0);
+
+ logmsg("[$pid]\n");
+
+ unless ($opt_s) {
+ unlink($pid . '.out');
+ unlink($pid . '.err');
+ }
+ }
+
+ kill(9, $badioctl);
+ waitpid($badioctl, 0);
+
+ unless ($opt_s) {
+ unlink($badioctl . '.out');
+ unlink($badioctl . '.err');
+ }
+
+ exit(0);
+}
+
+#
+# Run all the tests specified on the command-line (the entire test suite
+# by default) once for each dtrace command tested, skipping any tests
+# not valid for that command.
+#
+foreach $dtrace_cmd (@dtrace_cmds) {
+ run_tests($dtrace_cmd, $exception_lists{$dtrace_cmd});
+}
+
+$opt_q = 0; # force final summary to appear regardless of -q option
+
+logmsg("\n==== TEST RESULTS ====\n");
+foreach $key (keys %results) {
+ my $passed = $results{$key}{"passed"};
+ my $bypassed = $results{$key}{"bypassed"};
+ my $failed = $results{$key}{"failed"};
+ my $total = $results{$key}{"total"};
+
+ logmsg("\n mode: " . $key . "\n");
+ logmsg(" passed: " . $passed . "\n");
+ if ($bypassed) {
+ logmsg(" bypassed: " . $bypassed . "\n");
+ }
+ logmsg(" failed: " . $failed . "\n");
+ logmsg(" total: " . $total . "\n");
+}
+
+exit($errs != 0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_FUNC.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_FUNC.bad.d
new file mode 100644
index 0000000..d12454b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_FUNC.bad.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * An aggregation must call an aggregating function.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+
+ @counts["xyz"] = breakpoint();
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_MDIM.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_MDIM.bad.d
new file mode 100644
index 0000000..2c47289
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_MDIM.bad.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * An aggregation may not be used as a multi-dimensional array
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+
+ @counts[0][2] = count();
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_NULL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_NULL.bad.d
new file mode 100644
index 0000000..87d1818
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_NULL.bad.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * An aggregation must have an aggregating function applied.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+
+ @a[1];
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_REDEF.redef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_REDEF.redef.d
new file mode 100644
index 0000000..9b4b425
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_REDEF.redef.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test redefining the aggregation
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a = count();
+}
+
+END
+{
+ @a = max(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.avgtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.avgtoofew.d
new file mode 100644
index 0000000..106f4cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.avgtoofew.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * avg() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[pid] = avg(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.maxnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.maxnoarg.d
new file mode 100644
index 0000000..181e196
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.maxnoarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * max() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+BEGIN
+{
+ @a[pid] = max(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.mintoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.mintoofew.d
new file mode 100644
index 0000000..3ca34ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.mintoofew.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * min() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = min(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.quantizetoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.quantizetoofew.d
new file mode 100644
index 0000000..b746455
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.quantizetoofew.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * quantize() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = quantize(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d
new file mode 100644
index 0000000..262040f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * stddev() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[pid] = stddev(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.sumtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.sumtoofew.d
new file mode 100644
index 0000000..a77a2d5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.sumtoofew.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * sum() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = sum(probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_AGGARG.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_AGGARG.bad.d
new file mode 100644
index 0000000..0e6060a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_AGGARG.bad.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * The argument to clear() must be an aggregation.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=10ms
+#pragma D option switchrate=10ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i%5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 10/
+{
+ printf("Aggregation data before clear():\n");
+ printa(@func);
+
+ clear(count());
+
+ printf("Aggregation data after clear():\n");
+ printa(@func);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("Final aggregation data:\n");
+ printa(@func);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_PROTO.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_PROTO.bad.d
new file mode 100644
index 0000000..57fa884
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_CLEAR_PROTO.bad.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * clear() should handle no args as an error.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=10ms
+#pragma D option switchrate=10ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i%5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 10/
+{
+ printf("Aggregation data before clear():\n");
+ printa(@func);
+
+ clear();
+
+ printf("Aggregation data after clear():\n");
+ printa(@func);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("Final aggregation data:\n");
+ printa(@func);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_IDENT.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_IDENT.bad.d
new file mode 100644
index 0000000..866a7ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_IDENT.bad.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * An aggregation must call an aggregating function, not a probe
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+
+ @counts[0][2] = tick-1();
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_UNDEF.badaggfunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_UNDEF.badaggfunc.d
new file mode 100644
index 0000000..65c12da
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_FUNC_UNDEF.badaggfunc.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of a non-supported aggregate function.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+
+BEGIN
+{
+ @counts["badtest"] = foo();
+
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badexpr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badexpr.d
new file mode 100644
index 0000000..83e6ab7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badexpr.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test using an aggregation in an expression context.
+ * This should result in a compile-time error.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ trace(@a + 3);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badkey3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badkey3.d
new file mode 100644
index 0000000..67c5b64
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.badkey3.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of a dynamic expression as an aggregation key.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ @t[i] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.noeffect.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.noeffect.d
new file mode 100644
index 0000000..9bdff78
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_IDENT_UNDEF.noeffect.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test compiling an aggregation statement that has no effect.
+ * This should result in a compile-time error.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey1.d
new file mode 100644
index 0000000..abf3dd8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey1.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of a void expression as an aggregation key.
+ * This should result in a compile-time error.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1, (void)0] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey2.d
new file mode 100644
index 0000000..9490b82
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey2.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of a dynamic expression as an aggregation key.
+ * This should result in a compile-time error.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[0] = count();
+ @b[@a] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey4.d
new file mode 100644
index 0000000..057746e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_KEY_TYPE.badkey4.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test the use of a dynamic expression as an aggregation key.
+ * This should result in a compile-time error.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ @a[curpsinfo] = count();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqbad1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqbad1.d
new file mode 100644
index 0000000..6bb6765
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqbad1.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() lower bound around must be an integer constant
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ x = 'a';
+ @a[1] = lquantize(timestamp, x, 1000, 1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqshort.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqshort.d
new file mode 100644
index 0000000..6bb6765
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASETYPE.lqshort.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() lower bound around must be an integer constant
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ x = 'a';
+ @a[1] = lquantize(timestamp, x, 1000, 1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASEVAL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASEVAL.bad.d
new file mode 100644
index 0000000..23d318e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_BASEVAL.bad.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() lower bound must be a 32-bit quantity
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = lquantize(timestamp, 2147483657, 1000, 1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMTYPE.lqbad1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMTYPE.lqbad1.d
new file mode 100644
index 0000000..894f064
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMTYPE.lqbad1.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() upper bound around must be an integer constant
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ x = 'a';
+ @a[1] = lquantize(timestamp, 100, rand(), 1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMVAL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMVAL.bad.d
new file mode 100644
index 0000000..0a2f5e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_LIMVAL.bad.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() upper bound around must be an integer constant
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ x = 'a';
+ @a[1] = lquantize(timestamp, 100, 2147483657, 1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.d
new file mode 100644
index 0000000..b93ffab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @ = lquantize(0, 10, 20, 1);
+ @ = lquantize(0, 15, 20, 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.order.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.order.d
new file mode 100644
index 0000000..763c1e0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHBASE.order.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @ = lquantize(0, 10, 20, 1);
+ @ = lquantize(0, 15, 30, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.d
new file mode 100644
index 0000000..d9ba023
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @ = lquantize(0, 10, 20, 1);
+ @ = lquantize(0, 10, 2000, 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.order.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.order.d
new file mode 100644
index 0000000..62be0c5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHLIM.order.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @ = lquantize(0, 10, 20, 1);
+ @ = lquantize(0, 10, 2000, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHSTEP.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHSTEP.d
new file mode 100644
index 0000000..086f439
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MATCHSTEP.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @ = lquantize(0, 10, 20, 1);
+ @ = lquantize(0, 10, 20, 2);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MISMATCH.lqbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MISMATCH.lqbadarg.d
new file mode 100644
index 0000000..a4444ad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_MISMATCH.lqbadarg.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Upper bound must be greater than lower bound argument
+ *
+ * SECTION: Aggregations/Aggregations
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-1
+/i < 1000/
+{
+ @a[i] = lquantize(i, 1100, -100, -100 );
+ i += 100;
+}
+
+tick-1
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPLARGE.lqtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPLARGE.lqtoofew.d
new file mode 100644
index 0000000..664f70f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPLARGE.lqtoofew.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() should not accept more than 4 arguments.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = lquantize(1, 2, 3, 4, 5);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPSMALL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPSMALL.bad.d
new file mode 100644
index 0000000..634e8c0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPSMALL.bad.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Number of quantization levels must be a 16-bit quantity
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a[i] = lquantize(i, 0, 1000000, 10);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPTYPE.lqbadinc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPTYPE.lqbadinc.d
new file mode 100644
index 0000000..87c5127
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPTYPE.lqbadinc.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Upper bound must be greater than lower bound argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-1
+/i < 1000/
+{
+ @a[i] = lquantize(i, 0, 1100, -100);
+ i += 100;
+}
+
+tick-1
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPVAL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPVAL.bad.d
new file mode 100644
index 0000000..a90d757
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_LQUANT_STEPVAL.bad.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() step value should be a 16-bit quantity
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a[i] = lquantize(i, 100, 1100, 200000 );
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_AGGARG.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_AGGARG.bad.d
new file mode 100644
index 0000000..7e5974c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_AGGARG.bad.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * The first argument to normalize() should be an aggregation.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=1ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+
+ printf("normalized data:\n");
+ normalize(count(), 4);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_PROTO.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_PROTO.bad.d
new file mode 100644
index 0000000..82d819d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_PROTO.bad.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * normalize() accepts 2 args - passing fewer is an error.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=1ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("normalized data:\n");
+ normalize(@func);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_SCALAR.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_SCALAR.bad.d
new file mode 100644
index 0000000..14a2586
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_NORMALIZE_SCALAR.bad.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * The second argument to normalize() should be a scalar.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=1ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("normalized data:\n");
+ normalize(@func, "hello");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_ARG.lquantizetoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_ARG.lquantizetoofew.d
new file mode 100644
index 0000000..db4567f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_ARG.lquantizetoofew.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() should not accept a non-scalar value
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = lquantize(probefunc, probefunc, probefunc, probefunc);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgnoarg.d
new file mode 100644
index 0000000..628eeab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgnoarg.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * avg() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[1] = avg();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgtoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgtoomany.d
new file mode 100644
index 0000000..42e5c1c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.avgtoomany.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * avg() should not more than one argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[1] = avg(1, 2);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.counttoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.counttoomany.d
new file mode 100644
index 0000000..5dc5b80
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.counttoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * count() should not accept any arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a["badtest"] = count(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizenoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizenoarg.d
new file mode 100644
index 0000000..ae4b672
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizenoarg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * lquantize() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = lquantize();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizetoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizetoomany.d
new file mode 100644
index 0000000..bf87a46
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.lquantizetoomany.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * lquantize() should not have more than five (!) arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @[1] = lquantize(10, 0, 100, 1, 10, 20);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxnoarg.d
new file mode 100644
index 0000000..aad2c24
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxnoarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * max() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = max();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxtoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxtoomany.d
new file mode 100644
index 0000000..d0fb091
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.maxtoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * max() should not more than one argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = max(1, 2);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.minnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.minnoarg.d
new file mode 100644
index 0000000..09db51f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.minnoarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * min() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = min();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.mintoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.mintoomany.d
new file mode 100644
index 0000000..2647402
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.mintoomany.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * min() should not more than one argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = min(1, 2);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizenoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizenoarg.d
new file mode 100644
index 0000000..b33957a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizenoarg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * quantize() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = quantize();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizetoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizetoomany.d
new file mode 100644
index 0000000..9b162bd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.quantizetoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * quantize() should not have more than two arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[1] = quantize(1, 2, 3);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d
new file mode 100644
index 0000000..2952cf5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * stddev() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[1] = stddev();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d
new file mode 100644
index 0000000..c42e962
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * stddev() should not have more than one argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[1] = stddev(1, 2);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumnoarg.d
new file mode 100644
index 0000000..4f27901
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumnoarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * sum() should not accept a call with no arguments
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = sum();
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumtoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumtoomany.d
new file mode 100644
index 0000000..5e899be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.sumtoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * sum() should not more than one argument
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+BEGIN
+{
+ @a[pid] = sum(1, 2);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_AGGARG.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_AGGARG.bad.d
new file mode 100644
index 0000000..69cb729
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_AGGARG.bad.d
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+int i;
+
+BEGIN
+{
+ trunc(i);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badmany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badmany.d
new file mode 100644
index 0000000..61271a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badmany.d
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[0] = count();
+ trunc(@, 10, 20);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badnone.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badnone.d
new file mode 100644
index 0000000..e141e6c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_PROTO.badnone.d
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ trunc();
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_SCALAR.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_SCALAR.bad.d
new file mode 100644
index 0000000..e548576
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_TRUNC_SCALAR.bad.d
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[0] = count();
+ trunc(@, @);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d
new file mode 100644
index 0000000..26241b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+{
+ @ = quantize(1LL << i);
+ @ = quantize((1LL << i) + 1);
+ @ = quantize(-(1LL << i));
+ @ = quantize(-(1LL << i) - 1);
+ i++;
+}
+
+tick-10ms
+/i == 64/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d.out
new file mode 100644
index 0000000..356d6b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.allquant.d.out
@@ -0,0 +1,131 @@
+
+
+ value ------------- Distribution ------------- count
+-4611686018427387904 |@ 5
+-2305843009213693952 | 2
+-1152921504606846976 | 2
+-576460752303423488 | 2
+-288230376151711744 | 2
+-144115188075855872 | 2
+-72057594037927936 | 2
+-36028797018963968 | 2
+-18014398509481984 | 2
+-9007199254740992 | 2
+-4503599627370496 | 2
+-2251799813685248 | 2
+-1125899906842624 | 2
+-562949953421312 | 2
+-281474976710656 | 2
+-140737488355328 | 2
+ -70368744177664 | 2
+ -35184372088832 | 2
+ -17592186044416 | 2
+ -8796093022208 | 2
+ -4398046511104 | 2
+ -2199023255552 | 2
+ -1099511627776 | 2
+ -549755813888 | 2
+ -274877906944 | 2
+ -137438953472 | 2
+ -68719476736 | 2
+ -34359738368 | 2
+ -17179869184 | 2
+ -8589934592 | 2
+ -4294967296 | 2
+ -2147483648 | 2
+ -1073741824 | 2
+ -536870912 | 2
+ -268435456 | 2
+ -134217728 | 2
+ -67108864 | 2
+ -33554432 | 2
+ -16777216 | 2
+ -8388608 | 2
+ -4194304 | 2
+ -2097152 | 2
+ -1048576 | 2
+ -524288 | 2
+ -262144 | 2
+ -131072 | 2
+ -65536 | 2
+ -32768 | 2
+ -16384 | 2
+ -8192 | 2
+ -4096 | 2
+ -2048 | 2
+ -1024 | 2
+ -512 | 2
+ -256 | 2
+ -128 | 2
+ -64 | 2
+ -32 | 2
+ -16 | 2
+ -8 | 2
+ -4 | 2
+ -2 | 3
+ -1 | 1
+ 0 | 0
+ 1 | 1
+ 2 | 3
+ 4 | 2
+ 8 | 2
+ 16 | 2
+ 32 | 2
+ 64 | 2
+ 128 | 2
+ 256 | 2
+ 512 | 2
+ 1024 | 2
+ 2048 | 2
+ 4096 | 2
+ 8192 | 2
+ 16384 | 2
+ 32768 | 2
+ 65536 | 2
+ 131072 | 2
+ 262144 | 2
+ 524288 | 2
+ 1048576 | 2
+ 2097152 | 2
+ 4194304 | 2
+ 8388608 | 2
+ 16777216 | 2
+ 33554432 | 2
+ 67108864 | 2
+ 134217728 | 2
+ 268435456 | 2
+ 536870912 | 2
+ 1073741824 | 2
+ 2147483648 | 2
+ 4294967296 | 2
+ 8589934592 | 2
+ 17179869184 | 2
+ 34359738368 | 2
+ 68719476736 | 2
+ 137438953472 | 2
+ 274877906944 | 2
+ 549755813888 | 2
+ 1099511627776 | 2
+ 2199023255552 | 2
+ 4398046511104 | 2
+ 8796093022208 | 2
+ 17592186044416 | 2
+ 35184372088832 | 2
+ 70368744177664 | 2
+ 140737488355328 | 2
+ 281474976710656 | 2
+ 562949953421312 | 2
+1125899906842624 | 2
+2251799813685248 | 2
+4503599627370496 | 2
+9007199254740992 | 2
+18014398509481984 | 2
+36028797018963968 | 2
+72057594037927936 | 2
+144115188075855872 | 2
+288230376151711744 | 2
+576460752303423488 | 2
+1152921504606846976 | 2
+2305843009213693952 | 2
+4611686018427387904 | 3
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d
new file mode 100644
index 0000000..a4bfd3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive avg() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is a simple verifiable positive test of the avg() function.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = avg(i);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d.out
new file mode 100644
index 0000000..e3c0687
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg.d.out
@@ -0,0 +1,2 @@
+
+ 450
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d
new file mode 100644
index 0000000..5c1e77d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive avg() test using negative values
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is a simple verifiable positive test of the avg() function.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @ = avg(0);
+ @ = avg(-900);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d.out
new file mode 100644
index 0000000..3fafcd4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d.out
@@ -0,0 +1,2 @@
+
+ -450
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d
new file mode 100644
index 0000000..2acd8ee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for clearing aggregations
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i%5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 10/
+{
+ printf("Aggregation data before clear():\n");
+ printa(@func);
+
+ clear(@func);
+
+ printf("Aggregation data after clear():\n");
+ printa(@func);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("Final aggregation data:\n");
+ printa(@func);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d.out
new file mode 100644
index 0000000..486e4ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clear.d.out
@@ -0,0 +1,22 @@
+Aggregation data before clear():
+
+ 0 500
+ 1 700
+ 2 900
+ 3 1100
+ 4 1300
+Aggregation data after clear():
+
+ 0 0
+ 1 0
+ 2 0
+ 3 0
+ 4 0
+Final aggregation data:
+
+ 0 1500
+ 1 2700
+ 2 2900
+ 3 3100
+ 4 3300
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d
new file mode 100644
index 0000000..135e511
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive avg() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES:
+ * Verifies that printing a clear()'d aggregation with an avg()
+ * aggregation function doesn't cause problems.
+ *
+ */
+
+#pragma D option quiet
+
+tick-10ms
+/i++ < 5/
+{
+ @a = avg(timestamp);
+}
+
+tick-10ms
+/i == 5/
+{
+ exit(2);
+}
+
+END
+{
+ clear(@a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d.out
new file mode 100644
index 0000000..8d23188f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg.d.out
@@ -0,0 +1,2 @@
+
+ 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d
new file mode 100644
index 0000000..0f7a958
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive avg() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES:
+ * Verifies that printing a clear()'d aggregation with an avg()
+ * aggregation function of 0 doesn't cause divide-by-zero problems.
+ *
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=50ms
+#pragma D option aggrate=1ms
+
+tick-100ms
+/(x++ % 5) == 0/
+{
+ @time = avg(0);
+}
+
+tick-100ms
+/x > 5 && x <= 20/
+{
+ printa(" %@d\n", @time);
+ clear(@time);
+}
+
+tick-100ms
+/x > 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d.out
new file mode 100644
index 0000000..7cceedd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearavg2.d.out
@@ -0,0 +1,16 @@
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d
new file mode 100644
index 0000000..7aefed0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Denormalized aggregations can be cleared
+ *
+ * SECTION: Aggregations/Normalization;
+ * Aggregations/Clearing aggregations
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i != 10 || i != 20/
+{
+ @func[i%5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 10/
+{
+ printf("Denormalized data before clear:\n");
+ denormalize(@func);
+ printa(@func);
+
+ clear(@func);
+
+ printf("Aggregation data after clear:\n");
+ printa(@func);
+ i++
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("Final (denormalized) aggregation data:\n");
+ denormalize(@func);
+ printa(@func);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d.out
new file mode 100644
index 0000000..ed7f2f3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.cleardenormalize.d.out
@@ -0,0 +1,22 @@
+Denormalized data before clear:
+
+ 0 500
+ 1 700
+ 2 900
+ 3 1100
+ 4 1300
+Aggregation data after clear:
+
+ 0 0
+ 1 0
+ 2 0
+ 3 0
+ 4 0
+Final (denormalized) aggregation data:
+
+ 0 1500
+ 1 2700
+ 2 2900
+ 3 3100
+ 4 3300
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d
new file mode 100644
index 0000000..2d0ff83
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive lquantize()/clear() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES:
+ * Verifies that printing a clear()'d aggregation with an lquantize()
+ * aggregation function doesn't cause problems.
+ *
+ */
+
+
+#pragma D option switchrate=50ms
+#pragma D option aggrate=1ms
+#pragma D option quiet
+
+tick-100ms
+{
+ x++;
+ @a["linear"] = lquantize(x, 0, 100, 1);
+ @b["exp"] = quantize(x);
+}
+
+tick-100ms
+/(x % 5) == 0 && y++ < 5/
+{
+ printa(@a);
+ printa(@b);
+ clear(@a);
+ clear(@b);
+}
+
+tick-100ms
+/(x % 5) == 0 && y == 5/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d.out
new file mode 100644
index 0000000..e7e2a60
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearlquantize.d.out
@@ -0,0 +1,94 @@
+
+ linear
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@ 1
+ 2 |@@@@@@@@ 1
+ 3 |@@@@@@@@ 1
+ 4 |@@@@@@@@ 1
+ 5 |@@@@@@@@ 1
+ 6 | 0
+
+
+ exp
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@@@@ 2
+ 4 |@@@@@@@@@@@@@@@@ 2
+ 8 | 0
+
+
+ linear
+ value ------------- Distribution ------------- count
+ 5 | 0
+ 6 |@@@@@@@@ 1
+ 7 |@@@@@@@@ 1
+ 8 |@@@@@@@@ 1
+ 9 |@@@@@@@@ 1
+ 10 |@@@@@@@@ 1
+ 11 | 0
+
+
+ exp
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 4 |@@@@@@@@@@@@@@@@ 2
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 16 | 0
+
+
+ linear
+ value ------------- Distribution ------------- count
+ 10 | 0
+ 11 |@@@@@@@@ 1
+ 12 |@@@@@@@@ 1
+ 13 |@@@@@@@@ 1
+ 14 |@@@@@@@@ 1
+ 15 |@@@@@@@@ 1
+ 16 | 0
+
+
+ exp
+ value ------------- Distribution ------------- count
+ 4 | 0
+ 8 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 16 | 0
+
+
+ linear
+ value ------------- Distribution ------------- count
+ 15 | 0
+ 16 |@@@@@@@@ 1
+ 17 |@@@@@@@@ 1
+ 18 |@@@@@@@@ 1
+ 19 |@@@@@@@@ 1
+ 20 |@@@@@@@@ 1
+ 21 | 0
+
+
+ exp
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 32 | 0
+
+
+ linear
+ value ------------- Distribution ------------- count
+ 20 | 0
+ 21 |@@@@@@@@ 1
+ 22 |@@@@@@@@ 1
+ 23 |@@@@@@@@ 1
+ 24 |@@@@@@@@ 1
+ 25 |@@@@@@@@ 1
+ 26 | 0
+
+
+ exp
+ value ------------- Distribution ------------- count
+ 8 | 0
+ 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 32 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d
new file mode 100644
index 0000000..75cfa2d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Normalized aggregation data can be cleared
+ *
+ * SECTION: Aggregations/Normalization;
+ * Aggregations/Clearing aggregations
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 10/
+{
+ printf("Normalized data before clear:\n");
+ normalize(@func, 5);
+ printa(@func);
+
+ clear(@func);
+
+ printf("Aggregation data after clear:\n");
+ printa(@func);
+ i++
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("Final (normalized) aggregation data:\n");
+ normalize(@func, 5);
+ printa(@func);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d.out
new file mode 100644
index 0000000..e568427
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearnormalize.d.out
@@ -0,0 +1,22 @@
+Normalized data before clear:
+
+ 0 100
+ 1 140
+ 2 180
+ 3 220
+ 4 260
+Aggregation data after clear:
+
+ 0 0
+ 1 0
+ 2 0
+ 3 0
+ 4 0
+Final (normalized) aggregation data:
+
+ 0 300
+ 1 540
+ 2 580
+ 3 620
+ 4 660
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d
new file mode 100644
index 0000000..af3ecd5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Positive stddev() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES:
+ * Verifies that printing a clear()'d aggregation with an stddev()
+ * aggregation function doesn't cause problems.
+ *
+ */
+
+#pragma D option quiet
+
+tick-10ms
+/i++ < 5/
+{
+ @a = stddev(timestamp);
+}
+
+tick-10ms
+/i == 5/
+{
+ exit(2);
+}
+
+END
+{
+ clear(@a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out
new file mode 100644
index 0000000..8d23188f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out
@@ -0,0 +1,2 @@
+
+ 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d
new file mode 100644
index 0000000..e81d123
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Postive count() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = count();
+ @a = count();
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d.out
new file mode 100644
index 0000000..d34fd3b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count.d.out
@@ -0,0 +1,2 @@
+
+ 2
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d
new file mode 100644
index 0000000..624b1b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive count() test
+ *
+ * SECTION: Aggregations/Aggregations
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i != 10/
+{
+ i++;
+ @counts["tick-count"] = count();
+}
+
+tick-10ms
+/i == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d.out
new file mode 100644
index 0000000..4998a33
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count2.d.out
@@ -0,0 +1,2 @@
+
+ tick-count 10
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count3.d
new file mode 100644
index 0000000..5913ff6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.count3.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test multiple count() calls.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i != 10/
+{
+ i++;
+ @counts1[execname] = count();
+ @counts2[execname, arg0] = count();
+}
+
+tick-10ms
+/i == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d
new file mode 100644
index 0000000..37269e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Simple denormalization test
+ *
+ * SECTION: Aggregations/Normalization
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-10ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-10ms
+/i == 20/
+{
+ normalize(@func, 5);
+
+ printf("denormalized:");
+ denormalize(@func);
+ printa(@func);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d.out
new file mode 100644
index 0000000..fa4d0da
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalize.d.out
@@ -0,0 +1,7 @@
+denormalized:
+ 0 3000
+ 1 3400
+ 2 3800
+ 3 4200
+ 4 4600
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d
new file mode 100644
index 0000000..d63a83e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * denormalize() should work even if normalize() isn't called.
+ *
+ * SECTION: Aggregations/Normalization
+ *
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-10ms
+/i < 20/
+{
+ @func[i%5] = sum(i * 100);
+ i++;
+}
+
+tick-10ms
+/i == 20/
+{
+ printf("denormalized:");
+ denormalize(@func);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d.out
new file mode 100644
index 0000000..cc16f27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.denormalizeonly.d.out
@@ -0,0 +1,6 @@
+denormalized:
+ 0 3000
+ 1 3400
+ 2 3800
+ 3 4200
+ 4 4600
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d
new file mode 100644
index 0000000..8ff3aab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for normalization() with printa()
+ *
+ * SECTION: Aggregations/Normalization
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("normalized data:\n");
+ normalize(@func, 5);
+ printa("%u %@u\n", @func);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d.out
new file mode 100644
index 0000000..bbf345b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.fmtnormalize.d.out
@@ -0,0 +1,7 @@
+normalized data:
+0 600
+1 680
+2 760
+3 840
+4 920
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d
new file mode 100644
index 0000000..2b08a12
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive aggregation test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = count();
+ @b = max(1);
+ @c[0] = count();
+ @d[0] = max(1);
+
+ printa("\n@a = %@u\n", @a);
+ printa("@b = %@u\n", @b);
+ printa("@c = %@u\n", @c);
+ printa("@d = %@u\n", @d);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d.out
new file mode 100644
index 0000000..1f31450
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.forms.d.out
@@ -0,0 +1,6 @@
+
+@a = 1
+@b = 1
+@c = 1
+@d = 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.goodkey.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.goodkey.d
new file mode 100644
index 0000000..46becd5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.goodkey.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive aggregation key test
+ *
+ * SECTION: Aggregations/Aggregations
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i != 5/
+{
+ i++;
+ @counts[execname, pid, id, tid, arg0, vtimestamp ] = count();
+
+}
+
+tick-10ms
+/i == 5/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d
new file mode 100644
index 0000000..dbc8b6d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ j = 0;
+
+ @tour["Ghent", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Berlin", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["London", i++, j] = sum(5 - j);
+ @tour["Dublin", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Shanghai", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Zurich", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Regina", i++, j] = sum(5 - j);
+ @tour["Winnipeg", i++, j] = sum(5 - j);
+ @tour["Edmonton", i++, j] = sum(5 - j);
+ @tour["Calgary", i++, j] = sum(5 - j);
+ @tour["Vancouver", i++, j] = sum(5 - j);
+ @tour["Victoria", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Prague", i++, j] = sum(5 - j);
+ @tour["London", i++, j] = sum(5 - j);
+ j++;
+
+ @tour["Brisbane", i++, j] = sum(5 - j);
+ @tour["Sydney", i++, j] = sum(5 - j);
+ @tour["Melbourne", i++, j] = sum(5 - j);
+ j++;
+
+ setopt("aggsortkey", "false");
+ setopt("aggsortkeypos", "0");
+ @tour["Amsterdam", i++, j] = sum(5 - j);
+
+ printf("By value:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkey");
+ printf("\nBy key, position 0:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkeypos", "1");
+ printf("\nBy key, position 1:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkeypos", "2");
+ printf("\nBy key, position 2:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkey", "false");
+ setopt("aggsortkeypos", "0");
+ setopt("aggsortrev");
+
+ printf("\nReversed by value:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkey");
+ printf("\nReversed by key, position 0:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkeypos", "1");
+ printf("\nReversed by key, position 1:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ setopt("aggsortkeypos", "2");
+ printf("\nReversed by key, position 2:\n");
+ printa("%20s %8d %8d %8@d\n", @tour);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d.out
new file mode 100644
index 0000000..250d84b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.keysort.d.out
@@ -0,0 +1,160 @@
+By value:
+ Amsterdam 17 8 -3
+ Brisbane 14 7 -2
+ Melbourne 16 7 -2
+ Sydney 15 7 -2
+ London 13 6 -1
+ Prague 12 6 -1
+ Calgary 9 5 0
+ Edmonton 8 5 0
+ Regina 6 5 0
+ Vancouver 10 5 0
+ Victoria 11 5 0
+ Winnipeg 7 5 0
+ Zurich 5 4 1
+ Shanghai 4 3 2
+ Dublin 3 2 3
+ London 2 2 3
+ Berlin 1 1 4
+ Ghent 0 0 5
+
+By key, position 0:
+ Amsterdam 17 8 -3
+ Berlin 1 1 4
+ Brisbane 14 7 -2
+ Calgary 9 5 0
+ Dublin 3 2 3
+ Edmonton 8 5 0
+ Ghent 0 0 5
+ London 2 2 3
+ London 13 6 -1
+ Melbourne 16 7 -2
+ Prague 12 6 -1
+ Regina 6 5 0
+ Shanghai 4 3 2
+ Sydney 15 7 -2
+ Vancouver 10 5 0
+ Victoria 11 5 0
+ Winnipeg 7 5 0
+ Zurich 5 4 1
+
+By key, position 1:
+ Ghent 0 0 5
+ Berlin 1 1 4
+ London 2 2 3
+ Dublin 3 2 3
+ Shanghai 4 3 2
+ Zurich 5 4 1
+ Regina 6 5 0
+ Winnipeg 7 5 0
+ Edmonton 8 5 0
+ Calgary 9 5 0
+ Vancouver 10 5 0
+ Victoria 11 5 0
+ Prague 12 6 -1
+ London 13 6 -1
+ Brisbane 14 7 -2
+ Sydney 15 7 -2
+ Melbourne 16 7 -2
+ Amsterdam 17 8 -3
+
+By key, position 2:
+ Ghent 0 0 5
+ Berlin 1 1 4
+ Dublin 3 2 3
+ London 2 2 3
+ Shanghai 4 3 2
+ Zurich 5 4 1
+ Calgary 9 5 0
+ Edmonton 8 5 0
+ Regina 6 5 0
+ Vancouver 10 5 0
+ Victoria 11 5 0
+ Winnipeg 7 5 0
+ London 13 6 -1
+ Prague 12 6 -1
+ Brisbane 14 7 -2
+ Melbourne 16 7 -2
+ Sydney 15 7 -2
+ Amsterdam 17 8 -3
+
+Reversed by value:
+ Ghent 0 0 5
+ Berlin 1 1 4
+ London 2 2 3
+ Dublin 3 2 3
+ Shanghai 4 3 2
+ Zurich 5 4 1
+ Winnipeg 7 5 0
+ Victoria 11 5 0
+ Vancouver 10 5 0
+ Regina 6 5 0
+ Edmonton 8 5 0
+ Calgary 9 5 0
+ Prague 12 6 -1
+ London 13 6 -1
+ Sydney 15 7 -2
+ Melbourne 16 7 -2
+ Brisbane 14 7 -2
+ Amsterdam 17 8 -3
+
+Reversed by key, position 0:
+ Zurich 5 4 1
+ Winnipeg 7 5 0
+ Victoria 11 5 0
+ Vancouver 10 5 0
+ Sydney 15 7 -2
+ Shanghai 4 3 2
+ Regina 6 5 0
+ Prague 12 6 -1
+ Melbourne 16 7 -2
+ London 13 6 -1
+ London 2 2 3
+ Ghent 0 0 5
+ Edmonton 8 5 0
+ Dublin 3 2 3
+ Calgary 9 5 0
+ Brisbane 14 7 -2
+ Berlin 1 1 4
+ Amsterdam 17 8 -3
+
+Reversed by key, position 1:
+ Amsterdam 17 8 -3
+ Melbourne 16 7 -2
+ Sydney 15 7 -2
+ Brisbane 14 7 -2
+ London 13 6 -1
+ Prague 12 6 -1
+ Victoria 11 5 0
+ Vancouver 10 5 0
+ Calgary 9 5 0
+ Edmonton 8 5 0
+ Winnipeg 7 5 0
+ Regina 6 5 0
+ Zurich 5 4 1
+ Shanghai 4 3 2
+ Dublin 3 2 3
+ London 2 2 3
+ Berlin 1 1 4
+ Ghent 0 0 5
+
+Reversed by key, position 2:
+ Amsterdam 17 8 -3
+ Sydney 15 7 -2
+ Melbourne 16 7 -2
+ Brisbane 14 7 -2
+ Prague 12 6 -1
+ London 13 6 -1
+ Winnipeg 7 5 0
+ Victoria 11 5 0
+ Vancouver 10 5 0
+ Regina 6 5 0
+ Edmonton 8 5 0
+ Calgary 9 5 0
+ Zurich 5 4 1
+ Shanghai 4 3 2
+ London 2 2 3
+ Dublin 3 2 3
+ Berlin 1 1 4
+ Ghent 0 0 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d
new file mode 100644
index 0000000..dd25f86
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive lquantize() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the lquantize() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a[i] = lquantize(i, -100, 1100, 100 );
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d.out
new file mode 100644
index 0000000..fecb448
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantize.d.out
@@ -0,0 +1,61 @@
+
+ 0
+ value ------------- Distribution ------------- count
+ -100 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 100 | 0
+
+ 100
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 200 | 0
+
+ 200
+ value ------------- Distribution ------------- count
+ 100 | 0
+ 200 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 300 | 0
+
+ 300
+ value ------------- Distribution ------------- count
+ 200 | 0
+ 300 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 400 | 0
+
+ 400
+ value ------------- Distribution ------------- count
+ 300 | 0
+ 400 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 500 | 0
+
+ 500
+ value ------------- Distribution ------------- count
+ 400 | 0
+ 500 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 600 | 0
+
+ 600
+ value ------------- Distribution ------------- count
+ 500 | 0
+ 600 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 700 | 0
+
+ 700
+ value ------------- Distribution ------------- count
+ 600 | 0
+ 700 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 800 | 0
+
+ 800
+ value ------------- Distribution ------------- count
+ 700 | 0
+ 800 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 900 | 0
+
+ 900
+ value ------------- Distribution ------------- count
+ 800 | 0
+ 900 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1000 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d
new file mode 100644
index 0000000..003f846
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+tick-10ms
+/i++ < 10/
+{
+ @ = lquantize(i, 0, 10);
+ @ = lquantize(i, 0, 10);
+ @ = lquantize(i, 0, 10);
+ @ = lquantize(i, 0, 10);
+ @ = lquantize(i, 0, 10);
+}
+
+tick-10ms
+/i == 10/
+{
+ exit(0);
+}
+
+END
+{
+ normalize(@, 5);
+ printa(@);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d.out
new file mode 100644
index 0000000..76b55b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantnormal.d.out
@@ -0,0 +1,16 @@
+
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@ 1
+ 2 |@@@@ 1
+ 3 |@@@@ 1
+ 4 |@@@@ 1
+ 5 |@@@@ 1
+ 6 |@@@@ 1
+ 7 |@@@@ 1
+ 8 |@@@@ 1
+ 9 |@@@@ 1
+ >= 10 |@@@@ 1
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d
new file mode 100644
index 0000000..e9e6716
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @["Nixon"] = lquantize(-20, -10, 10, 1, 25);
+ @["Hoover"] = lquantize(20, -10, 10, 1, -100);
+ @["Harding"] = lquantize(-10, -10, 10, 1, 15);
+ @["Bush"] = lquantize(10, -10, 10, 1, 150);
+
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d.out
new file mode 100644
index 0000000..88d3505
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantrange.d.out
@@ -0,0 +1,23 @@
+
+ Hoover
+ value ------------- Distribution ------------- count
+ 9 | 0
+ >= 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100
+
+ Nixon
+ value ------------- Distribution ------------- count
+ < -10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 25
+ -10 | 0
+
+ Harding
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ -9 | 0
+
+ Bush
+ value ------------- Distribution ------------- count
+ 9 | 0
+ >= 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 150
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d
new file mode 100644
index 0000000..ad609ed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+/*
+ * This test verifies that the height of the ASCII quantization bars is
+ * determined using rounding and not truncated integer arithmetic.
+ */
+tick-10ms
+/i++ >= 27/
+{
+ exit(0);
+}
+
+tick-10ms
+/i > 8/
+{
+ @ = lquantize(2, 0, 4);
+}
+
+tick-10ms
+/i > 2 && i <= 8/
+{
+ @ = lquantize(1, 0, 4);
+}
+
+tick-10ms
+/i <= 2/
+{
+ @ = lquantize(0, 0, 4);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d.out
new file mode 100644
index 0000000..1aa94e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantround.d.out
@@ -0,0 +1,9 @@
+
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@ 2
+ 1 |@@@@@@@@@ 6
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 19
+ 3 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d
new file mode 100644
index 0000000..3905f2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ a = 7;
+ b = 13;
+ val = (-a * b) + a;
+}
+
+tick-1ms
+{
+ incr = val % b;
+ val += a;
+}
+
+tick-1ms
+/val == 0/
+{
+ val += a;
+}
+
+tick-1ms
+/incr != 0/
+{
+ i++;
+ @one[i] = lquantize(0, 10, 20, 1, incr);
+ @two[i] = lquantize(0, 1, 20, 5, incr);
+ @three[i] = lquantize(0, 0, 20, 1, incr);
+ @four[i] = lquantize(0, -10, 10, 1, incr);
+ @five[i] = lquantize(0, -10, 0, 1, incr);
+ @six[i] = lquantize(0, -10, -1, 1, incr);
+ @seven[i] = lquantize(0, -10, -2, 1, incr);
+}
+
+tick-1ms
+/incr == 0/
+{
+ printf("Zero below the range:\n");
+ printa(@one);
+ printf("\n");
+
+ printf("Zero just below the range:\n");
+ printa(@two);
+ printf("\n");
+
+ printf("Zero at the bottom of the range:\n");
+ printa(@three);
+ printf("\n");
+
+ printf("Zero within the range:\n");
+ printa(@four);
+ printf("\n");
+
+ printf("Zero at the top of the range:\n");
+ printa(@five);
+ printf("\n");
+
+ printf("Zero just above the range:\n");
+ printa(@six);
+ printf("\n");
+
+ printf("Zero above the range:\n");
+ printa(@seven);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d.out
new file mode 100644
index 0000000..330de38
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.lquantzero.d.out
@@ -0,0 +1,910 @@
+Zero below the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 10 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 10 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 10 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 10 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 10 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 10 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 10 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 10 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 10 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 10 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 10 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 10 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 10 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 10 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 10 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 10 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 10 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 10 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 10 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 10 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 10 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 10 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 10 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 10 | 0
+
+
+Zero just below the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 1 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 1 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 1 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 1 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 1 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 1 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 1 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 1 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 1 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 1 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 1 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ < 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 1 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 1 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 1 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 1 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 1 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 1 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 1 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 1 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 1 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ < 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 1 | 0
+
+
+Zero at the bottom of the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 1 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 1 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 1 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 1 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 1 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 1 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 1 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 1 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 1 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 1 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 1 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 1 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 1 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 1 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 1 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 1 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 1 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 1 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 1 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 1 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 1 | 0
+
+
+Zero within the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 1 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 1 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 1 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 1 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 1 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 1 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 1 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 1 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 1 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 1 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 1 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 1 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 1 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 1 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 1 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 1 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 1 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 1 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 1 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 1 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 1 | 0
+
+
+Zero at the top of the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+
+ 4
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+
+ 6
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+
+ 8
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+
+ 10
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+
+ 12
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+
+ 1
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+
+ 3
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+
+ 5
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+
+ 7
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+
+ 9
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+
+ 11
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+
+ 14
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+
+ 16
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+
+ 18
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+
+ 20
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+
+ 22
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+
+ 24
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+
+ 13
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+
+ 15
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+
+ 17
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+
+ 19
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+
+ 21
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+
+ 23
+ value ------------- Distribution ------------- count
+ -1 | 0
+ >= 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+
+
+Zero just above the range:
+
+ 2
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+
+ 4
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+
+ 6
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+
+ 8
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+
+ 10
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+
+ 12
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+
+ 1
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+
+ 3
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+
+ 5
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+
+ 7
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+
+ 9
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+
+ 11
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+
+ 14
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+
+ 16
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+
+ 18
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+
+ 20
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+
+ 22
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+
+ 24
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+
+ 13
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+
+ 15
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+
+ 17
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+
+ 19
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+
+ 21
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+
+ 23
+ value ------------- Distribution ------------- count
+ -2 | 0
+ >= -1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+
+
+Zero above the range:
+
+ 23
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+
+ 21
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+
+ 19
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+
+ 17
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+
+ 15
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+
+ 13
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+
+ 24
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+
+ 22
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+
+ 20
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+
+ 18
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+
+ 16
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+
+ 14
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+
+ 11
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+
+ 9
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+
+ 7
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+
+ 5
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+
+ 3
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+
+ 1
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+
+ 12
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+
+ 10
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+
+ 8
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+
+ 6
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+
+ 4
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+
+ 2
+ value ------------- Distribution ------------- count
+ -3 | 0
+ >= -2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d
new file mode 100644
index 0000000..0c973ad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive max() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the max() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = max(i);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ printa(@a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d.out
new file mode 100644
index 0000000..d3957f4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max.d.out
@@ -0,0 +1,3 @@
+
+ 900
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d
new file mode 100644
index 0000000..63486e5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive max() test using negative values
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the max() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @ = max(0);
+ @ = max(-900);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d.out
new file mode 100644
index 0000000..8d23188f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d.out
@@ -0,0 +1,2 @@
+
+ 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d
new file mode 100644
index 0000000..aff5452
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive min() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the min() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = min(i);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d.out
new file mode 100644
index 0000000..8d23188f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min.d.out
@@ -0,0 +1,2 @@
+
+ 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d
new file mode 100644
index 0000000..20f0a56
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive min() test using negative values
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the min() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @ = min(0);
+ @ = min(-900);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d.out
new file mode 100644
index 0000000..461b29c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d.out
@@ -0,0 +1,2 @@
+
+ -900
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d
new file mode 100644
index 0000000..c65fb52
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Multiple aggregates can be used within the same D script.
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ time_1 = timestamp;
+ i = 0;
+}
+
+tick-10ms
+/i <= 10/
+{
+ time_2 = timestamp;
+ new_time = time_2 - time_1;
+ @a[pid] = max(new_time);
+ @b[pid] = min(new_time);
+ @c[pid] = avg(new_time);
+ @d[pid] = sum(new_time);
+ @e[pid] = quantize(new_time);
+ @f[pid] = stddev(new_time);
+ @g[timestamp] = max(new_time);
+ @h[timestamp] = quantize(new_time);
+ @i[timestamp] = lquantize(new_time, 0, 10000, 1000);
+
+ time_1 = time_2;
+ i++;
+}
+
+tick-10ms
+/i == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d
new file mode 100644
index 0000000..b34d73f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test multiple aggregations and the default output order
+ *
+ * SECTION: Aggregations/Aggregations;
+ * Aggregations/Output
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = avg(i);
+ @b = sum(i);
+ @c = min(i);
+ @d = max(i);
+ @e = quantize(i);
+ @f = lquantize(i, 0, 1000, 100);
+ @g = stddev(i);
+
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out
new file mode 100644
index 0000000..579f78d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out
@@ -0,0 +1,37 @@
+
+ 450
+ 4500
+ 0
+ 900
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@ 1
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 |@@@@ 1
+ 128 |@@@@ 1
+ 256 |@@@@@@@@@@@@ 3
+ 512 |@@@@@@@@@@@@@@@@ 4
+ 1024 | 0
+
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@ 1
+ 100 |@@@@ 1
+ 200 |@@@@ 1
+ 300 |@@@@ 1
+ 400 |@@@@ 1
+ 500 |@@@@ 1
+ 600 |@@@@ 1
+ 700 |@@@@ 1
+ 800 |@@@@ 1
+ 900 |@@@@ 1
+ >= 1000 | 0
+
+ 287
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d
new file mode 100644
index 0000000..21d2fa9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test multiple aggregations and overriding default order with
+ * printa() statements.
+ *
+ * SECTION: Aggregations/Aggregations;
+ * Aggregations/Output
+ *
+ * NOTES: This is a simple verifiable test.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = count();
+ @b = avg(i);
+ @c = sum(i);
+ @d = min(i);
+ @e = max(i);
+ @f = quantize(i);
+ @g = lquantize(i, 0, 1000, 100);
+ @h = stddev(i);
+
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ printa("%@d\n", @h);
+ printa("%@d\n", @g);
+ printa("%@d\n", @f);
+ printa("%@d\n", @e);
+ printa("%@d\n", @d);
+ printa("%@d\n", @c);
+ printa("%@d\n", @b);
+ printa("%@d\n", @a);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out
new file mode 100644
index 0000000..ab97660
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out
@@ -0,0 +1,38 @@
+287
+
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@ 1
+ 100 |@@@@ 1
+ 200 |@@@@ 1
+ 300 |@@@@ 1
+ 400 |@@@@ 1
+ 500 |@@@@ 1
+ 600 |@@@@ 1
+ 700 |@@@@ 1
+ 800 |@@@@ 1
+ 900 |@@@@ 1
+ >= 1000 | 0
+
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@ 1
+ 1 | 0
+ 2 | 0
+ 4 | 0
+ 8 | 0
+ 16 | 0
+ 32 | 0
+ 64 |@@@@ 1
+ 128 |@@@@ 1
+ 256 |@@@@@@@@@@@@ 3
+ 512 |@@@@@@@@@@@@@@@@ 4
+ 1024 | 0
+
+900
+0
+4500
+450
+10
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d
new file mode 100644
index 0000000..2cfa184
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Multiple aggregations are supported
+ *
+ * SECTION: Aggregations/Normalization
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func1[i % 5] = sum(i * 100);
+ @func2[i % 5 + 1] = sum(i * 200);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("normalized data #1:\n");
+ normalize(@func1, 5);
+ printa(@func1);
+
+ printf("\nnormalized data #2:\n");
+ normalize(@func2, 5);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d.out
new file mode 100644
index 0000000..992b31e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multinormalize.d.out
@@ -0,0 +1,15 @@
+normalized data #1:
+
+ 0 600
+ 1 680
+ 2 760
+ 3 840
+ 4 920
+
+normalized data #2:
+
+ 1 1200
+ 2 1360
+ 3 1520
+ 4 1680
+ 5 1840
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d
new file mode 100644
index 0000000..d24884b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d
@@ -0,0 +1,150 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @["j-church"] = lquantize(1, 0, 10, 1, 100);
+ @["j-church"] = lquantize(1, 0, 10, 1, -99);
+ @["j-church"] = lquantize(1, 0, 10, 1, -1);
+ val = 123;
+}
+
+BEGIN
+{
+ @["k-ingleside"] = lquantize(1, 0, 10, 1, -val);
+}
+
+BEGIN
+{
+ @["l-taraval"] = lquantize(0, 0, 10, 1, -val);
+ @["l-taraval"] = lquantize(-1, 0, 10, 1, -val);
+ @["l-taraval"] = lquantize(1, 0, 10, 1, val);
+ @["l-taraval"] = lquantize(1, 0, 10, 1, val);
+}
+
+BEGIN
+{
+ @["m-oceanview"] = lquantize(1, 0, 10, 1, (1 << 63) - 1);
+ @["m-oceanview"] = lquantize(1, 0, 10, 1);
+ @["m-oceanview"] = lquantize(2, 0, 10, 1, (1 << 63) - 1);
+ @["m-oceanview"] = lquantize(8, 0, 10, 1, 400000);
+}
+
+BEGIN
+{
+ @["n-judah"] = lquantize(1, 0, 10, 1, val);
+ @["n-judah"] = lquantize(2, 0, 10, 1, val);
+ @["n-judah"] = lquantize(2, 0, 10, 1, val);
+ @["n-judah"] = lquantize(2, 0, 10, 1);
+}
+
+BEGIN
+{
+ this->i = 1;
+ this->val = (1 << 63) - 1;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["f-market"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+}
+
+BEGIN
+{
+ this->i = 1;
+
+ /*
+ * We want to test the ability to sort very large quantizations
+ * that differ by a small amount. Ideally, they would differ only
+ * by 1 -- but that is smaller than the precision of long doubles of
+ * this magnitude on x86. To assure that the same test works on x86
+ * just as it does on SPARC, we pick a value that is just larger than
+ * the precision at this magnitude. It should go without saying that
+ * this robustness on new ISAs very much depends on the precision
+ * of the long double representation.
+ */
+ this->val = (1 << 63) - 7;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+
+ @["s-castro"] = lquantize(this->i, 0, 10, 1, this->val);
+ this->i++;
+ this->val = ((1 << 63) - 1) / this->i;
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d.out
new file mode 100644
index 0000000..3b7533b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.neglquant.d.out
@@ -0,0 +1,64 @@
+
+ k-ingleside
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -123
+ 2 | 0
+
+ j-church
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 | 0
+ 1 | 0
+
+ l-taraval
+ value ------------- Distribution ------------- count
+ < 0 @@@@@| -123
+ 0 @@@@@| -123
+ 1 |@@@@@@@@@@ 246
+ 2 | 0
+
+ n-judah
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 123
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 247
+ 3 | 0
+
+ m-oceanview
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@| -9223372036854775808
+ 2 |@@@@@@@@@@ 9223372036854775807
+ 3 | 0
+ 4 | 0
+ 5 | 0
+ 6 | 0
+ 7 | 0
+ 8 | 400000
+ 9 | 0
+
+ s-castro
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@ 9223372036854775801
+ 2 |@@@@@@@@ 4611686018427387903
+ 3 |@@@@@ 3074457345618258602
+ 4 |@@@@ 2305843009213693951
+ 5 |@@@ 1844674407370955161
+ 6 |@@@ 1537228672809129301
+ 7 |@@ 1317624576693539401
+ 8 | 0
+
+ f-market
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@ 9223372036854775807
+ 2 |@@@@@@@@ 4611686018427387903
+ 3 |@@@@@ 3074457345618258602
+ 4 |@@@@ 2305843009213693951
+ 5 |@@@ 1844674407370955161
+ 6 |@@@ 1537228672809129301
+ 7 |@@ 1317624576693539401
+ 8 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d
new file mode 100644
index 0000000..440c483
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = 7;
+ b = 13;
+ val = (-a * b) + a;
+}
+
+tick-1ms
+{
+ incr = val % b;
+ val += a;
+}
+
+tick-1ms
+/val == 0/
+{
+ val += a;
+}
+
+tick-1ms
+/incr != 0/
+{
+ i++;
+ @quanty[i] = quantize(1, incr);
+ @lquanty[i] = lquantize(1, -10, 10, 1, incr);
+ @summy[i] = sum(incr);
+ @maxxy[i] = max(incr);
+ @minny[i] = min(incr);
+}
+
+tick-1ms
+/incr == 0/
+{
+ printf("Ordering of quantize() with some negative weights:\n");
+ printa(@quanty);
+ printf("\n");
+
+ printf("Ordering of lquantize() with some negative weights:\n");
+ printa(@lquanty);
+ printf("\n");
+
+ printf("Ordering of sum() with some negative weights:\n");
+ printa(@summy);
+ printf("\n");
+
+ printf("Ordering of max() with some negative weights:\n");
+ printa(@maxxy);
+ printf("\n");
+
+ printf("Ordering of min() with some negative weights:\n");
+ printa(@minny);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d.out
new file mode 100644
index 0000000..a03b685
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negorder.d.out
@@ -0,0 +1,376 @@
+Ordering of quantize() with some negative weights:
+
+ 2
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 2 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 2 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 2 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 2 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 2 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 2 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 2 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 2 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 2 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 2 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 2 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 2 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 2 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 2 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 2 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 2 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 2 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 2 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 2 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 2 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 2 | 0
+
+
+Ordering of lquantize() with some negative weights:
+
+ 2
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 2 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 2 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 2 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 2 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 2 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 2 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 2 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 2 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 2 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 2 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 2 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 2 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 2 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 2 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 2 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 2 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 2 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 2 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 2 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 2 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 2 | 0
+
+
+Ordering of sum() with some negative weights:
+
+ 2 -12
+ 4 -11
+ 6 -10
+ 8 -9
+ 10 -8
+ 12 -7
+ 1 -6
+ 3 -5
+ 5 -4
+ 7 -3
+ 9 -2
+ 11 -1
+ 14 1
+ 16 2
+ 18 3
+ 20 4
+ 22 5
+ 24 6
+ 13 7
+ 15 8
+ 17 9
+ 19 10
+ 21 11
+ 23 12
+
+Ordering of max() with some negative weights:
+
+ 2 -12
+ 4 -11
+ 6 -10
+ 8 -9
+ 10 -8
+ 12 -7
+ 1 -6
+ 3 -5
+ 5 -4
+ 7 -3
+ 9 -2
+ 11 -1
+ 14 1
+ 16 2
+ 18 3
+ 20 4
+ 22 5
+ 24 6
+ 13 7
+ 15 8
+ 17 9
+ 19 10
+ 21 11
+ 23 12
+
+Ordering of min() with some negative weights:
+
+ 2 -12
+ 4 -11
+ 6 -10
+ 8 -9
+ 10 -8
+ 12 -7
+ 1 -6
+ 3 -5
+ 5 -4
+ 7 -3
+ 9 -2
+ 11 -1
+ 14 1
+ 16 2
+ 18 3
+ 20 4
+ 22 5
+ 24 6
+ 13 7
+ 15 8
+ 17 9
+ 19 10
+ 21 11
+ 23 12
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d
new file mode 100644
index 0000000..bbc7263
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @["j-church"] = quantize(1, 100);
+ @["j-church"] = quantize(1, -99);
+ @["j-church"] = quantize(1, -1);
+ val = 123;
+}
+
+BEGIN
+{
+ @["k-ingleside"] = quantize(1, -val);
+}
+
+BEGIN
+{
+ @["l-taraval"] = quantize(0, -val);
+ @["l-taraval"] = quantize(-1, -val);
+ @["l-taraval"] = quantize(1, val);
+ @["l-taraval"] = quantize(1, val);
+}
+
+BEGIN
+{
+ @["m-oceanview"] = quantize(1, (1 << 63) - 1);
+ @["m-oceanview"] = quantize(1);
+ @["m-oceanview"] = quantize(2, (1 << 63) - 1);
+ @["m-oceanview"] = quantize(8, 400000);
+}
+
+BEGIN
+{
+ @["n-judah"] = quantize(1, val);
+ @["n-judah"] = quantize(2, val);
+ @["n-judah"] = quantize(2, val);
+ @["n-judah"] = quantize(2);
+}
+
+BEGIN
+{
+ this->i = 1;
+ this->val = (1 << 63) - 1;
+
+ @["f-market"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["f-market"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["f-market"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["f-market"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+}
+
+BEGIN
+{
+ this->i = 1;
+ this->val = (1 << 63) - 4;
+
+ @["s-castro"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["s-castro"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["s-castro"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+
+ @["s-castro"] = quantize(this->i, this->val);
+ this->i <<= 1;
+ this->val >>= 1;
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d.out
new file mode 100644
index 0000000..f8466b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negquant.d.out
@@ -0,0 +1,55 @@
+
+ k-ingleside
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -123
+ 2 | 0
+
+ j-church
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ l-taraval
+ value ------------- Distribution ------------- count
+ -2 | 0
+ -1 @@@@@| -123
+ 0 @@@@@| -123
+ 1 |@@@@@@@@@@ 246
+ 2 | 0
+
+ n-judah
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 123
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 247
+ 4 | 0
+
+ m-oceanview
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 @@@@@@@@@@| -9223372036854775808
+ 2 |@@@@@@@@@@ 9223372036854775807
+ 4 | 0
+ 8 | 400000
+ 16 | 0
+
+ s-castro
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@ 9223372036854775804
+ 2 |@@@@@@@@@@@ 4611686018427387902
+ 4 |@@@@@ 2305843009213693951
+ 8 |@@@ 1152921504606846975
+ 16 | 0
+
+ f-market
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@ 9223372036854775807
+ 2 |@@@@@@@@@@@ 4611686018427387903
+ 4 |@@@@@ 2305843009213693951
+ 8 |@@@ 1152921504606846975
+ 16 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d
new file mode 100644
index 0000000..f90eae1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+/i < 100/
+{
+ @[i] = sum(i);
+ i++;
+}
+
+tick-10ms
+/i == 100/
+{
+ exit(0);
+}
+
+END
+{
+ trunc(@, -10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d.out
new file mode 100644
index 0000000..c1b07a6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtrunc.d.out
@@ -0,0 +1,11 @@
+
+ 0 0
+ 1 1
+ 2 2
+ 3 3
+ 4 4
+ 5 5
+ 6 6
+ 7 7
+ 8 8
+ 9 9
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d
new file mode 100644
index 0000000..2a13d65
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+/i < 100/
+{
+ @[i] = lquantize(i, 0, 150);
+ @[i] = lquantize(i + 1, 0, 150);
+ @[i] = lquantize(i + 2, 0, 150);
+ @[i] = lquantize(i + 3, 0, 150);
+ i++;
+}
+
+tick-10ms
+/i == 100/
+{
+ exit(0);
+}
+
+END
+{
+ trunc(@, -5);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d.out
new file mode 100644
index 0000000..264aa39
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.negtruncquant.d.out
@@ -0,0 +1,46 @@
+
+ 0
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 |@@@@@@@@@@ 1
+ 1 |@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@ 1
+ 3 |@@@@@@@@@@ 1
+ 4 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@ 1
+ 3 |@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@ 1
+ 5 | 0
+
+ 2
+ value ------------- Distribution ------------- count
+ 1 | 0
+ 2 |@@@@@@@@@@ 1
+ 3 |@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@ 1
+ 5 |@@@@@@@@@@ 1
+ 6 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ 2 | 0
+ 3 |@@@@@@@@@@ 1
+ 4 |@@@@@@@@@@ 1
+ 5 |@@@@@@@@@@ 1
+ 6 |@@@@@@@@@@ 1
+ 7 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ 3 | 0
+ 4 |@@@@@@@@@@ 1
+ 5 |@@@@@@@@@@ 1
+ 6 |@@@@@@@@@@ 1
+ 7 |@@@@@@@@@@ 1
+ 8 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d
new file mode 100644
index 0000000..0bcc0fe
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for normalization()
+ *
+ * SECTION: Aggregations/Normalization
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+BEGIN
+{
+ i = 0;
+ start = timestamp;
+}
+
+tick-100ms
+/i < 20/
+{
+ @func[i % 5] = sum(i * 100);
+ i++;
+}
+
+tick-100ms
+/i == 20/
+{
+ printf("normalized data:\n");
+ normalize(@func, 5);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d.out
new file mode 100644
index 0000000..11193e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.normalize.d.out
@@ -0,0 +1,7 @@
+normalized data:
+
+ 0 600
+ 1 680
+ 2 760
+ 3 840
+ 4 920
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d
new file mode 100644
index 0000000..1390011
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @[8] = sum(1);
+ @[6] = sum(1);
+ @[7] = sum(1);
+ @[5] = sum(1);
+ @[3] = sum(1);
+ @[0] = sum(1);
+ @[9] = sum(1);
+
+ @tour["Ghent"] = sum(1);
+ @tour["Berlin"] = sum(1);
+ @tour["London"] = sum(1);
+ @tour["Dublin"] = sum(1);
+ @tour["Shanghai"] = sum(1);
+ @tour["Zurich"] = sum(1);
+ @tour["Regina"] = sum(1);
+ @tour["Winnipeg"] = sum(1);
+ @tour["Edmonton"] = sum(1);
+ @tour["Calgary"] = sum(1);
+
+ @ate[8, "Rice"] = sum(1);
+ @ate[8, "Oatmeal"] = sum(1);
+ @ate[8, "Barley"] = sum(1);
+ @ate[8, "Carrots"] = sum(1);
+ @ate[8, "Sweet potato"] = sum(1);
+ @ate[8, "Asparagus"] = sum(1);
+ @ate[8, "Squash"] = sum(1);
+
+ @chars['a'] = sum(1);
+ @chars['s'] = sum(1);
+ @chars['d'] = sum(1);
+ @chars['f'] = sum(1);
+
+ printa("%d\n", @);
+ printf("\n");
+
+ printa("%s\n", @tour);
+ printf("\n");
+
+ printa("%d %s\n", @ate);
+ printf("\n");
+
+ printa("%c\n", @chars);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d.out
new file mode 100644
index 0000000..505b0f3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.order.d.out
@@ -0,0 +1,33 @@
+0
+3
+5
+6
+7
+8
+9
+
+Berlin
+Calgary
+Dublin
+Edmonton
+Ghent
+London
+Regina
+Shanghai
+Winnipeg
+Zurich
+
+8 Asparagus
+8 Barley
+8 Carrots
+8 Oatmeal
+8 Rice
+8 Squash
+8 Sweet potato
+
+a
+d
+f
+s
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d
new file mode 100644
index 0000000..fad472a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive quantize() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the quantize() function.
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a[i] = quantize(i);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d.out
new file mode 100644
index 0000000..f4882ed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantize.d.out
@@ -0,0 +1,61 @@
+
+ 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+
+ 100
+ value ------------- Distribution ------------- count
+ 32 | 0
+ 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 128 | 0
+
+ 200
+ value ------------- Distribution ------------- count
+ 64 | 0
+ 128 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 256 | 0
+
+ 300
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ 400
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ 500
+ value ------------- Distribution ------------- count
+ 128 | 0
+ 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 512 | 0
+
+ 600
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ 700
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ 800
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
+ 900
+ value ------------- Distribution ------------- count
+ 256 | 0
+ 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1024 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d
new file mode 100644
index 0000000..e547b1e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int64_t val, shift;
+
+tick-1ms
+/val == 0/
+{
+ val = -(1 << shift);
+ shift++;
+}
+
+tick-1ms
+/shift == 32/
+{
+ exit(0);
+}
+
+tick-1ms
+/val == -1/
+{
+ val = (1 << shift);
+}
+
+tick-1ms
+{
+ @[shift] = quantize(val, val);
+ val >>= 1;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d.out
new file mode 100644
index 0000000..45df249
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantmany.d.out
@@ -0,0 +1,1208 @@
+
+ 1
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@ 1
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 4 | 0
+
+ 2
+ value ------------- Distribution ------------- count
+ -4 | 0
+ -2 @@@@| -2
+ -1 | 0
+ 0 | 0
+ 1 |@@ 1
+ 2 |@@@@ 2
+ 4 |@@@@@@@@@ 4
+ 8 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ -8 | 0
+ -4 @@@@| -4
+ -2 @@| -2
+ -1 | 0
+ 0 | 0
+ 1 |@ 1
+ 2 |@@ 2
+ 4 |@@@@ 4
+ 8 |@@@@@@@@ 8
+ 16 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ -16 | 0
+ -8 @@@@| -8
+ -4 @@| -4
+ -2 @| -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 |@ 2
+ 4 |@@ 4
+ 8 |@@@@ 8
+ 16 |@@@@@@@ 16
+ 32 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ -32 | 0
+ -16 @@@| -16
+ -8 @@| -8
+ -4 @| -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 |@ 4
+ 8 |@@ 8
+ 16 |@@@ 16
+ 32 |@@@@@@@ 32
+ 64 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ -64 | 0
+ -32 @@@| -32
+ -16 @@| -16
+ -8 @| -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 |@ 8
+ 16 |@@ 16
+ 32 |@@@ 32
+ 64 |@@@@@@@ 64
+ 128 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ -128 | 0
+ -64 @@@| -64
+ -32 @@| -32
+ -16 @| -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 |@ 16
+ 32 |@@ 32
+ 64 |@@@ 64
+ 128 |@@@@@@@ 128
+ 256 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ -256 | 0
+ -128 @@@| -128
+ -64 @@| -64
+ -32 @| -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 |@ 32
+ 64 |@@ 64
+ 128 |@@@ 128
+ 256 |@@@@@@@ 256
+ 512 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ -512 | 0
+ -256 @@@| -256
+ -128 @@| -128
+ -64 @| -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 |@ 64
+ 128 |@@ 128
+ 256 |@@@ 256
+ 512 |@@@@@@@ 512
+ 1024 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ -1024 | 0
+ -512 @@@| -512
+ -256 @@| -256
+ -128 @| -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 |@ 128
+ 256 |@@ 256
+ 512 |@@@ 512
+ 1024 |@@@@@@@ 1024
+ 2048 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ -2048 | 0
+ -1024 @@@| -1024
+ -512 @@| -512
+ -256 @| -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 |@ 256
+ 512 |@@ 512
+ 1024 |@@@ 1024
+ 2048 |@@@@@@@ 2048
+ 4096 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ -4096 | 0
+ -2048 @@@| -2048
+ -1024 @@| -1024
+ -512 @| -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 |@ 512
+ 1024 |@@ 1024
+ 2048 |@@@ 2048
+ 4096 |@@@@@@@ 4096
+ 8192 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ -8192 | 0
+ -4096 @@@| -4096
+ -2048 @@| -2048
+ -1024 @| -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 |@ 1024
+ 2048 |@@ 2048
+ 4096 |@@@ 4096
+ 8192 |@@@@@@@ 8192
+ 16384 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ -16384 | 0
+ -8192 @@@| -8192
+ -4096 @@| -4096
+ -2048 @| -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 |@ 2048
+ 4096 |@@ 4096
+ 8192 |@@@ 8192
+ 16384 |@@@@@@@ 16384
+ 32768 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ -32768 | 0
+ -16384 @@@| -16384
+ -8192 @@| -8192
+ -4096 @| -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 |@ 4096
+ 8192 |@@ 8192
+ 16384 |@@@ 16384
+ 32768 |@@@@@@@ 32768
+ 65536 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ -65536 | 0
+ -32768 @@@| -32768
+ -16384 @@| -16384
+ -8192 @| -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 |@ 8192
+ 16384 |@@ 16384
+ 32768 |@@@ 32768
+ 65536 |@@@@@@@ 65536
+ 131072 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ -131072 | 0
+ -65536 @@@| -65536
+ -32768 @@| -32768
+ -16384 @| -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 |@ 16384
+ 32768 |@@ 32768
+ 65536 |@@@ 65536
+ 131072 |@@@@@@@ 131072
+ 262144 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ -262144 | 0
+ -131072 @@@| -131072
+ -65536 @@| -65536
+ -32768 @| -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 |@ 32768
+ 65536 |@@ 65536
+ 131072 |@@@ 131072
+ 262144 |@@@@@@@ 262144
+ 524288 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ -524288 | 0
+ -262144 @@@| -262144
+ -131072 @@| -131072
+ -65536 @| -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 |@ 65536
+ 131072 |@@ 131072
+ 262144 |@@@ 262144
+ 524288 |@@@@@@@ 524288
+ 1048576 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ -1048576 | 0
+ -524288 @@@| -524288
+ -262144 @@| -262144
+ -131072 @| -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 |@ 131072
+ 262144 |@@ 262144
+ 524288 |@@@ 524288
+ 1048576 |@@@@@@@ 1048576
+ 2097152 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ -2097152 | 0
+ -1048576 @@@| -1048576
+ -524288 @@| -524288
+ -262144 @| -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 |@ 262144
+ 524288 |@@ 524288
+ 1048576 |@@@ 1048576
+ 2097152 |@@@@@@@ 2097152
+ 4194304 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ -4194304 | 0
+ -2097152 @@@| -2097152
+ -1048576 @@| -1048576
+ -524288 @| -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 |@ 524288
+ 1048576 |@@ 1048576
+ 2097152 |@@@ 2097152
+ 4194304 |@@@@@@@ 4194304
+ 8388608 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ -8388608 | 0
+ -4194304 @@@| -4194304
+ -2097152 @@| -2097152
+ -1048576 @| -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 |@ 1048576
+ 2097152 |@@ 2097152
+ 4194304 |@@@ 4194304
+ 8388608 |@@@@@@@ 8388608
+ 16777216 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ -16777216 | 0
+ -8388608 @@@| -8388608
+ -4194304 @@| -4194304
+ -2097152 @| -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 |@ 2097152
+ 4194304 |@@ 4194304
+ 8388608 |@@@ 8388608
+ 16777216 |@@@@@@@ 16777216
+ 33554432 | 0
+
+ 25
+ value ------------- Distribution ------------- count
+ -33554432 | 0
+ -16777216 @@@| -16777216
+ -8388608 @@| -8388608
+ -4194304 @| -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 |@ 4194304
+ 8388608 |@@ 8388608
+ 16777216 |@@@ 16777216
+ 33554432 |@@@@@@@ 33554432
+ 67108864 | 0
+
+ 26
+ value ------------- Distribution ------------- count
+ -67108864 | 0
+ -33554432 @@@| -33554432
+ -16777216 @@| -16777216
+ -8388608 @| -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 |@ 8388608
+ 16777216 |@@ 16777216
+ 33554432 |@@@ 33554432
+ 67108864 |@@@@@@@ 67108864
+ 134217728 | 0
+
+ 27
+ value ------------- Distribution ------------- count
+ -134217728 | 0
+ -67108864 @@@| -67108864
+ -33554432 @@| -33554432
+ -16777216 @| -16777216
+ -8388608 | -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 | 8388608
+ 16777216 |@ 16777216
+ 33554432 |@@ 33554432
+ 67108864 |@@@ 67108864
+ 134217728 |@@@@@@@ 134217728
+ 268435456 | 0
+
+ 28
+ value ------------- Distribution ------------- count
+ -268435456 | 0
+ -134217728 @@@| -134217728
+ -67108864 @@| -67108864
+ -33554432 @| -33554432
+ -16777216 | -16777216
+ -8388608 | -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 | 8388608
+ 16777216 | 16777216
+ 33554432 |@ 33554432
+ 67108864 |@@ 67108864
+ 134217728 |@@@ 134217728
+ 268435456 |@@@@@@@ 268435456
+ 536870912 | 0
+
+ 29
+ value ------------- Distribution ------------- count
+ -536870912 | 0
+ -268435456 @@@| -268435456
+ -134217728 @@| -134217728
+ -67108864 @| -67108864
+ -33554432 | -33554432
+ -16777216 | -16777216
+ -8388608 | -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 | 8388608
+ 16777216 | 16777216
+ 33554432 | 33554432
+ 67108864 |@ 67108864
+ 134217728 |@@ 134217728
+ 268435456 |@@@ 268435456
+ 536870912 |@@@@@@@ 536870912
+ 1073741824 | 0
+
+ 30
+ value ------------- Distribution ------------- count
+ -1073741824 | 0
+ -536870912 @@@| -536870912
+ -268435456 @@| -268435456
+ -134217728 @| -134217728
+ -67108864 | -67108864
+ -33554432 | -33554432
+ -16777216 | -16777216
+ -8388608 | -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 | 8388608
+ 16777216 | 16777216
+ 33554432 | 33554432
+ 67108864 | 67108864
+ 134217728 |@ 134217728
+ 268435456 |@@ 268435456
+ 536870912 |@@@ 536870912
+ 1073741824 |@@@@@@@ 1073741824
+ 2147483648 | 0
+
+ 31
+ value ------------- Distribution ------------- count
+ -2147483648 | 0
+ -1073741824 @@@| -1073741824
+ -536870912 @@| -536870912
+ -268435456 @| -268435456
+ -134217728 | -134217728
+ -67108864 | -67108864
+ -33554432 | -33554432
+ -16777216 | -16777216
+ -8388608 | -8388608
+ -4194304 | -4194304
+ -2097152 | -2097152
+ -1048576 | -1048576
+ -524288 | -524288
+ -262144 | -262144
+ -131072 | -131072
+ -65536 | -65536
+ -32768 | -32768
+ -16384 | -16384
+ -8192 | -8192
+ -4096 | -4096
+ -2048 | -2048
+ -1024 | -1024
+ -512 | -512
+ -256 | -256
+ -128 | -128
+ -64 | -64
+ -32 | -32
+ -16 | -16
+ -8 | -8
+ -4 | -4
+ -2 | -2
+ -1 | 0
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 4 | 4
+ 8 | 8
+ 16 | 16
+ 32 | 32
+ 64 | 64
+ 128 | 128
+ 256 | 256
+ 512 | 512
+ 1024 | 1024
+ 2048 | 2048
+ 4096 | 4096
+ 8192 | 8192
+ 16384 | 16384
+ 32768 | 32768
+ 65536 | 65536
+ 131072 | 131072
+ 262144 | 262144
+ 524288 | 524288
+ 1048576 | 1048576
+ 2097152 | 2097152
+ 4194304 | 4194304
+ 8388608 | 8388608
+ 16777216 | 16777216
+ 33554432 | 33554432
+ 67108864 | 67108864
+ 134217728 | 134217728
+ 268435456 |@ 268435456
+ 536870912 |@@ 536870912
+ 1073741824 |@@@ 1073741824
+ 2147483648 |@@@@@@@ 2147483648
+ 4294967296 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d
new file mode 100644
index 0000000..c40d69c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+/*
+ * This test verifies that the height of the ASCII quantization bars is
+ * determined using rounding and not truncated integer arithmetic.
+ */
+tick-10ms
+/i++ >= 27/
+{
+ exit(0);
+}
+
+tick-10ms
+/i > 8/
+{
+ @ = quantize(2);
+}
+
+tick-10ms
+/i > 2 && i <= 8/
+{
+ @ = quantize(1);
+}
+
+tick-10ms
+/i <= 2/
+{
+ @ = quantize(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d.out
new file mode 100644
index 0000000..9b89ec1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantround.d.out
@@ -0,0 +1,9 @@
+
+
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@ 2
+ 1 |@@@@@@@@@ 6
+ 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 19
+ 4 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d
new file mode 100644
index 0000000..bfa633c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ a = 7;
+ b = 13;
+ val = (-a * b) + a;
+}
+
+tick-1ms
+{
+ incr = val % b;
+ val += a;
+}
+
+tick-1ms
+/val == 0/
+{
+ val += a;
+}
+
+tick-1ms
+/incr != 0/
+{
+ i++;
+ @[i] = quantize(0, incr);
+}
+
+tick-1ms
+/incr == 0/
+{
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d.out
new file mode 100644
index 0000000..c2c1cf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.quantzero.d.out
@@ -0,0 +1,146 @@
+
+ 2
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 1 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 1 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 1 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 1 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 1 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 1 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 1 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 1 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 1 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 1 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 1 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 1 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 1 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 1 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 1 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 1 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 1 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 1 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 1 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 1 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 1 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 1 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 1 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 1 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signature.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signature.d
new file mode 100644
index 0000000..baa951a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signature.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This is a simple test to make sure that signature checking works properly
+ * for the fake-o types.
+ */
+BEGIN
+{
+ @stk[ustack()] = count();
+ @symmy[sym(0)] = count();
+ @usymmy[usym(0)] = count();
+ @funky[func(0)] = count();
+ @ufunky[ufunc(0)] = count();
+ @moddy[mod(0)] = count();
+ @umoddy[umod(0)] = count();
+}
+
+BEGIN
+{
+ @stk[ustack()] = count();
+ @symmy[sym(0)] = count();
+ @usymmy[usym(0)] = count();
+ @funky[func(0)] = count();
+ @ufunky[ufunc(0)] = count();
+ @moddy[mod(0)] = count();
+ @umoddy[umod(0)] = count();
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d
new file mode 100644
index 0000000..ed3d131
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Signed integer keys print and sort as expected.
+ *
+ * SECTION: Aggregations, Printing Aggregations
+ *
+ * NOTES: DTrace sorts integer keys as unsigned values, yet prints 32-
+ * and 64-bit integers as signed values. Since the Java DTrace API is
+ * expected to emulate this behavior, this test was added to ensure that
+ * the behavior is preserved. Consistency with trace() output is also
+ * tested.
+ */
+
+#pragma D option quiet
+#pragma D option aggsortkey
+
+BEGIN
+{
+ trace((char)-2);
+ trace("\n");
+ trace((char)-1);
+ trace("\n");
+ trace((char)0);
+ trace("\n");
+ trace((char)1);
+ trace("\n");
+ trace((char)2);
+ trace("\n");
+ trace("\n");
+
+ trace((short)-2);
+ trace("\n");
+ trace((short)-1);
+ trace("\n");
+ trace((short)0);
+ trace("\n");
+ trace((short)1);
+ trace("\n");
+ trace((short)2);
+ trace("\n");
+ trace("\n");
+
+ trace(-2);
+ trace("\n");
+ trace(-1);
+ trace("\n");
+ trace(0);
+ trace("\n");
+ trace(1);
+ trace("\n");
+ trace(2);
+ trace("\n");
+ trace("\n");
+
+ trace((long long)-2);
+ trace("\n");
+ trace((long long)-1);
+ trace("\n");
+ trace((long long)0);
+ trace("\n");
+ trace((long long)1);
+ trace("\n");
+ trace((long long)2);
+ trace("\n");
+
+ @i8[(char)-2] = sum(-2);
+ @i8[(char)-1] = sum(-1);
+ @i8[(char)0] = sum(0);
+ @i8[(char)1] = sum(1);
+ @i8[(char)2] = sum(2);
+
+ @i16[(short)-2] = sum(-2);
+ @i16[(short)-1] = sum(-1);
+ @i16[(short)0] = sum(0);
+ @i16[(short)1] = sum(1);
+ @i16[(short)2] = sum(2);
+
+ @i32[-2] = sum(-2);
+ @i32[-1] = sum(-1);
+ @i32[0] = sum(0);
+ @i32[1] = sum(1);
+ @i32[2] = sum(2);
+
+ @i64[(long long)-2] = sum(-2);
+ @i64[(long long)-1] = sum(-1);
+ @i64[(long long)0] = sum(0);
+ @i64[(long long)1] = sum(1);
+ @i64[(long long)2] = sum(2);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d.out
new file mode 100644
index 0000000..42e619e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeys.d.out
@@ -0,0 +1,44 @@
+254
+255
+0
+1
+2
+
+65534
+65535
+0
+1
+2
+
+-2
+-1
+0
+1
+2
+
+-2
+-1
+0
+1
+2
+
+ 0 0
+ 1 1
+ 2 2
+ 254 -2
+ 255 -1
+ 0 0
+ 1 1
+ 2 2
+ 65534 -2
+ 65535 -1
+ 0 0
+ 1 1
+ 2 2
+ -2 -2
+ -1 -1
+ 0 0
+ 1 1
+ 2 2
+ -2 -2
+ -1 -1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d
new file mode 100644
index 0000000..5836c6a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Signed integer keys print and sort as expected using the
+ * aggsortkeypos and aggsortrev options
+ *
+ * SECTION: Aggregations, Printing Aggregations
+ *
+ * NOTES: DTrace sorts integer keys as unsigned values, yet prints 32-
+ * and 64-bit integers as signed values. Since the Java DTrace API is
+ * expected to emulate this behavior, this test was added to ensure that
+ * the behavior is preserved.
+ */
+
+#pragma D option quiet
+#pragma D option aggsortkey
+#pragma D option aggsortkeypos=1
+#pragma D option aggsortrev
+
+BEGIN
+{
+ @i8["cat", (char)-2] = sum(-2);
+ @i8["dog", (char)-2] = sum(-22);
+ @i8["mouse", (char)-2] = sum(-222);
+ @i8["cat", (char)-1] = sum(-1);
+ @i8["dog", (char)-1] = sum(-11);
+ @i8["mouse", (char)-1] = sum(-111);
+ @i8["cat", (char)0] = sum(0);
+ @i8["dog", (char)0] = sum(10);
+ @i8["mouse", (char)0] = sum(100);
+ @i8["cat", (char)1] = sum(1);
+ @i8["dog", (char)1] = sum(11);
+ @i8["mouse", (char)1] = sum(111);
+ @i8["cat", (char)2] = sum(2);
+ @i8["dog", (char)2] = sum(22);
+ @i8["mouse", (char)2] = sum(222);
+
+ @i16["mouse", (short)-2] = sum(-2);
+ @i16["dog", (short)-2] = sum(-22);
+ @i16["cat", (short)-2] = sum(-222);
+ @i16["mouse", (short)-1] = sum(-1);
+ @i16["dog", (short)-1] = sum(-11);
+ @i16["cat", (short)-1] = sum(-111);
+ @i16["mouse", (short)0] = sum(0);
+ @i16["dog", (short)0] = sum(10);
+ @i16["cat", (short)0] = sum(100);
+ @i16["mouse", (short)1] = sum(1);
+ @i16["dog", (short)1] = sum(11);
+ @i16["cat", (short)1] = sum(111);
+ @i16["mouse", (short)2] = sum(2);
+ @i16["dog", (short)2] = sum(22);
+ @i16["cat", (short)2] = sum(222);
+
+ @i32["mouse", -2] = sum(-2);
+ @i32["bear", -2] = sum(-22);
+ @i32["cat", -2] = sum(-222);
+ @i32["mouse", -1] = sum(-1);
+ @i32["bear", -1] = sum(-11);
+ @i32["cat", -1] = sum(-111);
+ @i32["mouse", 0] = sum(0);
+ @i32["bear", 0] = sum(10);
+ @i32["cat", 0] = sum(100);
+ @i32["mouse", 1] = sum(1);
+ @i32["bear", 1] = sum(11);
+ @i32["cat", 1] = sum(111);
+ @i32["mouse", 2] = sum(2);
+ @i32["bear", 2] = sum(22);
+ @i32["cat", 2] = sum(222);
+
+ @i64["cat", (long long)-2] = sum(-2);
+ @i64["bear", (long long)-2] = sum(-22);
+ @i64["dog", (long long)-2] = sum(-222);
+ @i64["cat", (long long)-1] = sum(-1);
+ @i64["bear", (long long)-1] = sum(-11);
+ @i64["dog", (long long)-1] = sum(-111);
+ @i64["cat", (long long)0] = sum(0);
+ @i64["bear", (long long)0] = sum(10);
+ @i64["dog", (long long)0] = sum(100);
+ @i64["cat", (long long)1] = sum(1);
+ @i64["bear", (long long)1] = sum(11);
+ @i64["dog", (long long)1] = sum(111);
+ @i64["cat", (long long)2] = sum(2);
+ @i64["bear", (long long)2] = sum(22);
+ @i64["dog", (long long)2] = sum(222);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d.out
new file mode 100644
index 0000000..28e95ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.signedkeyspos.d.out
@@ -0,0 +1,61 @@
+
+ dog -1 -111
+ cat -1 -1
+ bear -1 -11
+ dog -2 -222
+ cat -2 -2
+ bear -2 -22
+ dog 2 222
+ cat 2 2
+ bear 2 22
+ dog 1 111
+ cat 1 1
+ bear 1 11
+ dog 0 100
+ cat 0 0
+ bear 0 10
+ mouse -1 -1
+ cat -1 -111
+ bear -1 -11
+ mouse -2 -2
+ cat -2 -222
+ bear -2 -22
+ mouse 2 2
+ cat 2 222
+ bear 2 22
+ mouse 1 1
+ cat 1 111
+ bear 1 11
+ mouse 0 0
+ cat 0 100
+ bear 0 10
+ mouse 65535 -1
+ dog 65535 -11
+ cat 65535 -111
+ mouse 65534 -2
+ dog 65534 -22
+ cat 65534 -222
+ mouse 2 2
+ dog 2 22
+ cat 2 222
+ mouse 1 1
+ dog 1 11
+ cat 1 111
+ mouse 0 0
+ dog 0 10
+ cat 0 100
+ mouse 255 -111
+ dog 255 -11
+ cat 255 -1
+ mouse 254 -222
+ dog 254 -22
+ cat 254 -2
+ mouse 2 222
+ dog 2 22
+ cat 2 2
+ mouse 1 111
+ dog 1 11
+ cat 1 1
+ mouse 0 100
+ dog 0 10
+ cat 0 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d
new file mode 100644
index 0000000..041b820
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Positive stddev() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is a simple verifiable positive test of the stddev() function.
+ * printa() for one aggregation, default printing behavior for the other
+ * so that we exercise both code paths.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = stddev(5000000000);
+ @a = stddev(5000000100);
+ @a = stddev(5000000200);
+ @a = stddev(5000000300);
+ @a = stddev(5000000400);
+ @a = stddev(5000000500);
+ @a = stddev(5000000600);
+ @a = stddev(5000000700);
+ @a = stddev(5000000800);
+ @a = stddev(5000000900);
+ @b = stddev(-5000000000);
+ @b = stddev(-5000000100);
+ @b = stddev(-5000000200);
+ @b = stddev(-5000000300);
+ @b = stddev(-5000000400);
+ @b = stddev(-5000000500);
+ @b = stddev(-5000000600);
+ @b = stddev(-5000000700);
+ @b = stddev(-5000000800);
+ @b = stddev(-5000000900);
+ printa("%@d\n", @a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out
new file mode 100644
index 0000000..0c02852
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out
@@ -0,0 +1,3 @@
+287
+
+ 287
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d
new file mode 100644
index 0000000..d508596
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d
@@ -0,0 +1,111 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#define INTFUNC(x) \
+ BEGIN \
+ /*DSTYLED*/ \
+ { \
+ subr++; \
+ @[(long)x] = sum(1); \
+ /*DSTYLED*/ \
+ }
+
+#define STRFUNC(x) \
+ BEGIN \
+ /*DSTYLED*/ \
+ { \
+ subr++; \
+ @str[x] = sum(1); \
+ /*DSTYLED*/ \
+ }
+
+#define VOIDFUNC(x) \
+ BEGIN \
+ /*DSTYLED*/ \
+ { \
+ subr++; \
+ /*DSTYLED*/ \
+ }
+
+INTFUNC(rand())
+INTFUNC(mutex_owned(&`cpu_lock))
+INTFUNC(mutex_owner(&`cpu_lock))
+INTFUNC(mutex_type_adaptive(&`cpu_lock))
+INTFUNC(mutex_type_spin(&`cpu_lock))
+INTFUNC(rw_read_held(&`vfssw_lock))
+INTFUNC(rw_write_held(&`vfssw_lock))
+INTFUNC(rw_iswriter(&`vfssw_lock))
+INTFUNC(copyin(NULL, 1))
+STRFUNC(copyinstr(NULL, 1))
+INTFUNC(speculation())
+INTFUNC(progenyof($pid))
+INTFUNC(strlen("fooey"))
+VOIDFUNC(copyout)
+VOIDFUNC(copyoutstr)
+INTFUNC(alloca(10))
+VOIDFUNC(bcopy)
+VOIDFUNC(copyinto)
+INTFUNC(msgdsize(NULL))
+INTFUNC(msgsize(NULL))
+INTFUNC(getmajor(0))
+INTFUNC(getminor(0))
+STRFUNC(ddi_pathname(NULL, 0))
+STRFUNC(strjoin("foo", "bar"))
+STRFUNC(lltostr(12373))
+STRFUNC(basename("/var/crash/systemtap"))
+STRFUNC(dirname("/var/crash/systemtap"))
+STRFUNC(cleanpath("/var/crash/systemtap"))
+STRFUNC(strchr("The SystemTap, The.", 't'))
+STRFUNC(strrchr("The SystemTap, The.", 't'))
+STRFUNC(strstr("The SystemTap, The.", "The"))
+STRFUNC(strtok("The SystemTap, The.", "T"))
+STRFUNC(substr("The SystemTap, The.", 0))
+INTFUNC(index("The SystemTap, The.", "The"))
+INTFUNC(rindex("The SystemTap, The.", "The"))
+INTFUNC(htons(0x1234))
+INTFUNC(htonl(0x12345678))
+INTFUNC(htonll(0x1234567890abcdefL))
+INTFUNC(ntohs(0x1234))
+INTFUNC(ntohl(0x12345678))
+INTFUNC(ntohll(0x1234567890abcdefL))
+STRFUNC(inet_ntoa((ipaddr_t *)alloca(sizeof (ipaddr_t))))
+STRFUNC(inet_ntoa6((in6_addr_t *)alloca(sizeof (in6_addr_t))))
+STRFUNC(inet_ntop(AF_INET, (void *)alloca(sizeof (ipaddr_t))))
+
+BEGIN
+/subr == DIF_SUBR_MAX + 1/
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("found %d subroutines, expected %d\n", subr, DIF_SUBR_MAX + 1);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d
new file mode 100644
index 0000000..1b9025a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive sum() test
+ *
+ * SECTION: Aggregations/Aggregations
+ *
+ * NOTES: This is verifiable simple positive test of the sum() function.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 1000/
+{
+ @a = sum(i);
+ i += 100;
+}
+
+tick-10ms
+/i == 1000/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d.out
new file mode 100644
index 0000000..5d8b37b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.sum.d.out
@@ -0,0 +1,2 @@
+
+ 4500
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d
new file mode 100644
index 0000000..d1c1b3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+/i < 100/
+{
+ @[i] = sum(i);
+ i++;
+}
+
+tick-10ms
+/i == 100/
+{
+ exit(0);
+}
+
+END
+{
+ trunc(@, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d.out
new file mode 100644
index 0000000..2e18ef8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc.d.out
@@ -0,0 +1,11 @@
+
+ 90 90
+ 91 91
+ 92 92
+ 93 93
+ 94 94
+ 95 95
+ 96 96
+ 97 97
+ 98 98
+ 99 99
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d
new file mode 100644
index 0000000..5c31069
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option aggrate=1ms
+#pragma D option switchrate=50ms
+
+int i;
+
+tick-100ms
+/i < 10/
+{
+ @[i] = sum(10 - i);
+ i++;
+}
+
+tick-100ms
+/i == 5/
+{
+ trunc(@);
+}
+
+tick-100ms
+/i == 10/
+{
+ exit(0);
+}
+
+END
+{
+ printa(@);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d.out
new file mode 100644
index 0000000..70dc7a0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.trunc0.d.out
@@ -0,0 +1,7 @@
+
+ 9 1
+ 8 2
+ 7 3
+ 6 4
+ 5 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d
new file mode 100644
index 0000000..8baa56a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+/i < 100/
+{
+ @[i] = lquantize(i, 0, 150);
+ @[i] = lquantize(i + 1, 0, 150);
+ @[i] = lquantize(i + 2, 0, 150);
+ @[i] = lquantize(i + 3, 0, 150);
+ i++;
+}
+
+tick-10ms
+/i == 100/
+{
+ exit(0);
+}
+
+END
+{
+ trunc(@, 5);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d.out
new file mode 100644
index 0000000..86975af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.truncquant.d.out
@@ -0,0 +1,46 @@
+
+ 95
+ value ------------- Distribution ------------- count
+ 94 | 0
+ 95 |@@@@@@@@@@ 1
+ 96 |@@@@@@@@@@ 1
+ 97 |@@@@@@@@@@ 1
+ 98 |@@@@@@@@@@ 1
+ 99 | 0
+
+ 96
+ value ------------- Distribution ------------- count
+ 95 | 0
+ 96 |@@@@@@@@@@ 1
+ 97 |@@@@@@@@@@ 1
+ 98 |@@@@@@@@@@ 1
+ 99 |@@@@@@@@@@ 1
+ 100 | 0
+
+ 97
+ value ------------- Distribution ------------- count
+ 96 | 0
+ 97 |@@@@@@@@@@ 1
+ 98 |@@@@@@@@@@ 1
+ 99 |@@@@@@@@@@ 1
+ 100 |@@@@@@@@@@ 1
+ 101 | 0
+
+ 98
+ value ------------- Distribution ------------- count
+ 97 | 0
+ 98 |@@@@@@@@@@ 1
+ 99 |@@@@@@@@@@ 1
+ 100 |@@@@@@@@@@ 1
+ 101 |@@@@@@@@@@ 1
+ 102 | 0
+
+ 99
+ value ------------- Distribution ------------- count
+ 98 | 0
+ 99 |@@@@@@@@@@ 1
+ 100 |@@@@@@@@@@ 1
+ 101 |@@@@@@@@@@ 1
+ 102 |@@@@@@@@@@ 1
+ 103 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d
new file mode 100644
index 0000000..ec0bee3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * aggsortkeypos option works when sorting by values, values are
+ * equal, and keys are compared to break the tie
+ *
+ * SECTION: Aggregations, Printing Aggregations
+ *
+ */
+
+#pragma D option quiet
+#pragma D option aggsortkeypos=1
+
+BEGIN
+{
+ @[1, 3] = sum(0);
+ @[2, 2] = sum(0);
+ @[3, 1] = sum(0);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d.out
new file mode 100644
index 0000000..9b0acf9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.valsortkeypos.d.out
@@ -0,0 +1,4 @@
+
+ 3 1 0
+ 2 2 0
+ 1 3 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0.d
new file mode 100644
index 0000000..0b7b661
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify that divide by 0 errors are caught
+ *
+ * SECTION:
+ * Types, Operators, and Expressions/Arithmetic Operators
+ */
+
+
+BEGIN
+{
+ c = 123/0;
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_1.d
new file mode 100644
index 0000000..1101795
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_1.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify that computed divide by 0 errors are caught
+ *
+ * SECTION:
+ * Types, Operators, and Expressions/Arithmetic Operators
+ */
+
+
+
+
+BEGIN
+{
+ c = 123/(7-7);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_2.d
new file mode 100644
index 0000000..4546961
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.divby0_2.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify that computed divide by 0 errors are caught
+ *
+ * SECTION:
+ * Types, Operators, and Expressions/Arithmetic Operators
+ */
+
+
+
+
+
+BEGIN
+{
+ c = 123/((7-7) * 999);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.modby0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.modby0.d
new file mode 100644
index 0000000..b2bf146
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_DIV_ZERO.modby0.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify that mod by 0 errors are caught
+ *
+ * SECTION:
+ * Types, Operators, and Expressions/Arithmetic Operators
+ */
+
+
+
+BEGIN
+{
+ c = 123%0;
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.addmin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.addmin.d
new file mode 100644
index 0000000..f20339c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.addmin.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call invalid / impossible arithmetic operations and make sure
+ * Test gives compilation error.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ i+-;
+ printf("The value of i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.divmin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.divmin.d
new file mode 100644
index 0000000..c11e64f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.divmin.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call invalid / impossible arithmetic operations and make sure
+ * Test gives compilation error.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 1;
+ i /-= i;
+ printf("The value of i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muladd.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muladd.d
new file mode 100644
index 0000000..bb107fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muladd.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call invalid / impossible arithmetic operations and make sure
+ * Test gives compilation error.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 1;
+ i *+= i;
+ printf("The value of i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muldiv.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muldiv.d
new file mode 100644
index 0000000..7d44b6c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/err.D_SYNTAX.muldiv.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call invalid / impossible arithmetic operations and make sure
+ * Test gives compilation error.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 1;
+ i */= i;
+ printf("The value of i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d
new file mode 100644
index 0000000..435f09f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.basics.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple Arithmetic expressions.
+ * Call simple expressions and make sure test succeeds.
+ * Match expected output in tst.basics.d.out
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ i = 1 + 2 + 3;
+ printf("The value of i is %d\n", i);
+
+ i = i * 3;
+ printf("The value of i is %d\n", i);
+
+ i = (i * 3) + i;
+ printf("The value of i is %d\n", i);
+
+ i = (i + (i * 3) + i) * i;
+ printf("The value of i is %d\n", i);
+
+ i = i - (i + (i * 3) + i) * i / i * i;
+ printf("The value of i is %d\n", i);
+
+ i = i * (i - 3 + 5 / i * i ) / i * 6;
+ printf("The value of i is %d\n", i);
+
+ i = i ^ 5;
+ printf("The value of i is %d\n", i);
+
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d
new file mode 100644
index 0000000..2db1b63
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arithmetic/tst.complex.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Complex expressions.
+ * Call complex expressions and make sure test succeeds.
+ * Match expected output in tst.complex.d.out
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ i = i++ + ++i;
+ printf("The value of i is %d\n", i);
+ i = i-- - --i;
+ printf("The value of i is %d\n", i);
+ i = i-- + ++i;
+ printf("The value of i is %d\n", i);
+ i += i++ + -- i + ++i - ++i * i ;
+ printf("The value of i is %d\n", i);
+ i -= i++ * 3;
+ printf("The value of i is %d\n", i);
+ i = i++/i--+i++-++i-++i;
+ printf("The value of i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_ARR_BADREF.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_ARR_BADREF.bad.d
new file mode 100644
index 0000000..d31b1f6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_ARR_BADREF.bad.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tuples can not be used in non-associative arrays.
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ */
+
+int x[5];
+
+BEGIN
+{
+ x[1, 2] = 1;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRBIG.toobig.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRBIG.toobig.d
new file mode 100644
index 0000000..80422e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRBIG.toobig.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Array declarations with indexs over INT_MAX return a
+ * D_DECL_ARRBIG errtag.
+ *
+ * SECTION:
+ * Pointers and Arrays/Array Declarations and Storage
+ */
+
+int x[88294967295];
+
+BEGIN
+{
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRNULL.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRNULL.bad.d
new file mode 100644
index 0000000..6e7a34f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRNULL.bad.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Arrays must have array dimensions
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ */
+
+int a[];
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRSUB.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRSUB.bad.d
new file mode 100644
index 0000000..f440367
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_ARRSUB.bad.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Arrays declarations must have a positive constant as a
+ * subscription.
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ */
+
+int a[-7];
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_PROTO_TYPE.badtuple.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_PROTO_TYPE.badtuple.d
new file mode 100644
index 0000000..7e879dc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_DECL_PROTO_TYPE.badtuple.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid tuple types result in a DT_DECL_ARRTYPE error.
+ *
+ * SECTION:
+ * Pointers and Arrays/Array Declarations and Storage
+ */
+
+
+int x[void, char];
+
+BEGIN
+{
+ x[trace(), 'a'] = 456;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_IDENT_UNDEF.badureg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_IDENT_UNDEF.badureg.d
new file mode 100644
index 0000000..e48541b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/err.D_IDENT_UNDEF.badureg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Arrays declarations must have a positive constant as a
+ * subscription.
+ *
+ * SECTION: User Process Tracing/uregs Array
+ */
+
+BEGIN
+{
+ printf("FOO = 0x%x\n", uregs[FOO]);
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic1.d
new file mode 100644
index 0000000..ba5b2cf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic1.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a[1] = 0;
+}
+
+tick-1
+/a[1] == 0/
+{
+ exit(0);
+}
+
+tick-1
+/a[1] != 0/
+{
+ printf("Expected 0, got %d\n", a[1]);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic2.d
new file mode 100644
index 0000000..14e1c5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic2.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a[1] = 0;
+ a[1]++;
+}
+
+tick-1
+/a[1] == 1/
+{
+ exit(0);
+}
+
+tick-1
+/a[1] != 1/
+{
+ printf("Expected 1, got %d\n", a[1]);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic3.d
new file mode 100644
index 0000000..897a12f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic3.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a[1] = 0;
+ ++a[1];
+}
+
+tick-1
+/a[1] == 1/
+{
+ exit(0);
+}
+
+tick-1
+/a[1] != 1/
+{
+ printf("Expected 1, got %d\n", a[1]);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic4.d
new file mode 100644
index 0000000..3635a42
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic4.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a["test"] = 0;
+}
+
+tick-1
+/a["test"] == 0/
+{
+ exit(0);
+}
+
+tick-1
+/a["test"] != 0/
+{
+ printf("Expected 0, got %d\n", a["test"]);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic5.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic5.d
new file mode 100644
index 0000000..866a8c3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic5.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a["test"] = 0;
+ b = ++a["test"];
+}
+
+tick-1
+/b == 1/
+{
+ exit(0);
+}
+
+tick-1
+/b != 1/
+{
+ printf("Expected b = 1, got %d\n", b);
+ exit(1);
+}
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic6.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic6.d
new file mode 100644
index 0000000..0371db3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.basic6.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple array test
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ a["test", "test"] = 0;
+ b = ++a["test", "test"];
+}
+
+tick-1
+/b == 1/
+{
+ exit(0);
+}
+
+tick-1
+/b != 1/
+{
+ printf("Expected b = 1, got %d\n", b);
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.uregsarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.uregsarray.d
new file mode 100644
index 0000000..b3fba0c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/arrays/tst.uregsarray.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive test to make sure that we can invoke common
+ * ureg[] aliases.
+ *
+ * SECTION: User Process Tracing/uregs Array
+ *
+ * NOTES: This test does no verification - the value of the output
+ * is not deterministic.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("R_PC = 0x%x\n", uregs[R_PC]);
+ printf("R_SP = 0x%x\n", uregs[R_SP]);
+ printf("R_R0 = 0x%x\n", uregs[R_R0]);
+ printf("R_R1 = 0x%x\n", uregs[R_R1]);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupgtype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupgtype.d
new file mode 100644
index 0000000..267d121
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupgtype.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test assigning a variable two different incompatible types. This should
+ * result in a compile-time error.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ x[123] = `kmem_flags;
+ x[456] = *`rootvp;
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupttype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupttype.d
new file mode 100644
index 0000000..ce360cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.dupttype.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test assigning a variable two different incompatible types. This should
+ * result in a compile-time error.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ self->x[123] = `kmem_flags;
+ self->x[456] = *`rootvp;
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.this.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.this.d
new file mode 100644
index 0000000..2af07ca
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_OP_INCOMPAT.this.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ *
+ * Declare 'this int' variable and assign inappropriate data type.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ *
+ */
+
+#pragma D option quiet
+
+this int x;
+
+BEGIN
+{
+ this->x = "dummy";
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_ARG.badsig.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_ARG.badsig.d
new file mode 100644
index 0000000..d682fc6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_ARG.badsig.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an associative array reference that is invalid because of a type
+ * signature mismatch -- this should produce a syntax error at compile time.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ x[123, "foo"] = timestamp;
+}
+
+END
+{
+ x[123, 456] = timestamp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toofew.d
new file mode 100644
index 0000000..b4e82b8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toofew.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an associative array reference that is invalid because of too few
+ * arguments -- this should produce a syntax error at compile time.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ x[123, 456] = timestamp;
+}
+
+END
+{
+ x[123] = timestamp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toomany.d
new file mode 100644
index 0000000..3dc5f7d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_PROTO_LEN.toomany.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an associative array reference that is invalid because of too many
+ * arguments -- this should produce a syntax error at compile time.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ x[123, 456] = timestamp;
+}
+
+END
+{
+ x[123, 456, 789] = timestamp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_SYNTAX.errassign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_SYNTAX.errassign.d
new file mode 100644
index 0000000..f31b66f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.D_SYNTAX.errassign.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Assign one to 10 elements; make sure fails to compile.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ x[10]=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+}
+
+END
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.tupoflow.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.tupoflow.d
new file mode 100644
index 0000000..8104202
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/err.tupoflow.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Generates an associative array reference that should overflow the tuple
+ * register stack. We should detect and report this at compile time.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ */
+
+BEGIN
+{
+ a[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] = 0;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.cpyarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.cpyarray.d
new file mode 100644
index 0000000..ca31cc3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.cpyarray.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Copy value from associative arrays to local variables.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ *
+ */
+
+#pragma D option quiet
+
+this int x;
+
+BEGIN
+{
+ a["abc", 123] = 123;
+}
+
+tick-10ms
+{
+ this->x = a["abc", 123]++;
+ printf("The value of x is %d\n", this->x);
+}
+
+tick-10ms
+{
+ this->x = a["abc", 123]++;
+ printf("The value of x is %d\n", this->x);
+}
+
+tick-10ms
+{
+ this->x = a["abc", 123]++;
+ printf("The value of x is %d\n", this->x);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.diffprofile.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.diffprofile.d
new file mode 100644
index 0000000..ad5fb37
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.diffprofile.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * To test Clause Local Variables ' this' across different profiles.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ *
+ */
+
+#pragma D option quiet
+
+this int x;
+this char c;
+
+tick-10ms
+{
+ this->x = 123;
+ this->c = 'D';
+ printf("The value of x is %d\n", this->x);
+}
+
+tick-10ms
+{
+ this->x = 235;
+ printf("The value of x is %d\n", this->x);
+}
+
+tick-10ms
+{
+ this->x = 456;
+ printf("The value of x is %d\n", this->x);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.initialize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.initialize.d
new file mode 100644
index 0000000..1ab222b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.initialize.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Clause local variables are not initialized to zero.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ *
+ */
+
+#pragma D option quiet
+
+this int x;
+
+BEGIN
+{
+ printf("the value of x is %d\n", this->x);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.invalidref.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.invalidref.d
new file mode 100644
index 0000000..446acfa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.invalidref.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Test to ensure that invalid stores to a global associative array
+ * are caught correctly.
+ */
+
+#pragma D option quiet
+
+int last_cmds[int][4];
+
+BEGIN
+{
+ errors = 0;
+ forward = 0;
+ backward = 0;
+}
+
+tick-1s
+/!forward/
+{
+ forward = 1;
+ last_cmds[1][4] = 0xdeadbeef;
+}
+
+tick-1s
+/!backward/
+{
+ backward = 1;
+ last_cmds[1][-5] = 0xdeadbeef;
+}
+
+tick-1s
+/errors > 1/
+{
+ exit(0);
+}
+
+tick-1s
+/n++ > 5/
+{
+ exit(1);
+}
+
+ERROR
+/arg4 == DTRACEFLT_BADADDR/
+{
+ errors++;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.misc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.misc.d
new file mode 100644
index 0000000..43147de
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.misc.d
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the different kinds of associative scalar references.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ * NOTES:
+ * In particular, we test accessing a DTrace associative array
+ * defined with scalar type (first ref that forces creation as both global
+ * and TLS), and DTrace associative array scalar subsequent references
+ * (both global and TLS).
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i != 5/
+{
+ x[123, "foo"] = 123;
+ self->x[456, "bar"] = 456;
+ i++;
+}
+
+tick-10ms
+/i != 5/
+{
+ printf("x[] = %d\n", x[123, "foo"]);
+ printf("self->x[] = %d\n", self->x[456, "bar"]);
+}
+
+tick-10ms
+/i == 5/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d
new file mode 100644
index 0000000..3a7d6a2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This test confirms the orthogonality of associative arrays and thread-local
+ * variables by intentionally deriving a matching key signature (based on
+ * t_did).
+ */
+uint64_t b[uint64_t];
+
+BEGIN
+{
+ self->a = 0xbad;
+}
+
+BEGIN
+/b[curthread->td_flags] == 0/
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("value should be 0; value is %x!", b[curthread->td_flags]);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.this.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.this.d
new file mode 100644
index 0000000..c4d01fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.this.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * To test Clause Local Variables ' this'.
+ *
+ * SECTION: Variables/Associative Arrays
+ *
+ *
+ */
+
+#pragma D option quiet
+
+this int x;
+this char c;
+
+BEGIN
+{
+ this->x = 123;
+ this->c = 'D';
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.valassign.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.valassign.d.out
new file mode 100644
index 0000000..948d82e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.valassign.d.out
@@ -0,0 +1,2 @@
+The value of i is 123
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.begin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.begin.d
new file mode 100644
index 0000000..c2a6088
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.begin.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Arguments to BEGIN provider not allowed.
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN::read:entry
+{
+ printf("Begin fired first\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.tick.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.tick.d
new file mode 100644
index 0000000..44a363f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/err.D_PDESC_ZERO.tick.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * concat of providers not allowed with BEGIN
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+
+BEGIN:tick-1
+{
+ printf("Begin fired first\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d
new file mode 100644
index 0000000..43e7744
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Order of provider flow, Begin, tick profile, and END.
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ printf("End fired after exit\n");
+}
+
+BEGIN
+{
+ printf("Begin fired first\n");
+}
+
+tick-1ms
+{
+ printf("tick fired second\n");
+ printf("Call exit\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d.out
new file mode 100644
index 0000000..a9d8ee1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.begin.d.out
@@ -0,0 +1,5 @@
+Begin fired first
+tick fired second
+Call exit
+End fired after exit
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d
new file mode 100644
index 0000000..3d5fd124
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Multiple BEGIN providers
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("Begin fired first\n");
+}
+BEGIN
+{
+ printf("Begin fired second\n");
+}
+BEGIN
+{
+ printf("Begin fired third\n");
+}
+BEGIN
+{
+ printf("Begin fired fourth\n");
+}
+BEGIN
+{
+ printf("Begin fired fifth\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d.out
new file mode 100644
index 0000000..e5bb996
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/begin/tst.multibegin.d.out
@@ -0,0 +1,6 @@
+Begin fired first
+Begin fired second
+Begin fired third
+Begin fired fourth
+Begin fired fifth
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_ADDROF_BITFIELD.BitfieldAddress.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_ADDROF_BITFIELD.BitfieldAddress.d
new file mode 100644
index 0000000..9c5aca4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_ADDROF_BITFIELD.BitfieldAddress.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Cannot take the address of a bit-field member using the &
+ * operator.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : 3;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ printf("address of a: %d\naddress of b: %d\naddress of c: %dn",
+ &var.a, &var.b, &var.c);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.NegBitField.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.NegBitField.d
new file mode 100644
index 0000000..acb296f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.NegBitField.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Bit-field width must be positive.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : -3;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.ZeroBitField.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.ZeroBitField.d
new file mode 100644
index 0000000..dfe24c5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFCONST.ZeroBitField.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Bit-fields must be positive and non-zero.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : 0;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.ExceedBaseType.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.ExceedBaseType.d
new file mode 100644
index 0000000..d9abfd1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.ExceedBaseType.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Bit-field width must be of a number of bits not larger than
+ * that of the corresponding base type.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord1{
+ char a : 10;
+} var1;
+
+struct bitRecord2{
+ short a : 33;
+} var2;
+
+struct bitRecord3{
+ long long a : 65;
+} var3;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.GreaterThan64.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.GreaterThan64.d
new file mode 100644
index 0000000..c1e359e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFSIZE.GreaterThan64.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Bit-field width cannot be greater than 64 bits in D.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : 65;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFTYPE.badtype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFTYPE.badtype.d
new file mode 100644
index 0000000..5e7b523
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_DECL_BFTYPE.badtype.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Non-integer types used for bitfields will result in a D_DECL_BFTYPE
+ * error.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bits {
+ float : 1;
+} xyz;
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_OFFSETOF_BITFIELD.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_OFFSETOF_BITFIELD.d
new file mode 100644
index 0000000..402a209
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_OFFSETOF_BITFIELD.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Cannot apply offsetof operator to a bit-field member.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ *
+ */
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 17;
+ int b : 3;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ printf("offsetof(struct bitRecord, a): %d\n",
+ offsetof(struct bitRecord, a));
+ printf("offsetof(struct bitRecord, b): %d\n",
+ offsetof(struct bitRecord, b));
+ printf("offsetof(struct bitRecord, c): %d\n",
+ offsetof(struct bitRecord, c));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_SIZEOF_BITFIELD.SizeofBitfield.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_SIZEOF_BITFIELD.SizeofBitfield.d
new file mode 100644
index 0000000..70c2834
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/err.D_SIZEOF_BITFIELD.SizeofBitfield.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Cannot apply sizeof operator to a bit-field member.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : 3;
+ int c : 12;
+} var;
+
+BEGIN
+{
+ printf("sizeof (a): %d\nsizeof (b): %d\nsizeof (c): %n",
+ sizeof (var.a), sizeof (var.b), sizeof (var.c));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.BitFieldPromotion.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.BitFieldPromotion.d
new file mode 100644
index 0000000..07ec728
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.BitFieldPromotion.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Bit-field will be automatically promoted to the next largest
+ * integer type for use in any expression and then the value assigned will
+ * warp around the maximum number assignable to the data type.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord{
+ int a : 1;
+ int b : 15;
+ int c : 31;
+} var;
+
+BEGIN
+{
+ var.a = 256;
+ var.b = 65536;
+ var.c = 4294967296;
+
+ printf("bitRecord.a: %d\nbitRecord.b: %d\nbitRecord.c: %d\n",
+ var.a, var.b, var.c);
+ exit(0);
+}
+
+END
+/(0 != var.a) || (0 != var.b) || (0 != var.c)/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.SizeofBitField.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.SizeofBitField.d
new file mode 100644
index 0000000..ce307de
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/bitfields/tst.SizeofBitField.d
@@ -0,0 +1,109 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: C and D compilers try to pack bits as efficiently as possible.
+ *
+ * SECTION: Structs and Unions/Bit-Fields
+ */
+
+#pragma D option quiet
+
+struct bitRecord1 {
+ int a : 1;
+} var1;
+
+struct bitRecord2 {
+ int a : 1;
+ int b : 3;
+} var2;
+
+struct bitRecord3 {
+ int a : 1;
+ int b : 3;
+ int c : 3;
+} var3;
+
+struct bitRecord4 {
+ int a : 1;
+ int b : 3;
+ int c : 3;
+ int d : 3;
+} var4;
+
+struct bitRecord5 {
+ int c : 12;
+ int a : 10;
+ int b : 3;
+} var5;
+
+struct bitRecord6 {
+ int a : 20;
+ int b : 3;
+ int c : 12;
+} var6;
+
+struct bitRecord7 {
+ long c : 32;
+ long long d: 9;
+ int e: 1;
+} var7;
+
+struct bitRecord8 {
+ char a : 2;
+ short b : 12;
+ long c : 32;
+} var8;
+
+struct bitRecord12 {
+ int a : 30;
+ int b : 30;
+ int c : 32;
+} var12;
+
+BEGIN
+{
+ printf("sizeof (bitRecord1): %d\n", sizeof (var1));
+ printf("sizeof (bitRecord2): %d\n", sizeof (var2));
+ printf("sizeof (bitRecord3): %d\n", sizeof (var3));
+ printf("sizeof (bitRecord4): %d\n", sizeof (var4));
+ printf("sizeof (bitRecord5): %d\n", sizeof (var5));
+ printf("sizeof (bitRecord6): %d\n", sizeof (var6));
+ printf("sizeof (bitRecord7): %d\n", sizeof (var7));
+ printf("sizeof (bitRecord8): %d\n", sizeof (var8));
+ printf("sizeof (bitRecord12): %d\n", sizeof (var12));
+ exit(0);
+}
+
+END
+/(1 != sizeof (var1)) || (2 != sizeof (var2)) || (3 != sizeof (var3)) ||
+ (4 != sizeof (var4)) || (5 != sizeof (var5)) || (6 != sizeof (var6))
+ || (7 != sizeof (var7)) || (8 != sizeof (var8)) || (12 != sizeof (var12))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.end.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.end.d
new file mode 100644
index 0000000..a480d67
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.end.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that buffer space for an END enabling is always reserved in a
+ * fill buffer. This will fail because the size of the END enabling
+ * (64 bytes) exceeds the size of the buffer (32 bytes).
+ *
+ * SECTION: Buffers and Buffering/fill Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/strsize
+ */
+
+#pragma D option bufpolicy=fill
+#pragma D option bufsize=32
+#pragma D option strsize=64
+
+BEGIN
+{
+ exit(0);
+}
+
+END
+{
+ trace(execname);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize1.d
new file mode 100644
index 0000000..4731bd1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize1.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "manual" will cause buffer
+ * allocation to fail for large principal buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufresize
+ *
+ */
+
+#pragma D option bufresize=manual
+#pragma D option bufsize=100t
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize2.d
new file mode 100644
index 0000000..4dfe6b6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize2.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "manual" will cause buffer
+ * allocation to fail for large aggregation buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/bufresize;
+ * Options and Tunables/aggsize
+ *
+ */
+
+#pragma D option bufresize=manual
+#pragma D option aggsize=100t
+
+BEGIN
+{
+ @a[probeprov] = count();
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize3.d
new file mode 100644
index 0000000..866a56c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.resize3.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "manual" will cause buffer
+ * allocation to fail for large speculative buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/bufresize;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option bufresize=manual
+#pragma D option specsize=100t
+
+BEGIN
+{
+ spec = speculation();
+}
+
+BEGIN
+{
+ speculate(spec);
+ trace(epid);
+}
+
+BEGIN
+{
+ commit(spec);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.zerobuf.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.zerobuf.d
new file mode 100644
index 0000000..a2e4435
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/err.zerobuf.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test with a bufsize of 0 - should return an error.
+ *
+ * SECTION:
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize
+ */
+
+#pragma D option bufsize=0
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.alignring.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.alignring.d
new file mode 100644
index 0000000..152acb6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.alignring.d
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for ring buffer policy.
+ *
+ * SECTION: Buffers and Buffering/ring Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+#pragma D option bufpolicy=ring
+#pragma D option bufsize=4k
+
+profile:::profile-1009hz
+{
+ printf("%x %x\n", (int)0xaaaa, (int)0xbbbb);
+}
+
+profile:::profile-1237hz
+{
+ printf("%x %x %x %x %x %x\n",
+ (int)0xcccc,
+ (int)0xdddd,
+ (int)0xeeee,
+ (int)0xffff,
+ (int)0xabab,
+ (int)0xacac);
+ printf("%x %x\n",
+ (uint64_t)0xaabbaabbaabbaabb,
+ (int)0xadad);
+}
+
+profile:::profile-1789hz
+{
+ printf("%x %x %x %x %x\n",
+ (int)0xaeae,
+ (int)0xafaf,
+ (unsigned char)0xaa,
+ (int)0xbcbc,
+ (int)0xbdbd);
+}
+
+profile-1543hz
+{}
+
+profile-1361hz
+{}
+
+tick-1sec
+/i++ >= 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.cputime.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.cputime.ksh
new file mode 100644
index 0000000..6ac0fa9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.cputime.ksh
@@ -0,0 +1,90 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -s /dev/stdin -x bufpolicy=$1 $1 <<EOF
+
+ #pragma D option quiet
+ #pragma D option statusrate=1hz
+
+ uint64_t total;
+ int thresh;
+
+ BEGIN
+ {
+ start = timestamp;
+ thresh = 10;
+ }
+
+ sched:::on-cpu
+ /pid == \$pid/
+ {
+ self->on = vtimestamp;
+ }
+
+ sched:::off-cpu
+ /self->on/
+ {
+ total += vtimestamp - self->on;
+ }
+
+ tick-1sec
+ /i++ == 10/
+ {
+ exit(0);
+ }
+
+ END
+ /((total * 100) / (timestamp - start)) > thresh/
+ {
+ printf("'%s' buffering policy took %d%% of CPU; ",
+ \$\$1, ((total * 100) / (timestamp - start)));
+ printf("expected no more than %d%%!\n", thresh);
+ exit(1);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+for policy in "fill ring switch"; do
+ script $policy
+
+ status=$?
+
+ if [ "$status" -ne 0 ]; then
+ exit $status
+ fi
+done
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.dynvarsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.dynvarsize.d
new file mode 100644
index 0000000..c8a0740
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.dynvarsize.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for dynamic variable size.
+ *
+ * SECTION: Buffers and Buffering/switch Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/switchrate
+ */
+
+#pragma D option dynvarsize=100
+#pragma D option quiet
+
+int n;
+
+tick-10ms
+/n++ < 100/
+{
+ a[n] = 1;
+}
+
+tick-10ms
+/n == 100/
+{
+ exit(2);
+}
+
+END
+/a[99]/
+{
+ exit(1);
+}
+
+END
+/!a[99]/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d
new file mode 100644
index 0000000..143ed64
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for fill buffer policy.
+ *
+ * SECTION: Buffers and Buffering/fill Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+/*
+ * This is a brute-force way of testing fill buffers. We assume that each
+ * printf() stores 8 bytes. Because each fill buffer is per-CPU, we must
+ * fill up our buffer in one series of enablings on a single CPU.
+ */
+#pragma D option bufpolicy=fill
+#pragma D option bufsize=64
+#pragma D option statusrate=10ms
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+{
+ printf("%d\n", i++);
+}
+
+tick-10ms
+/i >= 100/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d.out
new file mode 100644
index 0000000..fd8abec1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.fill1.d.out
@@ -0,0 +1,9 @@
+0
+1
+2
+3
+4
+5
+6
+7
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d
new file mode 100644
index 0000000..396a808
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "auto" will cause buffer
+ * allocation to succeed, even for large principal buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufresize
+ *
+ * NOTES:
+ * We use the undocumented "preallocate" option to make sure dtrace(1M)
+ * has enough space in its heap to allocate a buffer as large as the
+ * kernel's trace buffer.
+ */
+
+#pragma D option preallocate=100t
+#pragma D option bufresize=auto
+#pragma D option bufsize=100t
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d
new file mode 100644
index 0000000..50b814b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "auto" will cause buffer
+ * allocation to succeed, even for large aggregation buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/aggsize;
+ * Options and Tunables/bufresize
+ *
+ * NOTES:
+ * We use the undocumented "preallocate" option to make sure dtrace(1M)
+ * has enough space in its heap to allocate a buffer as large as the
+ * kernel's trace buffer.
+ */
+
+#pragma D option preallocate=100t
+#pragma D option bufresize=auto
+#pragma D option aggsize=100t
+
+BEGIN
+{
+ @a[probeprov] = count();
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize3.d
new file mode 100644
index 0000000..eb362fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize3.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Checks that setting "bufresize" to "auto" will cause buffer
+ * allocation to succeed, even for large speculative buffer sizes.
+ *
+ * SECTION: Buffers and Buffering/Buffer Resizing Policy;
+ * Options and Tunables/specsize;
+ * Options and Tunables/bufresize
+ *
+ * NOTES:
+ * On some small memory machines, this test may consume so much memory
+ * that it induces memory allocation failure in the dtrace library. This
+ * will manifest itself as an error like one of the following:
+ *
+ * dtrace: processing aborted: Memory allocation failure
+ * dtrace: could not enable tracing: Memory allocation failure
+ *
+ * These actually indicate that the test performed as expected; failures
+ * of the above nature should therefore be ignored.
+ *
+ */
+
+#pragma D option bufresize=auto
+#pragma D option specsize=100t
+
+BEGIN
+{
+ spec = speculation();
+}
+
+BEGIN
+{
+ speculate(spec);
+ trace(epid);
+}
+
+BEGIN
+{
+ commit(spec);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring1.d
new file mode 100644
index 0000000..67e7b87
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring1.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for ring buffer policy.
+ *
+ * SECTION: Buffers and Buffering/ring Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/switchrate
+ */
+
+/*
+ * We assume that a trace() of an integer stores at least 8 bytes. If ring
+ * buffering is not working properly, this trace() will induce a drop, and the
+ * counter won't be incremented. We set the switchrate to one second just to
+ * sure that a high switchrate doesn't mask broken ring buffers.
+ */
+#pragma D option bufpolicy=ring
+#pragma D option bufsize=50
+#pragma D option switchrate=1sec
+
+int n;
+int i;
+
+tick-10msec
+/n < 300/
+{
+ trace(i);
+ i++;
+}
+
+tick-10msec
+/n < 300/
+{
+ n++;
+}
+
+tick-10msec
+/n == 300/
+{
+ exit(2);
+}
+
+END
+{
+ exit(i == 300 ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d
new file mode 100644
index 0000000..cbf48f2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for ring buffer policy.
+ *
+ * SECTION: Buffers and Buffering/ring Policy;
+ * SECTION: Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+#pragma D option bufpolicy=ring
+#pragma D option bufsize=512k
+#pragma D option quiet
+
+tick-1sec
+/n < 5/
+{
+ printf("%d\n", n++);
+}
+
+tick-1sec
+/n == 5/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d.out
new file mode 100644
index 0000000..cc4d41a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring2.d.out
@@ -0,0 +1,6 @@
+0
+1
+2
+3
+4
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d
new file mode 100644
index 0000000..68e3588
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for ring buffer policy.
+ *
+ * SECTION: Buffers and Buffering/ring Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+/*
+ * We make some regrettable assumptions about the implementation in this test.
+ * First, we assume that each entry for the printf() of an int takes _exactly_
+ * eight bytes (four bytes for the EPID, four bytes for the payload). Second,
+ * we assume that by allocating storage for n + 1 records, we will get exactly
+ * n. Here is why: the final predicate that evaluates to false will reserve
+ * space that it won't use. This act of reservation will advance the wrapped
+ * offset. That record won't be subsequently used, but the wrapped offset has
+ * advanced. (And in this case, that old record is clobbered by the exit()
+ * anyway.) Thirdly: we rely on t_cpu/cpu_id. Finally: we rely on being
+ * able to run on the CPU that we first ran on.
+ */
+#pragma D option bufpolicy=ring
+#pragma D option bufsize=40
+#pragma D option quiet
+
+int n;
+
+BEGIN
+{
+ cpuid = -1;
+}
+
+tick-10msec
+/cpuid == -1/
+{
+ cpuid = curthread->t_cpu->cpu_id;
+}
+
+tick-10msec
+/curthread->t_cpu->cpu_id == cpuid && n < 100/
+{
+ printf("%d\n", n++);
+}
+
+tick-10msec
+/n == 100/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d.out
new file mode 100644
index 0000000..99fd231
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.ring3.d.out
@@ -0,0 +1,5 @@
+96
+97
+98
+99
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.smallring.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.smallring.d
new file mode 100644
index 0000000..2134a0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.smallring.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for ring buffer policy.
+ *
+ * SECTION: Buffers and Buffering/ring Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+#pragma D option bufpolicy=ring
+#pragma D option bufsize=16
+
+tick-10ms
+{
+ trace(0xbadbaddefec8d);
+}
+
+tick-10ms
+/0/
+{
+ trace((int)1);
+}
+
+tick-100ms
+/i++ > 2/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d
new file mode 100644
index 0000000..2840fee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for switch buffer policy.
+ *
+ * SECTION: Buffers and Buffering/switch Policy;
+ * Buffers and Buffering/Buffer Sizes;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/switchrate
+ */
+
+/*
+ * We assume that a printf() of an integer stores at least 8 bytes, and no more
+ * than 16 bytes.
+ */
+#pragma D option bufpolicy=switch
+#pragma D option bufsize=32
+#pragma D option switchrate=500msec
+#pragma D option quiet
+
+int n;
+int i;
+
+tick-1sec
+/n < 10/
+{
+ printf("%d\n", i);
+ i++;
+}
+
+tick-1sec
+/n < 10/
+{
+ n++;
+}
+
+tick-1sec
+/n == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d.out
new file mode 100644
index 0000000..ce6c2bc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.switch1.d.out
@@ -0,0 +1,11 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.cpuusage.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.cpuusage.d
new file mode 100644
index 0000000..e1e0dd8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.cpuusage.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print non assigned value and make sure it fails.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The cpuusage = %d\n", curlwpsinfo->pr_cpu);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.nice.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.nice.d
new file mode 100644
index 0000000..c7a4ad2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.nice.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * print non assigned value and make sure it fails.
+ *
+ * SECTION: Variables/Built-in Variables
+ *
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The nice for cpu usage %c\n", curlwpsinfo->pr_nice);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.priority.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.priority.d
new file mode 100644
index 0000000..6ebb3df
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.priority.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Print non assigned variables and make sure it fails.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The low value is high priority field = %d\n",
+ curlwpsinfo->pr_nice);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.prsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.prsize.d
new file mode 100644
index 0000000..f467f19
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.prsize.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print non assigned variables and make sure it fails.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("Size of process image in kbytes = %ld\n", curpsinfo->pr_size);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.rssize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.rssize.d
new file mode 100644
index 0000000..48057e1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/err.D_XLATE_NOCONV.rssize.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print non assigned variables and make sure it fails.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("Size of process image in kbytes = %ld\n", curpsinfo->pr_rssize);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0.d
new file mode 100644
index 0000000..ec3c277
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print arg0 and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The argument is %u\n", arg0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0clause.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0clause.d
new file mode 100644
index 0000000..4c782f8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg0clause.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print arg0 from a profile and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("Call probe read\n");
+}
+
+syscall:::entry
+{
+ printf("The argument is %u", arg0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1.d
new file mode 100644
index 0000000..993a376
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print arg1 and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The argument is %u\n", arg1);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8.d
new file mode 100644
index 0000000..b696d7c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print arg1 to arg8 and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The argument is %u %u %u %u %u %u %u %u\n", arg1, arg2,
+ arg3, arg4, arg5, arg6, arg7, arg8);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8clause.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8clause.d
new file mode 100644
index 0000000..fa62b03
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.arg1to8clause.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print arg1 to arg8 from a profile and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+syscall:::entry
+{
+ printf("The argument is %u %u %u %u %u %u %u %u\n", arg1, arg2,
+ arg3, arg4, arg5, arg6, arg7, arg8);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller.d
new file mode 100644
index 0000000..db1eabc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print 'caller' and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The caller is %u\n", caller);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller1.d
new file mode 100644
index 0000000..f1bfeed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.caller1.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print caller form profile and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("The caller is %u\n", caller);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid.d
new file mode 100644
index 0000000..4f04c65
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print 'epid'from profile and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("epid of this probe = %d\n", epid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid1.d
new file mode 100644
index 0000000..4cba65e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.epid1.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * print epid and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("epid of this probe = %d\n", epid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno.d
new file mode 100644
index 0000000..4d7a4ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print errno from profile and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("epid of this probe = %d\n", epid);
+ printf("the errno = %d\n", errno);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno1.d
new file mode 100644
index 0000000..ed233bf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.errno1.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print errno and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("epid of this probe = %d\n", epid);
+ printf("the errno = %d\n", errno);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.execname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.execname.d
new file mode 100644
index 0000000..b3007de
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.execname.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print execname and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+/execname == "dtrace" || execname == "java"/
+{
+ trace("execname matched");
+ exit(0);
+}
+
+BEGIN
+{
+ trace("execname didn't match");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.hpriority.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.hpriority.d
new file mode 100644
index 0000000..a0d8836
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.hpriority.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print hpriority and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The high priority = %d\n", curlwpsinfo->pr_pri);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id.d
new file mode 100644
index 0000000..291d91d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print 'id' from profile.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("id of this probe = %d\n", id);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id1.d
new file mode 100644
index 0000000..068cff6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.id1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print id and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("id of this probe = %d\n", id);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl.d
new file mode 100644
index 0000000..2e6f349
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print variable ipl
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("The interrupt priority level = %u\n", ipl);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl1.d
new file mode 100644
index 0000000..ef9278d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.ipl1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print ipl and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The interrupt priority level = %u\n", ipl);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo.d
new file mode 100644
index 0000000..f0e9d46
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print lwpsinfo_t structure values.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("The current thread's pr_flag is %d\n", curlwpsinfo->pr_flag);
+ printf("The current threads lwpid is %d\n", curlwpsinfo->pr_lwpid);
+ printf("The current thread's internal address is %u\n",
+ curlwpsinfo->pr_addr);
+ printf("The current thread's wait addr for sleeping lwp is %u\n",
+ curlwpsinfo->pr_wchan);
+ printf("The current lwp stat is %d\n", curlwpsinfo->pr_state);
+ printf("The printable character for pr_state %c\n",
+ curlwpsinfo->pr_sname);
+ printf("The syscall number = %d\n", curlwpsinfo->pr_syscall);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo1.d
new file mode 100644
index 0000000..aa11b07
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.lwpsinfo1.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print lwpsinfo_t variables and make sure it succeeds
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("The current thread's pr_flag is %d\n", curlwpsinfo->pr_flag);
+ printf("The current threads lwpid is %d\n", curlwpsinfo->pr_lwpid);
+ printf("The current thread's internal address is %u\n",
+ curlwpsinfo->pr_addr);
+ printf("The current thread's wait addr for sleeping lwp is %u\n",
+ curlwpsinfo->pr_wchan);
+ printf("The current lwp stat is %d\n", curlwpsinfo->pr_state);
+ printf("The printable character for pr_state %c\n",
+ curlwpsinfo->pr_sname);
+ printf("The syscall number = %d\n", curlwpsinfo->pr_syscall);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid.d
new file mode 100644
index 0000000..2dd80d7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print 'pid' from profile.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("process id = %d \n", pid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid1.d
new file mode 100644
index 0000000..5cee07c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.pid1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print 'pid' and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("process id = %d \n", pid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo.d
new file mode 100644
index 0000000..6961a0d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print psinfo structure values from profile.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("number of lwps in process = %d\n", curpsinfo->pr_nlwp);
+ printf("unique process id = %d\n", curpsinfo->pr_pid);
+ printf("process id of parent = %d\n", curpsinfo->pr_ppid);
+ printf("pid of process group leader = %d\n", curpsinfo->pr_pgid);
+ printf("session id = %d\n", curpsinfo->pr_sid);
+ printf("real user id = %d\n", curpsinfo->pr_uid);
+ printf("effective user id = %d\n", curpsinfo->pr_euid);
+ printf("real group id = %d\n", curpsinfo->pr_gid);
+ printf("effective group id = %d\n", curpsinfo->pr_egid);
+ printf("address of process = %u\n", curpsinfo->pr_addr);
+ exit (0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo1.d
new file mode 100644
index 0000000..b805e27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.psinfo1.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print psinfo structure values.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("number of lwps in process = %d\n", curpsinfo->pr_nlwp);
+ printf("unique process id = %d\n", curpsinfo->pr_pid);
+ printf("process id of parent = %d\n", curpsinfo->pr_ppid);
+ printf("pid of process group leader = %d\n", curpsinfo->pr_pgid);
+ printf("session id = %d\n", curpsinfo->pr_sid);
+ printf("real user id = %d\n", curpsinfo->pr_uid);
+ printf("effective user id = %d\n", curpsinfo->pr_euid);
+ printf("real group id = %d\n", curpsinfo->pr_gid);
+ printf("effective group id = %d\n", curpsinfo->pr_egid);
+ printf("address of process = %u\n", curpsinfo->pr_addr);
+ exit (0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid.d
new file mode 100644
index 0000000..1b16c8b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print tid from profile
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+
+tick-10ms
+{
+ printf("Thread id = %d \n", tid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid1.d
new file mode 100644
index 0000000..a0567e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.tid1.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * To print tid and make sure it succeeds.
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("Thread id = %d \n", tid);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.timestamp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.timestamp.d
new file mode 100644
index 0000000..cd94eac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.timestamp.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print build-in variable 'timestamp'
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->t = timestamp;
+ printf("The difftime = %d\n", timestamp - self->t);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.vtimestamp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.vtimestamp.d
new file mode 100644
index 0000000..cdbecfc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/builtinvar/tst.vtimestamp.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To print build-in variable 'vtimestamp'
+ *
+ * SECTION: Variables/Built-in Variables
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->t = vtimestamp;
+ printf("The difftime = %d\n", vtimestamp - self->t);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggfun.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggfun.d
new file mode 100644
index 0000000..f687717
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggfun.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a predicated
+ * clause inside an aggregating function.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/1/
+{
+ @a = max(x);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggtup.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggtup.d
new file mode 100644
index 0000000..1fa4974
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.aggtup.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a predicated
+ * clause inside an aggregation tuple.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/1/
+{
+ @a[x] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.arrtup.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.arrtup.d
new file mode 100644
index 0000000..6c1cdff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.arrtup.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a predicated
+ * clause inside an associate array tuple.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/1/
+{
+ a[x]++;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.body.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.body.d
new file mode 100644
index 0000000..da499cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.body.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a clause.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+{
+ exit(x);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.both.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.both.d
new file mode 100644
index 0000000..0070827
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.both.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a predicate
+ * and in a clause body.
+ *
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/x != 0/
+{
+ exit(x);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.pred.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.pred.d
new file mode 100644
index 0000000..0bfc86f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/err.D_IDENT_UNDEF.pred.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause where an unknown identifier appears in a predicate.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/x != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.nopred.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.nopred.d
new file mode 100644
index 0000000..44d1167
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.nopred.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause that has a body but no predicate.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.pred.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.pred.d
new file mode 100644
index 0000000..43bfedd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.pred.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause that has a body and a predicate.
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/$pid != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predfirst.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predfirst.d
new file mode 100644
index 0000000..c7f0b4e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predfirst.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause that has a body and a predicate where the
+ * predicate must be cooked first because it creates a variable.
+ *
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/x++ == 0/
+{
+ exit(x - 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predlast.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predlast.d
new file mode 100644
index 0000000..9ed904f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/clauses/tst.predlast.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test a clause that has a body and a predicate where the
+ * predicate must be cooked last because the clause creates
+ * a variable which is referenced in the predicate.
+ *
+ * SECTION: Program Structure / Probe Clauses and Declarations
+ *
+ */
+
+BEGIN
+/x == 0/
+{
+ exit(x++);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d
new file mode 100644
index 0000000..1015a251
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Test to check that attempting to enable a valid event with a frequency
+ * lower than the default platform limit will fail.
+ *
+ * This test will fail if:
+ * 1) The system under test does not define the 'PAPI_tot_ins' event.
+ * 2) The 'dcpc-min-overflow' variable in dcpc.conf has been modified.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ exit(0);
+}
+
+cpc:::PAPI_tot_ins-all-100
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d
new file mode 100644
index 0000000..f9b7809
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Tests that specifying an overflow value containing extraneous characters
+ * (only digits are allowed) will fail.
+ */
+
+BEGIN
+{
+ exit(0);
+}
+
+cpc:::PAPI_tot_ins-all-10000bonehead
+{
+ @[probename] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d
new file mode 100644
index 0000000..73f9575
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Tests that attempting to enable a probe containing a non existent event
+ * will fail.
+ */
+
+BEGIN
+{
+ exit(0);
+}
+
+cpc:::PAPI_cpc_bad-all-10000
+{
+ @[probename] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh
new file mode 100644
index 0000000..767d493
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+
+#
+# This tests that cpustat(1) should fail to start if the cpc provider
+# is already calling the shots.
+#
+# This script will fail if:
+# 1) The system under test does not define the 'PAPI_tot_ins'
+# generic event.
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ #pragma D option bufsize=128k
+
+ cpc:::PAPI_tot_ins-all-10000
+ {
+ @[probename] = count();
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+script 2>/dev/null &
+timeout=15
+
+#
+# Sleep while the above script fires into life. To guard against dtrace dying
+# and us sleeping forever we allow 15 secs for this to happen. This should be
+# enough for even the slowest systems.
+#
+while [ ! -f $dtraceout ]; do
+ sleep 1
+ timeout=$(($timeout-1))
+ if [ $timeout -eq 0 ]; then
+ echo "dtrace failed to start. Exiting."
+ exit 1
+ fi
+done
+
+cpustat -c PAPI_tot_ins 1 5
+status=$?
+
+rm $dtraceout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh
new file mode 100644
index 0000000..584469c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh
@@ -0,0 +1,70 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+
+#
+# This tests that enablings from the cpc provider will fail if cpustat(1) is
+# already master of the universe.
+#
+# This script will fail if:
+# 1) The system under test does not define the 'PAPI_tot_ins'
+# generic event.
+
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ #pragma D option bufsize=128k
+
+ BEGIN
+ {
+ exit(0);
+ }
+
+ cpc:::PAPI_tot_ins-all-10000
+ {
+ @[probename] = count();
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+
+cpustat -c PAPI_tot_ins 1 20 &
+pid=$!
+sleep 5
+script 2>/dev/null
+
+status=$?
+
+kill $pid
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh
new file mode 100644
index 0000000..f62b83d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh
@@ -0,0 +1,77 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+
+#
+# This script ensures that cputrack(1M) will fail to start when the cpc
+# provider has active enablings.
+#
+# The script will fail if:
+# 1) The system under test does not define the 'PAPI_tot_ins' event.
+#
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ #pragma D option bufsize=128k
+
+ cpc:::PAPI_tot_ins-all-10000
+ {
+ @[probename] = count();
+ }
+EOF
+}
+
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+script 2>/dev/null &
+timeout=15
+
+#
+# Sleep while the above script fires into life. To guard against dtrace dying
+# and us sleeping forever we allow 15 secs for this to happen. This should be
+# enough for even the slowest systems.
+#
+while [ ! -f $dtraceout ]; do
+ sleep 1
+ timeout=$(($timeout-1))
+ if [ $timeout -eq 0 ]; then
+ echo "dtrace failed to start. Exiting."
+ exit 1
+ fi
+done
+
+cputrack -c PAPI_tot_ins sleep 10
+status=$?
+
+rm $dtraceout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh
new file mode 100644
index 0000000..58d1e79
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh
@@ -0,0 +1,70 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+
+#
+# This script ensures that cputrack(1) will terminate when the cpc provider
+# kicks into life.
+#
+# The script will fail if:
+# 1) The system under test does not define the 'PAPI_tot_ins' event.
+#
+
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ #pragma D option bufsize=128k
+
+ cpc:::PAPI_tot_ins-all-10000
+ {
+ @[probename] = count();
+ }
+
+ tick-1s
+ /n++ > 10/
+ {
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+cputrack -c PAPI_tot_ins sleep 20 &
+cputrack_pid=$!
+sleep 5
+script 2>/dev/null &
+
+wait $cputrack_pid
+status=$?
+
+rm $dtraceout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d
new file mode 100644
index 0000000..a50bd71
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Test to check that attempting to enable too many probes will fail.
+ *
+ * This test will fail if:
+ * 1) We ever execute on a platform which is capable of programming 10
+ * 'PAPI_tot_ins' events simultaneously (which no current platforms are
+ * capable of doing).
+ * 2) The system under test does not define the 'PAPI_tot_ins' event.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ exit(0);
+}
+
+cpc:::PAPI_tot_ins-all-10000,
+cpc:::PAPI_tot_ins-all-10001,
+cpc:::PAPI_tot_ins-all-10002,
+cpc:::PAPI_tot_ins-all-10003,
+cpc:::PAPI_tot_ins-all-10004,
+cpc:::PAPI_tot_ins-all-10005,
+cpc:::PAPI_tot_ins-all-10006,
+cpc:::PAPI_tot_ins-all-10007,
+cpc:::PAPI_tot_ins-all-10008,
+cpc:::PAPI_tot_ins-all-10009
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh
new file mode 100644
index 0000000..7f026c9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh
@@ -0,0 +1,107 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This script verifies that we can fire a probe on each CPU that is in
+# an online state.
+#
+# The script will fail if:
+# 1) The system under test does not define the 'PAPI_tot_ins' event.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+numproc=`psrinfo | tail -1 | cut -f1`
+cpu=0
+dtraceout=/var/tmp/dtrace.out.$$
+scriptout=/var/tmp/script.out.$$
+
+spin()
+{
+ while [ 1 ]; do
+ :
+ done
+}
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ #pragma D option bufsize=128k
+ #pragma D option quiet
+
+ cpc:::PAPI_tot_ins-user-10000
+ /cpus[cpu] != 1/
+ {
+ cpus[cpu] = 1;
+ @a[cpu] = count();
+ }
+
+ tick-1s
+ /n++ > 10/
+ {
+ printa(@a);
+ exit(0);
+ }
+EOF
+}
+
+echo "" > $scriptout
+while [ $cpu -le $numproc ]
+do
+ if [ "`psrinfo -s $cpu 2> /dev/null`" -eq 1 ]; then
+ printf "%9d %16d\n" $cpu 1 >> $scriptout
+ spin &
+ allpids[$cpu]=$!
+ pbind -b $cpu $!
+ fi
+ cpu=$(($cpu+1))
+done
+echo "" >> $scriptout
+
+script
+
+diff $dtraceout $scriptout >/dev/null 2>&1
+status=$?
+
+# kill off the spinner processes
+cpu=0
+while [ $cpu -le $numproc ]
+do
+ if [ "`psrinfo -s $cpu 2> /dev/null`" -eq 1 ]; then
+ kill ${allpids[$cpu]}
+ fi
+ cpu=$(($cpu+1))
+done
+
+rm $dtraceout
+rm $scriptout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d
new file mode 100644
index 0000000..7ebf844
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Test that we can successfully enable a probe using a generic event.
+ * Currently, all platforms implement 'PAPI_tot_ins' so we'll use that.
+ * Note that this test will fail if the system under test does not
+ * implement that event.
+ *
+ * This test will fail if:
+ * 1) The system under test does not define the 'PAPI_tot_ins' event.
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=128k
+
+cpc:::PAPI_tot_ins-all-10000
+{
+ @[probename] = count();
+}
+
+tick-1s
+/n++ > 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh
new file mode 100644
index 0000000..96d1ab8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh
@@ -0,0 +1,81 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This script ensures that we can enable a probe which specifies a platform
+# specific event.
+#
+
+if [ $# != 1 ]; then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+
+get_event()
+{
+ perl /dev/stdin /dev/stdout << EOF
+ open CPUSTAT, '/usr/sbin/cpustat -h |'
+ or die "Couldn't run cpustat: \$!\n";
+ while (<CPUSTAT>) {
+ if (/(\s+)event\[*[0-9]-*[0-9]*\]*:/ && !/PAPI/) {
+ @a = split(/ /, \$_);
+ \$event = \$a[\$#a-1];
+ }
+ }
+
+ close CPUSTAT;
+ print "\$event\n";
+EOF
+}
+
+script()
+{
+ $dtrace -s /dev/stdin << EOD
+ #pragma D option quiet
+ #pragma D option bufsize=128k
+
+ cpc:::$1-all-10000
+ {
+ @[probename] = count();
+ }
+
+ tick-1s
+ /n++ > 5/
+ {
+ exit(0);
+ }
+EOD
+}
+
+event=$(get_event)
+script $event
+
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LOCASSC.NonLocalAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LOCASSC.NonLocalAssoc.d
new file mode 100644
index 0000000..4c8ee50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LOCASSC.NonLocalAssoc.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * associative arrays may not be declared as local variables
+ *
+ * SECTION: Errtags/D_DECL_LOCASSC
+ *
+ */
+
+#pragma D option quiet
+
+this int a[int];
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LONGINT.LongStruct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LONGINT.LongStruct.d
new file mode 100644
index 0000000..2c92bfd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_LONGINT.LongStruct.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * long and long long may only be used with integer or floating-point type
+ *
+ * SECTION: Errtags/D_DECL_LONGINT
+ *
+ */
+
+#pragma D option quiet
+
+long struct mystruct
+{
+ int i;
+};
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PARMCLASS.BadStorageClass.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PARMCLASS.BadStorageClass.d
new file mode 100644
index 0000000..8278747
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PARMCLASS.BadStorageClass.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * inappropriate storage class for function or associative array parameter
+ * throws a D_DECL_PARMCLASS
+ *
+ * SECTION: Errtags/D_DECL_PARMCLASS
+ *
+ */
+
+#pragma D option quiet
+
+
+int foo(static int);
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_NAME.VoidName.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_NAME.VoidName.d
new file mode 100644
index 0000000..3676c21
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_NAME.VoidName.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Assert that a void parameter in a declaration where void is permitted
+ * may not have a parameter formal name associated with it.
+ */
+
+int a(void v);
+
+BEGIN,
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_TYPE.Dyn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_TYPE.Dyn.d
new file mode 100644
index 0000000..aecf549
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_TYPE.Dyn.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Assert that a function parameter in a declaration may not use a dynamic
+ * DTrace type such as an associative array type.
+ */
+
+int a(int a[int]);
+
+BEGIN,
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VARARGS.VarLenArgs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VARARGS.VarLenArgs.d
new file mode 100644
index 0000000..22dbbe9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VARARGS.VarLenArgs.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * array tuples may not use variable-length argument lists
+ *
+ * SECTION: Errtags/ D_DECL_ARRVA
+ *
+ */
+
+#pragma D option quiet
+
+
+int a[...];
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VOID.NonSoleVoid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VOID.NonSoleVoid.d
new file mode 100644
index 0000000..620f0d7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_PROTO_VOID.NonSoleVoid.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * void must be sole parameter in a function declaration.
+ *
+ * SECTION: Errtags/D_DECL_FUNCVOID
+ *
+ */
+
+#pragma D option quiet
+
+int foo(int, void);
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_SIGNINT.UnsignedStruct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_SIGNINT.UnsignedStruct.d
new file mode 100644
index 0000000..db2e451
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_SIGNINT.UnsignedStruct.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * signed and unsigned may only be used with integer type
+ *
+ * SECTION: Errtags/D_DECL_SIGNINT
+ *
+ */
+
+#pragma D option quiet
+
+/*DSTYLED*/
+unsigned struct mystruct {
+ int i;
+};
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_VOIDATTR.ShortVoidDecl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_VOIDATTR.ShortVoidDecl.d
new file mode 100644
index 0000000..81f9081
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/err.D_DECL_VOIDATTR.ShortVoidDecl.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attributes may not be used with void type.
+ *
+ * SECTION: Errtags/D_DECL_VOIDATTR
+ *
+ */
+
+#pragma D option quiet
+
+short void ptr;
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.arrays.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.arrays.d
new file mode 100644
index 0000000..34ddd5f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.arrays.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test various kinds of array declarations.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+extern int a1[];
+
+extern int a2[1];
+
+extern int a3[123][456];
+
+extern int a4[123][456][789];
+
+extern int a5[5], a6[6][6], a7[7][7][7];
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.basics.d
new file mode 100644
index 0000000..4c1483e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.basics.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test a variety of extern declarations that exercise the different
+ * kinds of declarations that we can process.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+extern void *e1;
+extern char e2;
+extern signed char e3;
+extern unsigned char e4;
+extern short e5;
+extern signed short e6;
+extern unsigned short e7;
+extern int e8;
+extern e9;
+extern signed int e10;
+extern unsigned int e11;
+extern long e12;
+extern signed long e13;
+extern unsigned long e14;
+extern long long e15;
+extern signed long long e16;
+extern unsigned long long e17;
+extern float e18;
+extern double e19;
+extern long double e20;
+extern vnode_t e21;
+extern struct vnode e22;
+extern union sigval e23;
+extern enum uio_rw e24;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.funcs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.funcs.d
new file mode 100644
index 0000000..3b691eb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.funcs.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test various kinds of function declarations.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ */
+
+extern int getint(void);
+extern int *getptr(void);
+extern int *(*funcptr)(void);
+extern int **(**funcptrptr)(void);
+
+extern int noparms();
+extern int oneparm(int);
+extern int twoparms(int, int);
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.pointers.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.pointers.d
new file mode 100644
index 0000000..d0ab608
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.pointers.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test multiple extern declarations in a single list which build
+ * up a chain of pointers to pointers to pointers ...
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ */
+
+extern int e0, *e1, **e2, ***e3, ****e4, *****e5;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.varargsfuncs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.varargsfuncs.d
new file mode 100644
index 0000000..c12363f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/decls/tst.varargsfuncs.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test functions declarations with varargs
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ */
+
+#pragma D option quiet
+
+extern int varargs1(...);
+extern int varargs2(int, ...);
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/badptr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/badptr.d
new file mode 100644
index 0000000..c48c729
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/badptr.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 5-1
+ *
+ * SECTION:
+ * DocExamples/badptr
+ */
+
+BEGIN
+{
+ x = (int *)NULL;
+ y = *x;
+ trace(y);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/countdown.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/countdown.d
new file mode 100644
index 0000000..56b9881
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/countdown.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example
+ *
+ * SECTION:
+ * DocExamples/other
+ */
+
+dtrace:::BEGIN
+{
+ i = 10;
+}
+
+profile:::tick-1sec
+/i > 0/
+{
+ trace(i--);
+}
+
+profile:::tick-1000
+/i == 0/
+{
+ trace("blastoff!");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/counter.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/counter.d
new file mode 100644
index 0000000..8b7b1b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/counter.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc
+ *
+ * SECTION:
+ * DocExamples/other
+ */
+
+
+dtrace:::BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ i = i + 1;
+ trace(i);
+}
+
+dtrace:::END
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/errorpath.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/errorpath.d
new file mode 100644
index 0000000..76fd07c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/errorpath.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 17-1
+ *
+ * SECTION:
+ * DocExamples/errorpath
+ */
+
+
+BEGIN
+{
+ *(char *)NULL;
+}
+
+ERROR
+{
+ printf("Hit an error!");
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/hello.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/hello.d
new file mode 100644
index 0000000..8e1ef8f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/hello.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 1-1
+ *
+ * SECTION:
+ * DocExamples/hello
+ */
+
+
+BEGIN
+{
+ trace("hello, world");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/kstat.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/kstat.d
new file mode 100644
index 0000000..4987149
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/kstat.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 7-3
+ *
+ * SECTION:
+ * DocExamples/kstat
+ */
+
+
+#pragma D option quiet
+
+pid$1:libkstat:kstat_data_lookup:entry
+{
+ self->ksname = arg1;
+}
+
+pid$1:libkstat:kstat_data_lookup:return
+/self->ksname != NULL && arg1 != NULL/
+{
+ this->str = copyinstr(self->ksname);
+ this->ksp = (kstat_named_t *)copyin(arg1, sizeof (kstat_named_t));
+ printf("%s has ui64 value %u\n", this->str, this->ksp->value.ui64);
+}
+
+pid$1:libkstat:kstat_data_lookup:return
+/self->ksname != NULL && arg1 == NULL/
+{
+ self->ksname = NULL;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/ksyms.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/ksyms.d
new file mode 100644
index 0000000..932262b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/ksyms.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 7-2
+ *
+ * SECTION:
+ * DocExamples/ksyms
+ */
+
+
+/* Must run "strings -a /dev/ksyms in another shell on the system */
+
+
+#pragma D option quiet
+
+syscall::read:entry
+/curpsinfo->pr_psargs == "strings -a /dev/ksyms"/
+{
+ printf("read %u bytes to user address %x\n", arg2, arg1);
+ self->watched = 1;
+}
+
+syscall::read:return
+/self->watched/
+{
+ self->watched = 0;
+}
+
+fbt::uiomove:entry
+/self->watched/
+{
+ this->iov = args[3]->uio_iov;
+
+ printf("uiomove %u bytes to %p in pid %d\n", this->iov->iov_len,
+ this->iov->iov_base, pid);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/renormalize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/renormalize.d
new file mode 100644
index 0000000..7d2c6af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/renormalize.d
@@ -0,0 +1,55 @@
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Verify doc example 9-1
+ *
+ * SECTION:
+ * DocExamples/renormalize
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ start = timestamp;
+}
+
+syscall:::entry
+{
+ @func[execname] = count();
+}
+
+tick-10sec
+{
+ normalize(@func, (timestamp - start) / 1000000000);
+ printa(@func);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rtime.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rtime.d
new file mode 100644
index 0000000..087e819
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rtime.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 3-1
+ *
+ * SECTION:
+ * DocExamples/rtime
+ */
+
+
+#pragma D option quiet
+
+syscall::read:entry
+{
+ self->t = timestamp;
+}
+
+syscall::read:return
+/self->t != 0/
+{
+ printf("%d/%d spent %d nsecs in read(2)\n", pid,
+ tid, timestamp - self->t);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rw.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rw.d
new file mode 100644
index 0000000..6358a7d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rw.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example
+ *
+ * SECTION:
+ * DocExamples/other
+ */
+
+
+syscall::read:entry,
+syscall::write:entry
+/pid == 102429/
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwinfo.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwinfo.d
new file mode 100644
index 0000000..60f2b12
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwinfo.d
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 7-1
+ *
+ * SECTION:
+ * DocExamples/rwinfo
+ */
+
+
+#pragma D option quiet
+
+struct callinfo {
+ uint64_t ts;
+ uint64_t elapsed;
+ uint64_t calls;
+ size_t maxbytes;
+};
+
+struct callinfo i[string];
+
+syscall::read:entry,
+syscall::write:entry
+/pid == 100551/
+{
+ i[probefunc].ts = timestamp;
+ i[probefunc].calls++;
+ i[probefunc].maxbytes = arg2 > i[probefunc].maxbytes ?
+ arg2 : i[probefunc].maxbytes;
+}
+
+syscall::read:return,
+syscall::write:return
+/i[probefunc].ts != 0 && pid == 100551/
+{
+ i[probefunc].elapsed += timestamp - i[probefunc].ts;
+}
+
+END
+{
+ printf(" calls max bytes elapsed nsecs\n");
+ printf("----- ----- --------- -------------\n");
+ printf(" read %5d %9d %d\n", i["read"].calls,
+ i["read"].maxbytes, i["read"].elapsed);
+ printf(" write %5d %9d %d\n", i["write"].calls,
+ i["write"].maxbytes, i["write"].elapsed);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwtime.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwtime.d
new file mode 100644
index 0000000..2edffb9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/rwtime.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 7-1
+ *
+ * SECTION:
+ * DocExamples/rwinfo
+ */
+
+
+syscall::read:entry,
+syscall::write:entry
+/pid == 100551/
+{
+ ts[probefunc] = timestamp;
+}
+
+syscall::read:return,
+syscall::write:return
+/(ts[probefunc] != 0) && (pid == 100551)/
+{
+ printf("%d nsecs\n", timestamp - ts[probefunc]);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/specopen.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/specopen.d
new file mode 100644
index 0000000..dff3e62
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/specopen.d
@@ -0,0 +1,79 @@
+#!/usr/sbin/dtrace -Fs
+
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 13-1
+ *
+ * SECTION:
+ * DocExamples/specopen
+ */
+
+syscall::open:entry,
+syscall::open64:entry
+{
+ self->spec = speculation();
+ speculate(self->spec);
+
+ printf("%s", stringof(copyinstr(arg0)));
+}
+
+fbt:::
+/self->spec/
+{
+ speculate(self->spec);
+}
+
+syscall::open:return,
+syscall::open64:return
+/self->spec/
+{
+ speculate(self->spec);
+ trace(errno);
+}
+
+syscall::open:return,
+syscall::open64:return
+/self->spec && errno != 0/
+{
+ commit(self->spec);
+ self->spec = 0;
+}
+
+syscall::open:return,
+syscall::open64:return
+/self->spec && errno == 0/
+{
+ discard(self->spec);
+ self->spec = 0;
+}
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/truss.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/truss.d
new file mode 100644
index 0000000..b792520
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/truss.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc
+ *
+ * SECTION:
+ * DocExamples/truss
+ */
+
+
+
+dtrace:::BEGIN
+{
+ var = 30;
+ self->vaa = 24;
+}
+
+syscall::read:entry
+/pid == 102473/
+{
+ printf("var: %d, self->vaa: %d", var++, self->vaa++);
+}
+
+syscall::write:entry
+/pid == 102473/
+{
+ printf("var: %d, self->vaa: %d", var++, self->vaa++);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/trussrw.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/trussrw.d
new file mode 100644
index 0000000..9eb9bce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/trussrw.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify doc example 1-2
+ *
+ * SECTION:
+ * DocExamples/trussrw
+ */
+
+
+#pragma D option quiet
+
+syscall::read:entry,
+syscall::write:entry
+/pid == 100551/
+{
+ printf("%s(%d, 0x%x, %4d)", probefunc, arg0, arg1, arg2);
+}
+
+syscall::read:return,
+syscall::write:return
+/pid == 100551/
+{
+ printf("\t\t = %d\n", arg1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/userfunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/userfunc.d
new file mode 100644
index 0000000..0d83465
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/docsExamples/userfunc.d
@@ -0,0 +1,61 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verifying doc example 21-1
+ *
+ * SECTION:
+ * DocExamples/userfunc
+ *
+ */
+
+pid$1::$2:entry
+{
+ self->trace = 1;
+}
+
+pid$1::$2:return
+/self->trace/
+{
+ self->trace = 0;
+}
+
+pid$1:::entry,
+pid$1:::return
+/self->trace/
+{
+}
+
+
+
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_AGGREGATION.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_AGGREGATION.d
new file mode 100644
index 0000000..02b3243
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_AGGREGATION.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option strsize=1024
+#pragma D option aggsize=512
+
+BEGIN
+{
+ @["Harding"] = count();
+ @["Hoover"] = count();
+ @["Nixon"] = count();
+ @["Bush"] = count();
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DBLERROR.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DBLERROR.d
new file mode 100644
index 0000000..face4c8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DBLERROR.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ trace(*(int *)NULL);
+}
+
+ERROR
+{
+ trace(*(int *)NULL);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DYNAMIC.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DYNAMIC.d
new file mode 100644
index 0000000..f8a90f0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_DYNAMIC.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option strsize=1024
+#pragma D option dynvarsize=512
+
+BEGIN
+{
+ a["Harding"] = 1;
+ a["Hoover"] = 1;
+ a["Nixon"] = 1;
+ a["Bush"] = 1;
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.d
new file mode 100644
index 0000000..8389ce0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option strsize=1024
+#pragma D option bufsize=512
+
+BEGIN
+{
+ trace("Harding");
+ trace("Hoover");
+ trace("Nixon");
+ trace("Bush");
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.end.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.end.d
new file mode 100644
index 0000000..a723019
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_PRINCIPAL.end.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option strsize=1024
+#pragma D option bufsize=512
+
+BEGIN
+{
+ exit(0);
+}
+
+END
+{
+ trace("Harding");
+ trace("Hoover");
+ trace("Nixon");
+ trace("Bush");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPEC.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPEC.d
new file mode 100644
index 0000000..8f6df3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPEC.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option nspec=1
+#pragma D option specsize=32
+#pragma D option strsize=512
+
+BEGIN
+{
+ spec = speculation();
+ speculate(spec);
+ trace("The, SystemTap, The.");
+}
+
+BEGIN
+{
+ commit(spec);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPECUNAVAIL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPECUNAVAIL.d
new file mode 100644
index 0000000..1fd3974
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_SPECUNAVAIL.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option nspec=1
+
+BEGIN,
+BEGIN,
+BEGIN,
+BEGIN
+{
+ spec = speculation();
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_STKSTROVERFLOW.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_STKSTROVERFLOW.d
new file mode 100644
index 0000000..f5d6416
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/drops/drp.DTRACEDROP_STKSTROVERFLOW.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option destructive
+#pragma D option jstackstrsize=1
+#pragma D option quiet
+
+BEGIN
+{
+ system("java -version");
+}
+
+syscall:::entry
+{
+ @[jstack()] = count();
+}
+
+proc:::exit
+/progenyof($pid) && execname == "java"/
+{
+ exit(0);
+}
+
+END
+{
+ printa("\r", @);
+ printf("\n");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/err.D_PDESC_ZERO.InvalidDescription1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/err.D_PDESC_ZERO.InvalidDescription1.d
new file mode 100644
index 0000000..a0d1767
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/err.D_PDESC_ZERO.InvalidDescription1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: An invalid probe description throws a D_PDESC_ZERO error.
+ *
+ * SECTION: Errtags/D_PDESC_ZERO
+ *
+ */
+
+#pragma D option quiet
+
+fbt:bippity:boppity:boo
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.APIVersion.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.APIVersion.d
new file mode 100644
index 0000000..2156489
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.APIVersion.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* Assertion:
+ * Use the -V option to printout API version.
+ *
+ * SECTION:
+ * dtrace Utility/-V Option
+ *
+ * NOTES:
+ * Use /usr/sbin/dtrace -V on command line.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.AddSearchPath.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.AddSearchPath.d
new file mode 100644
index 0000000..53fe67a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.AddSearchPath.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The -I option can be used to search path for #include files when used
+ * in conjunction with the -C option. The specified directory is inserted into
+ * the search path adhead of the default directory list.
+ *
+ * SECTION: dtrace Utility/-C Option;
+ * dtrace Utility/-I Option
+ *
+ * NOTES:
+ * Create a file <filename> and define the variable VALUE in it. Move it a
+ * directory <dirname> different from the current directory. Change the value
+ * of <filename> appropriately in the code below.
+ * Invoke: dtrace -C -I <dirname> -s man.AddSearchPath.d
+ * Verify VALUE.
+ */
+
+
+#pragma D option quiet
+
+#include "filename"
+
+BEGIN
+{
+ printf("Value of VALUE: %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.CoalesceTrace.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.CoalesceTrace.d
new file mode 100644
index 0000000..3cd9d02
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.CoalesceTrace.d
@@ -0,0 +1,67 @@
+#!/bin/ksh -p
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ *
+ * ASSERTION:
+ * Testing -F option with several probes.
+ *
+ * SECTION: dtrace Utility/-F Option
+ *
+ * NOTES: Manually verify using:
+ * "/usr/sbin/dtrace -F -s man.CoalesceTrace.d" on command line.
+ *
+ * Verify that the for the indent characters are -> <- for non-syscall
+ * entry/return pairs (e.g. fbt ones) and => <= for syscall ones and
+ * | for profile ones.
+ *
+ */
+
+BEGIN
+{
+ i = 0;
+ j = 0;
+ k = 0;
+}
+
+syscall::read:
+{
+ printf("syscall: %d\n", i++);
+}
+
+fbt:genunix:read:
+{
+ printf("fbt: %d\n", j++);
+}
+
+profile:::tick-10sec
+{
+ printf("profile: %d\n", k++);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ELFGeneration.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ELFGeneration.d
new file mode 100644
index 0000000..a30a140
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ELFGeneration.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -G option with dtrace utility produces an ELF file containing a
+ * DTrace program. If the filename used with the -s option does ends
+ * with .d, and the -o option is not used, then the output ELF file is
+ * in filename.o
+ *
+ * SECTION: dtrace Utility/-G Option
+ *
+ * NOTES: Use this file as
+ * /usr/sbin/dtrace -G -s man.ELFGeneration.d
+ * Delete the file man.ELFGeneration.d.o
+ *
+ */
+
+BEGIN
+{
+ printf("This test should compile.\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.IncludedFilePath.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.IncludedFilePath.d
new file mode 100644
index 0000000..f4e4e4e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.IncludedFilePath.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using the -CH option with dtrace invocation displays the list of
+ * pathnames of included files one per line to the stderr.
+ *
+ * SECTION: dtrace Utility/-C Option;
+ * dtrace Utility/-H Option
+ *
+ * NOTES: Use this file as
+ * /usr/sbin/dtrace -qCH -s man.IncludedFilePath.d
+ *
+ */
+
+#include "stdio.h"
+
+BEGIN
+{
+ printf("This test should compile.\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithFunctions b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithFunctions
new file mode 100644
index 0000000..e3db127
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithFunctions
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -f option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-f Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -lf profile
+ * RESULT: Silent output without any probes listed.
+ *
+ * 2)
+ * /usr/sbin/dtrace -lf genunix
+ * RESULT: Silent output without any probes listed.
+ *
+ * 3)
+ * /usr/sbin/dtrace -lf read
+ * RESULT: matching list of probes with function read.
+ *
+ * 4)
+ * /usr/sbin/dtrace -lf genunix:read
+ * RESULT: matching list of probes with module genunix and
+ * function read.
+ *
+ * 5)
+ * /usr/sbin/dtrace -lf sysinfo:genunix:read
+ * RESULT: matching list of probes with provider sysinfo, module
+ * genunix and function read.
+ *
+ * 6)
+ * /usr/sbin/dtrace -lf :genunix::
+ * RESULT: Silent output without any probes listed.
+ *
+ * 7)
+ * /usr/sbin/dtrace -lf ::read:
+ * RESULT: Silent output without any probes listed.
+ *
+ * 8)
+ * /usr/sbin/dtrace -lf profile:::profile-97
+ * RESULT: not a valid probe description.
+ *
+ * 9)
+ * /usr/sbin/dtrace -lf read -lf write
+ * RESULT: matching list of both read and write probes.
+ *
+ * 10)
+ * /usr/sbin/dtrace -lf read -lm fight
+ * RESULT: List of only read probes.
+ *
+ * 11)
+ * /usr/sbin/dtrace -lf fight -lf write
+ * RESULT: List of only write probes.
+ *
+ * 12) Has been automated.
+ * /usr/sbin/dtrace -lf fbt:des:des3_crunch_block:return
+ * RESULT: not a valid probe description.
+ *
+ * 13)
+ * /usr/sbin/dtrace -lf read'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 14)
+ * /usr/sbin/dtrace -lf read '{printf("FOUND");}'
+ * RESULT: List of only read probes.
+ *
+ * 15)
+ * /usr/sbin/dtrace -lf read'/probename == "entry"/{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithIDs b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithIDs
new file mode 100644
index 0000000..2b46ce3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithIDs
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -i option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-i Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -l
+ * RESULT: List of all available probes.
+ *
+ * 2)
+ * /usr/sbin/dtrace -li 0
+ * RESULT: invalid probe identifier 0.
+ *
+ * 3) automated in tst.InvalidId1.d.ksh
+ * /usr/sbin/dtrace -li -3
+ * RESULT: not a valid id range
+ *
+ * 4)
+ * /usr/sbin/dtrace -li 0-2
+ * RESULT: List of probes including 1 and 2 or error.
+ *
+ * 5) automated in tst.InvalidId2.d.ksh
+ * /usr/sbin/dtrace -li 4-2
+ * RESULT: not a valid id range
+ *
+ * 6) automated in tst.InvalidId3.d.ksh
+ * /usr/sbin/dtrace -li 2-2
+ * RESULT: not a valid id range
+ *
+ * 7)
+ * /usr/sbin/dtrace -li 1 2 3 4
+ * RESULT: only the first probe id is listed and other extraneous
+ * charaters are not considered.
+ *
+ * 8)
+ * /usr/sbin/dtrace -li 0 - 2
+ * RESULT: only the first probe id is listed and other extraneous
+ * charaters are not considered.
+ *
+ * 9)
+ * /usr/sbin/dtrace -li 1 -li 2-4 -li 4 -li 5
+ * RESULT: Probe descriptions listed for all ids specified. Once
+ * for each specification on the command line.
+ *
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithModules b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithModules
new file mode 100644
index 0000000..167c72a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithModules
@@ -0,0 +1,91 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -m option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-m Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -lm profile
+ * RESULT: Silent output without any probes listed.
+ *
+ * 2)
+ * /usr/sbin/dtrace -lm genunix
+ * RESULT: matching list of probes with module name genunix.
+ *
+ * 3)
+ * /usr/sbin/dtrace -lm vtrace:genunix
+ * RESULT: matching list of probes with provider vtrace and module
+ * genunix.
+ *
+ * 4) automated in tst.InvalidModule1.d.ksh
+ * /usr/sbin/dtrace -lm :genunix::
+ * RESULT: not a valid probe description
+ *
+ * 5) automated in tst.InvalidModule2.d.ksh
+ * /usr/sbin/dtrace -lm profile:::profile-97
+ * RESULT: not a valid probe description.
+ *
+ * 6)
+ * /usr/sbin/dtrace -lm genunix -lm unix
+ * RESULT: matching list of both genunix and unix probes.
+ *
+ * 7)
+ * /usr/sbin/dtrace -lm genunix -lm foounix
+ * RESULT: List of only genunix probes.
+ *
+ * 8)
+ * /usr/sbin/dtrace -lm foounix -lm unix
+ * RESULT: List of only unix probes.
+ *
+ * 9) automated in tst.InvalidModule3.d.ksh
+ * /usr/sbin/dtrace -lm fbt:des:des3_crunch_block:return
+ * RESULT: not a valid probe description.
+ *
+ * 10)
+ * /usr/sbin/dtrace -lm fbt:genunix'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 11)
+ * /usr/sbin/dtrace -lm genunix'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 12)
+ * /usr/sbin/dtrace -lm unix '{printf("FOUND");}'
+ * RESULT: List of only unix probes.
+ *
+ * 13) automated in tst.InvalidModule4.d.ksh
+ * /usr/sbin/dtrace -lm
+ * unix'/probefunc == "preempt"/{printf("FOUND");}'
+ * RESULT: not a valid probe description.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithNames b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithNames
new file mode 100644
index 0000000..aabf1b2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithNames
@@ -0,0 +1,128 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -n option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-n Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -ln profile
+ * RESULT: Silent output without any probes listed.
+ *
+ * 2)
+ * /usr/sbin/dtrace -ln genunix
+ * RESULT: Silent output without any probes listed.
+ *
+ * 3)
+ * /usr/sbin/dtrace -ln read
+ * RESULT: Silent output without any probes listed.
+ *
+ * 4)
+ * /usr/sbin/dtrace -ln BEGIN
+ * RESULT: list of one probe with name BEGIN.
+ *
+ * 5)
+ * /usr/sbin/dtrace -ln begin
+ * RESULT: Silent output without any probes listed.
+ *
+ * 6)
+ * /usr/sbin/dtrace -ln genunix:read
+ * RESULT: Silent output without any probes listed.
+ *
+ * 7)
+ * /usr/sbin/dtrace -ln genunix:read:
+ * RESULT: matching list of probes with module genunix and
+ * function read.
+ *
+ * 8)
+ * /usr/sbin/dtrace -ln sysinfo:genunix:read
+ * RESULT: Silent output without any probes listed.
+ *
+ * 9)
+ * /usr/sbin/dtrace -ln sysinfo:genunix:read:
+ * RESULT: matching list of probes with provider sysinfo, module
+ * genunix and function read.
+ *
+ * 10) /usr/sbin/dtrace -ln :genunix::
+ * RESULT: matching list of probes with module genunix
+ *
+ * 11)
+ * /usr/sbin/dtrace -ln :genunix:
+ * RESULT: Silent output without any probes listed.
+ *
+ * 12)
+ * /usr/sbin/dtrace -ln ::read:
+ * RESULT: matching list of probes with and function read.
+ *
+ * 13)
+ * /usr/sbin/dtrace -ln profile:::profile-97
+ * RESULT: matching list of probes with provider profile and function
+ * profile-97
+ *
+ * 14)
+ * /usr/sbin/dtrace -ln read: -ln write:
+ * RESULT: matching list of both read and write probes.
+ *
+ * 15)
+ * /usr/sbin/dtrace -ln read: -ln fight:
+ * RESULT: List of only read probes.
+ *
+ * 16)
+ * /usr/sbin/dtrace -ln fight: -ln write:
+ * RESULT: List of only write probes.
+ *
+ * 17)
+ * /usr/sbin/dtrace -ln fbt:des:des3_crunch_block:return
+ * RESULT: Silent output of only the header.
+ *
+ * 18)
+ * /usr/sbin/dtrace -ln read:'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 19)
+ * /usr/sbin/dtrace -ln read:entry'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 20)
+ * /usr/sbin/dtrace -ln BEGIN'{Printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 21)
+ * /usr/sbin/dtrace -ln BEGIN '{printf("FOUND");}'
+ * RESULT: List of only BEGIN probe.
+ *
+ * 22)
+ * /usr/sbin/dtrace -ln
+ * BEGIN'/probename == "entry"/{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithProviders b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithProviders
new file mode 100644
index 0000000..961d409
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ListProbesWithProviders
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -P option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-P Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -lP profile
+ * RESULT: List of only profile probes.
+ *
+ * 2)
+ * /usr/sbin/dtrace -lP foofile
+ * RESULT: Silent output without any probes listed.
+ *
+ * 3) automated in tst.InvalidProvider2.d.ksh
+ * /usr/sbin/dtrace -lP profile:::
+ * RESULT: not a valid probe description
+ *
+ * 4) automated in tst.InvalidProvider1.d.ksh
+ * /usr/sbin/dtrace -lP profile:::profile-97
+ * RESULT: not a valid probe description.
+ *
+ * 5)
+ * /usr/sbin/dtrace -lP profile -lP syscall
+ * RESULT: matching list of both profile and syscall probes.
+ *
+ * 6)
+ * /usr/sbin/dtrace -lP profile -lP foofile
+ * RESULT: List of only profile probes.
+ *
+ * 7)
+ * /usr/sbin/dtrace -lP foofile -lP profile
+ * RESULT: List of only profile probes.
+ *
+ * 8) authomated in tst.InvalidProvider3.d.ksh
+ * /usr/sbin/dtrace -lP fbt:des:des3_crunch_block:return
+ * RESULT: not a valid probe description.
+ *
+ * 9)
+ * /usr/sbin/dtrace -lP profile'{printf("FOUND");}'
+ * RESULT: Silent output without any probes listed.
+ *
+ * 10)
+ * /usr/sbin/dtrace -lP profile '{printf("FOUND");}'
+ * RESULT: List of only profile probes.
+ *
+ * 11) automated in tst.InvalidProvider4.d.ksh
+ * /usr/sbin/dtrace -lP
+ * profile'/probename == "profile-199"/{printf("FOUND");}'
+ * RESULT: not a valid probe description.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ShowCompilerCode.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ShowCompilerCode.d
new file mode 100644
index 0000000..556811d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.ShowCompilerCode.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -S option with dtrace utility shows the intermediate compiler code.
+ *
+ * SECTION: dtrace Utility/-S Option
+ *
+ * NOTES: Use this file as
+ * /usr/sbin/dtrace -qSs man.ShowCompilerCode.d
+ *
+ */
+
+BEGIN
+{
+ printf("This test should compile %d\n", 1);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceFunctions b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceFunctions
new file mode 100644
index 0000000..4c9c1c5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceFunctions
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -f option.
+ *
+ * SECTION: dtrace Utility/-f Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1) automated in tst.InvalidTraceFunc1.d.ksh
+ * /usr/sbin/dtrace -f profile
+ * RESULT: invalid probe specifier
+ *
+ * 2) automated in tst.InvalidTraceFunc2.d.ksh
+ * /usr/sbin/dtrace -f genunix
+ * RESULT: invalid probe specifier
+ *
+ * 3)
+ * /usr/sbin/dtrace -f read
+ * RESULT: tracing of matching list of probes with function read.
+ *
+ * 4) automated in tst.InvalidTraceFunc3.d.ksh
+ * /usr/sbin/dtrace -f read:
+ * RESULT: invalid probe specifier
+ *
+ * 5)
+ * /usr/sbin/dtrace -f ::read
+ * RESULT: tracing of matching list of probes with function read.
+ *
+ * 6) automated in tst.InvalidTraceFunc4.d.ksh
+ * /usr/sbin/dtrace -f ::read:
+ * RESULT: invalid probe specifier
+ *
+ * 7)
+ * /usr/sbin/dtrace -f genunix:read
+ * RESULT: tracing of probes with module genunix and function read.
+ *
+ * 8)
+ * /usr/sbin/dtrace -f sysinfo:genunix:read
+ * RESULT: tracing of probes with provider sysinfo, module genunix
+ * and function read.
+ *
+ * 9)
+ * /usr/sbin/dtrace -f sysinfo::read
+ * RESULT: tracing of probes with provider sysinfo and function read.
+ *
+ * 10) automated in tst.InvalidTraceFunc5.d.ksh
+ * /usr/sbin/dtrace -f :genunix::
+ * RESULT: invalid probe specifier
+ *
+ * 11) automated in tst.InvalidTraceFunc6.d.ksh
+ * /usr/sbin/dtrace -f profile:::profile-97
+ * RESULT: invalid probe specifier.
+ *
+ * 12)
+ * /usr/sbin/dtrace -f read -f write
+ * RESULT: tracing of both read and write probes.
+ *
+ * 13)
+ * /usr/sbin/dtrace -f read -f fight
+ * RESULT: Count of matching read probes and invalid probe specifier
+ * for fight
+ *
+ * 14) automated in tst.InvalidTraceFunc8.d.ksh
+ * /usr/sbin/dtrace -f fight -f write
+ * RESULT: invalid probe specifier.
+ *
+ * 15) automated in tst.InvalidTraceFunc7.d.ksh
+ * /usr/sbin/dtrace -f fbt:des:des3_crunch_block:return
+ * RESULT: invalid probe specifier.
+ *
+ * 16)
+ * /usr/sbin/dtrace -f read'{printf("FOUND");}'
+ * RESULT: tracing of probes with function read and with message FOUND
+ *
+ * 17)
+ * /usr/sbin/dtrace -f ::read'{printf("FOUND");}'
+ * RESULT: tracing of probes with function read and with message FOUND
+ *
+ * 18) automated in tst.InvalidTraceFunc9.d.ksh
+ * /usr/sbin/dtrace -f read '{printf("FOUND");}'
+ * RESULT: invalid probe specifier.
+ *
+ * 19)
+ * /usr/sbin/dtrace -f read'/probename == "entry"/{printf("FOUND");}'
+ * RESULT: tracing of probes with function read, name entry and with
+ * message FOUND
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceIDs b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceIDs
new file mode 100644
index 0000000..d9615b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceIDs
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -l option with -i option.
+ *
+ * SECTION: dtrace Utility/-l Option;
+ * dtrace Utility/-i Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1) automated in tst.InvalidTraceID1.d.ksh
+ * /usr/sbin/dtrace -i 0
+ * RESULT: invalid probe specifier.
+ *
+ * 2) automated in tst.InvalidTraceID2.d.ksh
+ * /usr/sbin/dtrace -i -3
+ * RESULT: not a valid id range
+ *
+ * 3) automated in tst.InvalidTraceID3.d.ksh
+ * /usr/sbin/dtrace -i 0-2
+ * RESULT: not a valid id range
+ *
+ * 4) automated in tst.InvalidTraceID4.d.ksh
+ * /usr/sbin/dtrace -i 4-2
+ * RESULT: not a valid id range
+ *
+ * 5) automated in tst.InvalidTraceID5.d.ksh
+ * /usr/sbin/dtrace -i 2-2
+ * RESULT: not a valid id range
+ *
+ * 6) automated in tst.InvalidTraceID6.d.ksh
+ * /usr/sbin/dtrace -i 1 2 3 4
+ * RESULT: invalid probe specifier.
+ *
+ * 7) automated in tst.InvalidTraceID7.d.ksh
+ * /usr/sbin/dtrace -i 0 - 2
+ * RESULT: invalid probe specifier.
+ *
+ * 8)
+ * /usr/sbin/dtrace -i 1 -i 2-4 -i 4 -i 5
+ * RESULT: Only the BEGIN probe is traced and the others are not.
+ *
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceModule b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceModule
new file mode 100644
index 0000000..9c4401e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceModule
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tracing a module using the -m option.
+ *
+ * SECTION: dtrace Utility/-m Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1) automated in tst.InvalidTraceModule1.d.ksh
+ * /usr/sbin/dtrace -m profile
+ * RESULT: invalid probe specifier
+ *
+ * 2)
+ * /usr/sbin/dtrace -m genunix
+ * RESULT: trace of all probes with module genunix.
+ *
+ * 3)
+ * /usr/sbin/dtrace -m vtrace:genunix
+ * RESULT: trace of probes with provider vtrace and module genunix.
+ *
+ * 4) automated in tst.InvalidTraceModule2.d.ksh
+ * /usr/sbin/dtrace -m :genunix::
+ * RESULT: invalid probe specifier
+ *
+ * 5)
+ * /usr/sbin/dtrace -m :genunix
+ * RESULT: trace of all probes with module genunix.
+ *
+ * 6) automated in tst.InvalidTraceModule3.d.ksh
+ * /usr/sbin/dtrace -m genunix::
+ * RESULT: invalid probe specifier
+ *
+ * 7) automated in tst.InvalidTraceModule4.d.ksh
+ * /usr/sbin/dtrace -m profile:::profile-97
+ * RESULT: not a valid probe description.
+ *
+ * 8)
+ * /usr/sbin/dtrace -m genunix -m unix
+ * RESULT: tracing of both genunix and unix probes.
+ *
+ * 9)
+ * /usr/sbin/dtrace -m genunix -m foounix
+ * RESULT: Number of probes matching the description genunix
+ * and an invalid probe specifier for foounix.
+ *
+ * 10) automated in tst.InvalidTraceModule5.d.ksh
+ * /usr/sbin/dtrace -m foounix -m unix
+ * RESULT: invalid probe specifier for foounix.
+ *
+ * 11) automated in tst.InvalidTraceModule6.d.ksh
+ * /usr/sbin/dtrace -m fbt:des:des3_crunch_block:return
+ * RESULT: invalid probe description.
+ *
+ * 12)
+ * /usr/sbin/dtrace -m fbt:genunix'{printf("FOUND");}'
+ * RESULT: tracing of all the probes matching provider fbt and module
+ * genunix.
+ *
+ * 13)
+ * /usr/sbin/dtrace -m genunix'{printf("FOUND");}'
+ * RESULT: tracing of all the probes matching module genunix with
+ * message FOUND
+ *
+ * 14)
+ * /usr/sbin/dtrace -m :genunix'{printf("FOUND");}'
+ * RESULT: tracing of all the probes matching module genunix with
+ * message FOUND
+ *
+ * 15) automated in tst.InvalidTraceModule7.d.ksh
+ * /usr/sbin/dtrace -m genunix::'{printf("FOUND");}'
+ * RESULT: invalid probe specifier.
+ *
+ * 16) automated in tst.InvalidTraceModule8.d.ksh
+ * /usr/sbin/dtrace -m genunix:'{printf("FOUND");}'
+ * RESULT: invalid probe specifier.
+ *
+ * 17)
+ * /usr/sbin/dtrace -m unix '{printf("FOUND");}'
+ * RESULT: invalid probe specifier.
+ *
+ * 18)
+ * /usr/sbin/dtrace -m
+ * unix'/probefunc == "preempt"/{printf("FOUND");}'
+ * RESULT: tracing of all the probes matching module genunix,
+ * probe function preempt with message FOUND.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceNames b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceNames
new file mode 100644
index 0000000..c3e7555
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceNames
@@ -0,0 +1,129 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -n option.
+ *
+ * SECTION: dtrace Utility/-n Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1) automated in tst.InvalidTraceName1.d.ksh
+ * /usr/sbin/dtrace -n profile
+ * RESULT: invalid probe specifier
+ *
+ * 2) automated in tst.InvalidTraceName2.d.ksh
+ * /usr/sbin/dtrace -n genunix
+ * RESULT: invalid probe specifier
+ *
+ * 3) automated in tst.InvalidTraceName3.d.ksh
+ * /usr/sbin/dtrace -n read
+ * RESULT: invalid probe specifier
+ *
+ * 4)
+ * /usr/sbin/dtrace -n BEGIN
+ * RESULT: trace of one probe with name BEGIN.
+ *
+ * 5) automated in tst.InvalidTraceName4.d.ksh
+ * /usr/sbin/dtrace -n begin
+ * RESULT: invalid probe specifier
+ *
+ * 6) automated in tst.InvalidTraceName5.d.ksh
+ * /usr/sbin/dtrace -n genunix:read
+ * RESULT: invalid probe specifier
+ *
+ * 7)
+ * /usr/sbin/dtrace -n genunix:read:
+ * RESULT: trace of probes with module genunix and function read.
+ *
+ * 8) automated in tst.InvalidTraceName6.d.ksh
+ * /usr/sbin/dtrace -n sysinfo:genunix:read
+ * RESULT: invalid probe specifier
+ *
+ * 9)
+ * /usr/sbin/dtrace -n sysinfo:genunix:read:
+ * RESULT: tracing of probes with provider sysinfo, module genunix
+ * and function read.
+ *
+ * 10)
+ * /usr/sbin/dtrace -n :genunix::
+ * RESULT: tracing of probes with module genunix
+ *
+ * 11) automated in tst.InvalidTraceName7.d.ksh
+ * /usr/sbin/dtrace -n :genunix:
+ * RESULT: invalid probe specifier
+ *
+ * 12)
+ * /usr/sbin/dtrace -n ::read:
+ * RESULT: tracing of probes with function read.
+ *
+ * 13)
+ * /usr/sbin/dtrace -n profile:::profile-97
+ * RESULT: tracing of probes with provider profile and name
+ * profile-97
+ *
+ * 14)
+ * /usr/sbin/dtrace -n read: -n write:
+ * RESULT: tracing of both read and write probes.
+ *
+ * 15)
+ * /usr/sbin/dtrace -n read: -n fight:
+ * RESULT: Count of mathching read probes and invalid probe specifier
+ * for fight:
+ *
+ * 16) automated in tst.InvalidTraceName8.d.ksh
+ * /usr/sbin/dtrace -n fight: -n write:
+ * RESULT: invalid probe specifier
+ *
+ * 17)
+ * /usr/sbin/dtrace -n fbt:des:des3_crunch_block:return
+ * RESULT: trace of the specified probe.
+ *
+ * 18)
+ * /usr/sbin/dtrace -n read:'{printf("FOUND");}'
+ * RESULT: Trace of all the probes with module read and a message
+ * saying FOUND.
+ *
+ * 19)
+ * /usr/sbin/dtrace -n read:entry'{printf("FOUND");}'
+ * RESULT: Trace of all the probes with module read, name entry.Output
+ * of a message saying FOUND.
+ *
+ * 20)
+ * /usr/sbin/dtrace -n BEGIN'{printf("FOUND");}'
+ * RESULT: Trace of the BEGIN probe with the message FOUND.
+ *
+ * 21) automated in tst.InvalidTraceName9.d.ksh
+ * /usr/sbin/dtrace -n BEGIN '{printf("FOUND");}'
+ * RESULT: invalid probe specifier
+ *
+ * 22)
+ * /usr/sbin/dtrace -n BEGIN'/probename == "entry"/{printf("FOUND");}'
+ * RESULT: Tracing of BEGIN function but no message FOUND.
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceProvider b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceProvider
new file mode 100644
index 0000000..f52f395
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.TraceProvider
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -P option to trace all the probes provided by the particular
+ * provider.
+ *
+ * SECTION: dtrace Utility/-P Option
+ *
+ * NOTES: Manually check:
+ *
+ * 1)
+ * /usr/sbin/dtrace -P profile
+ * RESULT: Trace of all profile probes.
+ *
+ * 2) automated in tst.InvalidTraceProvider1.d.ksh
+ * /usr/sbin/dtrace -P foofile
+ * RESULT: invalid probe specifier
+ *
+ * 3) automated in tst.InvalidTraceProvider2.d.ksh
+ * /usr/sbin/dtrace -P profile:::
+ * RESULT: invalid probe specifier
+ *
+ * 4) automated in tst.InvalidTraceProvider3.d.ksh
+ * /usr/sbin/dtrace -P profile:::profile-97
+ * RESULT: invalid probe specifier
+ *
+ * 5)
+ * /usr/sbin/dtrace -P profile -P syscall
+ * RESULT: matching traces of both profile and syscall probes.
+ *
+ * 6)
+ * /usr/sbin/dtrace -P profile -P foofile
+ * RESULT: Count of profile probes that matched and invalid
+ * probe specifier for foofile and no tracing.
+ *
+ * 7) automated in tst.InvalidTraceProvider4.d.ksh
+ * /usr/sbin/dtrace -P fbt:des:des3_crunch_block:return
+ * RESULT: invalid probe specifier
+ *
+ * 8)
+ * /usr/sbin/dtrace -P profile'{printf("FOUND");}'
+ * RESULT: Traces of all the matching profile probes with the
+ * FOUND message.
+ *
+ * 9) automated in tst.InvalidTraceProvider5.d.ksh
+ * /usr/sbin/dtrace -P profile '{printf("FOUND");}'
+ * RESULT: invalid probe specifier
+ *
+ * 10)
+ * /usr/sbin/dtrace -P
+ * profile'/probename == "profile-199"/{printf("FOUND");}'
+ * RESULT: Traces of the matching profile probe with the
+ * FOUND message.
+ *
+ *
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.VerboseStabilityReport.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.VerboseStabilityReport.d
new file mode 100644
index 0000000..2374228
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/man.VerboseStabilityReport.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using -v option with dtrace utility produces a program stability report
+ * showing the minimum interface stability and dependency level for
+ * the specified D programs.
+ *
+ * SECTION: dtrace Utility/-s Option;
+ * dtrace Utility/-v Option
+ *
+ * NOTES: Use this file as
+ * /usr/sbin/dtrace -vs man.VerboseStabilityReport.d
+ *
+ */
+
+BEGIN
+{
+ printf("This test should compile: %d\n", 2);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh
new file mode 100644
index 0000000..b36f1e4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh
@@ -0,0 +1,82 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -I option can be used to search path for #include files when used
+# in conjunction with the -C option. The specified directory is inserted into
+# the search path adhead of the default directory list.
+#
+# SECTION: dtrace Utility/-C Option
+# SECTION: dtrace Utility/-I Option
+#
+##
+
+script()
+{
+ $dtrace -C -I /tmp -s /dev/stdin <<EOF
+ #pragma D option quiet
+#include "test.h"
+
+ BEGIN
+ /1520 != VALUE/
+ {
+ printf("VALUE: %d, Test should fail\n", VALUE);
+ exit(1);
+ }
+
+ BEGIN
+ /1520 == VALUE/
+ {
+ printf("VALUE: %d, Test should pass\n", VALUE);
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+tempfile=/tmp/test.h
+echo "#define VALUE 1520" > $tempfile
+
+dtrace=$1
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+/bin/rm -f $tempfile
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeGiga.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeGiga.d.ksh
new file mode 100644
index 0000000..2f0c567
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeGiga.d.ksh
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION:
+# The trace buffer size can include any of the size suffixes k, m, g or t
+#
+# SECTION: dtrace Utility/-b Option
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -b 1g -b 2g -e
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeKilo.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeKilo.d.ksh
new file mode 100644
index 0000000..d969b48
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeKilo.d.ksh
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION:
+# The trace buffer size can include any of the size suffixes k, m, g or t
+#
+# SECTION: dtrace Utility/-b Option
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -b 1k -b 2k -e
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeMega.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeMega.d.ksh
new file mode 100644
index 0000000..a08327a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeMega.d.ksh
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION:
+# The trace buffer size can include any of the size suffixes k, m, g or t
+#
+# SECTION: dtrace Utility/-b Option
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -b 1m -b 2m -e
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeTera.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeTera.d.ksh
new file mode 100644
index 0000000..00f2c66
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.BufsizeTera.d.ksh
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION:
+# The trace buffer size can include any of the size suffixes k, m, g or t
+#
+# SECTION: dtrace Utility/-b Option
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -b 1t -b 2t -e
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel32.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel32.d.ksh
new file mode 100644
index 0000000..e4ef38d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel32.d.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# If the -32 option is specified, dtrace will force the D compiler to
+# compile a program using the 32-bit data model.
+#
+# SECTION: dtrace Utility/-32 Option
+#
+##
+
+script()
+{
+ $dtrace -32 -s /dev/stdin <<EOF
+ BEGIN
+ /4 != sizeof(long)/
+ {
+ printf("Not targeted for 32 bit machine\n");
+ exit(1);
+ }
+
+ BEGIN
+ /4 == sizeof(long)/
+ {
+ printf("Targeted for 32 bit machine\n");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel64.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel64.d.ksh
new file mode 100644
index 0000000..8a9de0c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DataModel64.d.ksh
@@ -0,0 +1,74 @@
+#!/bin/ksh
+
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# If the -64 option is specified, dtrace will force the D compiler to
+# compile a program using the 64-bit data model.
+#
+# SECTION: dtrace Utility/-64 Option
+#
+##
+
+script()
+{
+ $dtrace -64 -s /dev/stdin <<EOF
+ BEGIN
+ /8 != sizeof(long)/
+ {
+ printf("Not targeted for 64 bit machine\n");
+ exit(1);
+ }
+
+ BEGIN
+ /8 == sizeof(long)/
+ {
+ printf("Targeted for 64 bit machine\n");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh
new file mode 100644
index 0000000..9be2b29
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh
@@ -0,0 +1,68 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -D option can be used to define a name when used in conjunction
+# with the -C option.
+#
+# SECTION: dtrace Utility/-C Option;
+# dtrace Utility/-D Option
+#
+##
+
+script()
+{
+ $dtrace -C -D VALUE=40 -s /dev/stdin <<EOF
+ #pragma D option quiet
+
+ BEGIN
+ {
+ printf("Value of VALUE: %d\n", VALUE);
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh.out
new file mode 100644
index 0000000..5f91ad1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DefineNameWithCPP.d.ksh.out
@@ -0,0 +1,2 @@
+Value of VALUE: 40
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh
new file mode 100644
index 0000000..0259db3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh
@@ -0,0 +1,56 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -w option can be used to permit destructive actions in D programs.
+#
+# SECTION: dtrace Utility/-w Option;
+# dtrace Utility/-f Option
+#
+##
+
+
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qwf read'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh.out
new file mode 100644
index 0000000..8975980
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithFunction.d.ksh.out
@@ -0,0 +1 @@
+Done chilling
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh
new file mode 100644
index 0000000..6d3913f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -w option can be used to permit destructive actions in D programs.
+#
+# SECTION: dtrace Utility/-w Option;
+# dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qwi 1'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh.out
new file mode 100644
index 0000000..8975980
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithID.d.ksh.out
@@ -0,0 +1 @@
+Done chilling
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh
new file mode 100644
index 0000000..8ab32fd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -w option can be used to permit destructive actions in D programs.
+#
+# SECTION: dtrace Utility/-w Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qwm kernel'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh.out
new file mode 100644
index 0000000..8975980
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh.out
@@ -0,0 +1 @@
+Done chilling
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh
new file mode 100644
index 0000000..b21903f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -w option can be used to permit destructive actions in D programs.
+#
+# SECTION: dtrace Utility/-w Option;
+# dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qwn BEGIN'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh.out
new file mode 100644
index 0000000..8975980
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithName.d.ksh.out
@@ -0,0 +1 @@
+Done chilling
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh
new file mode 100644
index 0000000..09dafec
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -w option can be used to permit destructive actions in D programs.
+#
+# SECTION: dtrace Utility/-w Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qwP syscall'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh.out
new file mode 100644
index 0000000..8975980
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithProvider.d.ksh.out
@@ -0,0 +1 @@
+Done chilling
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithoutW.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithoutW.d.ksh
new file mode 100644
index 0000000..9f051b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithoutW.d.ksh
@@ -0,0 +1,55 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Destructive actions will not compile or are not enabled without the
+# -w option in D programs.
+#
+# SECTION: dtrace Utility/-w Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qP syscall'{chill(15); printf("Done chilling"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh
new file mode 100644
index 0000000..a4f4670
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Using -G option with dtrace utility produces an ELF file containing a
+# DTrace program. If the filename used with the -s option does not end
+# with .d, and the -o option is not used, then the output ELF file is
+# in d.out.
+#
+# SECTION: dtrace Utility/-G Option
+#
+##
+
+script()
+{
+ $dtrace -G -s /dev/stdin <<EOF
+ BEGIN
+ {
+ printf("This test should compile.\n");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+if [ ! -a "d.out" ]; then
+ echo $tst: file not generated
+ exit 1
+fi
+
+/bin/rm -f "d.out"
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh
new file mode 100644
index 0000000..503dd50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh
@@ -0,0 +1,74 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Using -G option with dtrace utility produces an ELF file containing a
+# DTrace program. The output file can be named as required using the
+# -o option in conjunction with the -G option.
+#
+# SECTION: dtrace Utility/-G Option;
+# dtrace Utility/-o Option
+#
+##
+
+script()
+{
+ $dtrace -G -o outputFile -s /dev/stdin <<EOF
+ BEGIN
+ {
+ printf("This test should compile.\n");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+if [ ! -a "outputFile" ]; then
+ echo $tst: file not generated
+ exit 1
+fi
+
+/bin/rm -f "outputFile"
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus1.d.ksh
new file mode 100644
index 0000000..70a9f49
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus1.d.ksh
@@ -0,0 +1,56 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# When a fatal error occurs such that the program compilation fails or the
+# specified request cannot be satisfied, an exit status of 1 is returned.
+#
+#
+# SECTION: dtrace Utility/Exit Status
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -s wassup
+status=$?
+
+if [ "$status" -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus2.d.ksh
new file mode 100644
index 0000000..a058d3a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExitStatus2.d.ksh
@@ -0,0 +1,55 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# When invalid command line options or arguments are specified an exit status
+# of 2 is returned.
+#
+# SECTION: dtrace Utility/Exit Status
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -9
+status=$?
+
+if [ "$status" -ne 2 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExtraneousProbeIds.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExtraneousProbeIds.d.ksh
new file mode 100644
index 0000000..090fc4a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ExtraneousProbeIds.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -i option with extraneous probe identifiers.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 12 10 -i 23
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName1.d.ksh
new file mode 100644
index 0000000..c28c782
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName1.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f BEGIN
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName2.d.ksh
new file mode 100644
index 0000000..d431579
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidFuncName2.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f 4.56
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId1.d.ksh
new file mode 100644
index 0000000..814b88d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId1.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -li option can be used to list the probes from their ids. An id of
+# negative integer is invalid
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -li -3
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId2.d.ksh
new file mode 100644
index 0000000..f9f4407
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId2.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -li option can be used to list the probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -li 4-2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId3.d.ksh
new file mode 100644
index 0000000..efb03ae
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidId3.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -li option can be used to list the probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -li 2-2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule1.d.ksh
new file mode 100644
index 0000000..a896ff3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule1.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lm option can be used to list the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lm :genunix::
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule2.d.ksh
new file mode 100644
index 0000000..820cc64
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule2.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lm option can be used to list the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lm profile:::profile-97
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule3.d.ksh
new file mode 100644
index 0000000..b56e6c3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule3.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lm option can be used to list the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lm fbt:des:des3_crunch_block:return
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule4.d.ksh
new file mode 100644
index 0000000..0ef9d95
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidModule4.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lm option can be used to list the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lm unix'/probefunc == "preempt"/{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProbeIdentifier.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProbeIdentifier.d.ksh
new file mode 100644
index 0000000..66e0e1a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProbeIdentifier.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -i option with invalid probe identifier.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i i23
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider1.d.ksh
new file mode 100644
index 0000000..327e2d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider1.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lP option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lP profile:::profile-97
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider2.d.ksh
new file mode 100644
index 0000000..2262449
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider2.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lP option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lP profile:::
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider3.d.ksh
new file mode 100644
index 0000000..775b327
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider3.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lP option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lP fbt:des:des3_crunch_block:return
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider4.d.ksh
new file mode 100644
index 0000000..04343f3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidProvider4.d.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -lP option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-l Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -lP profile'/probename == "profile-199"/{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc1.d.ksh
new file mode 100644
index 0000000..1395f3b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc1.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f profile
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc2.d.ksh
new file mode 100644
index 0000000..4231e5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc2.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f genunix
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc3.d.ksh
new file mode 100644
index 0000000..3c5b178
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc3.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f read:
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc4.d.ksh
new file mode 100644
index 0000000..bb8460d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc4.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f ::read:
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc5.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc5.d.ksh
new file mode 100644
index 0000000..5446676
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc5.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f :genunix::
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc6.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc6.d.ksh
new file mode 100644
index 0000000..645e6d9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc6.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f profile:::profile-97
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc7.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc7.d.ksh
new file mode 100644
index 0000000..a93d5c4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc7.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f fbt:des:des3_crunch_block:return
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc8.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc8.d.ksh
new file mode 100644
index 0000000..22ab3b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc8.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f fight -f write
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc9.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc9.d.ksh
new file mode 100644
index 0000000..2af27a3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceFunc9.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -f option with an invalid function name.
+#
+# SECTION: dtrace Utility/-f Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -f read '{printf("FOUND");}'
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID1.d.ksh
new file mode 100644
index 0000000..46096d2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID1.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 0
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID2.d.ksh
new file mode 100644
index 0000000..f406ce0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID2.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i -3
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID3.d.ksh
new file mode 100644
index 0000000..fc2a24d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID3.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 0-2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID4.d.ksh
new file mode 100644
index 0000000..5fd6fd6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID4.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 4-2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID5.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID5.d.ksh
new file mode 100644
index 0000000..0ac46db
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID5.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 2-2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID6.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID6.d.ksh
new file mode 100644
index 0000000..778d485
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID6.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 1 2 3 4
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID7.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID7.d.ksh
new file mode 100644
index 0000000..8a0f2d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceID7.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -i option can be used to enable the trace of probes from their ids. A
+# non-increasing range will not list any probes.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 0 - 2
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule1.d.ksh
new file mode 100644
index 0000000..56dee0d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule1.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m profile
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule2.d.ksh
new file mode 100644
index 0000000..a508fe1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule2.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m :genunix::
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule3.d.ksh
new file mode 100644
index 0000000..599ce93
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule3.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m genunix::
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule4.d.ksh
new file mode 100644
index 0000000..e0e8786
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule4.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m profile:::profile-97
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule5.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule5.d.ksh
new file mode 100644
index 0000000..8583060
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule5.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m foounix -m unix
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule6.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule6.d.ksh
new file mode 100644
index 0000000..6125fb0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule6.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m fbt:des:des3_crunch_block:return
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule7.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule7.d.ksh
new file mode 100644
index 0000000..e689627
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule7.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m genunix::'{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule8.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule8.d.ksh
new file mode 100644
index 0000000..692821b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceModule8.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -m option can be used to enable the probes from their module names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -m genunix:'{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName1.d.ksh
new file mode 100644
index 0000000..43c61af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName1.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n profile
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName2.d.ksh
new file mode 100644
index 0000000..70a5218
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName2.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n genunix
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName3.d.ksh
new file mode 100644
index 0000000..efb5ad0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName3.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n not_a_valid_probe
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName4.d.ksh
new file mode 100644
index 0000000..04845b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName4.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n begin
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName5.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName5.d.ksh
new file mode 100644
index 0000000..df17231
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName5.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n genunix:read
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName6.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName6.d.ksh
new file mode 100644
index 0000000..10f13cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName6.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n sysinfo:genunix:read
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName7.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName7.d.ksh
new file mode 100644
index 0000000..b22561f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName7.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n :genunix:
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName8.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName8.d.ksh
new file mode 100644
index 0000000..f66055e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName8.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n fight: -n write:
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName9.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName9.d.ksh
new file mode 100644
index 0000000..a4239ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceName9.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -n option can be used to enable the trace of probes from their names.
+#
+# SECTION: dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n BEGIN '{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider1.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider1.d.ksh
new file mode 100644
index 0000000..0a792c5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider1.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -P option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-P Option;
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -P foofile
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider2.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider2.d.ksh
new file mode 100644
index 0000000..1763142
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider2.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -P option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-P Option;
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -P profile:::
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider3.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider3.d.ksh
new file mode 100644
index 0000000..a854932
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider3.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -P option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-P Option;
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -P profile:::profile-97
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider4.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider4.d.ksh
new file mode 100644
index 0000000..f8a1359
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider4.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -P option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-P Option;
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -P fbt:des:des3_crunch_block:return
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider5.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider5.d.ksh
new file mode 100644
index 0000000..cec4297
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.InvalidTraceProvider5.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -P option can be used to list the probes from their provider names.
+# Invalid module names result in error.
+#
+# SECTION: dtrace Utility/-P Option;
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -P profile '{printf("FOUND");}'
+
+status=$?
+
+echo $status
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.MultipleInvalidProbeId.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.MultipleInvalidProbeId.d.ksh
new file mode 100644
index 0000000..8f2ceef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.MultipleInvalidProbeId.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -i option with multiple valid and invalid probe identifiers.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 12 -i 10 -i 0
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh
new file mode 100644
index 0000000..e4d093e4f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -C option is used to run the C preprocessor over D programs before
+# compiling them. The -H option used in conjuction with the -C option
+# lists the pathnames of the included files to STDERR.
+#
+# SECTION: dtrace Utility/-C Option;
+# dtrace Utility/-H Option
+#
+##
+
+script()
+{
+ $dtrace -CH -s /dev/stdin <<EOF
+
+
+ BEGIN
+ {
+ printf("This test should compile\n");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh
new file mode 100644
index 0000000..4bfbf76
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh
@@ -0,0 +1,65 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Using the -q option suppresses the dtrace messages and prints only the
+# data traced by trace() and printf() to stdout.
+#
+# SECTION: dtrace Utility/-q Option
+#
+##
+
+script()
+{
+ $dtrace -q -s /dev/stdin <<EOF
+
+ BEGIN
+ {
+ printf("I am the only one.");
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh.out
new file mode 100644
index 0000000..20e31b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.QuietMode.d.ksh.out
@@ -0,0 +1 @@
+I am the only one.
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh
new file mode 100644
index 0000000..16cd05f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh
@@ -0,0 +1,67 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Using the -e option exits after compiling any requests but before
+# enabling probes.
+#
+# SECTION: dtrace Utility/-e Option
+#
+##
+
+script()
+{
+ $dtrace -e -s /dev/stdin <<EOF
+ #pragma D option quiet
+ BEGIN
+ {
+ i = 100;
+ printf("Value of i: %d\n", i);
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.TestCompile.d.ksh.out
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.UnDefineNameWithCPP.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.UnDefineNameWithCPP.d.ksh
new file mode 100644
index 0000000..4c1eb50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.UnDefineNameWithCPP.d.ksh
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -D option can be used to define a name when used in conjunction
+# with the -C option. The -U option can be used to undefine a name in
+# conjunction with the -C option.
+#
+# SECTION: dtrace Utility/-C Option;
+# dtrace Utility/-D Option;
+# dtrace Utility/-U Option
+#
+##
+
+script()
+{
+ $dtrace -C -D VALUE=40 -U VALUE -s /dev/stdin <<EOF
+ #pragma D option quiet
+
+ BEGIN
+ {
+ printf("Value of VALUE: %d\n", VALUE);
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh
new file mode 100644
index 0000000..5e61f05
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -Z option can be used to permit descriptions that match
+# zero probes.
+#
+# SECTION: dtrace Utility/-Z Option;
+# dtrace Utility/-f Option
+#
+##
+
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qZf wassup'{printf("Iamkool");}' \
+-qf read'{printf("I am done"); exit(0);}'
+
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh.out
new file mode 100644
index 0000000..0f2e1aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroFunctionProbes.d.ksh.out
@@ -0,0 +1 @@
+I am done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh
new file mode 100644
index 0000000..c34a4aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -Z option can be used to permit descriptions that match
+# zero probes.
+#
+# SECTION: dtrace Utility/-Z Option;
+# dtrace Utility/-m Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qZm wassup'{printf("Iamkool");}' \
+-qm BEGIN'{printf("I am done"); exit(0);}'
+
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh.out
new file mode 100644
index 0000000..0f2e1aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroModuleProbes.d.ksh.out
@@ -0,0 +1 @@
+I am done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh
new file mode 100644
index 0000000..90175a5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh
@@ -0,0 +1,56 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -Z option can be used to permit descriptions that match
+# zero probes.
+#
+# SECTION: dtrace Utility/-Z Option;
+# dtrace Utility/-n Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qZn wassup'{printf("Iamkool");}' \
+-qn BEGIN'{printf("I am done"); exit(0);}'
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh.out
new file mode 100644
index 0000000..0f2e1aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroNameProbes.d.ksh.out
@@ -0,0 +1 @@
+I am done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbeIdentfier.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbeIdentfier.d.ksh
new file mode 100644
index 0000000..9af4d2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbeIdentfier.d.ksh
@@ -0,0 +1,53 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Testing -i option with zero probe identifier.
+#
+# SECTION: dtrace Utility/-i Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -i 0
+
+if [ $? -ne 1 ]; then
+ echo $tst: dtrace failed
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbesWithoutZ.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbesWithoutZ.d.ksh
new file mode 100644
index 0000000..afc7d76
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProbesWithoutZ.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# Without the -Z option probe descriptions that do not match any known
+# probes will cause an error or will not be enabled.
+#
+# SECTION: dtrace Utility/-Z Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qP wassup'{printf("Iamkool");}' \
+-qP profile'{printf("I am done"); exit(0);}'
+
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo $tst: dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh
new file mode 100644
index 0000000..f2646bd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh
@@ -0,0 +1,57 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+##
+#
+# ASSERTION:
+# The -Z option can be used to permit descriptions that match
+# zero probes.
+#
+# SECTION: dtrace Utility/-Z Option;
+# dtrace Utility/-P Option
+#
+##
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qZP wassup'{printf("Iamkool");}' \
+-qP profile'{printf("I am done"); exit(0);}'
+
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh.out
new file mode 100644
index 0000000..0f2e1aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ZeroProviderProbes.d.ksh.out
@@ -0,0 +1 @@
+I am done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/err.D_IDENT_UNDEF.timespent.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/err.D_IDENT_UNDEF.timespent.d
new file mode 100644
index 0000000..04ccb72
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/err.D_IDENT_UNDEF.timespent.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Calculate timestamp between BEGIN and END.
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ total = timestamp - start;
+}
+
+BEGIN
+{
+ start = timestamp;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.end.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.end.d
new file mode 100644
index 0000000..56c1a4c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.end.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Sequence flow of END profile.
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ printf("End fired after exit\n");
+}
+
+BEGIN
+{
+ printf("Begin fired first\n");
+}
+
+tick-1
+{
+ printf("tick fired second\n");
+ printf("Call exit\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.endwithoutbegin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.endwithoutbegin.d
new file mode 100644
index 0000000..6291960
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.endwithoutbegin.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * END without BEGIN profile
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ printf("End fired after exit\n");
+}
+
+tick-1
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multibeginend.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multibeginend.d
new file mode 100644
index 0000000..4f6ec92
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multibeginend.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tests multiple END profile.
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ printf("End1 fired after exit\n");
+}
+END
+{
+ printf("End2 fired after exit\n");
+}
+END
+{
+ printf("End3 fired after exit\n");
+}
+END
+{
+ printf("End4 fired after exit\n");
+}
+
+BEGIN
+{
+ printf("Begin fired first\n");
+}
+BEGIN
+{
+ printf("Begin fired second\n");
+}
+BEGIN
+{
+ printf("Begin fired third\n");
+}
+BEGIN
+{
+ printf("Begin fired fourth\n");
+}
+BEGIN
+{
+ printf("Begin fired fifth\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multiend.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multiend.d
new file mode 100644
index 0000000..e6629fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/end/tst.multiend.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tests Multiple END and single BEGIN
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+END
+{
+ printf("End1 fired after exit\n");
+}
+END
+{
+ printf("End2 fired after exit\n");
+}
+END
+{
+ printf("End3 fired after exit\n");
+}
+END
+{
+ printf("End4 fired after exit\n");
+}
+
+BEGIN
+{
+ printf("Begin fired first\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_DECL_IDRED.EnumSameName.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_DECL_IDRED.EnumSameName.d
new file mode 100644
index 0000000..7e5427a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_DECL_IDRED.EnumSameName.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Enumerations assigning same or different values to the same identifier in
+ * different enumerations should throw a compiler error.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+enum colors {
+ RED,
+ GREEN,
+ BLUE
+};
+
+enum shades {
+ RED,
+ ORANGE,
+ GREEN,
+ WHITE
+};
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_UNKNOWN.RepeatIdentifiers.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_UNKNOWN.RepeatIdentifiers.d
new file mode 100644
index 0000000..2b4266d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/err.D_UNKNOWN.RepeatIdentifiers.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Repeating the same identifier in the same enumeration will throw a compiler
+ * error.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ * NOTES:
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+enum colors {
+ RED,
+ GREEN,
+ GREEN = 2,
+ BLUE
+};
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumEquality.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumEquality.d
new file mode 100644
index 0000000..cbf9369
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumEquality.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the identifiers in different D enumerations at same position for
+ * equality.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+#pragma D option quiet
+
+enum colors {
+ RED,
+ GREEN,
+ BLUE
+};
+
+enum shades {
+ WHITE,
+ BLACK,
+ YELLOW
+};
+
+
+profile:::tick-1sec
+/(WHITE == RED) && (YELLOW == BLUE) && (GREEN == BLACK)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumSameValue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumSameValue.d
new file mode 100644
index 0000000..26a4d50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumSameValue.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Enumerations assigning the same value to different identifiers in the same
+ * enumeration should work okay.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ * NOTES:
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+enum colors {
+ RED = 2,
+ GREEN = 2,
+ BLUE = 2
+};
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumValAssign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumValAssign.d
new file mode 100644
index 0000000..f721c50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/enum/tst.EnumValAssign.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test the D enumerations with and without initilialization of the identifiers.
+ * Also test for values with negative integer assignments, expressions and
+ * fractions.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+enum colors {
+ RED,
+ ORANGE = 5 + 5,
+ YELLOW = 2,
+ GREEN,
+ BLUE = GREEN + ORANGE,
+ PINK = 5/4,
+ INDIGO = -2,
+ VIOLET
+};
+
+profile:::tick-1sec
+/(0 == RED) && (10 == ORANGE) && (2 == YELLOW) && (3 == GREEN) &&
+ (13 == BLUE) && (1 == PINK) && (-2 == INDIGO) && (-1 == VIOLET)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_BADADDR.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_BADADDR.d
new file mode 100644
index 0000000..5eb3e94
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_BADADDR.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To test DTRACEFLT_BADADDR error
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+ERROR
+{
+ printf("The arguments are %u %u %u %u %u\n",
+ arg1, arg2, arg3, arg4, arg5);
+ printf("The value of arg4 = %u\n", DTRACEFLT_BADADDR);
+ exit(0);
+}
+
+BEGIN
+{
+ *(char *)NULL;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_DIVZERO.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_DIVZERO.d
new file mode 100644
index 0000000..5b93168
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_DIVZERO.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To test DTRACEFLT_DIVZERO error
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+ERROR
+{
+ printf("The arguments are %u %u %u %d %u\n",
+ arg1, arg2, arg3, arg4, arg5);
+ exit(0);
+}
+
+char *s;
+
+BEGIN
+{
+ i = 1;
+ j = 2;
+ j = i/(j-2);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_UNKNOWN.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_UNKNOWN.d
new file mode 100644
index 0000000..6de75bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.DTRACEFLT_UNKNOWN.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To test DTRACEFLT_UNKNOWN error
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+ERROR
+{
+ printf("The arguments are %u %u %u %u %u\n",
+ arg1, arg2, arg3, arg4, arg5);
+ printf("The value of arg4 = %u\n", DTRACEFLT_UNKNOWN);
+ exit(0);
+}
+
+BEGIN
+{
+ x = (int *) 64;
+ y = *x;
+ trace(y);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.error.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.error.d
new file mode 100644
index 0000000..3b1d653
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.error.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To fire ERROR probe
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+ERROR
+{
+ printf("Error fired\n");
+ exit(0);
+}
+
+BEGIN
+{
+ *(char *)NULL;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.errorend.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.errorend.d
new file mode 100644
index 0000000..0bb4a6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/error/tst.errorend.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Flow of ERROR probe
+ *
+ * SECTION: dtrace Provider
+ *
+ */
+
+
+#pragma D option quiet
+
+ERROR
+{
+ printf("Error fired\n");
+ exit(0);
+}
+
+END
+{
+ printf("End fired after exit\n");
+}
+
+BEGIN
+{
+ *(char *)NULL;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.D_PROTO_LEN.noarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.D_PROTO_LEN.noarg.d
new file mode 100644
index 0000000..9a9a8f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.D_PROTO_LEN.noarg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Call exit() without arguments.
+ *
+ * SECTION: Actions and Subroutines/exit()
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ exit()
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.exitarg1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.exitarg1.d
new file mode 100644
index 0000000..d3067d1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/err.exitarg1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Basic test - call with 1
+ *
+ * SECTION: Actions and Subroutines/exit()
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/tst.basic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/tst.basic1.d
new file mode 100644
index 0000000..24f841c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/exit/tst.basic1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test
+ *
+ * SECTION: Actions and Subroutines/exit()
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/err.D_PDESC_ZERO.notreturn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/err.D_PDESC_ZERO.notreturn.d
new file mode 100644
index 0000000..5e3d5fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/err.D_PDESC_ZERO.notreturn.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: Call fbt provider over non existent function and make
+ * sure it results in compilation error.
+ *
+ * SECTION: FBT Provider/Probes
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->traceme = 1;
+}
+
+void bar();
+
+fbt::bar:entry
+{
+ printf("Entering the function\n");
+}
+
+fbt::bar:return
+{
+ printf("Returning the function\n");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.basic.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.basic.d
new file mode 100644
index 0000000..ff6da26
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.basic.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: simple fbt arguments test.
+ *
+ * SECTION: FBT Provider/Probes
+ */
+
+#pragma D option quiet
+
+tick-1
+{
+ self->traceme = 1;
+}
+
+fbt:::
+/self->traceme/
+{
+ printf("The arguments are %u %u %u %u %u %u %u %u\n", arg0, arg1,
+ arg3, arg4, arg5, arg6, arg7, arg8);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d
new file mode 100644
index 0000000..78e107e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionentry.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: FBT provider function entry and exit test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:entry
+{
+ printf("Entering the ioctl function\n");
+}
+
+fbt::ioctl:return
+{
+ printf("Returning from ioctl function\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d
new file mode 100644
index 0000000..6d1b8a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.functionreturnvalue.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: Fbt provider return value verify test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:return
+{
+ printf("The function return value is stored in %u\n", arg1);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d
new file mode 100644
index 0000000..c2c7bf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.ioctlargs.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: FBT provider arguments scan test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:entry
+{
+ printf("Entering the ioctl function\n");
+ printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
+}
+
+fbt::ioctl:return
+{
+ printf("Returning from ioctl function\n");
+ printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d
new file mode 100644
index 0000000..be2c0d6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offset.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: FBT provider return value offset verification test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+BEGIN
+{
+ self->traceme = 1;
+}
+
+fbt::ioctl:entry
+{
+ printf("Entering the function\n");
+}
+
+fbt::ioctl:return
+{
+ printf("The offset = %u\n", arg0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d
new file mode 100644
index 0000000..240744b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.offsetzero.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: FBT provider argument 0 test
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:entry
+{
+ printf("Entering the ioctl function\n");
+ printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
+ exit(0);
+}
+
+fbt::ioctl:return
+{
+ printf("Returning from ioctl function\n");
+ printf("The few arguments are %u %u %u %u\n", arg0, arg1, arg2, arg3);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return.d
new file mode 100644
index 0000000..b269710e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: simple fbt provider return test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->traceme = 1;
+}
+
+fbt:::entry
+{
+ printf("Entering the function\n");
+}
+
+fbt:::return
+{
+ printf("Returning the function\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d
new file mode 100644
index 0000000..cadbaa0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.return0.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: simple fbt provider arg0 and probfunc print test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:return
+/arg1 == 0/
+{
+ printf("%s %x returned 0", probefunc, arg0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d
new file mode 100644
index 0000000..67ef106
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/fbtprovider/tst.tailcall.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION: simple fbt provider tailcall test.
+ *
+ * SECTION: FBT Provider/Probe arguments
+ */
+
+#pragma D option quiet
+#pragma D option statusrate=10ms
+
+fbt::ioctl:entry
+{
+ self->traceme = 1;
+}
+
+fbt:::entry
+/self->traceme/
+{
+ printf("called %s\n", probefunc);
+}
+
+fbt::ioctl:return
+/self->traceme/
+{
+ self->traceme = 0;
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_FUNC_UNDEF.progenyofbad1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
new file mode 100644
index 0000000..bfd1eed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * progenyof() should accept one argument - a pid
+ *
+ * SECTION: Actions and Subroutines/progenyof()
+ *
+ */
+
+
+BEGIN
+{
+ progencyof(1, 2);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_OP_VFPTR.badop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_OP_VFPTR.badop.d
new file mode 100644
index 0000000..d219bb1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_OP_VFPTR.badop.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * +=, -= must handle invalid variables.
+ *
+ * SECTION: Types, Operators, and Expressions/Assignment Operators
+ *
+ */
+
+
+int p;
+
+BEGIN
+{
+ p = 1;
+ p -= alloca(10);
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.chillbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.chillbadarg.d
new file mode 100644
index 0000000..08bd981
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.chillbadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * chill() should handle a bad argument.
+ *
+ * SECTION: Actions and Subroutines/chill()
+ *
+ */
+
+
+BEGIN
+{
+ chill("badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.copyoutbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.copyoutbadarg.d
new file mode 100644
index 0000000..5c02378
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.copyoutbadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * copyout() must handle invalid argument types.
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+
+BEGIN
+{
+ copyout("not_void_*", "not_uinptr_t", "not_size_t");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.mobadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.mobadarg.d
new file mode 100644
index 0000000..4df8d18
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.mobadarg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_owned() should handle an invalid argument passed.
+ *
+ * SECTION: Actions and Subroutines/mutex_owned()
+ *
+ */
+
+BEGIN
+{
+ mutex_owned("badarg");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.raisebadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.raisebadarg.d
new file mode 100644
index 0000000..a3336ef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.raisebadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * raise() should generate an error if any arguments are sent.
+ *
+ * SECTION: Actions and Subroutines/raise()
+ *
+ */
+
+
+BEGIN
+{
+ raise("badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d
new file mode 100644
index 0000000..9d4e40b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.tolower.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower(2152006));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d
new file mode 100644
index 0000000..2c1389b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_ARG.toupper.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(toupper(timestamp));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.allocanoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.allocanoarg.d
new file mode 100644
index 0000000..a2af00f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.allocanoarg.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * alloca() should handle no arguments as an error
+ *
+ * SECTION: Actions and Subroutines/alloca()
+ *
+ */
+
+#pragma D option quiet
+
+
+
+BEGIN
+{
+ ptr = alloca();
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.badbreakpoint.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.badbreakpoint.d
new file mode 100644
index 0000000..0cb567a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.badbreakpoint.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * breakpoint() should handle arguments passed as an error.
+ *
+ * SECTION: Actions and Subroutines/breakpoint()
+ *
+ */
+
+
+BEGIN
+{
+ breakpoint(1, 2);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoofew.d
new file mode 100644
index 0000000..a0018fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoofew.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * chill() should handle no arguments.
+ *
+ * SECTION: Actions and Subroutines/chill()
+ *
+ */
+
+
+BEGIN
+{
+ chill();
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoomany.d
new file mode 100644
index 0000000..f24e9ef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.chilltoomany.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * chill() should handle too many arguments.
+ *
+ * SECTION: Actions and Subroutines/chill()
+ *
+ */
+
+BEGIN
+{
+ chill(1000, 1000, 1000);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrbadarg.d
new file mode 100644
index 0000000..1f07814
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrbadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * copyoutstr() must handle invalid argument types.
+ *
+ * SECTION: Actions and Subroutines/copyoutstr()
+ *
+ */
+
+
+BEGIN
+{
+ copyoutstr("string", "not_uintptr_t");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrtoofew.d
new file mode 100644
index 0000000..e01868c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyoutstrtoofew.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Calling copyoutstr() with less than 2 arguments will generate an error
+ *
+ * SECTION: Actions and Subroutines/copyoutstr()
+ *
+ */
+
+
+BEGIN
+{
+ copyoutstr("string");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoofew.d
new file mode 100644
index 0000000..f3706f6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoofew.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Calling copyout() with less than 3 arguments will generate an error
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+
+BEGIN
+{
+ copyout(0, 20);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoomany.d
new file mode 100644
index 0000000..6fab90d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.copyouttoomany.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * copyout() should handle too many arguments passed.
+ *
+ * SECTION: Actions and Subroutines/copyin();
+ * Actions and Subroutines/copyinstr()
+ *
+ */
+
+
+BEGIN
+{
+ copyout((void *)3, (uintptr_t)1000, (size_t)1000, "toomany");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d
new file mode 100644
index 0000000..cf4dd5e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_owned() should handle too few args passed
+ *
+ * SECTION: Actions and Subroutines/mutex_owned()
+ *
+ */
+
+lockstat:kernel:mtx_lock:adaptive-acquire
+{
+ mutex_owned();
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d
new file mode 100644
index 0000000..6cc4be0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_owned() should handle too many args passed
+ *
+ * SECTION: Actions and Subroutines/mutex_owned()
+ *
+ */
+
+lockstat:kernel:mtx_lock:adaptive-acquire
+{
+ mutex_owned((kmutex_t *)arg0, 99);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtabadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtabadarg.d
new file mode 100644
index 0000000..6ad1e47
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtabadarg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_type_adaptive() should handle an invalid argument passed.
+ *
+ * SECTION: Actions and Subroutines/mutex_type_adaptive()
+ *
+ */
+
+
+BEGIN
+{
+ mutex_type_adaptive(trace());
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d
new file mode 100644
index 0000000..61d967a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * mutex_type_adaptive() should handle too few args passed
+ *
+ * SECTION: Actions and Subroutines/mutex_type_adaptive()
+ *
+ */
+
+
+lockstat:kernel:mtx_lock:adaptive-acquire
+{
+ mutex_type_adaptive();
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d
new file mode 100644
index 0000000..f2c3178
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_type_adaptive() should handle too many args passed
+ *
+ * SECTION: Actions and Subroutines/mutex_type_adaptive()
+ *
+ */
+
+
+lockstat:kernel:mtx_lock:adaptive-acquire
+{
+ mutex_type_adaptive((kmutex_t *)arg0, 99);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.panicbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.panicbadarg.d
new file mode 100644
index 0000000..87589b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.panicbadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * panic() should handle any argument passed as an error.
+ *
+ * SECTION: Actions and Subroutines/panic()
+ *
+ */
+
+
+BEGIN
+{
+ panic("badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.progenyofbad2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.progenyofbad2.d
new file mode 100644
index 0000000..51c8674
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.progenyofbad2.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * progenyof() should return an error if the argument is an
+ * incorrect type.
+ *
+ * SECTION: Actions and Subroutines/progenyof()
+ *
+ */
+
+
+BEGIN
+{
+ progenyof(trace());
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.stopbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.stopbadarg.d
new file mode 100644
index 0000000..8b60507
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.stopbadarg.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * stop() should generate an error if any arguments are sent.
+ *
+ * SECTION: Actions and Subroutines/stop()
+ *
+ */
+
+
+BEGIN
+{
+ stop("badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d
new file mode 100644
index 0000000..7d9c27f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolower.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower());
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d
new file mode 100644
index 0000000..afaa7f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.tolowertoomany.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower("dory", "eel", "roughy"));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d
new file mode 100644
index 0000000..9658f6a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.toupper.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(toupper());
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d
new file mode 100644
index 0000000..bee8697
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.touppertoomany.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(tolower("haino", "tylo"));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_STRINGOF_TYPE.badstringof.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_STRINGOF_TYPE.badstringof.d
new file mode 100644
index 0000000..fec5649
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_STRINGOF_TYPE.badstringof.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * stringof() accepts a scalar, pointer, or string
+ *
+ * SECTION: Types, Operators, and Expressions/Precedence
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%s", stringof (trace(0)));
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_VAR_UNDEF.badvar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_VAR_UNDEF.badvar.d
new file mode 100644
index 0000000..bb4fd2d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_VAR_UNDEF.badvar.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * +=, -= must handle invalid variables.
+ *
+ * SECTION: Types, Operators, and Expressions/Assignment Operators
+ *
+ */
+
+
+BEGIN
+{
+ p -= trace(0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca.d
new file mode 100644
index 0000000..572daa3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * memory allocated by alloca() is only valid within the clause
+ * it is allocated.
+ *
+ * SECTION: Actions and Subroutines/alloca()
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr = alloca(sizeof (int));
+}
+
+tick-1
+{
+ bcopy((void *)&`kmem_flags, ptr, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca2.d
new file mode 100644
index 0000000..fbbf8e2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badalloca2.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * alloca() cannot be used to "unconsume" scratch space memory by
+ * accepting a negative offset.
+ *
+ * SECTION: Actions and Subroutines/alloca()
+ *
+ */
+
+BEGIN
+{
+ ptr = alloca(10);
+ ptr = alloca(0xffffffffffffffff);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy.d
new file mode 100644
index 0000000..d7184b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * bcopy should not allow a copy to memory that is not scratch memory.
+ *
+ * SECTION: Actions and Subroutines/alloca();
+ * Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr = alloca(sizeof (int));
+
+ /* Attempt a copy from scratch memory to a kernel address */
+
+ bcopy(ptr, (void *)&`kmem_flags, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy1.d
new file mode 100644
index 0000000..c29eb2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy1.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should not copy from one memory location to another
+ * if the memory is not properly allocated
+ *
+ * SECTION: Actions and Subroutines/alloca();
+ * Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr = alloca(0);
+
+ /* Attempt to bcopy to scratch memory that isn't allocated */
+ bcopy((void *)&`kmem_flags, ptr, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy2.d
new file mode 100644
index 0000000..6d49e6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy2.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should not copy from one memory location to another
+ * if the memory is not properly allocated
+ *
+ * SECTION: Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+int *ptr;
+
+BEGIN
+{
+ /* Attempt to copy to non-scratch memory */
+
+ bcopy((void *)&`kmem_flags, ptr, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy3.d
new file mode 100644
index 0000000..c362caa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy3.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should not copy from one memory location to another
+ * if the memory is not properly allocated
+ *
+ * SECTION: Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ /* Attempt to copy to a NULL address */
+ bcopy((void *)&`kmem_flags, (void *)NULL, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy4.d
new file mode 100644
index 0000000..4148ae7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy4.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should not copy from one memory location to another
+ * if the source memory location is not valid.
+ *
+ * SECTION: Actions and Subroutines/alloca();
+ * Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ ptr = alloca(sizeof (int));
+
+ /* Attempt to copy from a NULL address */
+ bcopy((void *)NULL, ptr, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy5.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy5.d
new file mode 100644
index 0000000..a0cbd5d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy5.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should not copy from one memory location to another
+ * if the source memory location is not valid.
+ *
+ * SECTION: Actions and Subroutines/alloca();
+ * Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+int *badptr;
+
+BEGIN
+{
+ ptr = alloca(sizeof (int));
+
+ /* Attempt to copy from a invalid address */
+ bcopy(badptr, ptr, sizeof (int));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy6.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy6.d
new file mode 100644
index 0000000..3277014
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badbcopy6.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ bcopy("bad news", alloca(1), -1);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badchill.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badchill.d
new file mode 100644
index 0000000..b394a88
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.badchill.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ chill(200);
+ chill(((hrtime_t)1 << 63) - 1);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.chillbadarg.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.chillbadarg.ksh
new file mode 100644
index 0000000..98f04dd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.chillbadarg.ksh
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+# ident "%Z%%M% %I% %E% SMI"
+
+dtrace_script()
+{
+
+ $dtrace -w -s /dev/stdin <<EOF
+
+ /*
+ * ASSERTION:
+ * Verify that chill() refuses args greater than
+ * 500 milliseconds.
+ *
+ * SECTION: Actions and Subroutines/chill()
+ *
+ */
+
+ BEGIN
+ {
+ chill(500000001);
+ exit(1);
+ }
+
+ ERROR
+ {
+ exit(1)
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+dtrace_script &
+child=$!
+
+wait $child
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyout.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyout.d
new file mode 100644
index 0000000..6b9db3b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyout.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * copyout() should handle invalid args.
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ i = 3;
+ copyout((void *)i, 0, 5);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutbadaddr.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutbadaddr.ksh
new file mode 100644
index 0000000..de5c47d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutbadaddr.ksh
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+# ident "%Z%%M% %I% %E% SMI"
+
+
+dtrace_script()
+{
+
+ $dtrace -w -s /dev/stdin <<EOF
+
+ /*
+ * ASSERTION:
+ * Verify that copyout() handles bad addresses.
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+ BEGIN
+ {
+ ptr = alloca(sizeof (char *));
+ copyinto(curpsinfo->pr_envp, sizeof (char *), ptr);
+ copyout(ptr, 0, sizeof (char *));
+ }
+
+ ERROR
+ {
+ exit(1)
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+dtrace_script &
+child=$!
+
+wait $child
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutstrbadaddr.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutstrbadaddr.ksh
new file mode 100644
index 0000000..181702b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.copyoutstrbadaddr.ksh
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+# ident "%Z%%M% %I% %E% SMI"
+
+
+dtrace_script()
+{
+
+ $dtrace -w -s /dev/stdin <<EOF
+
+ /*
+ * ASSERTION:
+ * Verify that copyout() handles bad addresses.
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+ BEGIN
+ {
+ ptr = alloca(sizeof (char *));
+ copyinto(curpsinfo->pr_envp, sizeof (char *), ptr);
+ copyout(ptr, 0, sizeof (char *));
+ }
+
+ ERROR
+ {
+ exit(1)
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+dtrace_script &
+child=$!
+
+wait $child
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoa6badaddr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoa6badaddr.d
new file mode 100644
index 0000000..81ce643
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoa6badaddr.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+struct in6_addr *ip6a;
+
+BEGIN
+{
+ ip6a = 0;
+
+ printf("%s\n", inet_ntop(AF_INET6, ip6a));
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoabadaddr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoabadaddr.d
new file mode 100644
index 0000000..3f0d8e45
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntoabadaddr.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+ipaddr_t *ip4a;
+
+BEGIN
+{
+ ip4a = 0;
+
+ printf("%s\n", inet_ntoa(ip4a));
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadaddr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadaddr.d
new file mode 100644
index 0000000..74ce760
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadaddr.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+ipaddr_t *ip4a;
+
+BEGIN
+{
+ ip4a = 0;
+
+ printf("%s\n", inet_ntop(AF_INET, ip4a));
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadarg.d
new file mode 100644
index 0000000..2731385
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.inet_ntopbadarg.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+ipaddr_t *ip4a;
+
+BEGIN
+{
+ this->buf4a = alloca(sizeof (ipaddr_t));
+ ip4a = this->buf4a;
+ *ip4a = htonl(0xc0a80117);
+
+ printf("%s\n", inet_ntop(-1, ip4a));
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.badfreopen.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.badfreopen.ksh
new file mode 100644
index 0000000..72f6b87
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.badfreopen.ksh
@@ -0,0 +1,102 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -wq -o $tmpfile -s /dev/stdin 2> $errfile <<EOF
+ BEGIN
+ {
+ /*
+ * All of these should fail...
+ */
+ freopen("..");
+ freopen("%s", ".");
+ freopen("%c%c", '.', '.');
+ freopen("%c", '.');
+
+ /*
+ * ...so stdout should still be open here.
+ */
+ printf("%d", ++i);
+
+ freopen("%s%s", ".", ".");
+ freopen("%s%s", ".", ".");
+
+ printf("%d", ++i);
+ }
+
+ BEGIN
+ /i == 2/
+ {
+ /*
+ * ...and here.
+ */
+ printf("%d\n", ++i);
+ exit(0);
+ }
+
+ BEGIN
+ {
+ exit(1);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+tmpfile=/tmp/tst.badfreopen.$$
+errfile=/tmp/tst.badfreopen.$$.stderr
+
+script
+status=$?
+
+if [ "$status" -eq 0 ]; then
+ i=`cat $tmpfile`
+
+ if [[ $i != "123" ]]; then
+ echo "$0: unexpected contents in $tmpfile: " \
+ "expected 123, found $i"
+ status=100
+ fi
+
+ i=`wc -l $errfile | nawk '{ print $1 }'`
+
+ if [ "$i" -lt 6 ]; then
+ echo "$0: expected at least 6 lines of stderr, found $i lines"
+ status=101
+ fi
+else
+ cat $errfile > /dev/fd/2
+fi
+
+rm $tmpfile $errfile
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d
new file mode 100644
index 0000000..6fb996c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+/*
+ * This test verifies that the basename() and dirname() functions are working
+ * properly. Note that the output of this is a ksh script. When run,
+ * it will give no output if the output is correct.
+ */
+BEGIN
+{
+ dir[i++] = "/foo/bar/baz";
+ dir[i++] = "/foo/bar///baz/";
+ dir[i++] = "/foo/bar/baz/";
+ dir[i++] = "/foo/bar/baz//";
+ dir[i++] = "/foo/bar/baz/.";
+ dir[i++] = "/foo/bar/baz/./";
+ dir[i++] = "/foo/bar/baz/.//";
+ dir[i++] = "foo/bar/baz/";
+ dir[i++] = "/";
+ dir[i++] = "./";
+ dir[i++] = "//";
+ dir[i++] = "/.";
+ dir[i++] = "/./";
+ dir[i++] = "/./.";
+ dir[i++] = "/.//";
+ dir[i++] = ".";
+ dir[i++] = "f";
+ dir[i++] = "f/";
+ dir[i++] = "/////";
+ dir[i++] = "";
+
+ end = i;
+ i = 0;
+
+ printf("#!/usr/bin/ksh\n\n");
+}
+
+tick-1ms
+/i < end/
+{
+ printf("if [ `basename \"%s\"` != \"%s\" ]; then\n",
+ dir[i], basename(dir[i]));
+ printf(" echo \"basename(\\\"%s\\\") is \\\"%s\\\"; ",
+ dir[i], basename(dir[i]));
+ printf("expected \\\"`basename \"%s\"`\"\\\"\n", dir[i]);
+ printf("fi\n\n");
+ printf("if [ `dirname \"%s\"` != \"%s\" ]; then\n",
+ dir[i], dirname(dir[i]));
+ printf(" echo \"dirname(\\\"%s\\\") is \\\"%s\\\"; ",
+ dir[i], dirname(dir[i]));
+ printf("expected \\\"`dirname \"%s\"`\"\\\"\n", dir[i]);
+ printf("fi\n\n");
+ i++;
+}
+
+tick-1ms
+/i == end/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d.out
new file mode 100644
index 0000000..e16541a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.basename.d.out
@@ -0,0 +1,163 @@
+#!/usr/bin/ksh
+
+if [ `basename "/foo/bar/baz"` != "baz" ]; then
+ echo "basename(\"/foo/bar/baz\") is \"baz\"; expected \"`basename "/foo/bar/baz"`"\"
+fi
+
+if [ `dirname "/foo/bar/baz"` != "/foo/bar" ]; then
+ echo "dirname(\"/foo/bar/baz\") is \"/foo/bar\"; expected \"`dirname "/foo/bar/baz"`"\"
+fi
+
+if [ `basename "/foo/bar///baz/"` != "baz" ]; then
+ echo "basename(\"/foo/bar///baz/\") is \"baz\"; expected \"`basename "/foo/bar///baz/"`"\"
+fi
+
+if [ `dirname "/foo/bar///baz/"` != "/foo/bar" ]; then
+ echo "dirname(\"/foo/bar///baz/\") is \"/foo/bar\"; expected \"`dirname "/foo/bar///baz/"`"\"
+fi
+
+if [ `basename "/foo/bar/baz/"` != "baz" ]; then
+ echo "basename(\"/foo/bar/baz/\") is \"baz\"; expected \"`basename "/foo/bar/baz/"`"\"
+fi
+
+if [ `dirname "/foo/bar/baz/"` != "/foo/bar" ]; then
+ echo "dirname(\"/foo/bar/baz/\") is \"/foo/bar\"; expected \"`dirname "/foo/bar/baz/"`"\"
+fi
+
+if [ `basename "/foo/bar/baz//"` != "baz" ]; then
+ echo "basename(\"/foo/bar/baz//\") is \"baz\"; expected \"`basename "/foo/bar/baz//"`"\"
+fi
+
+if [ `dirname "/foo/bar/baz//"` != "/foo/bar" ]; then
+ echo "dirname(\"/foo/bar/baz//\") is \"/foo/bar\"; expected \"`dirname "/foo/bar/baz//"`"\"
+fi
+
+if [ `basename "/foo/bar/baz/."` != "." ]; then
+ echo "basename(\"/foo/bar/baz/.\") is \".\"; expected \"`basename "/foo/bar/baz/."`"\"
+fi
+
+if [ `dirname "/foo/bar/baz/."` != "/foo/bar/baz" ]; then
+ echo "dirname(\"/foo/bar/baz/.\") is \"/foo/bar/baz\"; expected \"`dirname "/foo/bar/baz/."`"\"
+fi
+
+if [ `basename "/foo/bar/baz/./"` != "." ]; then
+ echo "basename(\"/foo/bar/baz/./\") is \".\"; expected \"`basename "/foo/bar/baz/./"`"\"
+fi
+
+if [ `dirname "/foo/bar/baz/./"` != "/foo/bar/baz" ]; then
+ echo "dirname(\"/foo/bar/baz/./\") is \"/foo/bar/baz\"; expected \"`dirname "/foo/bar/baz/./"`"\"
+fi
+
+if [ `basename "/foo/bar/baz/.//"` != "." ]; then
+ echo "basename(\"/foo/bar/baz/.//\") is \".\"; expected \"`basename "/foo/bar/baz/.//"`"\"
+fi
+
+if [ `dirname "/foo/bar/baz/.//"` != "/foo/bar/baz" ]; then
+ echo "dirname(\"/foo/bar/baz/.//\") is \"/foo/bar/baz\"; expected \"`dirname "/foo/bar/baz/.//"`"\"
+fi
+
+if [ `basename "foo/bar/baz/"` != "baz" ]; then
+ echo "basename(\"foo/bar/baz/\") is \"baz\"; expected \"`basename "foo/bar/baz/"`"\"
+fi
+
+if [ `dirname "foo/bar/baz/"` != "foo/bar" ]; then
+ echo "dirname(\"foo/bar/baz/\") is \"foo/bar\"; expected \"`dirname "foo/bar/baz/"`"\"
+fi
+
+if [ `basename "/"` != "/" ]; then
+ echo "basename(\"/\") is \"/\"; expected \"`basename "/"`"\"
+fi
+
+if [ `dirname "/"` != "/" ]; then
+ echo "dirname(\"/\") is \"/\"; expected \"`dirname "/"`"\"
+fi
+
+if [ `basename "./"` != "." ]; then
+ echo "basename(\"./\") is \".\"; expected \"`basename "./"`"\"
+fi
+
+if [ `dirname "./"` != "." ]; then
+ echo "dirname(\"./\") is \".\"; expected \"`dirname "./"`"\"
+fi
+
+if [ `basename "//"` != "/" ]; then
+ echo "basename(\"//\") is \"/\"; expected \"`basename "//"`"\"
+fi
+
+if [ `dirname "//"` != "/" ]; then
+ echo "dirname(\"//\") is \"/\"; expected \"`dirname "//"`"\"
+fi
+
+if [ `basename "/."` != "." ]; then
+ echo "basename(\"/.\") is \".\"; expected \"`basename "/."`"\"
+fi
+
+if [ `dirname "/."` != "/" ]; then
+ echo "dirname(\"/.\") is \"/\"; expected \"`dirname "/."`"\"
+fi
+
+if [ `basename "/./"` != "." ]; then
+ echo "basename(\"/./\") is \".\"; expected \"`basename "/./"`"\"
+fi
+
+if [ `dirname "/./"` != "/" ]; then
+ echo "dirname(\"/./\") is \"/\"; expected \"`dirname "/./"`"\"
+fi
+
+if [ `basename "/./."` != "." ]; then
+ echo "basename(\"/./.\") is \".\"; expected \"`basename "/./."`"\"
+fi
+
+if [ `dirname "/./."` != "/." ]; then
+ echo "dirname(\"/./.\") is \"/.\"; expected \"`dirname "/./."`"\"
+fi
+
+if [ `basename "/.//"` != "." ]; then
+ echo "basename(\"/.//\") is \".\"; expected \"`basename "/.//"`"\"
+fi
+
+if [ `dirname "/.//"` != "/" ]; then
+ echo "dirname(\"/.//\") is \"/\"; expected \"`dirname "/.//"`"\"
+fi
+
+if [ `basename "."` != "." ]; then
+ echo "basename(\".\") is \".\"; expected \"`basename "."`"\"
+fi
+
+if [ `dirname "."` != "." ]; then
+ echo "dirname(\".\") is \".\"; expected \"`dirname "."`"\"
+fi
+
+if [ `basename "f"` != "f" ]; then
+ echo "basename(\"f\") is \"f\"; expected \"`basename "f"`"\"
+fi
+
+if [ `dirname "f"` != "." ]; then
+ echo "dirname(\"f\") is \".\"; expected \"`dirname "f"`"\"
+fi
+
+if [ `basename "f/"` != "f" ]; then
+ echo "basename(\"f/\") is \"f\"; expected \"`basename "f/"`"\"
+fi
+
+if [ `dirname "f/"` != "." ]; then
+ echo "dirname(\"f/\") is \".\"; expected \"`dirname "f/"`"\"
+fi
+
+if [ `basename "/////"` != "/" ]; then
+ echo "basename(\"/////\") is \"/\"; expected \"`basename "/////"`"\"
+fi
+
+if [ `dirname "/////"` != "/" ]; then
+ echo "dirname(\"/////\") is \"/\"; expected \"`dirname "/////"`"\"
+fi
+
+if [ `basename ""` != "." ]; then
+ echo "basename(\"\") is \".\"; expected \"`basename ""`"\"
+fi
+
+if [ `dirname ""` != "." ]; then
+ echo "dirname(\"\") is \".\"; expected \"`dirname ""`"\"
+fi
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.bcopy.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.bcopy.d
new file mode 100644
index 0000000..8501ff4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.bcopy.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * bcopy should copy from one memory location to another
+ *
+ * SECTION: Actions and Subroutines/alloca();
+ * Actions and Subroutines/bcopy()
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr = alloca(sizeof (int));
+ bcopy((void *)&`kmem_flags, ptr, sizeof (int));
+ intp = (int *)ptr;
+ ret = (`kmem_flags == *intp) ? 0 : 1;
+}
+
+tick-1
+/ret == 0/
+{
+ exit(0);
+}
+
+tick-1
+/ret == 1/
+{
+ printf("memory address contained 0x%x, expected 0x%x\n",
+ *intp, `kmem_flags);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.chill.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.chill.ksh
new file mode 100644
index 0000000..aae1c68
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.chill.ksh
@@ -0,0 +1,77 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+dtrace_script()
+{
+
+ $dtrace -w -s /dev/stdin <<EOF
+
+ /*
+ * ASSERTION:
+ * Positive test of chill()
+ *
+ * SECTION: Actions and Subroutines/chill()
+ *
+ * NOTES: This test does no verification - it's not possible. So,
+ * we just run this and make sure it runs.
+ */
+
+ BEGIN
+ {
+ i = 0;
+ }
+
+ syscall:::entry
+ /i <= 5/
+ {
+ chill(100000000);
+ i++;
+ }
+
+ syscall:::entry
+ /i > 5/
+ {
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+dtrace_script &
+child=$!
+
+wait $child
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d
new file mode 100644
index 0000000..2f05418
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ path[i++] = "/foo/bar/baz";
+ path[i++] = "/foo/bar///baz/";
+ path[i++] = "/foo/bar/baz/";
+ path[i++] = "/foo/bar/baz//";
+ path[i++] = "/foo/bar/baz/.";
+ path[i++] = "/foo/bar/baz/./";
+ path[i++] = "/foo/bar/../../baz/.//";
+ path[i++] = "foo/bar/./././././baz/";
+ path[i++] = "/foo/bar/baz/../../../../../../";
+ path[i++] = "/../../../../../../";
+ path[i++] = "/./";
+ path[i++] = "/foo/bar/baz/../../bop/bang/../../bar/baz/";
+ path[i++] = "./";
+ path[i++] = "//";
+ path[i++] = "/.";
+ path[i++] = "/./";
+ path[i++] = "/./.";
+ path[i++] = "/.//";
+ path[i++] = ".";
+ path[i++] = "/////";
+ path[i++] = "";
+
+ end = i;
+ i = 0;
+}
+
+tick-1ms
+/i < end/
+{
+ printf("cleanpath(\"%s\") = \"%s\"\n", path[i], cleanpath(path[i]));
+ i++;
+}
+
+tick-1ms
+/i == end/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d.out
new file mode 100644
index 0000000..b8bdc09
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.cleanpath.d.out
@@ -0,0 +1,22 @@
+cleanpath("/foo/bar/baz") = "/foo/bar/baz"
+cleanpath("/foo/bar///baz/") = "/foo/bar/baz/"
+cleanpath("/foo/bar/baz/") = "/foo/bar/baz/"
+cleanpath("/foo/bar/baz//") = "/foo/bar/baz/"
+cleanpath("/foo/bar/baz/.") = "/foo/bar/baz/."
+cleanpath("/foo/bar/baz/./") = "/foo/bar/baz/"
+cleanpath("/foo/bar/../../baz/.//") = "/baz/"
+cleanpath("foo/bar/./././././baz/") = "foo/bar/baz/"
+cleanpath("/foo/bar/baz/../../../../../../") = "/"
+cleanpath("/../../../../../../") = "/"
+cleanpath("/./") = "/"
+cleanpath("/foo/bar/baz/../../bop/bang/../../bar/baz/") = "/foo/bar/baz/"
+cleanpath("./") = "./"
+cleanpath("//") = "/"
+cleanpath("/.") = "/."
+cleanpath("/./") = "/"
+cleanpath("/./.") = "/."
+cleanpath("/.//") = "/"
+cleanpath(".") = "."
+cleanpath("/////") = "/"
+cleanpath("") = ""
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyin.d
new file mode 100644
index 0000000..186b974
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyin.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * This D ditty tests the ability to perform both copyin and copyinstr. We
+ * grab the value or pr_envp, read the first pointer from the user stack,
+ * and then copyinstr the first environment variable and print it.
+ *
+ * SECTION: Actions and Subroutines/copyin();
+ * Actions and Subroutines/copyinstr();
+ * User Process Tracing/copyin() and copyinstr()
+ */
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_ILP32/
+{
+ envp = *(uint32_t *)copyin(curpsinfo->pr_envp, sizeof (uint32_t));
+ printf("envp[0] = \"%s\"", copyinstr(envp));
+ exit(0);
+}
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_LP64/
+{
+ envp = *(uint64_t *)copyin(curpsinfo->pr_envp, sizeof (uint64_t));
+ printf("envp[0] = \"%s\"", copyinstr(envp));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyinto.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyinto.d
new file mode 100644
index 0000000..c282e61
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.copyinto.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * test copyinto by copying the first string of the user's
+ * environment.
+ *
+ * SECTION: Actions and Subroutines/copyinto()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_ILP32/
+{
+ envp = alloca(sizeof (uint32_t));
+ copyinto(curpsinfo->pr_envp, sizeof (uint32_t), envp);
+ printf("envp[0] = \"%s\"", copyinstr(*(uint32_t *)envp));
+ exit(0);
+}
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_LP64/
+{
+ envp = alloca(sizeof (uint64_t));
+ copyinto(curpsinfo->pr_envp, sizeof (uint64_t), envp);
+ printf("envp[0] = \"%s\"", copyinstr(*(uint64_t *)envp));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ddi_pathname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ddi_pathname.d
new file mode 100644
index 0000000..3716d0c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ddi_pathname.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ this->dev = (struct dev_info *)alloca(sizeof (struct dev_info));
+ this->minor1 =
+ (struct ddi_minor_data *)alloca(sizeof (struct ddi_minor_data));
+ this->minor2 =
+ (struct ddi_minor_data *)alloca(sizeof (struct ddi_minor_data));
+ this->minor3 =
+ (struct ddi_minor_data *)alloca(sizeof (struct ddi_minor_data));
+
+ this->minor1->d_minor.dev = 0;
+ this->minor1->next = this->minor2;
+
+ this->minor2->d_minor.dev = 0;
+ this->minor2->next = this->minor3;
+
+ this->minor3->d_minor.dev = 0;
+ this->minor3->next = this->minor1;
+
+ this->dev->devi_minor = this->minor1;
+ trace(ddi_pathname(this->dev, 1));
+}
+
+ERROR
+/arg4 == DTRACEFLT_ILLOP/
+{
+ exit(0);
+}
+
+ERROR
+/arg4 != DTRACEFLT_ILLOP/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.default.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.default.d
new file mode 100644
index 0000000..c4a4e4f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.default.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Verify that empty clauses are OK.
+ *
+ * SECTION: Actions and Subroutines/Default Action
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 1;
+
+}
+
+syscall:::entry
+{
+
+
+}
+
+tick-1
+/i != 0/
+{
+ exit(0);
+}
+
+
+END
+{
+
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.freopen.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.freopen.ksh
new file mode 100644
index 0000000..f87d6e1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.freopen.ksh
@@ -0,0 +1,111 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -wq -o $tmpfile -s /dev/stdin $tmpfile <<EOF
+ BEGIN
+ {
+ i = 0;
+ }
+
+ tick-10ms
+ {
+ freopen("%s.%d", \$\$1, i);
+ printf("%d\n", i)
+ }
+
+ tick-10ms
+ /++i == $iter/
+ {
+ freopen("");
+ printf("%d\n", i);
+ exit(0);
+ }
+EOF
+}
+
+cleanup()
+{
+ let i=0
+
+ if [ -f $tmpfile ]; then
+ rm $tmpfile
+ fi
+
+ while [ "$i" -lt "$iter" ]; do
+ if [ -f $tmpfile.$i ]; then
+ rm $tmpfile.$i
+ fi
+ let i=i+1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+tmpfile=/tmp/tst.freopen.$$
+iter=20
+
+script
+status=$?
+
+let i=0
+
+if [ -f $tmpfile.$iter ]; then
+ echo "$0: did not expect to find file: $tmpfile.$iter"
+ cleanup
+ exit 100
+fi
+
+mv $tmpfile $tmpfile.$iter
+let iter=iter+1
+
+while [ "$i" -lt "$iter" ]; do
+ if [ ! -f $tmpfile.$i ]; then
+ echo "$0: did not find expected file: $tmpfile.$i"
+ cleanup
+ exit 101
+ fi
+
+ j=`cat $tmpfile.$i`
+
+ if [ "$i" -ne "$j" ]; then
+ echo "$0: unexpected contents in $tmpfile.$i: " \
+ "expected $i, found $j"
+ cleanup
+ exit 102
+ fi
+
+ rm $tmpfile.$i
+ let i=i+1
+done
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh
new file mode 100644
index 0000000..b02af07
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -q -o $tmpfile -s /dev/stdin <<EOF
+ tick-10ms
+ {
+ printf("%d\n", i++);
+ }
+
+ tick-10ms
+ /i == 10/
+ {
+ ftruncate();
+ }
+
+ tick-10ms
+ /i == 20/
+ {
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+tmpfile=/tmp/tst.ftruncate.$$
+
+script
+status=$?
+
+cat $tmpfile
+rm $tmpfile
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh.out
new file mode 100644
index 0000000..3360fd2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.ftruncate.ksh.out
@@ -0,0 +1,11 @@
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.hton.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.hton.d
new file mode 100644
index 0000000..4908251
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.hton.d
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test network byte-ordering routines.
+ */
+
+#if defined(__amd64__) || defined(__i386__)
+#define _LITTLE_ENDIAN
+#endif
+
+BEGIN
+{
+ before[0] = 0x1122LL;
+ before[1] = 0x11223344LL;
+ before[2] = 0x1122334455667788LL;
+
+#ifdef _LITTLE_ENDIAN
+ after[0] = 0x2211LL;
+ after[1] = 0x44332211LL;
+ after[2] = 0x8877665544332211LL;
+#else
+ after[0] = 0x1122LL;
+ after[1] = 0x11223344LL;
+ after[2] = 0x1122334455667788LL;
+#endif
+}
+
+BEGIN
+/after[0] != htons(before[0])/
+{
+ printf("%x rather than %x", htons(before[0]), after[0]);
+ exit(1);
+}
+
+BEGIN
+/after[0] != ntohs(before[0])/
+{
+ printf("%x rather than %x", ntohs(before[0]), after[0]);
+ exit(1);
+}
+
+BEGIN
+/after[1] != htonl(before[1])/
+{
+ printf("%x rather than %x", htonl(before[1]), after[1]);
+ exit(1);
+}
+
+BEGIN
+/after[1] != ntohl(before[1])/
+{
+ printf("%x rather than %x", ntohl(before[1]), after[1]);
+ exit(1);
+}
+
+BEGIN
+/after[2] != htonll(before[2])/
+{
+ printf("%x rather than %x", htonll(before[2]), after[2]);
+ exit(1);
+}
+
+BEGIN
+/after[2] != ntohll(before[2])/
+{
+ printf("%x rather than %x", ntohll(before[2]), after[2]);
+ exit(1);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d
new file mode 100644
index 0000000..1ec9697
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d
@@ -0,0 +1,226 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+struct {
+ string str;
+ string substr;
+ int haspos;
+ int position;
+} command[int];
+
+int i;
+
+BEGIN
+{
+ command[i].str = "foobarbaz";
+ command[i].substr = "barbaz";
+ i++;
+
+ command[i].str = "foofoofoo";
+ command[i].substr = "foo";
+ i++;
+
+ command[i].str = "boofoofoo";
+ command[i].substr = "foo";
+ i++;
+
+ command[i].str = "foobarbaz";
+ command[i].substr = "barbazzy";
+ i++;
+
+ command[i].str = "foobar";
+ command[i].substr = "foobar";
+ i++;
+
+ command[i].str = "foobar";
+ command[i].substr = "foobarbaz";
+ i++;
+
+ command[i].str = "";
+ command[i].substr = "foobar";
+ i++;
+
+ command[i].str = "foobar";
+ command[i].substr = "";
+ i++;
+
+ command[i].str = "";
+ command[i].substr = "";
+ i++;
+
+ command[i].str = "foo";
+ command[i].substr = "";
+ i++;
+
+ end = j = k = 0;
+ printf("#!/usr/bin/perl\n\nBEGIN {\n");
+}
+
+tick-1ms
+/j < i && end == 0/
+{
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = -400;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = -1;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = 0;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = strlen(command[j].str) / 2;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = strlen(command[j].str);
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = strlen(command[j].str) + 1;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = strlen(command[j].str) + 2;
+ k++;
+
+ command[i + k].str = command[j].str;
+ command[i + k].substr = command[j].substr;
+ command[i + k].haspos = 1;
+ command[i + k].position = 400;
+ k++;
+
+ j++;
+}
+
+tick-1ms
+/j == i && end == 0/
+{
+ end = k;
+ i = 0;
+}
+
+tick-1ms
+/end != 0 && i < end && !command[i].haspos/
+{
+ this->result = index(command[i].str, command[i].substr);
+
+ printf("\tif (index(\"%s\", \"%s\") != %d) {\n",
+ command[i].str, command[i].substr, this->result);
+ printf("\t\tprintf(\"perl => index(\\\"%s\\\", \\\"%s\\\") = ",
+ command[i].str, command[i].substr);
+ printf("%%d\\n\",\n\t\t index(\"%s\", \"%s\"));\n",
+ command[i].str, command[i].substr);
+ printf("\t\tprintf(\" D => index(\\\"%s\\\", \\\"%s\\\") = ",
+ command[i].str, command[i].substr);
+ printf("%d\\n\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/end != 0 && i < end && !command[i].haspos/
+{
+ this->result = rindex(command[i].str, command[i].substr);
+
+ printf("\tif (rindex(\"%s\", \"%s\") != %d) {\n",
+ command[i].str, command[i].substr, this->result);
+ printf("\t\tprintf(\"perl => rindex(\\\"%s\\\", \\\"%s\\\") = ",
+ command[i].str, command[i].substr);
+ printf("%%d\\n\",\n\t\t rindex(\"%s\", \"%s\"));\n",
+ command[i].str, command[i].substr);
+ printf("\t\tprintf(\" D => rindex(\\\"%s\\\", \\\"%s\\\") = ",
+ command[i].str, command[i].substr);
+ printf("%d\\n\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/end != 0 && i < end && command[i].haspos/
+{
+ this->result = index(command[i].str,
+ command[i].substr, command[i].position);
+
+ printf("\tif (index(\"%s\", \"%s\", %d) != %d) {\n", command[i].str,
+ command[i].substr, command[i].position, this->result);
+ printf("\t\tprintf(\"perl => index(\\\"%s\\\", \\\"%s\\\", %d) = ",
+ command[i].str, command[i].substr, command[i].position);
+ printf("%%d\\n\",\n\t\t index(\"%s\", \"%s\", %d));\n",
+ command[i].str, command[i].substr, command[i].position);
+ printf("\t\tprintf(\" D => index(\\\"%s\\\", \\\"%s\\\", %d) = ",
+ command[i].str, command[i].substr, command[i].position);
+ printf("%d\\n\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/end != 0 && i < end && command[i].haspos/
+{
+ this->result = rindex(command[i].str,
+ command[i].substr, command[i].position);
+
+ printf("\tif (rindex(\"%s\", \"%s\", %d) != %d) {\n", command[i].str,
+ command[i].substr, command[i].position, this->result);
+ printf("\t\tprintf(\"perl => rindex(\\\"%s\\\", \\\"%s\\\", %d) = ",
+ command[i].str, command[i].substr, command[i].position);
+ printf("%%d\\n\",\n\t\t rindex(\"%s\", \"%s\", %d));\n",
+ command[i].str, command[i].substr, command[i].position);
+ printf("\t\tprintf(\" D => rindex(\\\"%s\\\", \\\"%s\\\", %d) = ",
+ command[i].str, command[i].substr, command[i].position);
+ printf("%d\\n\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/end != 0 && ++i == end/
+{
+ printf("\texit($failed);\n}\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d.out
new file mode 100644
index 0000000..276576c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d.out
@@ -0,0 +1,1126 @@
+#!/usr/perl5/bin/perl
+
+BEGIN {
+ if (index("foobarbaz", "barbaz") != 3) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\") = %d\n",
+ index("foobarbaz", "barbaz"));
+ printf(" D => index(\"foobarbaz\", \"barbaz\") = 3\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz") != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\") = %d\n",
+ rindex("foobarbaz", "barbaz"));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\") = 3\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo") != 0) {
+ printf("perl => index(\"foofoofoo\", \"foo\") = %d\n",
+ index("foofoofoo", "foo"));
+ printf(" D => index(\"foofoofoo\", \"foo\") = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo") != 6) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\") = %d\n",
+ rindex("foofoofoo", "foo"));
+ printf(" D => rindex(\"foofoofoo\", \"foo\") = 6\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo") != 3) {
+ printf("perl => index(\"boofoofoo\", \"foo\") = %d\n",
+ index("boofoofoo", "foo"));
+ printf(" D => index(\"boofoofoo\", \"foo\") = 3\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo") != 6) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\") = %d\n",
+ rindex("boofoofoo", "foo"));
+ printf(" D => rindex(\"boofoofoo\", \"foo\") = 6\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy") != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\") = %d\n",
+ index("foobarbaz", "barbazzy"));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\") = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy") != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\") = %d\n",
+ rindex("foobarbaz", "barbazzy"));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\") = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar") != 0) {
+ printf("perl => index(\"foobar\", \"foobar\") = %d\n",
+ index("foobar", "foobar"));
+ printf(" D => index(\"foobar\", \"foobar\") = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar") != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\") = %d\n",
+ rindex("foobar", "foobar"));
+ printf(" D => rindex(\"foobar\", \"foobar\") = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz") != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\") = %d\n",
+ index("foobar", "foobarbaz"));
+ printf(" D => index(\"foobar\", \"foobarbaz\") = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz") != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\") = %d\n",
+ rindex("foobar", "foobarbaz"));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\") = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar") != -1) {
+ printf("perl => index(\"\", \"foobar\") = %d\n",
+ index("", "foobar"));
+ printf(" D => index(\"\", \"foobar\") = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar") != -1) {
+ printf("perl => rindex(\"\", \"foobar\") = %d\n",
+ rindex("", "foobar"));
+ printf(" D => rindex(\"\", \"foobar\") = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "") != 0) {
+ printf("perl => index(\"foobar\", \"\") = %d\n",
+ index("foobar", ""));
+ printf(" D => index(\"foobar\", \"\") = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "") != 6) {
+ printf("perl => rindex(\"foobar\", \"\") = %d\n",
+ rindex("foobar", ""));
+ printf(" D => rindex(\"foobar\", \"\") = 6\n");
+ $failed++;
+ }
+
+ if (index("", "") != 0) {
+ printf("perl => index(\"\", \"\") = %d\n",
+ index("", ""));
+ printf(" D => index(\"\", \"\") = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "") != 0) {
+ printf("perl => rindex(\"\", \"\") = %d\n",
+ rindex("", ""));
+ printf(" D => rindex(\"\", \"\") = 0\n");
+ $failed++;
+ }
+
+ if (index("foo", "") != 0) {
+ printf("perl => index(\"foo\", \"\") = %d\n",
+ index("foo", ""));
+ printf(" D => index(\"foo\", \"\") = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foo", "") != 3) {
+ printf("perl => rindex(\"foo\", \"\") = %d\n",
+ rindex("foo", ""));
+ printf(" D => rindex(\"foo\", \"\") = 3\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", -400) != 3) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", -400) = %d\n",
+ index("foobarbaz", "barbaz", -400));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", -400) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", -400) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", -400) = %d\n",
+ rindex("foobarbaz", "barbaz", -400));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", -1) != 3) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", -1) = %d\n",
+ index("foobarbaz", "barbaz", -1));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", -1) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", -1) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", -1) = %d\n",
+ rindex("foobarbaz", "barbaz", -1));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 0) != 3) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 0) = %d\n",
+ index("foobarbaz", "barbaz", 0));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 0) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 0) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 0) = %d\n",
+ rindex("foobarbaz", "barbaz", 0));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 4) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 4) = %d\n",
+ index("foobarbaz", "barbaz", 4));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 4) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 4) != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 4) = %d\n",
+ rindex("foobarbaz", "barbaz", 4));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 4) = 3\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 9) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 9) = %d\n",
+ index("foobarbaz", "barbaz", 9));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 9) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 9) != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 9) = %d\n",
+ rindex("foobarbaz", "barbaz", 9));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 9) = 3\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 10) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 10) = %d\n",
+ index("foobarbaz", "barbaz", 10));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 10) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 10) != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 10) = %d\n",
+ rindex("foobarbaz", "barbaz", 10));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 10) = 3\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 11) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 11) = %d\n",
+ index("foobarbaz", "barbaz", 11));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 11) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 11) != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 11) = %d\n",
+ rindex("foobarbaz", "barbaz", 11));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 11) = 3\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbaz", 400) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbaz\", 400) = %d\n",
+ index("foobarbaz", "barbaz", 400));
+ printf(" D => index(\"foobarbaz\", \"barbaz\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbaz", 400) != 3) {
+ printf("perl => rindex(\"foobarbaz\", \"barbaz\", 400) = %d\n",
+ rindex("foobarbaz", "barbaz", 400));
+ printf(" D => rindex(\"foobarbaz\", \"barbaz\", 400) = 3\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", -400) != 0) {
+ printf("perl => index(\"foofoofoo\", \"foo\", -400) = %d\n",
+ index("foofoofoo", "foo", -400));
+ printf(" D => index(\"foofoofoo\", \"foo\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", -400) != -1) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", -400) = %d\n",
+ rindex("foofoofoo", "foo", -400));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", -1) != 0) {
+ printf("perl => index(\"foofoofoo\", \"foo\", -1) = %d\n",
+ index("foofoofoo", "foo", -1));
+ printf(" D => index(\"foofoofoo\", \"foo\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", -1) != -1) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", -1) = %d\n",
+ rindex("foofoofoo", "foo", -1));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 0) != 0) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 0) = %d\n",
+ index("foofoofoo", "foo", 0));
+ printf(" D => index(\"foofoofoo\", \"foo\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 0) != 0) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 0) = %d\n",
+ rindex("foofoofoo", "foo", 0));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 4) != 6) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 4) = %d\n",
+ index("foofoofoo", "foo", 4));
+ printf(" D => index(\"foofoofoo\", \"foo\", 4) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 4) != 3) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 4) = %d\n",
+ rindex("foofoofoo", "foo", 4));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 4) = 3\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 9) != -1) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 9) = %d\n",
+ index("foofoofoo", "foo", 9));
+ printf(" D => index(\"foofoofoo\", \"foo\", 9) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 9) != 6) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 9) = %d\n",
+ rindex("foofoofoo", "foo", 9));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 9) = 6\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 10) != -1) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 10) = %d\n",
+ index("foofoofoo", "foo", 10));
+ printf(" D => index(\"foofoofoo\", \"foo\", 10) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 10) != 6) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 10) = %d\n",
+ rindex("foofoofoo", "foo", 10));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 10) = 6\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 11) != -1) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 11) = %d\n",
+ index("foofoofoo", "foo", 11));
+ printf(" D => index(\"foofoofoo\", \"foo\", 11) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 11) != 6) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 11) = %d\n",
+ rindex("foofoofoo", "foo", 11));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 11) = 6\n");
+ $failed++;
+ }
+
+ if (index("foofoofoo", "foo", 400) != -1) {
+ printf("perl => index(\"foofoofoo\", \"foo\", 400) = %d\n",
+ index("foofoofoo", "foo", 400));
+ printf(" D => index(\"foofoofoo\", \"foo\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foofoofoo", "foo", 400) != 6) {
+ printf("perl => rindex(\"foofoofoo\", \"foo\", 400) = %d\n",
+ rindex("foofoofoo", "foo", 400));
+ printf(" D => rindex(\"foofoofoo\", \"foo\", 400) = 6\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", -400) != 3) {
+ printf("perl => index(\"boofoofoo\", \"foo\", -400) = %d\n",
+ index("boofoofoo", "foo", -400));
+ printf(" D => index(\"boofoofoo\", \"foo\", -400) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", -400) != -1) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", -400) = %d\n",
+ rindex("boofoofoo", "foo", -400));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", -1) != 3) {
+ printf("perl => index(\"boofoofoo\", \"foo\", -1) = %d\n",
+ index("boofoofoo", "foo", -1));
+ printf(" D => index(\"boofoofoo\", \"foo\", -1) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", -1) != -1) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", -1) = %d\n",
+ rindex("boofoofoo", "foo", -1));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 0) != 3) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 0) = %d\n",
+ index("boofoofoo", "foo", 0));
+ printf(" D => index(\"boofoofoo\", \"foo\", 0) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 0) != -1) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 0) = %d\n",
+ rindex("boofoofoo", "foo", 0));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 4) != 6) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 4) = %d\n",
+ index("boofoofoo", "foo", 4));
+ printf(" D => index(\"boofoofoo\", \"foo\", 4) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 4) != 3) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 4) = %d\n",
+ rindex("boofoofoo", "foo", 4));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 4) = 3\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 9) != -1) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 9) = %d\n",
+ index("boofoofoo", "foo", 9));
+ printf(" D => index(\"boofoofoo\", \"foo\", 9) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 9) != 6) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 9) = %d\n",
+ rindex("boofoofoo", "foo", 9));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 9) = 6\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 10) != -1) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 10) = %d\n",
+ index("boofoofoo", "foo", 10));
+ printf(" D => index(\"boofoofoo\", \"foo\", 10) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 10) != 6) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 10) = %d\n",
+ rindex("boofoofoo", "foo", 10));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 10) = 6\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 11) != -1) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 11) = %d\n",
+ index("boofoofoo", "foo", 11));
+ printf(" D => index(\"boofoofoo\", \"foo\", 11) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 11) != 6) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 11) = %d\n",
+ rindex("boofoofoo", "foo", 11));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 11) = 6\n");
+ $failed++;
+ }
+
+ if (index("boofoofoo", "foo", 400) != -1) {
+ printf("perl => index(\"boofoofoo\", \"foo\", 400) = %d\n",
+ index("boofoofoo", "foo", 400));
+ printf(" D => index(\"boofoofoo\", \"foo\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("boofoofoo", "foo", 400) != 6) {
+ printf("perl => rindex(\"boofoofoo\", \"foo\", 400) = %d\n",
+ rindex("boofoofoo", "foo", 400));
+ printf(" D => rindex(\"boofoofoo\", \"foo\", 400) = 6\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", -400) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", -400) = %d\n",
+ index("foobarbaz", "barbazzy", -400));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", -400) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", -400) = %d\n",
+ rindex("foobarbaz", "barbazzy", -400));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", -1) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", -1) = %d\n",
+ index("foobarbaz", "barbazzy", -1));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", -1) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", -1) = %d\n",
+ rindex("foobarbaz", "barbazzy", -1));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 0) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 0) = %d\n",
+ index("foobarbaz", "barbazzy", 0));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 0) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 0) = %d\n",
+ rindex("foobarbaz", "barbazzy", 0));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 4) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 4) = %d\n",
+ index("foobarbaz", "barbazzy", 4));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 4) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 4) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 4) = %d\n",
+ rindex("foobarbaz", "barbazzy", 4));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 4) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 9) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 9) = %d\n",
+ index("foobarbaz", "barbazzy", 9));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 9) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 9) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 9) = %d\n",
+ rindex("foobarbaz", "barbazzy", 9));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 9) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 10) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 10) = %d\n",
+ index("foobarbaz", "barbazzy", 10));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 10) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 10) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 10) = %d\n",
+ rindex("foobarbaz", "barbazzy", 10));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 10) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 11) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 11) = %d\n",
+ index("foobarbaz", "barbazzy", 11));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 11) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 11) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 11) = %d\n",
+ rindex("foobarbaz", "barbazzy", 11));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 11) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobarbaz", "barbazzy", 400) != -1) {
+ printf("perl => index(\"foobarbaz\", \"barbazzy\", 400) = %d\n",
+ index("foobarbaz", "barbazzy", 400));
+ printf(" D => index(\"foobarbaz\", \"barbazzy\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobarbaz", "barbazzy", 400) != -1) {
+ printf("perl => rindex(\"foobarbaz\", \"barbazzy\", 400) = %d\n",
+ rindex("foobarbaz", "barbazzy", 400));
+ printf(" D => rindex(\"foobarbaz\", \"barbazzy\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", -400) != 0) {
+ printf("perl => index(\"foobar\", \"foobar\", -400) = %d\n",
+ index("foobar", "foobar", -400));
+ printf(" D => index(\"foobar\", \"foobar\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", -400) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobar\", -400) = %d\n",
+ rindex("foobar", "foobar", -400));
+ printf(" D => rindex(\"foobar\", \"foobar\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", -1) != 0) {
+ printf("perl => index(\"foobar\", \"foobar\", -1) = %d\n",
+ index("foobar", "foobar", -1));
+ printf(" D => index(\"foobar\", \"foobar\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", -1) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobar\", -1) = %d\n",
+ rindex("foobar", "foobar", -1));
+ printf(" D => rindex(\"foobar\", \"foobar\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 0) != 0) {
+ printf("perl => index(\"foobar\", \"foobar\", 0) = %d\n",
+ index("foobar", "foobar", 0));
+ printf(" D => index(\"foobar\", \"foobar\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 0) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 0) = %d\n",
+ rindex("foobar", "foobar", 0));
+ printf(" D => rindex(\"foobar\", \"foobar\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 3) != -1) {
+ printf("perl => index(\"foobar\", \"foobar\", 3) = %d\n",
+ index("foobar", "foobar", 3));
+ printf(" D => index(\"foobar\", \"foobar\", 3) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 3) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 3) = %d\n",
+ rindex("foobar", "foobar", 3));
+ printf(" D => rindex(\"foobar\", \"foobar\", 3) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 6) != -1) {
+ printf("perl => index(\"foobar\", \"foobar\", 6) = %d\n",
+ index("foobar", "foobar", 6));
+ printf(" D => index(\"foobar\", \"foobar\", 6) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 6) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 6) = %d\n",
+ rindex("foobar", "foobar", 6));
+ printf(" D => rindex(\"foobar\", \"foobar\", 6) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 7) != -1) {
+ printf("perl => index(\"foobar\", \"foobar\", 7) = %d\n",
+ index("foobar", "foobar", 7));
+ printf(" D => index(\"foobar\", \"foobar\", 7) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 7) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 7) = %d\n",
+ rindex("foobar", "foobar", 7));
+ printf(" D => rindex(\"foobar\", \"foobar\", 7) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 8) != -1) {
+ printf("perl => index(\"foobar\", \"foobar\", 8) = %d\n",
+ index("foobar", "foobar", 8));
+ printf(" D => index(\"foobar\", \"foobar\", 8) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 8) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 8) = %d\n",
+ rindex("foobar", "foobar", 8));
+ printf(" D => rindex(\"foobar\", \"foobar\", 8) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobar", 400) != -1) {
+ printf("perl => index(\"foobar\", \"foobar\", 400) = %d\n",
+ index("foobar", "foobar", 400));
+ printf(" D => index(\"foobar\", \"foobar\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobar", 400) != 0) {
+ printf("perl => rindex(\"foobar\", \"foobar\", 400) = %d\n",
+ rindex("foobar", "foobar", 400));
+ printf(" D => rindex(\"foobar\", \"foobar\", 400) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", -400) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", -400) = %d\n",
+ index("foobar", "foobarbaz", -400));
+ printf(" D => index(\"foobar\", \"foobarbaz\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", -400) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", -400) = %d\n",
+ rindex("foobar", "foobarbaz", -400));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", -1) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", -1) = %d\n",
+ index("foobar", "foobarbaz", -1));
+ printf(" D => index(\"foobar\", \"foobarbaz\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", -1) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", -1) = %d\n",
+ rindex("foobar", "foobarbaz", -1));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 0) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 0) = %d\n",
+ index("foobar", "foobarbaz", 0));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 0) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 0) = %d\n",
+ rindex("foobar", "foobarbaz", 0));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 3) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 3) = %d\n",
+ index("foobar", "foobarbaz", 3));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 3) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 3) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 3) = %d\n",
+ rindex("foobar", "foobarbaz", 3));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 3) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 6) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 6) = %d\n",
+ index("foobar", "foobarbaz", 6));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 6) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 6) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 6) = %d\n",
+ rindex("foobar", "foobarbaz", 6));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 6) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 7) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 7) = %d\n",
+ index("foobar", "foobarbaz", 7));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 7) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 7) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 7) = %d\n",
+ rindex("foobar", "foobarbaz", 7));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 7) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 8) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 8) = %d\n",
+ index("foobar", "foobarbaz", 8));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 8) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 8) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 8) = %d\n",
+ rindex("foobar", "foobarbaz", 8));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 8) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "foobarbaz", 400) != -1) {
+ printf("perl => index(\"foobar\", \"foobarbaz\", 400) = %d\n",
+ index("foobar", "foobarbaz", 400));
+ printf(" D => index(\"foobar\", \"foobarbaz\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "foobarbaz", 400) != -1) {
+ printf("perl => rindex(\"foobar\", \"foobarbaz\", 400) = %d\n",
+ rindex("foobar", "foobarbaz", 400));
+ printf(" D => rindex(\"foobar\", \"foobarbaz\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", -400) != -1) {
+ printf("perl => index(\"\", \"foobar\", -400) = %d\n",
+ index("", "foobar", -400));
+ printf(" D => index(\"\", \"foobar\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", -400) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", -400) = %d\n",
+ rindex("", "foobar", -400));
+ printf(" D => rindex(\"\", \"foobar\", -400) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", -1) != -1) {
+ printf("perl => index(\"\", \"foobar\", -1) = %d\n",
+ index("", "foobar", -1));
+ printf(" D => index(\"\", \"foobar\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", -1) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", -1) = %d\n",
+ rindex("", "foobar", -1));
+ printf(" D => rindex(\"\", \"foobar\", -1) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 0) != -1) {
+ printf("perl => index(\"\", \"foobar\", 0) = %d\n",
+ index("", "foobar", 0));
+ printf(" D => index(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 0) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 0) = %d\n",
+ rindex("", "foobar", 0));
+ printf(" D => rindex(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 0) != -1) {
+ printf("perl => index(\"\", \"foobar\", 0) = %d\n",
+ index("", "foobar", 0));
+ printf(" D => index(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 0) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 0) = %d\n",
+ rindex("", "foobar", 0));
+ printf(" D => rindex(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 0) != -1) {
+ printf("perl => index(\"\", \"foobar\", 0) = %d\n",
+ index("", "foobar", 0));
+ printf(" D => index(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 0) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 0) = %d\n",
+ rindex("", "foobar", 0));
+ printf(" D => rindex(\"\", \"foobar\", 0) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 1) != -1) {
+ printf("perl => index(\"\", \"foobar\", 1) = %d\n",
+ index("", "foobar", 1));
+ printf(" D => index(\"\", \"foobar\", 1) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 1) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 1) = %d\n",
+ rindex("", "foobar", 1));
+ printf(" D => rindex(\"\", \"foobar\", 1) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 2) != -1) {
+ printf("perl => index(\"\", \"foobar\", 2) = %d\n",
+ index("", "foobar", 2));
+ printf(" D => index(\"\", \"foobar\", 2) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 2) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 2) = %d\n",
+ rindex("", "foobar", 2));
+ printf(" D => rindex(\"\", \"foobar\", 2) = -1\n");
+ $failed++;
+ }
+
+ if (index("", "foobar", 400) != -1) {
+ printf("perl => index(\"\", \"foobar\", 400) = %d\n",
+ index("", "foobar", 400));
+ printf(" D => index(\"\", \"foobar\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (rindex("", "foobar", 400) != -1) {
+ printf("perl => rindex(\"\", \"foobar\", 400) = %d\n",
+ rindex("", "foobar", 400));
+ printf(" D => rindex(\"\", \"foobar\", 400) = -1\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", -400) != 0) {
+ printf("perl => index(\"foobar\", \"\", -400) = %d\n",
+ index("foobar", "", -400));
+ printf(" D => index(\"foobar\", \"\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", -400) != 0) {
+ printf("perl => rindex(\"foobar\", \"\", -400) = %d\n",
+ rindex("foobar", "", -400));
+ printf(" D => rindex(\"foobar\", \"\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", -1) != 0) {
+ printf("perl => index(\"foobar\", \"\", -1) = %d\n",
+ index("foobar", "", -1));
+ printf(" D => index(\"foobar\", \"\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", -1) != 0) {
+ printf("perl => rindex(\"foobar\", \"\", -1) = %d\n",
+ rindex("foobar", "", -1));
+ printf(" D => rindex(\"foobar\", \"\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 0) != 0) {
+ printf("perl => index(\"foobar\", \"\", 0) = %d\n",
+ index("foobar", "", 0));
+ printf(" D => index(\"foobar\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 0) != 0) {
+ printf("perl => rindex(\"foobar\", \"\", 0) = %d\n",
+ rindex("foobar", "", 0));
+ printf(" D => rindex(\"foobar\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 3) != 3) {
+ printf("perl => index(\"foobar\", \"\", 3) = %d\n",
+ index("foobar", "", 3));
+ printf(" D => index(\"foobar\", \"\", 3) = 3\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 3) != 3) {
+ printf("perl => rindex(\"foobar\", \"\", 3) = %d\n",
+ rindex("foobar", "", 3));
+ printf(" D => rindex(\"foobar\", \"\", 3) = 3\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 6) != 6) {
+ printf("perl => index(\"foobar\", \"\", 6) = %d\n",
+ index("foobar", "", 6));
+ printf(" D => index(\"foobar\", \"\", 6) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 6) != 6) {
+ printf("perl => rindex(\"foobar\", \"\", 6) = %d\n",
+ rindex("foobar", "", 6));
+ printf(" D => rindex(\"foobar\", \"\", 6) = 6\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 7) != 6) {
+ printf("perl => index(\"foobar\", \"\", 7) = %d\n",
+ index("foobar", "", 7));
+ printf(" D => index(\"foobar\", \"\", 7) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 7) != 6) {
+ printf("perl => rindex(\"foobar\", \"\", 7) = %d\n",
+ rindex("foobar", "", 7));
+ printf(" D => rindex(\"foobar\", \"\", 7) = 6\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 8) != 6) {
+ printf("perl => index(\"foobar\", \"\", 8) = %d\n",
+ index("foobar", "", 8));
+ printf(" D => index(\"foobar\", \"\", 8) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 8) != 6) {
+ printf("perl => rindex(\"foobar\", \"\", 8) = %d\n",
+ rindex("foobar", "", 8));
+ printf(" D => rindex(\"foobar\", \"\", 8) = 6\n");
+ $failed++;
+ }
+
+ if (index("foobar", "", 400) != 6) {
+ printf("perl => index(\"foobar\", \"\", 400) = %d\n",
+ index("foobar", "", 400));
+ printf(" D => index(\"foobar\", \"\", 400) = 6\n");
+ $failed++;
+ }
+
+ if (rindex("foobar", "", 400) != 6) {
+ printf("perl => rindex(\"foobar\", \"\", 400) = %d\n",
+ rindex("foobar", "", 400));
+ printf(" D => rindex(\"foobar\", \"\", 400) = 6\n");
+ $failed++;
+ }
+
+ if (index("", "", -400) != 0) {
+ printf("perl => index(\"\", \"\", -400) = %d\n",
+ index("", "", -400));
+ printf(" D => index(\"\", \"\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", -400) != 0) {
+ printf("perl => rindex(\"\", \"\", -400) = %d\n",
+ rindex("", "", -400));
+ printf(" D => rindex(\"\", \"\", -400) = 0\n");
+ $failed++;
+ }
+
+ if (index("", "", -1) != 0) {
+ printf("perl => index(\"\", \"\", -1) = %d\n",
+ index("", "", -1));
+ printf(" D => index(\"\", \"\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", -1) != 0) {
+ printf("perl => rindex(\"\", \"\", -1) = %d\n",
+ rindex("", "", -1));
+ printf(" D => rindex(\"\", \"\", -1) = 0\n");
+ $failed++;
+ }
+
+ if (index("", "", 0) != 0) {
+ printf("perl => index(\"\", \"\", 0) = %d\n",
+ index("", "", 0));
+ printf(" D => index(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", 0) != 0) {
+ printf("perl => rindex(\"\", \"\", 0) = %d\n",
+ rindex("", "", 0));
+ printf(" D => rindex(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("", "", 0) != 0) {
+ printf("perl => index(\"\", \"\", 0) = %d\n",
+ index("", "", 0));
+ printf(" D => index(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", 0) != 0) {
+ printf("perl => rindex(\"\", \"\", 0) = %d\n",
+ rindex("", "", 0));
+ printf(" D => rindex(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("", "", 0) != 0) {
+ printf("perl => index(\"\", \"\", 0) = %d\n",
+ index("", "", 0));
+ printf(" D => index(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", 0) != 0) {
+ printf("perl => rindex(\"\", \"\", 0) = %d\n",
+ rindex("", "", 0));
+ printf(" D => rindex(\"\", \"\", 0) = 0\n");
+ $failed++;
+ }
+
+ if (index("", "", 1) != 0) {
+ printf("perl => index(\"\", \"\", 1) = %d\n",
+ index("", "", 1));
+ printf(" D => index(\"\", \"\", 1) = 0\n");
+ $failed++;
+ }
+
+ if (rindex("", "", 1) != 0) {
+ printf("perl => rindex(\"\", \"\", 1) = %d\n",
+ rindex("", "", 1));
+ printf(" D => rindex(\"\", \"\", 1) = 0\n");
+ $failed++;
+ }
+
+ exit($failed);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d
new file mode 100644
index 0000000..fbc5620
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+in_addr_t *ip4a;
+in_addr_t *ip4b;
+in_addr_t *ip4c;
+in_addr_t *ip4d;
+
+BEGIN
+{
+ this->buf4a = alloca(sizeof (in_addr_t));
+ this->buf4b = alloca(sizeof (in_addr_t));
+ this->buf4c = alloca(sizeof (in_addr_t));
+ this->buf4d = alloca(sizeof (in_addr_t));
+ ip4a = this->buf4a;
+ ip4b = this->buf4b;
+ ip4c = this->buf4c;
+ ip4d = this->buf4d;
+
+ *ip4a = htonl(0xc0a80117);
+ *ip4b = htonl(0x7f000001);
+ *ip4c = htonl(0xffffffff);
+ *ip4d = htonl(0x00000000);
+
+ printf("%s\n", inet_ntoa(ip4a));
+ printf("%s\n", inet_ntoa(ip4b));
+ printf("%s\n", inet_ntoa(ip4c));
+ printf("%s\n", inet_ntoa(ip4d));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d.out
new file mode 100644
index 0000000..ab535e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa.d.out
@@ -0,0 +1,5 @@
+192.168.1.23
+127.0.0.1
+255.255.255.255
+0.0.0.0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d
new file mode 100644
index 0000000..40b3849
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d
@@ -0,0 +1,95 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+struct in6_addr *ip6a;
+struct in6_addr *ip6b;
+struct in6_addr *ip6c;
+struct in6_addr *ip6d;
+struct in6_addr *ip6e;
+struct in6_addr *ip6f;
+struct in6_addr *ip6g;
+
+BEGIN
+{
+ this->buf6a = alloca(sizeof (struct in6_addr));
+ this->buf6b = alloca(sizeof (struct in6_addr));
+ this->buf6c = alloca(sizeof (struct in6_addr));
+ this->buf6d = alloca(sizeof (struct in6_addr));
+ this->buf6e = alloca(sizeof (struct in6_addr));
+ this->buf6f = alloca(sizeof (struct in6_addr));
+ this->buf6g = alloca(sizeof (struct in6_addr));
+ ip6a = this->buf6a;
+ ip6b = this->buf6b;
+ ip6c = this->buf6c;
+ ip6d = this->buf6d;
+ ip6e = this->buf6e;
+ ip6f = this->buf6f;
+ ip6g = this->buf6g;
+
+ ip6a->__u6_addr.__u6_addr8[0] = 0xfe;
+ ip6a->__u6_addr.__u6_addr8[1] = 0x80;
+ ip6a->__u6_addr.__u6_addr8[8] = 0x02;
+ ip6a->__u6_addr.__u6_addr8[9] = 0x14;
+ ip6a->__u6_addr.__u6_addr8[10] = 0x4f;
+ ip6a->__u6_addr.__u6_addr8[11] = 0xff;
+ ip6a->__u6_addr.__u6_addr8[12] = 0xfe;
+ ip6a->__u6_addr.__u6_addr8[13] = 0x0b;
+ ip6a->__u6_addr.__u6_addr8[14] = 0x76;
+ ip6a->__u6_addr.__u6_addr8[15] = 0xc8;
+ ip6b->__u6_addr.__u6_addr8[0] = 0x10;
+ ip6b->__u6_addr.__u6_addr8[1] = 0x80;
+ ip6b->__u6_addr.__u6_addr8[10] = 0x08;
+ ip6b->__u6_addr.__u6_addr8[11] = 0x08;
+ ip6b->__u6_addr.__u6_addr8[13] = 0x20;
+ ip6b->__u6_addr.__u6_addr8[13] = 0x0c;
+ ip6b->__u6_addr.__u6_addr8[14] = 0x41;
+ ip6b->__u6_addr.__u6_addr8[15] = 0x7a;
+ ip6c->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6e->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6e->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6f->__u6_addr.__u6_addr8[10] = 0xff;
+ ip6f->__u6_addr.__u6_addr8[11] = 0xff;
+ ip6f->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6f->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6g->__u6_addr.__u6_addr8[10] = 0xff;
+ ip6g->__u6_addr.__u6_addr8[11] = 0xfe;
+ ip6g->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6g->__u6_addr.__u6_addr8[15] = 0x01;
+
+ printf("%s\n", inet_ntoa6(ip6a));
+ printf("%s\n", inet_ntoa6(ip6b));
+ printf("%s\n", inet_ntoa6(ip6c));
+ printf("%s\n", inet_ntoa6(ip6d));
+ printf("%s\n", inet_ntoa6(ip6e));
+ printf("%s\n", inet_ntoa6(ip6f));
+ printf("%s\n", inet_ntoa6(ip6g));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d.out
new file mode 100644
index 0000000..d87c1f6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntoa6.d.out
@@ -0,0 +1,8 @@
+fe80::214:4fff:fe0b:76c8
+1080::808:c:417a
+::1
+::
+127.0.0.1
+127.0.0.1
+::fffe:7f00:1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d
new file mode 100644
index 0000000..21452d6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d
@@ -0,0 +1,138 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+inline int AF_INET = 2;
+inline int AF_INET6 = 28;
+
+in_addr_t *ip4a;
+in_addr_t *ip4b;
+in_addr_t *ip4c;
+in_addr_t *ip4d;
+struct in6_addr *ip6a;
+struct in6_addr *ip6b;
+struct in6_addr *ip6c;
+struct in6_addr *ip6d;
+struct in6_addr *ip6e;
+struct in6_addr *ip6f;
+struct in6_addr *ip6g;
+struct in6_addr *ip6h;
+
+BEGIN
+{
+ this->buf4a = alloca(sizeof (in_addr_t));
+ this->buf4b = alloca(sizeof (in_addr_t));
+ this->buf4c = alloca(sizeof (in_addr_t));
+ this->buf4d = alloca(sizeof (in_addr_t));
+ this->buf6a = alloca(sizeof (struct in6_addr));
+ this->buf6b = alloca(sizeof (struct in6_addr));
+ this->buf6c = alloca(sizeof (struct in6_addr));
+ this->buf6d = alloca(sizeof (struct in6_addr));
+ this->buf6e = alloca(sizeof (struct in6_addr));
+ this->buf6f = alloca(sizeof (struct in6_addr));
+ this->buf6g = alloca(sizeof (struct in6_addr));
+ this->buf6h = alloca(sizeof (struct in6_addr));
+ ip4a = this->buf4a;
+ ip4b = this->buf4b;
+ ip4c = this->buf4c;
+ ip4d = this->buf4d;
+ ip6a = this->buf6a;
+ ip6b = this->buf6b;
+ ip6c = this->buf6c;
+ ip6d = this->buf6d;
+ ip6e = this->buf6e;
+ ip6f = this->buf6f;
+ ip6g = this->buf6g;
+ ip6h = this->buf6h;
+
+ *ip4a = htonl(0xc0a80117);
+ *ip4b = htonl(0x7f000001);
+ *ip4c = htonl(0xffffffff);
+ *ip4d = htonl(0x00000000);
+ ip6a->__u6_addr.__u6_addr8[0] = 0xfe;
+ ip6a->__u6_addr.__u6_addr8[1] = 0x80;
+ ip6a->__u6_addr.__u6_addr8[8] = 0x02;
+ ip6a->__u6_addr.__u6_addr8[9] = 0x14;
+ ip6a->__u6_addr.__u6_addr8[10] = 0x4f;
+ ip6a->__u6_addr.__u6_addr8[11] = 0xff;
+ ip6a->__u6_addr.__u6_addr8[12] = 0xfe;
+ ip6a->__u6_addr.__u6_addr8[13] = 0x0b;
+ ip6a->__u6_addr.__u6_addr8[14] = 0x76;
+ ip6a->__u6_addr.__u6_addr8[15] = 0xc8;
+ ip6b->__u6_addr.__u6_addr8[0] = 0x10;
+ ip6b->__u6_addr.__u6_addr8[1] = 0x80;
+ ip6b->__u6_addr.__u6_addr8[10] = 0x08;
+ ip6b->__u6_addr.__u6_addr8[11] = 0x08;
+ ip6b->__u6_addr.__u6_addr8[13] = 0x20;
+ ip6b->__u6_addr.__u6_addr8[13] = 0x0c;
+ ip6b->__u6_addr.__u6_addr8[14] = 0x41;
+ ip6b->__u6_addr.__u6_addr8[15] = 0x7a;
+ ip6c->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6e->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6e->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6f->__u6_addr.__u6_addr8[10] = 0xff;
+ ip6f->__u6_addr.__u6_addr8[11] = 0xff;
+ ip6f->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6f->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6g->__u6_addr.__u6_addr8[10] = 0xff;
+ ip6g->__u6_addr.__u6_addr8[11] = 0xfe;
+ ip6g->__u6_addr.__u6_addr8[12] = 0x7f;
+ ip6g->__u6_addr.__u6_addr8[15] = 0x01;
+ ip6h->__u6_addr.__u6_addr8[0] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[1] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[2] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[3] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[4] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[5] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[6] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[7] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[8] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[9] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[10] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[11] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[12] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[13] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[14] = 0xff;
+ ip6h->__u6_addr.__u6_addr8[15] = 0xff;
+
+ printf("%s\n", inet_ntop(AF_INET, ip4a));
+ printf("%s\n", inet_ntop(AF_INET, ip4b));
+ printf("%s\n", inet_ntop(AF_INET, ip4c));
+ printf("%s\n", inet_ntop(AF_INET, ip4d));
+ printf("%s\n", inet_ntop(AF_INET6, ip6a));
+ printf("%s\n", inet_ntop(AF_INET6, ip6b));
+ printf("%s\n", inet_ntop(AF_INET6, ip6c));
+ printf("%s\n", inet_ntop(AF_INET6, ip6d));
+ printf("%s\n", inet_ntop(AF_INET6, ip6e));
+ printf("%s\n", inet_ntop(AF_INET6, ip6f));
+ printf("%s\n", inet_ntop(AF_INET6, ip6g));
+ printf("%s\n", inet_ntop(AF_INET6, ip6h));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d.out
new file mode 100644
index 0000000..7c8311c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.inet_ntop.d.out
@@ -0,0 +1,13 @@
+192.168.1.23
+127.0.0.1
+255.255.255.255
+0.0.0.0
+fe80::214:4fff:fe0b:76c8
+1080::808:c:417a
+::1
+::
+::127.0.0.1
+::ffff:127.0.0.1
+::fffe:7f00:1
+ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d
new file mode 100644
index 0000000..03e295a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%s\n", lltostr(0));
+ printf("%s\n", lltostr(1));
+ printf("%s\n", lltostr(-1));
+ printf("%s\n", lltostr(123456789));
+ printf("%s\n", lltostr(-123456789));
+ printf("%s\n", lltostr(1LL << 62));
+ printf("%s\n", lltostr(-(1LL << 62)));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d.out
new file mode 100644
index 0000000..e007c64
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostr.d.out
@@ -0,0 +1,8 @@
+0
+1
+-1
+123456789
+-123456789
+4611686018427387904
+-4611686018427387904
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d
new file mode 100644
index 0000000..1afe37d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+int64_t val[int];
+
+BEGIN
+{
+ base = -2;
+ i = 0;
+ val[i++] = -10;
+ val[i++] = -1;
+ val[i++] = 0;
+ val[i++] = 10;
+ val[i++] = 100;
+ val[i++] = 1000;
+ val[i++] = (1LL << 62);
+ maxval = i;
+ i = 0;
+}
+
+tick-1ms
+/i < maxval/
+{
+ printf("base %2d of %20d: ", base, val[i]);
+}
+
+tick-1ms
+/i < maxval/
+{
+ printf(" %s\n", lltostr(val[i], base));
+}
+
+ERROR
+{
+ printf(" <error>\n");
+}
+
+tick-1ms
+/i < maxval/
+{
+ i++;
+}
+
+tick-1ms
+/i == maxval/
+{
+ i = 0;
+ base++;
+}
+
+tick-1ms
+/base > 40/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out
new file mode 100644
index 0000000..94e2257
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.lltostrbase.d.out
@@ -0,0 +1,302 @@
+base -2 of -10: <error>
+base -2 of -1: <error>
+base -2 of 0: <error>
+base -2 of 10: <error>
+base -2 of 100: <error>
+base -2 of 1000: <error>
+base -2 of 4611686018427387904: <error>
+base -1 of -10: <error>
+base -1 of -1: <error>
+base -1 of 0: <error>
+base -1 of 10: <error>
+base -1 of 100: <error>
+base -1 of 1000: <error>
+base -1 of 4611686018427387904: <error>
+base 0 of -10: <error>
+base 0 of -1: <error>
+base 0 of 0: <error>
+base 0 of 10: <error>
+base 0 of 100: <error>
+base 0 of 1000: <error>
+base 0 of 4611686018427387904: <error>
+base 1 of -10: <error>
+base 1 of -1: <error>
+base 1 of 0: <error>
+base 1 of 10: <error>
+base 1 of 100: <error>
+base 1 of 1000: <error>
+base 1 of 4611686018427387904: <error>
+base 2 of -10: 1111111111111111111111111111111111111111111111111111111111110110
+base 2 of -1: 1111111111111111111111111111111111111111111111111111111111111111
+base 2 of 0: 0
+base 2 of 10: 1010
+base 2 of 100: 1100100
+base 2 of 1000: 1111101000
+base 2 of 4611686018427387904: 100000000000000000000000000000000000000000000000000000000000000
+base 3 of -10: 11112220022122120101211020120210210211120
+base 3 of -1: 11112220022122120101211020120210210211220
+base 3 of 0: 0
+base 3 of 10: 101
+base 3 of 100: 10201
+base 3 of 1000: 1101001
+base 3 of 4611686018427387904: 1010201120122220002201001122110012110111
+base 4 of -10: 33333333333333333333333333333312
+base 4 of -1: 33333333333333333333333333333333
+base 4 of 0: 0
+base 4 of 10: 22
+base 4 of 100: 1210
+base 4 of 1000: 33220
+base 4 of 4611686018427387904: 10000000000000000000000000000000
+base 5 of -10: 2214220303114400424121122411
+base 5 of -1: 2214220303114400424121122430
+base 5 of 0: 0
+base 5 of 10: 20
+base 5 of 100: 400
+base 5 of 1000: 13000
+base 5 of 4611686018427387904: 302141200402211214402403104
+base 6 of -10: 3520522010102100444244410
+base 6 of -1: 3520522010102100444244423
+base 6 of 0: 0
+base 6 of 10: 14
+base 6 of 100: 244
+base 6 of 1000: 4344
+base 6 of 4611686018427387904: 550120301313313111041104
+base 7 of -10: 45012021522523134134556
+base 7 of -1: 45012021522523134134601
+base 7 of 0: 0
+base 7 of 10: 13
+base 7 of 100: 202
+base 7 of 1000: 2626
+base 7 of 4611686018427387904: 11154003640456024361134
+base 8 of -10: 01777777777777777777766
+base 8 of -1: 01777777777777777777777
+base 8 of 0: 0
+base 8 of 10: 012
+base 8 of 100: 0144
+base 8 of 1000: 01750
+base 8 of 4611686018427387904: 0400000000000000000000
+base 9 of -10: 145808576354216723746
+base 9 of -1: 145808576354216723756
+base 9 of 0: 0
+base 9 of 10: 11
+base 9 of 100: 121
+base 9 of 1000: 1331
+base 9 of 4611686018427387904: 33646586081048405414
+base 10 of -10: -10
+base 10 of -1: -1
+base 10 of 0: 0
+base 10 of 10: 10
+base 10 of 100: 100
+base 10 of 1000: 1000
+base 10 of 4611686018427387904: 4611686018427387904
+base 11 of -10: 335500516a429071276
+base 11 of -1: 335500516a429071284
+base 11 of 0: 0
+base 11 of 10: a
+base 11 of 100: 91
+base 11 of 1000: 82a
+base 11 of 4611686018427387904: 9140013181078458a4
+base 12 of -10: 839365134a2a240706
+base 12 of -1: 839365134a2a240713
+base 12 of 0: 0
+base 12 of 10: a
+base 12 of 100: 84
+base 12 of 1000: 6b4
+base 12 of 4611686018427387904: 20b3a733a268670194
+base 13 of -10: 219505a9511a867b66
+base 13 of -1: 219505a9511a867b72
+base 13 of 0: 0
+base 13 of 10: a
+base 13 of 100: 79
+base 13 of 1000: 5bc
+base 13 of 4611686018427387904: 6c1349246a2881c84
+base 14 of -10: 8681049adb03db166
+base 14 of -1: 8681049adb03db171
+base 14 of 0: 0
+base 14 of 10: a
+base 14 of 100: 72
+base 14 of 1000: 516
+base 14 of 4611686018427387904: 219038263637dd3c4
+base 15 of -10: 2c1d56b648c6cd106
+base 15 of -1: 2c1d56b648c6cd110
+base 15 of 0: 0
+base 15 of 10: a
+base 15 of 100: 6a
+base 15 of 1000: 46a
+base 15 of 4611686018427387904: a7e8ce189a933404
+base 16 of -10: 0xfffffffffffffff6
+base 16 of -1: 0xffffffffffffffff
+base 16 of 0: 0x0
+base 16 of 10: 0xa
+base 16 of 100: 0x64
+base 16 of 1000: 0x3e8
+base 16 of 4611686018427387904: 0x4000000000000000
+base 17 of -10: 67979g60f5428008
+base 17 of -1: 67979g60f5428010
+base 17 of 0: 0
+base 17 of 10: a
+base 17 of 100: 5f
+base 17 of 1000: 37e
+base 17 of 4611686018427387904: 1a6a6ca03e10a88d
+base 18 of -10: 2d3fgb0b9cg4bd26
+base 18 of -1: 2d3fgb0b9cg4bd2f
+base 18 of 0: 0
+base 18 of 10: a
+base 18 of 100: 5a
+base 18 of 1000: 31a
+base 18 of 4611686018427387904: c588bdbfgd12ge4
+base 19 of -10: 141c8786h1ccaag7
+base 19 of -1: 141c8786h1ccaagg
+base 19 of 0: 0
+base 19 of 10: a
+base 19 of 100: 55
+base 19 of 1000: 2ec
+base 19 of 4611686018427387904: 5ecbb6fi9h7ggi9
+base 20 of -10: b53bjh07be4dj06
+base 20 of -1: b53bjh07be4dj0f
+base 20 of 0: 0
+base 20 of 10: a
+base 20 of 100: 50
+base 20 of 1000: 2a0
+base 20 of 4611686018427387904: 2g5hjj51hib39f4
+base 21 of -10: 5e8g4ggg7g56di6
+base 21 of -1: 5e8g4ggg7g56dif
+base 21 of 0: 0
+base 21 of 10: a
+base 21 of 100: 4g
+base 21 of 1000: 25d
+base 21 of 4611686018427387904: 18hjgjjjhebh8f4
+base 22 of -10: 2l4lf104353j8k6
+base 22 of -1: 2l4lf104353j8kf
+base 22 of 0: 0
+base 22 of 10: a
+base 22 of 100: 4c
+base 22 of 1000: 21a
+base 22 of 4611686018427387904: g6g95gc0hha7g4
+base 23 of -10: 1ddh88h2782i50j
+base 23 of -1: 1ddh88h2782i515
+base 23 of 0: 0
+base 23 of 10: a
+base 23 of 100: 48
+base 23 of 1000: 1kb
+base 23 of 4611686018427387904: 93a22467dc4chd
+base 24 of -10: l12ee5fn0ji1i6
+base 24 of -1: l12ee5fn0ji1if
+base 24 of 0: 0
+base 24 of 10: a
+base 24 of 100: 44
+base 24 of 1000: 1hg
+base 24 of 4611686018427387904: 566ffd9ni4mcag
+base 25 of -10: c9c336o0mlb7e6
+base 25 of -1: c9c336o0mlb7ef
+base 25 of 0: 0
+base 25 of 10: a
+base 25 of 100: 40
+base 25 of 1000: 1f0
+base 25 of 4611686018427387904: 32970kc6bo2kg4
+base 26 of -10: 7b7n2pcniokcg6
+base 26 of -1: 7b7n2pcniokcgf
+base 26 of 0: 0
+base 26 of 10: a
+base 26 of 100: 3m
+base 26 of 1000: 1cc
+base 26 of 4611686018427387904: 1m8c769io65344
+base 27 of -10: 4eo8hfam6fllmf
+base 27 of -1: 4eo8hfam6fllmo
+base 27 of 0: 0
+base 27 of 10: a
+base 27 of 100: 3j
+base 27 of 1000: 1a1
+base 27 of 4611686018427387904: 13jfho2j1hc5cd
+base 28 of -10: 2nc6j26l66rho6
+base 28 of -1: 2nc6j26l66rhof
+base 28 of 0: 0
+base 28 of 10: a
+base 28 of 100: 3g
+base 28 of 1000: 17k
+base 28 of 4611686018427387904: jo1ilfj8fkpd4
+base 29 of -10: 1n3rsh11f098re
+base 29 of -1: 1n3rsh11f098rn
+base 29 of 0: 0
+base 29 of 10: a
+base 29 of 100: 3d
+base 29 of 1000: 15e
+base 29 of 4611686018427387904: d0slim0b029e6
+base 30 of -10: 14l9lkmo30o406
+base 30 of -1: 14l9lkmo30o40f
+base 30 of 0: 0
+base 30 of 10: a
+base 30 of 100: 3a
+base 30 of 1000: 13a
+base 30 of 4611686018427387904: 8k9rrkl0ml104
+base 31 of -10: nd075ib45k866
+base 31 of -1: nd075ib45k86f
+base 31 of 0: 0
+base 31 of 10: a
+base 31 of 100: 37
+base 31 of 1000: 118
+base 31 of 4611686018427387904: 5qfh94i8okhh4
+base 32 of -10: fvvvvvvvvvvvm
+base 32 of -1: fvvvvvvvvvvvv
+base 32 of 0: 0
+base 32 of 10: a
+base 32 of 100: 34
+base 32 of 1000: v8
+base 32 of 4611686018427387904: 4000000000000
+base 33 of -10: b1w8p7j5q9r66
+base 33 of -1: b1w8p7j5q9r6f
+base 33 of 0: 0
+base 33 of 10: a
+base 33 of 100: 31
+base 33 of 1000: ua
+base 33 of 4611686018427387904: 2p826a4q6ivi4
+base 34 of -10: 7orp63sh4dph8
+base 34 of -1: 7orp63sh4dphh
+base 34 of 0: 0
+base 34 of 10: a
+base 34 of 100: 2w
+base 34 of 1000: te
+base 34 of 4611686018427387904: 1vnvr0wl9ketu
+base 35 of -10: 5g24a25twkwf6
+base 35 of -1: 5g24a25twkwff
+base 35 of 0: 0
+base 35 of 10: a
+base 35 of 100: 2u
+base 35 of 1000: sk
+base 35 of 4611686018427387904: 1cqrb9a7gvgu4
+base 36 of -10: 3w5e11264sgs6
+base 36 of -1: 3w5e11264sgsf
+base 36 of 0: 0
+base 36 of 10: a
+base 36 of 100: 2s
+base 36 of 1000: rs
+base 36 of 4611686018427387904: z1ci99jj7474
+base 37 of -10: <error>
+base 37 of -1: <error>
+base 37 of 0: <error>
+base 37 of 10: <error>
+base 37 of 100: <error>
+base 37 of 1000: <error>
+base 37 of 4611686018427387904: <error>
+base 38 of -10: <error>
+base 38 of -1: <error>
+base 38 of 0: <error>
+base 38 of 10: <error>
+base 38 of 100: <error>
+base 38 of 1000: <error>
+base 38 of 4611686018427387904: <error>
+base 39 of -10: <error>
+base 39 of -1: <error>
+base 39 of 0: <error>
+base 39 of 10: <error>
+base 39 of 100: <error>
+base 39 of 1000: <error>
+base 39 of 4611686018427387904: <error>
+base 40 of -10: <error>
+base 40 of -1: <error>
+base 40 of 0: <error>
+base 40 of 10: <error>
+base 40 of 100: <error>
+base 40 of 1000: <error>
+base 40 of 4611686018427387904: <error>
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d
new file mode 100644
index 0000000..0f97aa1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_owned() should return a non-zero value if the calling
+ * thread currently holds the mutex.
+ *
+ * SECTION: Actions and Subroutines/mutex_owned()
+ */
+
+#pragma D option quiet
+
+lockstat:::adaptive-acquire
+{
+ this->owned = mutex_owned((struct mtx *)arg0);
+ this->owner = mutex_owner((struct mtx *)arg0);
+}
+
+lockstat:::adaptive-acquire
+/!this->owned/
+{
+ printf("mutex_owned() returned 0, expected non-zero\n");
+ exit(1);
+}
+
+lockstat:::adaptive-acquire
+/this->owner != curthread/
+{
+ printf("current thread is not current owner of owned lock\n");
+ exit(1);
+}
+
+lockstat:::adaptive-acquire
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d
new file mode 100644
index 0000000..dbb10c3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_owner() should return a pointer to the kernel thread holding
+ * the mutex.
+ *
+ * SECTION: Actions and Subroutines/mutex_owner()
+ *
+ * NOTES: This assertion can't be verified so we'll just call it.
+ */
+
+
+
+
+#pragma D option quiet
+
+struct thread *ptr;
+
+BEGIN
+{
+ i = 0;
+}
+
+lockstat::mtx_lock:adaptive-acquire
+{
+
+ ptr = mutex_owner((struct mtx *)arg0);
+ i++;
+}
+
+tick-1
+/i > 5/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d
new file mode 100644
index 0000000..ac43e79
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * mutex_type_adaptive() should return a non-zero value if the
+ * mutex is an adaptive one.
+ *
+ * SECTION: Actions and Subroutines/mutex_type_adaptive()
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ ret = -99;
+}
+
+mtx_lock:adaptive-acquire
+{
+ ret = mutex_type_adaptive((struct mtx *)arg0);
+ i++;
+}
+
+tick-1
+/ret == 1/
+{
+ exit(0);
+}
+
+tick-1
+/i == 100 && ret == 0/
+{
+ printf("mutex_type_adaptive returned 0, expected non-zero\n");
+ exit(1);
+}
+
+tick-1
+/i == 100 && ret == -99/
+{
+ printf("No adaptive_mutexs called in the time this test was run.\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.progenyof.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.progenyof.d
new file mode 100644
index 0000000..0291158
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.progenyof.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * progenyof() should return non-zero if the pid passed is in the
+ # progeny of the calling process.
+ *
+ * SECTION: Actions and Subroutines/progenyof()
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ res_1 = -1;
+ res_2 = -1;
+ res_3 = -1;
+
+ res_1 = progenyof($ppid); /* this will always be true */
+ res_2 = progenyof($ppid + 1); /* this will always be false */
+ res_3 = progenyof(1); /* this will always be true */
+}
+
+
+tick-1
+/res_1 > 0 && res_2 == 0 && res_3 > 0/
+{
+ exit(0);
+}
+
+tick-1
+/res_1 <= 0 || res_2 != 0 || res_3 <= 0/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.rand.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.rand.d
new file mode 100644
index 0000000..51f4491
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.rand.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test rand()
+ *
+ * SECTION: Actions and Subroutines/rand()
+ */
+
+
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-1
+/i != 10/
+{
+ i++;
+ trace(rand());
+}
+
+tick-1
+/i == 10/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d
new file mode 100644
index 0000000..8dc8f89
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ str = "fooeyfooeyfoo";
+ this->success = 0;
+
+ c = 'f';
+ printf("strchr(\"%s\", '%c') = \"%s\"\n", str, c, strchr(str, c));
+ printf("strrchr(\"%s\", '%c') = \"%s\"\n", str, c, strrchr(str, c));
+
+ c = 'y';
+ printf("strchr(\"%s\", '%c') = \"%s\"\n", str, c, strchr(str, c));
+ printf("strrchr(\"%s\", '%c') = \"%s\"\n", str, c, strrchr(str, c));
+
+ printf("strrchr(\"%s\", '%c') = \"%s\"\n", strchr(str, c), c,
+ strrchr(strchr(str, c), c));
+
+ this->success = 1;
+}
+
+BEGIN
+/!this->success/
+{
+ exit(1);
+}
+
+BEGIN
+/strchr(str, 'a') != NULL/
+{
+ exit(2);
+}
+
+BEGIN
+/strrchr(str, 'a') != NULL/
+{
+ exit(3);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d.out
new file mode 100644
index 0000000..328b531
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strchr.d.out
@@ -0,0 +1,6 @@
+strchr("fooeyfooeyfoo", 'f') = "fooeyfooeyfoo"
+strrchr("fooeyfooeyfoo", 'f') = "foo"
+strchr("fooeyfooeyfoo", 'y') = "yfooeyfoo"
+strrchr("fooeyfooeyfoo", 'y') = "yfoo"
+strrchr("yfooeyfoo", 'y') = "yfoo"
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d
new file mode 100644
index 0000000..392c18a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%s\n", strjoin("foo", "baz"));
+ printf("%s\n", strjoin("foo", ""));
+ printf("%s\n", strjoin("", "baz"));
+ printf("%s\n", strjoin("", ""));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d.out
new file mode 100644
index 0000000..6572869
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strjoin.d.out
@@ -0,0 +1,5 @@
+foobaz
+foo
+baz
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d
new file mode 100644
index 0000000..0c81b7a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ str = "foobarbarbazbarbop";
+ this->success = 0;
+
+ c = str;
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ c = "baz";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ c = "bar";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ c = "bazbarbop";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ c = "barba";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n",
+ strstr(str, "baz"), strstr(str, "zba"),
+ strstr(strstr(str, "baz"), strstr(str, "zba")));
+
+ c = "";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ str = "";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ str = "f";
+ c = "f";
+ printf("strstr(\"%s\", \"%s\") = \"%s\"\n", str, c, strstr(str, c));
+
+ this->success = 1;
+}
+
+BEGIN
+/!this->success/
+{
+ exit(1);
+}
+
+BEGIN
+/strstr(str, "barbarf") != NULL/
+{
+ exit(2);
+}
+
+BEGIN
+/strstr(str, "foobarbarbazbarbopp") != NULL/
+{
+ exit(3);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d.out
new file mode 100644
index 0000000..f9121db
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strstr.d.out
@@ -0,0 +1,10 @@
+strstr("foobarbarbazbarbop", "foobarbarbazbarbop") = "foobarbarbazbarbop"
+strstr("foobarbarbazbarbop", "baz") = "bazbarbop"
+strstr("foobarbarbazbarbop", "bar") = "barbarbazbarbop"
+strstr("foobarbarbazbarbop", "bazbarbop") = "bazbarbop"
+strstr("foobarbarbazbarbop", "barba") = "barbarbazbarbop"
+strstr("bazbarbop", "zbarbop") = "zbarbop"
+strstr("foobarbarbazbarbop", "") = "foobarbarbazbarbop"
+strstr("", "") = ""
+strstr("f", "f") = "f"
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d
new file mode 100644
index 0000000..47092ba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d
@@ -0,0 +1,146 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ this->str = ",,,Carrots,,Barley,Oatmeal,,,Beans,";
+}
+
+BEGIN
+/(this->field = strtok(this->str, ",")) == NULL/
+{
+ exit(1);
+}
+
+BEGIN
+{
+ printf("%s\n", this->field);
+}
+
+BEGIN
+/(this->field = strtok(NULL, ",")) == NULL/
+{
+ exit(2);
+}
+
+BEGIN
+{
+ printf("%s\n", this->field);
+}
+
+BEGIN
+/(this->field = strtok(NULL, ",")) == NULL/
+{
+ exit(3);
+}
+
+BEGIN
+{
+ printf("%s\n", this->field);
+}
+
+BEGIN
+/(this->field = strtok(NULL, ",")) == NULL/
+{
+ exit(4);
+}
+
+BEGIN
+{
+ printf("%s\n", this->field);
+}
+
+BEGIN
+/(self->a = strtok(NULL, ",")) != NULL/
+{
+ printf("unexpected field: %s\n", this->field);
+ exit(5);
+}
+
+struct {
+ string s1;
+ string s2;
+ string result;
+} command[int];
+
+int i;
+
+BEGIN
+{
+ command[i].s1 = "";
+ command[i].s2 = "";
+ command[i].result = "";
+ i++;
+
+ command[i].s1 = "foo";
+ command[i].s2 = "";
+ command[i].result = command[i].s1;
+ i++;
+
+ command[i].s1 = "foobar";
+ command[i].s2 = "o";
+ command[i].result = "f";
+ i++;
+
+ command[i].s1 = "oobar";
+ command[i].s2 = "o";
+ command[i].result = "bar";
+ i++;
+
+ command[i].s1 = "foo";
+ command[i].s2 = "bar";
+ command[i].result = command[i].s1;
+ i++;
+
+ command[i].s1 = "";
+ command[i].s2 = "foo";
+ command[i].result = "";
+ i++;
+
+ end = i;
+ i = 0;
+}
+
+tick-1ms
+/i < end &&
+ (this->result = strtok(command[i].s1, command[i].s2)) != command[i].result/
+{
+ printf("strtok(\"%s\", \"%s\") = \"%s\", expected \"%s\"",
+ command[i].s1, command[i].s2,
+ this->result != NULL ? this->result : "<null>",
+ command[i].result != NULL ? command[i].result : "<null>");
+ exit(6 + i);
+}
+
+tick-1ms
+/++i == end/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d.out
new file mode 100644
index 0000000..4bc3727
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok.d.out
@@ -0,0 +1,5 @@
+Carrots
+Barley
+Oatmeal
+Beans
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok_null.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok_null.d
new file mode 100644
index 0000000..6de4f97
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.strtok_null.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Test that a strtok(NULL, ...) without first calling strtok(string, ...)
+ * produces an error
+ */
+
+BEGIN
+{
+ trace(strtok(NULL, "!"));
+ exit(1);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d
new file mode 100644
index 0000000..edee644
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d
@@ -0,0 +1,231 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option strsize=32
+
+struct {
+ int index;
+ int length;
+ int nolen;
+ int alt;
+} command[int];
+
+int i;
+
+BEGIN
+{
+ str = "foobarbazbop";
+ str2 = "";
+ altstr = "CRAIG: Positioned them, I don't ";
+ altstr2 = "know... I'm fairly wide guy.";
+
+ command[i].index = 3;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = 300;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = -10;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = 0;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = 1;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = strlen(str) - 1;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = strlen(str);
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = strlen(str) + 1;
+ command[i].nolen = 1;
+ i++;
+
+ command[i].index = 8;
+ command[i].length = 20;
+ i++;
+
+ command[i].index = 4;
+ command[i].length = 4;
+ i++;
+
+ command[i].index = 5;
+ command[i].length = strlen(str) - command[i].index + 1;
+ i++;
+
+ command[i].index = 5;
+ command[i].length = strlen(str) - command[i].index + 2;
+ i++;
+
+ command[i].index = 400;
+ command[i].length = 20;
+ i++;
+
+ command[i].index = 400;
+ command[i].length = 0;
+ i++;
+
+ command[i].index = 400;
+ command[i].length = -1;
+ i++;
+
+ command[i].index = 3;
+ command[i].length = 0;
+ i++;
+
+ command[i].index = 3;
+ command[i].length = -1;
+ i++;
+
+ command[i].index = 3;
+ command[i].length = -4;
+ i++;
+
+ command[i].index = 3;
+ command[i].length = -20;
+ i++;
+
+ command[i].index = -10;
+ command[i].length = -5;
+ i++;
+
+ command[i].index = 0;
+ command[i].length = 400;
+ i++;
+
+ command[i].index = -1;
+ command[i].length = 400;
+ i++;
+
+ command[i].index = -1;
+ command[i].length = 0;
+ i++;
+
+ command[i].index = -1;
+ command[i].length = -1;
+ i++;
+
+ command[i].index = -2 * strlen(str);
+ command[i].length = 2 * strlen(str);
+ i++;
+
+ command[i].index = -2 * strlen(str);
+ command[i].length = strlen(str);
+ i++;
+
+ command[i].index = -2 * strlen(str);
+ command[i].length = strlen(str) + 1;
+ i++;
+
+ command[i].index = -1 * strlen(str);
+ command[i].length = strlen(str);
+ i++;
+
+ command[i].index = -1 * strlen(str);
+ command[i].length = strlen(str) - 1;
+ i++;
+
+ command[i].index = 100;
+ command[i].length = 10;
+ command[i].alt = 1;
+ i++;
+
+ command[i].index = 100;
+ command[i].nolen = 1;
+ command[i].alt = 1;
+ i++;
+
+ end = i;
+ i = 0;
+ printf("#!/usr/perl5/bin/perl\n\nBEGIN {\n");
+
+}
+
+tick-1ms
+/i < end && command[i].nolen/
+{
+ this->str = command[i].alt ? altstr : str;
+ this->str2 = command[i].alt ? altstr2 : str2;
+ this->result = substr(command[i].alt ?
+ "CRAIG: Positioned them, I don't know... I'm fairly wide guy." :
+ str, command[i].index);
+
+ printf("\tif (substr(\"%s%s\", %d) ne \"%s\") {\n",
+ this->str, this->str2, command[i].index, this->result);
+
+ printf("\t\tprintf(\"perl => substr(\\\"%s%s\\\", %d) = ",
+ this->str, this->str2, command[i].index);
+ printf("\\\"%%s\\\"\\n\",\n\t\t substr(\"%s%s\", %d));\n",
+ this->str, this->str2, command[i].index);
+ printf("\t\tprintf(\" D => substr(\\\"%s%s\\\", %d) = ",
+ this->str, this->str2, command[i].index);
+ printf("\\\"%%s\\\"\\n\",\n\t\t \"%s\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/i < end && !command[i].nolen/
+{
+ this->str = command[i].alt ? altstr : str;
+ this->str2 = command[i].alt ? altstr2 : str2;
+ this->result = substr(command[i].alt ?
+ "CRAIG: Positioned them, I don't know... I'm fairly wide guy." :
+ str, command[i].index, command[i].length);
+
+ printf("\tif (substr(\"%s%s\", %d, %d) ne \"%s\") {\n",
+ this->str, this->str2, command[i].index, command[i].length,
+ this->result);
+ printf("\t\tprintf(\"perl => substr(\\\"%s%s\\\", %d, %d) = ",
+ this->str, this->str2, command[i].index, command[i].length);
+ printf("\\\"%%s\\\"\\n\",\n\t\t substr(\"%s%s\", %d, %d));\n",
+ this->str, this->str2, command[i].index, command[i].length);
+ printf("\t\tprintf(\" D => substr(\\\"%s%s\\\", %d, %d) = ",
+ this->str, this->str2, command[i].index, command[i].length);
+ printf("\\\"%%s\\\"\\n\",\n\t\t \"%s\");\n", this->result);
+ printf("\t\t$failed++;\n");
+ printf("\t}\n\n");
+}
+
+tick-1ms
+/++i == end/
+{
+ printf("\texit($failed);\n}\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out
new file mode 100644
index 0000000..5b498ef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out
@@ -0,0 +1,254 @@
+#!/usr/perl5/bin/perl
+
+BEGIN {
+ if (substr("foobarbazbop", 3) ne "barbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 3) = \"%s\"\n",
+ substr("foobarbazbop", 3));
+ printf(" D => substr(\"foobarbazbop\", 3) = \"%s\"\n",
+ "barbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 300) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 300) = \"%s\"\n",
+ substr("foobarbazbop", 300));
+ printf(" D => substr(\"foobarbazbop\", 300) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -10) ne "obarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", -10) = \"%s\"\n",
+ substr("foobarbazbop", -10));
+ printf(" D => substr(\"foobarbazbop\", -10) = \"%s\"\n",
+ "obarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 0) ne "foobarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 0) = \"%s\"\n",
+ substr("foobarbazbop", 0));
+ printf(" D => substr(\"foobarbazbop\", 0) = \"%s\"\n",
+ "foobarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 1) ne "oobarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 1) = \"%s\"\n",
+ substr("foobarbazbop", 1));
+ printf(" D => substr(\"foobarbazbop\", 1) = \"%s\"\n",
+ "oobarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 11) ne "p") {
+ printf("perl => substr(\"foobarbazbop\", 11) = \"%s\"\n",
+ substr("foobarbazbop", 11));
+ printf(" D => substr(\"foobarbazbop\", 11) = \"%s\"\n",
+ "p");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 12) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 12) = \"%s\"\n",
+ substr("foobarbazbop", 12));
+ printf(" D => substr(\"foobarbazbop\", 12) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 13) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 13) = \"%s\"\n",
+ substr("foobarbazbop", 13));
+ printf(" D => substr(\"foobarbazbop\", 13) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 8, 20) ne "zbop") {
+ printf("perl => substr(\"foobarbazbop\", 8, 20) = \"%s\"\n",
+ substr("foobarbazbop", 8, 20));
+ printf(" D => substr(\"foobarbazbop\", 8, 20) = \"%s\"\n",
+ "zbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 4, 4) ne "arba") {
+ printf("perl => substr(\"foobarbazbop\", 4, 4) = \"%s\"\n",
+ substr("foobarbazbop", 4, 4));
+ printf(" D => substr(\"foobarbazbop\", 4, 4) = \"%s\"\n",
+ "arba");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 5, 8) ne "rbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 5, 8) = \"%s\"\n",
+ substr("foobarbazbop", 5, 8));
+ printf(" D => substr(\"foobarbazbop\", 5, 8) = \"%s\"\n",
+ "rbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 5, 9) ne "rbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 5, 9) = \"%s\"\n",
+ substr("foobarbazbop", 5, 9));
+ printf(" D => substr(\"foobarbazbop\", 5, 9) = \"%s\"\n",
+ "rbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 400, 20) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 400, 20) = \"%s\"\n",
+ substr("foobarbazbop", 400, 20));
+ printf(" D => substr(\"foobarbazbop\", 400, 20) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 400, 0) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 400, 0) = \"%s\"\n",
+ substr("foobarbazbop", 400, 0));
+ printf(" D => substr(\"foobarbazbop\", 400, 0) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 400, -1) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 400, -1) = \"%s\"\n",
+ substr("foobarbazbop", 400, -1));
+ printf(" D => substr(\"foobarbazbop\", 400, -1) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 3, 0) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 3, 0) = \"%s\"\n",
+ substr("foobarbazbop", 3, 0));
+ printf(" D => substr(\"foobarbazbop\", 3, 0) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 3, -1) ne "barbazbo") {
+ printf("perl => substr(\"foobarbazbop\", 3, -1) = \"%s\"\n",
+ substr("foobarbazbop", 3, -1));
+ printf(" D => substr(\"foobarbazbop\", 3, -1) = \"%s\"\n",
+ "barbazbo");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 3, -4) ne "barba") {
+ printf("perl => substr(\"foobarbazbop\", 3, -4) = \"%s\"\n",
+ substr("foobarbazbop", 3, -4));
+ printf(" D => substr(\"foobarbazbop\", 3, -4) = \"%s\"\n",
+ "barba");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 3, -20) ne "") {
+ printf("perl => substr(\"foobarbazbop\", 3, -20) = \"%s\"\n",
+ substr("foobarbazbop", 3, -20));
+ printf(" D => substr(\"foobarbazbop\", 3, -20) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -10, -5) ne "obarb") {
+ printf("perl => substr(\"foobarbazbop\", -10, -5) = \"%s\"\n",
+ substr("foobarbazbop", -10, -5));
+ printf(" D => substr(\"foobarbazbop\", -10, -5) = \"%s\"\n",
+ "obarb");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", 0, 400) ne "foobarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", 0, 400) = \"%s\"\n",
+ substr("foobarbazbop", 0, 400));
+ printf(" D => substr(\"foobarbazbop\", 0, 400) = \"%s\"\n",
+ "foobarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -1, 400) ne "p") {
+ printf("perl => substr(\"foobarbazbop\", -1, 400) = \"%s\"\n",
+ substr("foobarbazbop", -1, 400));
+ printf(" D => substr(\"foobarbazbop\", -1, 400) = \"%s\"\n",
+ "p");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -1, 0) ne "") {
+ printf("perl => substr(\"foobarbazbop\", -1, 0) = \"%s\"\n",
+ substr("foobarbazbop", -1, 0));
+ printf(" D => substr(\"foobarbazbop\", -1, 0) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -1, -1) ne "") {
+ printf("perl => substr(\"foobarbazbop\", -1, -1) = \"%s\"\n",
+ substr("foobarbazbop", -1, -1));
+ printf(" D => substr(\"foobarbazbop\", -1, -1) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -24, 24) ne "foobarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", -24, 24) = \"%s\"\n",
+ substr("foobarbazbop", -24, 24));
+ printf(" D => substr(\"foobarbazbop\", -24, 24) = \"%s\"\n",
+ "foobarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -24, 12) ne "") {
+ printf("perl => substr(\"foobarbazbop\", -24, 12) = \"%s\"\n",
+ substr("foobarbazbop", -24, 12));
+ printf(" D => substr(\"foobarbazbop\", -24, 12) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -24, 13) ne "f") {
+ printf("perl => substr(\"foobarbazbop\", -24, 13) = \"%s\"\n",
+ substr("foobarbazbop", -24, 13));
+ printf(" D => substr(\"foobarbazbop\", -24, 13) = \"%s\"\n",
+ "f");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -12, 12) ne "foobarbazbop") {
+ printf("perl => substr(\"foobarbazbop\", -12, 12) = \"%s\"\n",
+ substr("foobarbazbop", -12, 12));
+ printf(" D => substr(\"foobarbazbop\", -12, 12) = \"%s\"\n",
+ "foobarbazbop");
+ $failed++;
+ }
+
+ if (substr("foobarbazbop", -12, 11) ne "foobarbazbo") {
+ printf("perl => substr(\"foobarbazbop\", -12, 11) = \"%s\"\n",
+ substr("foobarbazbop", -12, 11));
+ printf(" D => substr(\"foobarbazbop\", -12, 11) = \"%s\"\n",
+ "foobarbazbo");
+ $failed++;
+ }
+
+ if (substr("CRAIG: Positioned them, I don't know... I'm fairly wide guy.", 100, 10) ne "") {
+ printf("perl => substr(\"CRAIG: Positioned them, I don't know... I'm fairly wide guy.\", 100, 10) = \"%s\"\n",
+ substr("CRAIG: Positioned them, I don't know... I'm fairly wide guy.", 100, 10));
+ printf(" D => substr(\"CRAIG: Positioned them, I don't know... I'm fairly wide guy.\", 100, 10) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ if (substr("CRAIG: Positioned them, I don't know... I'm fairly wide guy.", 100) ne "") {
+ printf("perl => substr(\"CRAIG: Positioned them, I don't know... I'm fairly wide guy.\", 100) = \"%s\"\n",
+ substr("CRAIG: Positioned them, I don't know... I'm fairly wide guy.", 100));
+ printf(" D => substr(\"CRAIG: Positioned them, I don't know... I'm fairly wide guy.\", 100) = \"%s\"\n",
+ "");
+ $failed++;
+ }
+
+ exit($failed);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d
new file mode 100644
index 0000000..2c02541
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option aggsortkey
+
+/*
+ * This is to check that we're correctly null-terminating the result of the
+ * substr() subroutine.
+ */
+
+tick-1ms
+/i++ > 1000/
+{
+ exit(0);
+}
+
+tick-1ms
+{
+ @[substr((i & 1) ? "Bryan is smart" : "he's not a dummy", 0,
+ (i & 1) ? 8 : 18)] = count();
+}
+
+END
+{
+ printa("%s\n", @);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d.out
new file mode 100644
index 0000000..26c19aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.substrminate.d.out
@@ -0,0 +1,3 @@
+Bryan is
+he's not a dummy
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d
new file mode 100644
index 0000000..b7ffbfa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option destructive
+
+BEGIN
+{
+ this->a = 9;
+ this->b = -2;
+
+ system("echo %s %d %d", "foo", this->a, this->b);
+ system("ping localhost");
+ system("echo %d", ++this->a);
+ system("ping localhost");
+ system("echo %d", ++this->a);
+ system("ping localhost");
+ system("echo %d", ++this->a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d.out
new file mode 100644
index 0000000..cd0d735
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.system.d.out
@@ -0,0 +1,8 @@
+foo 9 -2
+localhost is alive
+10
+localhost is alive
+11
+localhost is alive
+12
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d
new file mode 100644
index 0000000..2539630
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.tolower.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+
+ input[i] = "ahi";
+ expected[i++] = "ahi";
+
+ input[i] = "MaHi!";
+ expected[i++] = "mahi!";
+
+ input[i] = " Nase-5";
+ expected[i++] = " nase-5";
+
+ input[i] = "!@#$%";
+ expected[i++] = "!@#$%";
+
+ i = 0;
+}
+
+tick-1ms
+/input[i] != NULL && (this->out = tolower(input[i])) != expected[i]/
+{
+ printf("expected tolower(\"%s\") to be \"%s\"; found \"%s\"\n",
+ input[i], expected[i], this->out);
+ exit(1);
+}
+
+tick-1ms
+/input[i] != NULL/
+{
+ printf("tolower(\"%s\") is \"%s\", as expected\n",
+ input[i], expected[i]);
+}
+
+tick-1ms
+/input[i++] == NULL/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d
new file mode 100644
index 0000000..fd803f2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.toupper.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+
+ input[i] = "ahi";
+ expected[i++] = "AHI";
+
+ input[i] = "MaHi!";
+ expected[i++] = "MAHI!";
+
+ input[i] = " dace-9";
+ expected[i++] = " DACE-9";
+
+ input[i] = "!@#$%";
+ expected[i++] = "!@#$%";
+
+ i = 0;
+}
+
+tick-1ms
+/input[i] != NULL && (this->out = toupper(input[i])) != expected[i]/
+{
+ printf("expected toupper(\"%s\") to be \"%s\"; found \"%s\"\n",
+ input[i], expected[i], this->out);
+ exit(1);
+}
+
+tick-1ms
+/input[i] != NULL/
+{
+ printf("toupper(\"%s\") is \"%s\", as expected\n",
+ input[i], expected[i]);
+}
+
+tick-1ms
+/input[i++] == NULL/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_ADDROF_LVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_ADDROF_LVAL.d
new file mode 100644
index 0000000..8f5d694
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_ADDROF_LVAL.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * & can not be applied to a non-lvalue
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ */
+
+BEGIN
+{
+ trace(&1);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_EMPTY.empty.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_EMPTY.empty.d
new file mode 100644
index 0000000..929ccc6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/err.D_EMPTY.empty.d
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test the "empty translation unit" error path.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.clauses.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.clauses.d
new file mode 100644
index 0000000..a993029
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.clauses.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test the kinds of probe definition clause grammar rules.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations;
+ * Program Structure/Actions
+ */
+
+
+BEGIN
+{}
+
+BEGIN
+/1/
+{}
+
+tick-1
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.stmts.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.stmts.d
new file mode 100644
index 0000000..03a015a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/grammar/tst.stmts.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test the various kinds of D probe description statement
+ * rules in the grammar.
+ *
+ * SECTION: Program Structure/Probe Descriptions
+ *
+ */
+
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-1
+/i != 20/
+{
+ i++;
+ x = 0;
+ stack();
+ @a = count();
+ @b = max(x);
+ @c[x] = count();
+ @d[x] = max(x);
+}
+
+tick-1
+/i = 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh
new file mode 100644
index 0000000..b8240d6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh
@@ -0,0 +1,76 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This test verifies that we only use the first entry of a file with a given
+# name in the library path
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+firstinc=${TMPDIR:-/tmp}/firstinc.$$
+secondinc=${TMPDIR:-/tmp}/secondinc.$$
+expexit=23
+
+setup_include()
+{
+ mkdir $firstinc
+ mkdir $secondinc
+ cat > $firstinc/lib.d <<EOF
+inline int foobar = $expexit;
+#pragma D binding "1.0" foobar
+EOF
+ cat > $secondinc/lib.d <<EOF
+inline int foobar = 42;
+#pragma D binding "1.0" foobar
+EOF
+}
+
+clean()
+{
+ rm -rf $firstinc
+ rm -rf $secondinc
+}
+
+fail()
+{
+ echo "$@"
+ clean
+ exit 1
+}
+
+setup_include
+
+dtrace -L$firstinc -L$secondinc -e -n 'BEGIN{ exit(foobar) }'
+[[ $? != 0 ]] && fail "Failed to compile with same file in include path twice"
+dtrace -L$firstinc -L$secondinc -n 'BEGIN{ exit(foobar) }'
+status=$?
+[[ $status != $expexit ]] && fail "Exited with unexpected status code: $status"
+clean
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef1.d
new file mode 100644
index 0000000..39f2996
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef1.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test handling of an inline definition that overrides a previous
+ * definition of an inline definition.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline int foo = timestamp;
+inline int foo = 8;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef2.d
new file mode 100644
index 0000000..1df5908
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_DECL_IDRED.redef2.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test handling of an inline definition that overrides a previous
+ * definition of a dtrace built-in function.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline int rand = 7;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_IDENT_UNDEF.recur.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_IDENT_UNDEF.recur.d
new file mode 100644
index 0000000..95522d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_IDENT_UNDEF.recur.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * D program to test recursive inline definitions. This script should
+ * properly detect that foo is undefined on the right-hand side and fail.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline int foo = foo + 3;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef1.d
new file mode 100644
index 0000000..a42afb7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef1.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Attempt to create an invalid inline definition by creating an
+ * inline of a function type. This should fail to compile.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline cyc_func_t i = "i am a cyclic function";
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef2.d
new file mode 100644
index 0000000..9a246b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.baddef2.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Attempt to create an invalid inline definition by creating an
+ * inline of incompatible types. This should fail to compile.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline int i = "i am a string";
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.badxlate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.badxlate.d
new file mode 100644
index 0000000..963b604
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/err.D_OP_INCOMPAT.badxlate.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test an invalid inline definition of a translator. An inlined translation
+ * must have the same type as the translator output.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+inline vfs_t *invalid = xlate<psinfo_t>(curthread->t_procp);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineDataAssign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineDataAssign.d
new file mode 100644
index 0000000..c7ab62f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineDataAssign.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Declare different types of inline data types.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES: The commented lines defining floats and doubles should be uncommented
+ * once the functionality is provided.
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+inline char new_char = 'c';
+inline short new_short = 10;
+inline int new_int = 100;
+inline long new_long = 1234567890;
+inline long long new_long_long = 1234512345;
+inline int8_t new_int8 = 'p';
+inline int16_t new_int16 = 20;
+inline int32_t new_int32 = 200;
+inline int64_t new_int64 = 2000000;
+inline intptr_t new_intptr = 0x12345;
+inline uint8_t new_uint8 = 'q';
+inline uint16_t new_uint16 = 30;
+inline uint32_t new_uint32 = 300;
+inline uint64_t new_uint64 = 3000000;
+inline uintptr_t new_uintptr = 0x67890;
+/* inline float new_float = 1.23456;
+inline double new_double = 2.34567890;
+inline long double new_long_double = 3.567890123;
+*/
+
+inline int * pointer = &`kmem_flags;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineExpression.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineExpression.d
new file mode 100644
index 0000000..d67d3f2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineExpression.d
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ *
+ * Test different inline assignments by various expressions.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES: The commented lines for the floats and doubles should be uncommented
+ * once the functionality is implemented.
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+inline char new_char = 'c' + 2;
+inline short new_short = 10 * new_char;
+inline int new_int = 100 + new_short;
+inline long new_long = 1234567890;
+inline long long new_long_long = 1234512345 * new_long;
+inline int8_t new_int8 = 'p';
+inline int16_t new_int16 = 20 / new_int8;
+inline int32_t new_int32 = 200;
+inline int64_t new_int64 = 2000000 * (-new_int16);
+inline intptr_t new_intptr = 0x12345 - 129;
+inline uint8_t new_uint8 = 'q';
+inline uint16_t new_uint16 = 30 - new_uint8;
+inline uint32_t new_uint32 = 300 - 0;
+inline uint64_t new_uint64 = 3000000;
+inline uintptr_t new_uintptr = 0x67890 / new_uint64;
+
+/* inline float new_float = 1.23456;
+inline double new_double = 2.34567890;
+inline long double new_long_double = 3.567890123;
+*/
+
+inline int * pointer = &`kmem_flags;
+inline int result = 3 > 2 ? 3 : 2;
+
+BEGIN
+{
+ printf("new_char: %c\nnew_short: %d\nnew_int: %d\nnew_long: %d\n",
+ new_char, new_short, new_int, new_long);
+ printf("new_long_long: %d\nnew_int8: %d\nnew_int16: %d\n",
+ new_long_long, new_int8, new_int16);
+ printf("new_int32: %d\nnew_int64: %d\n", new_int32, new_int64);
+ printf("new_intptr: %d\nnew_uint8: %d\nnew_uint16: %d\n",
+ new_intptr, new_uint8, new_uint16);
+ printf("new_uint32:%d\nnew_uint64: %d\nnew_uintptr:%d\nresult:%d",
+ new_uint32, new_uint64, new_uintptr, result);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d
new file mode 100644
index 0000000..7f188fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Test the code generation and results of the various kinds of inlines.
+ * In particular, we test constant and expression-based scalar inlines,
+ * associative array inlines, and inlines using translators.
+ */
+
+#pragma D option quiet
+
+inline int i0 = 100 + 23; /* constant-folded integer constant */
+inline string i1 = probename; /* string variable reference */
+inline int i2 = pid != 0; /* expression involving a variable */
+
+struct s {
+ int s_x;
+};
+
+translator struct s < int T > {
+ s_x = T + 1;
+};
+
+inline struct s i3 = xlate < struct s > (i0); /* translator */
+inline int i4[int x, int y] = x + y; /* associative array */
+inline int i5[int x] = (xlate < struct s > (x)).s_x; /* array by xlate */
+
+BEGIN
+{
+ printf("i0 = %d\n", i0);
+ printf("i1 = %s\n", i1);
+ printf("i2 = %d\n", i2);
+
+ printf("i3.s_x = %d\n", i3.s_x);
+ printf("i4[10, 20] = %d\n", i4[10, 20]);
+ printf("i5[123] = %d\n", i5[123]);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d.out
new file mode 100644
index 0000000..c9a603b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineKinds.d.out
@@ -0,0 +1,7 @@
+i0 = 123
+i1 = BEGIN
+i2 = 1
+i3.s_x = 124
+i4[10, 20] = 30
+i5[123] = 124
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineTypedef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineTypedef.d
new file mode 100644
index 0000000..a624765
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineTypedef.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Create inline names from aliases created using typedef.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ *
+ * NOTES:
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+typedef char new_char;
+inline new_char char_var = 'c';
+
+typedef int * pointer;
+inline pointer p = &`kmem_flags;
+
+BEGIN
+{
+ printf("char_var: %c\npointer p: %d", char_var, *p);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineWritableAssign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineWritableAssign.d
new file mode 100644
index 0000000..a7842a3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/inline/tst.InlineWritableAssign.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Create inline names from aliases created using typedef.
+ *
+ * SECTION: Type and Constant Definitions/Inlines
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+struct record {
+ char c;
+ int i;
+};
+
+struct record rec1;
+inline struct record rec2 = rec1;
+
+union var {
+ char c;
+ int i;
+};
+
+union var un1;
+inline union var un2 = un1;
+
+
+BEGIN
+{
+ rec1.c = 'c';
+ rec1.i = 10;
+
+ un1.c = 'd';
+
+ printf("rec1.c: %c\nrec1.i:%d\nun1.c: %c\n", rec1.c, rec1.i, un1.c);
+ printf("rec2.c: %c\nrec2.i:%d\nun2.c: %c\n", rec2.c, rec2.i, un2.c);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.c
new file mode 100644
index 0000000..3cded11
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.c
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <assert.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+static sigjmp_buf env;
+
+static void
+interrupt(int sig)
+{
+ siglongjmp(env, sig);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *file = "/dev/null";
+ int i, n, fds[10];
+ struct sigaction act;
+
+ if (argc > 1) {
+ (void) fprintf(stderr, "Usage: %s\n", argv[0]);
+ return (EXIT_FAILURE);
+ }
+
+ act.sa_handler = interrupt;
+ act.sa_flags = 0;
+
+ (void) sigemptyset(&act.sa_mask);
+ (void) sigaction(SIGUSR1, &act, NULL);
+
+ closefrom(0);
+ n = 0;
+
+ /*
+ * With all of our file descriptors closed, wait here spinning in bogus
+ * ioctl() calls until DTrace hits us with a SIGUSR1 to start the test.
+ */
+ if (sigsetjmp(env, 1) == 0) {
+ for (;;)
+ (void) ioctl(-1, -1, NULL);
+ }
+
+ /*
+ * To test the fds[] array, we open /dev/null (a file with reliable
+ * pathname and properties) using various flags and seek offsets.
+ */
+ fds[n++] = open(file, O_RDONLY);
+ fds[n++] = open(file, O_WRONLY);
+ fds[n++] = open(file, O_RDWR);
+
+ fds[n++] = open(file, O_RDWR | O_APPEND | O_CREAT | O_DSYNC |
+ O_LARGEFILE | O_NOCTTY | O_NONBLOCK | O_NDELAY | O_RSYNC |
+ O_SYNC | O_TRUNC | O_XATTR, 0666);
+
+ fds[n++] = open(file, O_RDWR);
+ (void) lseek(fds[n - 1], 123, SEEK_SET);
+
+ /*
+ * Once we have all the file descriptors in the state we want to test,
+ * issue a bogus ioctl() on each fd with cmd -1 and arg NULL to whack
+ * our DTrace script into recording the content of the fds[] array.
+ */
+ for (i = 0; i < n; i++)
+ (void) ioctl(fds[i], -1, NULL);
+
+ assert(n <= sizeof (fds) / sizeof (fds[0]));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d
new file mode 100644
index 0000000..52a3312
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option destructive
+#pragma D option quiet
+
+syscall::ioctl:entry
+/pid == $1 && arg0 == -1u/
+{
+ raise(SIGUSR1); /* kick tst.fds.c out of its busy-wait loop */
+}
+
+syscall::ioctl:entry
+/pid == $1 && arg0 != -1u && arg1 == -1u && arg2 == NULL/
+{
+ printf("fds[%d] fi_name = %s\n", arg0, fds[arg0].fi_name);
+ printf("fds[%d] fi_dirname = %s\n", arg0, fds[arg0].fi_dirname);
+ printf("fds[%d] fi_pathname = %s\n", arg0, fds[arg0].fi_pathname);
+ printf("fds[%d] fi_fs = %s\n", arg0, fds[arg0].fi_fs);
+ printf("fds[%d] fi_mount = %s\n", arg0, fds[arg0].fi_mount);
+ printf("fds[%d] fi_offset = %d\n", arg0, fds[arg0].fi_offset);
+ printf("fds[%d] fi_oflags = 0x%x\n", arg0, fds[arg0].fi_oflags);
+}
+
+proc:::exit
+/pid == $1/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d.out
new file mode 100644
index 0000000..9d26826
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/io/tst.fds.d.out
@@ -0,0 +1,36 @@
+fds[0] fi_name = mm@0:null
+fds[0] fi_dirname = /devices/pseudo
+fds[0] fi_pathname = /devices/pseudo/mm@0:null
+fds[0] fi_fs = specfs
+fds[0] fi_mount = /devices
+fds[0] fi_offset = 0
+fds[0] fi_oflags = 0x0
+fds[1] fi_name = mm@0:null
+fds[1] fi_dirname = /devices/pseudo
+fds[1] fi_pathname = /devices/pseudo/mm@0:null
+fds[1] fi_fs = specfs
+fds[1] fi_mount = /devices
+fds[1] fi_offset = 0
+fds[1] fi_oflags = 0x1
+fds[2] fi_name = mm@0:null
+fds[2] fi_dirname = /devices/pseudo
+fds[2] fi_pathname = /devices/pseudo/mm@0:null
+fds[2] fi_fs = specfs
+fds[2] fi_mount = /devices
+fds[2] fi_offset = 0
+fds[2] fi_oflags = 0x2
+fds[3] fi_name = mm@0:null
+fds[3] fi_dirname = /devices/pseudo
+fds[3] fi_pathname = /devices/pseudo/mm@0:null
+fds[3] fi_fs = specfs
+fds[3] fi_mount = /devices
+fds[3] fi_offset = 0
+fds[3] fi_oflags = 0xebda
+fds[4] fi_name = mm@0:null
+fds[4] fi_dirname = /devices/pseudo
+fds[4] fi_pathname = /devices/pseudo/mm@0:null
+fds[4] fi_fs = specfs
+fds[4] fi_mount = /devices
+fds[4] fi_offset = 123
+fds[4] fi_oflags = 0x2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
new file mode 100755
index 0000000..128263e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl -w
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# get.ipv4remote.pl [tcpport]
+#
+# Find an IPv4 reachable remote host using both ifconfig(1M) and ping(1M).
+# If a tcpport is specified, return a host that is also listening on this
+# TCP port. Print the local address and the remote address, or an
+# error message if no suitable remote host was found. Exit status is 0 if
+# a host was found.
+#
+
+use strict;
+use IO::Socket;
+
+my $MAXHOSTS = 32; # max hosts to port scan
+my $TIMEOUT = 3; # connection timeout
+my $tcpport = @ARGV == 1 ? $ARGV[0] : 0;
+
+#
+# Determine local IP address
+#
+my $local = "";
+my $remote = "";
+my %Broadcast;
+my $up;
+open IFCONFIG, '/sbin/ifconfig -a |' or die "Couldn't run ifconfig: $!\n";
+while (<IFCONFIG>) {
+ next if /^lo/;
+
+ # "UP" is always printed first (see print_flags() in ifconfig.c):
+ $up = 1 if /^[a-z].*<UP,/;
+ $up = 0 if /^[a-z].*<,/;
+
+ # assume output is "inet X ... broadcast Z":
+ if (/inet (\S+) .* broadcast (\S+)/) {
+ my ($addr, $bcast) = ($1, $2);
+ $Broadcast{$addr} = $bcast;
+ $local = $addr if $up and $local eq "";
+ $up = 0;
+ }
+}
+close IFCONFIG;
+die "Could not determine local IP address" if $local eq "";
+
+#
+# Find the first remote host that responds to an icmp echo,
+# which isn't a local address.
+#
+open PING, "/sbin/ping -ns $Broadcast{$local} 56 $MAXHOSTS |" or
+ die "Couldn't run ping: $!\n";
+while (<PING>) {
+ if (/bytes from (.*): / and not defined $Broadcast{$1}) {
+ my $addr = $1;
+
+ if ($tcpport != 0) {
+ #
+ # Test TCP
+ #
+ my $socket = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => $addr,
+ PeerPort => $tcpport,
+ Timeout => $TIMEOUT,
+ );
+ next unless $socket;
+ close $socket;
+ }
+
+ $remote = $addr;
+ last;
+ }
+}
+close PING;
+die "Can't find a remote host for testing: No suitable response from " .
+ "$Broadcast{$local}\n" if $remote eq "";
+
+print "$local $remote\n";
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
new file mode 100755
index 0000000..837ca3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# get.ipv6remote.pl
+#
+# Find an IPv6 reachable remote host using both ifconfig(1M) and ping(1M).
+# Print the local address and the remote address, or print nothing if either
+# no IPv6 interfaces or remote hosts were found. (Remote IPv6 testing is
+# considered optional, and so not finding another IPv6 host is not an error
+# state we need to log.) Exit status is 0 if a host was found.
+#
+
+use strict;
+use IO::Socket;
+
+my $MAXHOSTS = 32; # max hosts to scan
+my $TIMEOUT = 3; # connection timeout
+my $MULTICAST = "FF02::1"; # IPv6 multicast address
+
+#
+# Determine local IP address
+#
+my $local = "";
+my $remote = "";
+my %Local;
+my $up;
+open IFCONFIG, '/sbin/ifconfig -a inet6 |'
+ or die "Couldn't run ifconfig: $!\n";
+while (<IFCONFIG>) {
+ next if /^lo/;
+
+ # "UP" is always printed first (see print_flags() in ifconfig.c):
+ $up = 1 if /^[a-z].*<UP,/;
+ $up = 0 if /^[a-z].*<,/;
+
+ # assume output is "inet6 ...":
+ if (m:inet6 (\S+)/:) {
+ my $addr = $1;
+ $Local{$addr} = 1;
+ $local = $addr if $up and $local eq "";
+ $up = 0;
+ }
+}
+close IFCONFIG;
+exit 1 if $local eq "";
+
+#
+# Find the first remote host that responds to an icmp echo,
+# which isn't a local address.
+#
+open PING, "/sbin/ping -ns -A inet6 $MULTICAST 56 $MAXHOSTS |" or
+ die "Couldn't run ping: $!\n";
+while (<PING>) {
+ if (/bytes from (.*): / and not defined $Local{$1}) {
+ $remote = $1;
+ last;
+ }
+}
+close PING;
+exit 2 if $remote eq "";
+
+print "$local $remote\n";
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh
new file mode 100755
index 0000000..0f2b64a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh
@@ -0,0 +1,70 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 ICMP to a local address.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. Unrelated ICMP on lo0 traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+
+$dtrace -c "/sbin/ping $local 3" -qs /dev/stdin <<EOF | sort -n
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out
new file mode 100644
index 0000000..41d6e0c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out
@@ -0,0 +1,6 @@
+
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255)
+127.0.0.1 is alive
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
new file mode 100755
index 0000000..c18dc76
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
@@ -0,0 +1,125 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {ip,tcp}:::{send,receive} of IPv4 TCP to local host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The local ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection and checks that at least the
+# following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
+
+# The actual count tested is 5 each way, since we are tracing both
+# source and destination events.
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$local",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $local port $tcpport" unless \$s;
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ tcpreceive++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 5 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 5 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
new file mode 100644
index 0000000..2a85b98
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
@@ -0,0 +1,7 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
new file mode 100755
index 0000000..6d08e24
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
@@ -0,0 +1,93 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test ip:::{send,receive} of IPv4 UDP to a local address.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP message using ping and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
+# 1 x ip:::receive (UDP received)
+#
+# No udp:::receive event is expected as the response ping -U elicits is
+# an ICMP PORT_UNREACHABLE response rather than a UDP packet, and locally
+# the echo request UDP packet only reaches IP, so the udp:::receive probe
+# is not triggered by it.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+
+$dtrace -c "/sbin/ping -U $local" -qs /dev/stdin <<EOF | grep -v 'is alive'
+BEGIN
+{
+ ipsend = udpsend = ipreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ udpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ ipreceive++;
+}
+
+END
+{
+ printf("Minimum UDP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 1 ? "yes" : "no");
+ printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
new file mode 100644
index 0000000..bca5532
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
@@ -0,0 +1,6 @@
+Minimum UDP events seen
+
+ip:::send - yes
+ip:::receive - yes
+udp:::send - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh
new file mode 100755
index 0000000..87553ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh
@@ -0,0 +1,81 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 ICMP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable.
+# 4. An unrelated ICMP between these hosts was traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+$dtrace -c "/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \
+ grep -v 'is alive' | sort -n
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out
new file mode 100644
index 0000000..b5915f8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out
@@ -0,0 +1,3 @@
+
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 4 0 255)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
new file mode 100755
index 0000000..e513ace
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
@@ -0,0 +1,128 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {tcp,ip}:::{send,receive} of IPv4 TCP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on ssh.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection and checks that at least the
+# following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr $tcpport | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$dest",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $dest port $tcpport" unless \$s;
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source"/
+{
+ tcpreceive++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 3 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 2 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 3 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 2 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
new file mode 100644
index 0000000..2a85b98
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
@@ -0,0 +1,7 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
new file mode 100755
index 0000000..cc7a32c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
@@ -0,0 +1,88 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {udp,ip}:::{send,receive} of IPv4 UDP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP message using ping and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+$dtrace -c "/sbin/ping -U $dest" -qs /dev/stdin <<EOF | grep -v 'is alive'
+BEGIN
+{
+ ipsend = udpsend = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ udpsend++;
+}
+
+END
+{
+ printf("Minimum UDP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
new file mode 100644
index 0000000..bdbbe1f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
@@ -0,0 +1,5 @@
+Minimum UDP events seen
+
+ip:::send - yes
+udp:::send - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh
new file mode 100755
index 0000000..f63d1ed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh
@@ -0,0 +1,82 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv6 ICMP to a local address. This creates a
+# temporary lo0/inet6 interface if one doesn't already exist.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. Unrelated ICMPv6 on lo0 traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=::1
+
+if ! ifconfig lo0 inet6 > /dev/null 2>&1; then
+ if ! ifconfig lo0 inet6 plumb up; then
+ print -u2 "could not plumb lo0 inet6 for testing"
+ exit 3
+ fi
+ removeinet6=1
+else
+ removeinet6=0
+fi
+
+$dtrace -c "/sbin/ping -A inet6 $local 3" -qs /dev/stdin <<EOF | sort -n
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+EOF
+
+if (( removeinet6 )); then
+ ifconfig lo0 inet6 unplumb
+fi
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out
new file mode 100644
index 0000000..529d251
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out
@@ -0,0 +1,6 @@
+
+::1 is alive
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh
new file mode 100755
index 0000000..c859e6b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh
@@ -0,0 +1,88 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv6 ICMP to a remote host. This test is
+# skipped if there are no physical interfaces configured with IPv6, or no
+# other IPv6 hosts are reachable.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. An unrelated ICMPv6 between these hosts was traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv6remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ print -nu2 "Could not find a local IPv6 interface and a remote IPv6 "
+ print -u2 "host. Aborting test.\n"
+ print -nu2 "For this test to continue, a \"ping -ns -A inet6 FF02::1\" "
+ print -u2 "must respond with a\nremote IPv6 host."
+ exit 3
+fi
+
+#
+# Shake loose any ICMPv6 Neighbor advertisement messages before tracing.
+#
+/sbin/ping $dest 3 > /dev/null 2>&1
+
+$dtrace -c "/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \
+ grep -v 'is alive' | sort -n
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out
new file mode 100644
index 0000000..1ddcd07
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out
@@ -0,0 +1,3 @@
+
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh
new file mode 100644
index 0000000..5e0c747
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh
@@ -0,0 +1,182 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the local ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp fusion send and
+# receive events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The local ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, 1 message then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, 1 message then the FIN ACK)
+#
+# The actual ip count tested is 5 each way, since we are tracing both
+# source and destination events. The actual tcp count tested is 7
+# each way, since the TCP fusion send/receive events will not reach IP.
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$local",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $local port $tcpport" unless \$s;
+ print \$s "testing state machine transitions";
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+ connreq = connest = connaccept = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+ tcpreceive++;
+}
+
+tcp:::state-change
+{
+ state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ connest++;
+}
+
+tcp:::accept-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connaccept++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 7 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 7 ? "yes" : "no");
+ printf("tcp:::state-change to syn-sent - %s\n",
+ state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to syn-received - %s\n",
+ state_event[TCP_STATE_SYN_RECEIVED] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to established - %s\n",
+ state_event[TCP_STATE_ESTABLISHED] >= 2 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-1 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to close-wait - %s\n",
+ state_event[TCP_STATE_CLOSE_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-2 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to last-ack - %s\n",
+ state_event[TCP_STATE_LAST_ACK] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to time-wait - %s\n",
+ state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::connect-request - %s\n",
+ connreq >=1 ? "yes" : "no");
+ printf("tcp:::connect-established - %s\n",
+ connest >=1 ? "yes" : "no");
+ printf("tcp:::accept-established - %s\n",
+ connaccept >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out
new file mode 100644
index 0000000..ea1c27e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out
@@ -0,0 +1,18 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to syn-received - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to last-ack - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+tcp:::accept-established - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh
new file mode 100644
index 0000000..4bf4362
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh
@@ -0,0 +1,172 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the remote ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp send and receive
+# events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The remote ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 4 x ip:::send (2 during the TCP handshake, the message, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, the messages, then a FIN)
+# 3 x ip:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr $tcpport | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$dest",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $dest port $tcpport" unless \$s;
+ print \$s "testing state machine transitions";
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+ connreq = connest = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ tcpreceive++;
+}
+
+tcp:::state-change
+{
+ state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ connest++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 4 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 3 ? "yes" : "no");
+ printf("tcp:::state-change to syn-sent - %s\n",
+ state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to established - %s\n",
+ state_event[TCP_STATE_ESTABLISHED] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-1 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-2 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to time-wait - %s\n",
+ state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::connect-request - %s\n",
+ connreq >=1 ? "yes" : "no");
+ printf("tcp:::connect-established - %s\n",
+ connest >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out
new file mode 100644
index 0000000..27388fb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out
@@ -0,0 +1,15 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/manifest/test.jar-manifest b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/manifest/test.jar-manifest
new file mode 100644
index 0000000..8f07fb2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/manifest/test.jar-manifest
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path: /usr/share/lib/java/dtrace.jar
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestAbort.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestAbort.java
new file mode 100644
index 0000000..310dd18
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestAbort.java
@@ -0,0 +1,158 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+import java.util.NoSuchElementException;
+
+/**
+ * Regression for 6426129 abort() after close() throws
+ * NoSuchElementException.
+ */
+public class TestAbort {
+ static boolean aborted = false;
+
+ public static void
+ main(String[] args)
+ {
+ Consumer consumer = new LocalConsumer();
+
+ // Test for deadlock (bug 6419880)
+ try {
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ consumer.close();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ consumer = new LocalConsumer();
+
+ // Should be able to abort an unopened consumer
+ try {
+ aborted = false;
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStopped(ConsumerEvent e) {
+ aborted = true;
+ }
+ });
+ consumer.abort();
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ if (!aborted) {
+ throw new IllegalStateException("consumer not aborted");
+ }
+ consumer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ consumer = new LocalConsumer();
+
+ // Should be safe to call abort() in any state
+ try {
+ consumer.abort();
+ consumer.open();
+ consumer.abort();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.abort();
+ consumer.enable();
+ consumer.abort();
+ consumer.go();
+ consumer.abort();
+ consumer.close();
+ // Should be safe to call after close()
+ try {
+ consumer.abort();
+ } catch (NoSuchElementException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ consumer = new LocalConsumer();
+
+ // Tests that close() throws expected exception when called on
+ // synchronized consumer.
+ try {
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ synchronized (consumer) {
+ consumer.close();
+ }
+ } catch (IllegalThreadStateException e) {
+ try {
+ consumer.close();
+ System.out.println("Successful");
+ System.exit(0);
+ } catch (NoSuchElementException x) {
+ x.printStackTrace();
+ System.exit(1);
+ }
+ }
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.err.println("Failed");
+ System.exit(1);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestBean.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestBean.java
new file mode 100644
index 0000000..dd4a969
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestBean.java
@@ -0,0 +1,706 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+import java.util.*;
+import java.io.*;
+import java.beans.*;
+import java.lang.reflect.*;
+
+/**
+ * Regression test for serialization and XML encoding/decoding. Tests
+ * every Serializable class in the Java DTrace API by creating a dummy
+ * instance, writing it to a file, then reading it back in and comparing
+ * the string values of the object before and after, as well as
+ * verifying object equality before and after if the class overrides the
+ * equals() method.
+ */
+public class TestBean {
+ public static final String[] TESTS = new String[] {
+ "ExitRecord",
+ "AggregationRecord",
+ "Aggregation",
+ "Tuple",
+ "ScalarRecord",
+ "KernelStackRecord",
+ "LogDistribution",
+ "LinearDistribution",
+ "Option",
+ "ProcessState",
+ "ProbeDescription",
+ "PrintaRecord",
+ "PrintfRecord",
+ "ProbeData",
+ "Aggregate",
+ "UserStackRecord",
+ "AvgValue",
+ "CountValue",
+ "SumValue",
+ "MinValue",
+ "MaxValue",
+ "Error",
+ "Drop",
+ "InterfaceAttributes",
+ "ProgramInfo",
+ "ProbeInfo",
+ "Probe",
+ "Flow",
+ "KernelSymbolRecord",
+ "UserSymbolRecord",
+ "UserSymbolRecord$Value",
+ "Program",
+ "Program$File",
+ "StddevValue"
+ };
+
+ static File file;
+
+ static void
+ exit(int status)
+ {
+ System.out.flush();
+ System.err.flush();
+ System.exit(status);
+ }
+
+ public static XMLEncoder
+ getXMLEncoder(File file)
+ {
+ XMLEncoder encoder = null;
+ try {
+ OutputStream out = new BufferedOutputStream
+ (new FileOutputStream(file));
+ encoder = new XMLEncoder(out);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ return encoder;
+ }
+
+ public static XMLDecoder
+ getXMLDecoder(File file)
+ {
+ return getXMLDecoder(file, null);
+ }
+
+ public static XMLDecoder
+ getXMLDecoder(File file, ExceptionListener exceptionListener)
+ {
+ XMLDecoder decoder = null;
+ try {
+ InputStream in = new BufferedInputStream
+ (new FileInputStream(file));
+ decoder = new XMLDecoder(in, null, exceptionListener);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ return decoder;
+ }
+
+ public static ExitRecord
+ getExitRecord()
+ {
+ ExitRecord r = new ExitRecord(1);
+ return r;
+ }
+
+ public static AggregationRecord
+ getAggregationRecord()
+ {
+ Tuple tuple = getTuple();
+ AggregationValue value = new CountValue(7);
+ AggregationRecord r = new AggregationRecord(tuple, value);
+ return r;
+ }
+
+ public static Aggregation
+ getAggregation()
+ {
+ List < AggregationRecord > list =
+ new ArrayList < AggregationRecord > ();
+ AggregationRecord r;
+ r = getAggregationRecord();
+ list.add(r);
+
+ ValueRecord v1 = new ScalarRecord(new byte[] {(byte)1, (byte)2,
+ (byte)3}, 3);
+ ValueRecord v2 = new ScalarRecord("shebang!", 256);
+ Tuple tuple = new Tuple(v1, v2);
+ AggregationValue value = getLinearDistribution();
+ r = new AggregationRecord(tuple, value);
+ list.add(r);
+
+ Aggregation a = new Aggregation("counts", 2, list);
+ return a;
+ }
+
+ public static Tuple
+ getTuple()
+ {
+ ValueRecord r1 = new ScalarRecord("cat", 256);
+ ValueRecord r2 = new ScalarRecord(new Integer(9), 2);
+ ValueRecord r3 = new KernelStackRecord(
+ new StackFrame[] {
+ new StackFrame("has"),
+ new StackFrame("nine"),
+ new StackFrame("lives")},
+ new byte[] { (byte)0, (byte)1, (byte)2 });
+ ValueRecord r4 = new ScalarRecord(new byte[] {(byte)1, (byte)2,
+ (byte)3}, 3);
+
+ Tuple tuple = new Tuple(r1, r2, r3, r4);
+ return tuple;
+ }
+
+ public static ScalarRecord
+ getScalarRecord()
+ {
+ Object v = new byte[] {(byte)1, (byte)2, (byte)3};
+ ScalarRecord r = new ScalarRecord(v, 3);
+ return r;
+ }
+
+ public static KernelStackRecord
+ getKernelStackRecord()
+ {
+ StackFrame[] stackFrames = new StackFrame[] {
+ new StackFrame("Frame 1"),
+ new StackFrame("Frame 2"),
+ new StackFrame("Frame 3")
+ };
+ KernelStackRecord r = new KernelStackRecord(stackFrames,
+ new byte[] { (byte)0, (byte)1, (byte)2 });
+ return r;
+ }
+
+ public static LogDistribution
+ getLogDistribution()
+ {
+ List < Distribution.Bucket > buckets =
+ new ArrayList < Distribution.Bucket > ();
+ Distribution.Bucket bucket;
+ int n = 0;
+ long base = 0;
+ long i;
+ long sign;
+ long nextSign;
+ long power;
+ long nextPower;
+ long lowerBound;
+ long upperBound;
+ for (i = -62; i <= 62; ++i) {
+ if (i == 0) {
+ bucket = new Distribution.Bucket(-1, -1, n++);
+ buckets.add(bucket);
+ bucket = new Distribution.Bucket(0, 0, n++);
+ buckets.add(bucket);
+ bucket = new Distribution.Bucket(1, 1, n++);
+ buckets.add(bucket);
+ continue;
+ }
+ sign = ((i < 0) ? -1L : 1L);
+ power = (sign * i);
+ nextSign = (((i + 1) < 0) ? -1L : 1L);
+ nextPower = (nextSign * (i + 1));
+ lowerBound = sign * ((long) Math.pow(2L, power));
+ upperBound = (nextPower == 0 ? -2L :
+ (nextSign * ((long) Math.pow(2L, nextPower))) - 1);
+ if ((upperBound > 0) && ((upperBound * 2L) < 0)) {
+ upperBound = Long.MAX_VALUE;
+ }
+ bucket = new Distribution.Bucket(lowerBound, upperBound, n++);
+ buckets.add(bucket);
+ }
+ LogDistribution d = new LogDistribution(buckets);
+ return d;
+ }
+
+ public static LinearDistribution
+ getLinearDistribution()
+ {
+ List < Distribution.Bucket > buckets =
+ new ArrayList < Distribution.Bucket > ();
+ Distribution.Bucket bucket;
+ int n = 10; // number of buckets
+ int base = 1;
+ int step = 10;
+ bucket = new Distribution.Bucket(Long.MIN_VALUE, (base - 1), 0);
+ buckets.add(bucket);
+ for (int i = base; i < (n * step); i += step) {
+ bucket = new Distribution.Bucket(i, (i + (step - 1)),
+ ((i - 1) / step));
+ buckets.add(bucket);
+ }
+ bucket = new Distribution.Bucket((n * step) + 1, Long.MAX_VALUE, 0);
+ buckets.add(bucket);
+ LinearDistribution d = new LinearDistribution(base, step, buckets);
+ return d;
+ }
+
+ public static Option
+ getOption()
+ {
+ Option option = new Option("aggrate", "1s");
+ return option;
+ }
+
+ public static ProcessState
+ getProcessState()
+ {
+ ProcessState p = new ProcessState(123456, "UNDEAD",
+ 3, "SIGSTOP",
+ -2, "Process stopped on dime");
+ return p;
+ }
+
+ public static ProbeDescription
+ getProbeDescription()
+ {
+ ProbeDescription d = new ProbeDescription(256, "syscall", null,
+ "malloc", "entry");
+ return d;
+ }
+
+ public static PrintaRecord
+ getPrintaRecord()
+ {
+ List < Aggregation > aggregations = new ArrayList < Aggregation > ();
+ Aggregation a = getAggregation();
+ aggregations.add(a);
+ aggregations.add(a);
+ Map < Tuple, String > formattedOutput =
+ new HashMap < Tuple, String > ();
+ for (Tuple t : a.asMap().keySet()) {
+ formattedOutput.put(t, "cat");
+ }
+ List < Tuple > tuples = new ArrayList < Tuple > ();
+ for (Tuple t : a.asMap().keySet()) {
+ tuples.add(t);
+ }
+ Collections.sort(tuples);
+ PrintaRecord r = new PrintaRecord(1234567890L,
+ aggregations, formattedOutput, tuples,
+ "Yes, this is the formatted printa() output");
+ return r;
+ }
+
+ public static PrintfRecord
+ getPrintfRecord()
+ {
+ List < ValueRecord > list = new ArrayList < ValueRecord > ();
+ ValueRecord v1 = getScalarRecord();
+ ValueRecord v2 = new ScalarRecord(new Integer(7), 4);
+ list.add(v1);
+ list.add(v2);
+ PrintfRecord r = new PrintfRecord(list,
+ "long formatted string");
+ return r;
+ }
+
+ public static ProbeData
+ getProbeData()
+ {
+ List < Record > list = new ArrayList < Record > ();
+ list.add(getPrintaRecord());
+ list.add(getPrintfRecord());
+ list.add(getScalarRecord());
+ list.add(getUserSymbolRecord());
+ list.add(getUserStackRecord());
+ list.add(getExitRecord());
+ ProbeData d = new ProbeData(7, 1, getProbeDescription(),
+ getFlow(), list);
+ return d;
+ }
+
+ public static Aggregate
+ getAggregate()
+ {
+ List < Aggregation > list = new ArrayList < Aggregation > ();
+ list.add(getAggregation());
+
+ List < AggregationRecord > reclist =
+ new ArrayList < AggregationRecord > ();
+ AggregationRecord r;
+ ValueRecord v1 = new ScalarRecord("cat", 256);
+ ValueRecord v2 = new ScalarRecord("dog", 256);
+ ValueRecord v3 = new ScalarRecord("mouse", 256);
+ ValueRecord v4 = new ScalarRecord("mouse", 256);
+ ValueRecord v5 = new ScalarRecord(new Byte((byte) 'C'), 1);
+ ValueRecord v6 = new ScalarRecord(new Short((short) 7), 2);
+ Tuple tuple = new Tuple(v1, v2, v3, v4, v5, v6);
+ AggregationValue value = getCountValue();
+ r = new AggregationRecord(tuple, value);
+ reclist.add(r);
+ list.add(new Aggregation("times", 1, reclist));
+
+ Aggregate a = new Aggregate(1234567890L, list);
+ return a;
+ }
+
+ public static UserStackRecord
+ getUserStackRecord()
+ {
+ StackFrame[] frames = new StackFrame[] {
+ new StackFrame("User Stack Frame 1"),
+ new StackFrame("User Stack Frame 2"),
+ new StackFrame("User Stack Frame 3")
+ };
+ UserStackRecord r = new UserStackRecord(123456, frames,
+ new byte[] { (byte)0, (byte)1, (byte)2 });
+ return r;
+ }
+
+ public static AvgValue
+ getAvgValue()
+ {
+ AvgValue v = new AvgValue(5, 20, 4);
+ return v;
+ }
+
+ public static CountValue
+ getCountValue()
+ {
+ CountValue v = new CountValue(9);
+ return v;
+ }
+
+ public static MinValue
+ getMinValue()
+ {
+ MinValue v = new MinValue(101);
+ return v;
+ }
+
+ public static MaxValue
+ getMaxValue()
+ {
+ MaxValue v = new MaxValue(101);
+ return v;
+ }
+
+ public static SumValue
+ getSumValue()
+ {
+ SumValue v = new SumValue(25);
+ return v;
+ }
+
+ public static org.opensolaris.os.dtrace.Error
+ getError()
+ {
+ ProbeDescription probe = getProbeDescription();
+ org.opensolaris.os.dtrace.Error e =
+ new org.opensolaris.os.dtrace.Error(probe, 8, 3,
+ 1, 20, "DTRACEFLT_BADALIGN", -1, "error on enabled probe ID 8 " +
+ "(ID " + probe.getID() + ": " + probe + "): Bad alignment " +
+ "(0x33ef) in action #1 at DIF offset 20");
+ return e;
+ }
+
+ public static Drop
+ getDrop()
+ {
+ Drop drop = new Drop(2, "SPECBUSY", 72, 1041,
+ "Guess we dropped stuff all over the place.");
+ return drop;
+ }
+
+ public static InterfaceAttributes
+ getInterfaceAttributes()
+ {
+ InterfaceAttributes a = new InterfaceAttributes(
+ InterfaceAttributes.Stability.UNSTABLE,
+ InterfaceAttributes.Stability.EVOLVING,
+ InterfaceAttributes.DependencyClass.ISA);
+ return a;
+ }
+
+ public static ProgramInfo
+ getProgramInfo()
+ {
+ ProgramInfo info = new ProgramInfo(getInterfaceAttributes(),
+ getInterfaceAttributes(), 256);
+ return info;
+ }
+
+ public static ProbeInfo
+ getProbeInfo()
+ {
+ ProbeInfo info = new ProbeInfo(getInterfaceAttributes(),
+ getInterfaceAttributes());
+ return info;
+ }
+
+ public static Probe
+ getProbe()
+ {
+ Probe p = new Probe(getProbeDescription(), getProbeInfo());
+ return p;
+ }
+
+ public static Flow
+ getFlow()
+ {
+ Flow f = new Flow(Flow.Kind.RETURN.name(), 3);
+ return f;
+ }
+
+ public static KernelSymbolRecord
+ getKernelSymbolRecord()
+ {
+ KernelSymbolRecord r = new KernelSymbolRecord("mod`func+0x4", -1L);
+ return r;
+ }
+
+ public static UserSymbolRecord
+ getUserSymbolRecord()
+ {
+ UserSymbolRecord r = new UserSymbolRecord(7, "mod`func+0x4", -1L);
+ return r;
+ }
+
+ public static UserSymbolRecord.Value
+ getUserSymbolRecord$Value()
+ {
+ UserSymbolRecord.Value v = new UserSymbolRecord.Value(7, -1L);
+ return v;
+ }
+
+ public static Program
+ getProgram()
+ {
+ final String PROGRAM = "syscall:::entry { @[execname] = count(); }";
+ Consumer consumer = new LocalConsumer();
+ Program p;
+ try {
+ consumer.open();
+ p = consumer.compile(PROGRAM);
+ consumer.close();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ p = null;
+ }
+ return p;
+ }
+
+ public static Program.File
+ getProgram$File()
+ {
+ final String PROGRAM = "syscall:::entry { @[execname] = count(); }";
+ Consumer consumer = new LocalConsumer();
+ Program p;
+ try {
+ OutputStream out = new FileOutputStream(file);
+ out.write(PROGRAM.getBytes(), 0, PROGRAM.length());
+ out.flush();
+ out.close();
+ consumer.open();
+ p = consumer.compile(file);
+ consumer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ p = null;
+ }
+ return Program.File.class.cast(p);
+ }
+
+ public static StddevValue
+ getStddevValue()
+ {
+ StddevValue v = new StddevValue(37, 114, 5, Integer.toString(9544));
+ return v;
+ }
+
+ @SuppressWarnings("unchecked")
+ static String
+ getString(Object o)
+ {
+ String s;
+ if (o instanceof ScalarRecord) {
+ o = ((ScalarRecord)o).getValue();
+ }
+
+ if (o instanceof byte[]) {
+ s = Arrays.toString((byte[])o);
+ } else if (o instanceof Object[]) {
+ s = Arrays.toString((Object[])o);
+ } else {
+ Class c = o.getClass();
+ try {
+ Method m = c.getDeclaredMethod("toLogString");
+ s = (String)m.invoke(o);
+ } catch (Exception e) {
+ s = o.toString();
+ }
+ }
+ return s;
+ }
+
+ static void
+ checkEquality(Object obj, Object newobj)
+ {
+ // If the class overrides equals(), make sure the re-created
+ // object still equals the original object
+ try {
+ Method eq = obj.getClass().getDeclaredMethod("equals",
+ Object.class);
+ Boolean ret = (Boolean) eq.invoke(obj, newobj);
+ if (ret != true) {
+ System.err.println("serialization failed: " +
+ obj.getClass().getName());
+ exit(1);
+ }
+ } catch (Exception e) {
+ // Does not override equals(), although a super-class might.
+ // A better test would check for any superclass other than
+ // Object.class.
+ }
+ }
+
+ static void
+ performSerializationTest(File file, String classname)
+ throws IOException, ClassNotFoundException
+ {
+ String methodName = "get" + classname;
+ Object obj = null;
+ Object newobj = null;
+ try {
+ Method method = TestBean.class.getDeclaredMethod(methodName);
+ obj = method.invoke(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+
+ System.out.println(classname + ":");
+ String serialized = getString(obj);
+ System.out.println(" serialized: " + serialized);
+ FileOutputStream fos = new FileOutputStream(file);
+ ObjectOutputStream out = new ObjectOutputStream(fos);
+ out.writeObject(obj);
+ out.close();
+ FileInputStream fis = new FileInputStream(file);
+ ObjectInputStream in = new ObjectInputStream(fis);
+ newobj = in.readObject();
+ in.close();
+ String deserialized = getString(newobj);
+ System.out.println(" deserialized: " + deserialized);
+
+ if (!serialized.equals(deserialized)) {
+ System.err.println("serialization failed: " + classname);
+ exit(1);
+ }
+ checkEquality(obj, newobj);
+ }
+
+ static void
+ performBeanTest(File file, String classname)
+ {
+ String methodName = "get" + classname;
+ Object obj = null;
+ Object newobj = null;
+ try {
+ Method method = TestBean.class.getDeclaredMethod(methodName);
+ obj = method.invoke(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+
+ Class c = obj.getClass();
+ if (c.getConstructors().length == 0) {
+ return;
+ }
+
+ System.out.println(classname + ":");
+ XMLEncoder encoder = getXMLEncoder(file);
+ String encoded = getString(obj);
+ System.out.println(" encoded: " + encoded);
+ encoder.writeObject(obj);
+ encoder.close();
+ XMLDecoder decoder = getXMLDecoder(file);
+ newobj = decoder.readObject();
+ String decoded = getString(newobj);
+ System.out.println(" decoded: " + decoded);
+ decoder.close();
+
+ if (!encoded.equals(decoded)) {
+ System.err.println("bean persistence failed: " + classname);
+ exit(1);
+ }
+ checkEquality(obj, newobj);
+ }
+
+ public static void
+ main(String[] args)
+ {
+ if ((args.length != 1) && (args.length != 2)) {
+ System.err.println("usage: java TestBean < filename > " +
+ "[ < classname > ]");
+ exit(1);
+ }
+
+ String filename = args[0];
+ String classname = null;
+ if (args.length >= 2) {
+ classname = args[1];
+ }
+
+ file = new File(filename);
+ try {
+ if (!file.canRead()) {
+ try {
+ file.createNewFile();
+ } catch (Exception e) {
+ System.err.println("failed to create " + filename);
+ exit(1);
+ }
+ }
+ } catch (SecurityException e) {
+ System.err.println("failed to open " + filename);
+ exit(1);
+ }
+
+ String[] tests = (classname == null ? TESTS:
+ new String[] { classname });
+ try {
+ for (int i = 0; i < tests.length; ++i) {
+ performSerializationTest(file, tests[i]);
+ performBeanTest(file, tests[i]);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ exit(1);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestClose.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestClose.java
new file mode 100644
index 0000000..c7a9e89
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestClose.java
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression for bug 6419880 close() hangs running consumer.
+ */
+public class TestClose {
+ public static void
+ main(String[] args)
+ {
+ Consumer consumer = new LocalConsumer();
+
+ try {
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ consumer.close();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ consumer = new LocalConsumer();
+
+ try {
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ // Test new rule that close() is illegal while holding
+ // lock on consumer.
+ synchronized (consumer) {
+ consumer.close();
+ }
+ } catch (IllegalThreadStateException e) {
+ consumer.close();
+ System.out.println("Successful");
+ System.exit(0);
+ }
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.err.println("Failed");
+ System.exit(1);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java
new file mode 100644
index 0000000..b5ace25
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestDrop.java
@@ -0,0 +1,169 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+import java.util.*;
+import java.util.concurrent.atomic.*;
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression test for 6521523 aggregation drops can hang the Java
+ * DTrace API.
+ */
+public class TestDrop {
+ static final String PROGRAM =
+ "fbt:genunix::entry { @[execname, pid] = count(); }";
+
+ static AtomicLong consumerThreadID = new AtomicLong();
+ static AtomicLong getAggregateThreadID = new AtomicLong();
+ static AtomicBoolean done = new AtomicBoolean();
+ static int seconds;
+
+ private static void
+ startTimer()
+ {
+ if (seconds <= 0) {
+ return;
+ }
+
+ final Timer timer = new Timer();
+ timer.schedule(new TimerTask() {
+ public void run() {
+ done.set(true);
+ timer.cancel();
+ }
+ }, seconds * 1000L);
+ }
+
+ private static void
+ sampleAggregate(Consumer consumer) throws DTraceException
+ {
+ while (consumer.isRunning() && !done.get()) {
+ try {
+ Thread.currentThread().sleep(50);
+ } catch (InterruptedException e) {
+ }
+
+ consumer.getAggregate(Collections. <String> emptySet());
+ }
+ }
+
+ private static void
+ startAggregateThread(final Consumer consumer)
+ {
+ Runnable aggregateSampler = new Runnable() {
+ public void run() {
+ Thread t = Thread.currentThread();
+ getAggregateThreadID.set(t.getId());
+ Throwable x = null;
+ try {
+ sampleAggregate(consumer);
+ } catch (Throwable e) {
+ x = e;
+ }
+
+ if (Thread.holdsLock(LocalConsumer.class)) {
+ if (x != null) {
+ x.printStackTrace();
+ }
+ System.out.println("Lock held");
+ System.exit(1);
+ } else {
+ System.out.println("Lock released");
+ consumer.close(); // blocks if lock held
+ }
+ }
+ };
+
+ Thread t = new Thread(aggregateSampler, "Aggregate Sampler");
+ t.start();
+ }
+
+ static void
+ usage()
+ {
+ System.err.println("usage: java TestDrop [ seconds ]");
+ System.exit(2);
+ }
+
+ public static void
+ main(String[] args)
+ {
+ if (args.length == 1) {
+ try {
+ seconds = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ usage();
+ }
+ } else if (args.length > 1) {
+ usage();
+ }
+
+ final Consumer consumer = new LocalConsumer() {
+ protected Thread createThread() {
+ Runnable worker = new Runnable() {
+ public void run() {
+ Thread t = Thread.currentThread();
+ consumerThreadID.set(t.getId());
+ work();
+ }
+ };
+ Thread t = new Thread(worker);
+ return t;
+ }
+ };
+
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStarted(ConsumerEvent e) {
+ startAggregateThread(consumer);
+ startTimer();
+ }
+ public void dataDropped(DropEvent e) throws ConsumerException {
+ Thread t = Thread.currentThread();
+ if (t.getId() == getAggregateThreadID.get()) {
+ Drop drop = e.getDrop();
+ throw new ConsumerException(drop.getDefaultMessage(),
+ drop);
+ }
+ }
+ });
+
+ try {
+ consumer.open();
+ consumer.setOption(Option.aggsize, Option.kb(1));
+ consumer.setOption(Option.aggrate, Option.millis(101));
+ consumer.compile(PROGRAM);
+ consumer.enable();
+ consumer.go(new ExceptionHandler() {
+ public void handleException(Throwable e) {
+ e.printStackTrace();
+ }
+ });
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestEnable.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestEnable.java
new file mode 100644
index 0000000..0e5a608
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestEnable.java
@@ -0,0 +1,151 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Prove that enable() handles multiple programs, recognizing programs
+ * that are already enabled and programs that were compiled by another
+ * consumer.
+ */
+public class TestEnable {
+ static void
+ exit(int status)
+ {
+ System.out.flush();
+ System.err.flush();
+ System.exit(status);
+ }
+
+ public static void
+ main(String[] args)
+ {
+ Consumer consumer = new LocalConsumer();
+
+ try {
+ consumer.open();
+ Program p0 = consumer.compile("dtrace:::BEGIN");
+ Program p1 = consumer.compile("syscall:::entry");
+ Program p2 = consumer.compile("dtrace:::END");
+ consumer.enable(p0);
+ consumer.enable(p1);
+ try {
+ consumer.go();
+ System.err.println("go() illegal, not all programs " +
+ "enabled (p0, p1)");
+ exit(1);
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ try {
+ consumer.enable();
+ System.err.println("enable() illegal, some programs " +
+ "already enabled (p0, p1)");
+ exit(1);
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ try {
+ consumer.enable(p0);
+ System.err.println("cannot enable a program that " +
+ "has already been enabled (p0)");
+ exit(1);
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ consumer.enable(p2);
+ Program p3 = consumer.compile("syscall:::return");
+ try {
+ consumer.go();
+ System.err.println("go() illegal, not all programs " +
+ "enabled (p0, p1, p2)");
+ exit(1);
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ try {
+ consumer.enable();
+ System.err.println("enable() illegal, some programs " +
+ "already enabled (p0, p1, p2)");
+ exit(1);
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ // Try to fool the consumer with a program compiled by
+ // another consumer
+ Consumer consumer2 = new LocalConsumer();
+ consumer2.open();
+ Program p3x = consumer2.compile("syscall:::return");
+ try {
+ consumer.enable(p3x);
+ System.err.println("cannot enable program compiled " +
+ "by another consumer");
+ exit(1);
+ } catch (IllegalArgumentException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1);
+ } finally {
+ consumer2.close();
+ }
+ consumer.enable(p3);
+ consumer.go();
+ consumer.close();
+
+ // Enable all compiled programs at once
+ consumer = new LocalConsumer();
+ consumer.open();
+ consumer.compile("dtrace:::BEGIN");
+ consumer.compile("syscall:::entry");
+ consumer.compile("dtrace:::END");
+ consumer.enable();
+ consumer.go();
+ consumer.close();
+ exit(0);
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java
new file mode 100644
index 0000000..2bc43ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression for bug 6413280 lookupKernelFunction() and
+ * lookupUserFunction() truncate last character.
+ */
+public class TestFunctionLookup {
+ static final String kernelLookupProgram = "sdt:::callout-start { " +
+ "@[((callout_t *)arg0)->c_func] = count(); }";
+ static final String userLookupProgram = "pid$target::f2:entry { " +
+ "@[arg0] = count(); }";
+
+ public static void
+ main(String[] args)
+ {
+ if (args.length != 1) {
+ System.err.println("usage: java TestFunctionLookup <command>");
+ System.exit(1);
+ }
+ String cmd = args[0];
+
+ Consumer consumer = new LocalConsumer();
+ try {
+ consumer.open();
+ consumer.compile(kernelLookupProgram);
+ consumer.enable();
+ consumer.go();
+ Aggregate a;
+ Number address;
+ String f;
+ boolean done = false;
+ for (int i = 0; (i < 20) && !done; ++i) {
+ Thread.currentThread().sleep(100);
+ a = consumer.getAggregate();
+ for (Aggregation agg : a.getAggregations()) {
+ for (Tuple tuple : agg.asMap().keySet()) {
+ address = (Number)tuple.get(0).getValue();
+ if (address instanceof Integer) {
+ int addr = (Integer)address;
+ f = consumer.lookupKernelFunction(addr);
+ } else {
+ long addr = (Long)address;
+ f = consumer.lookupKernelFunction(addr);
+ }
+ if (f.equals("genunix`cv_wakeup")) {
+ System.out.println(f);
+ done = true;
+ }
+ }
+ }
+ }
+ consumer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ consumer = new LocalConsumer();
+ try {
+ consumer.open();
+ int pid = consumer.createProcess(cmd);
+ consumer.compile(userLookupProgram);
+ consumer.enable();
+ consumer.go();
+ Thread.currentThread().sleep(500);
+ Aggregate a = consumer.getAggregate();
+ Number address;
+ String f;
+ for (Aggregation agg : a.getAggregations()) {
+ for (Tuple tuple : agg.asMap().keySet()) {
+ address = (Number)tuple.get(0).getValue();
+ if (address instanceof Integer) {
+ int addr = (Integer)address;
+ f = consumer.lookupUserFunction(pid, addr);
+ } else {
+ long addr = (Long)address;
+ f = consumer.lookupUserFunction(pid, addr);
+ }
+ System.out.println(f);
+ }
+ }
+ consumer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java
new file mode 100644
index 0000000..e02df85
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java
@@ -0,0 +1,252 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+import org.opensolaris.os.dtrace.*;
+import java.util.*;
+
+/**
+ * Assert getAggregate() can explicitly specify the anonymous aggregation.
+ */
+public class TestGetAggregate {
+ static final String programString =
+ "profile:::tick-50ms" +
+ "{" +
+ " @ = count();" +
+ " @a = count();" +
+ "}";
+
+ static final String ANONYMOUS_AGGREGATION = "";
+ static final int TICK = 50;
+ static final int EXPECTED_TICKS = 3;
+ static final int INTERVALS = 4;
+
+ static void
+ testIncluded(Consumer consumer, String ... aggregationNames)
+ throws DTraceException, InterruptedException
+ {
+ Aggregate aggregate;
+ Set <String> included = new HashSet <String> ();
+ int n = 1;
+
+ for (String name : aggregationNames) {
+ included.add(name);
+ }
+
+ // Wait up to a full second to obtain aggregate data. Without a
+ // time limit, we'll loop forever if no aggregation was
+ // successfully included.
+ do {
+ Thread.sleep(TICK);
+ aggregate = consumer.getAggregate(included, null);
+ } while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
+
+ for (String name : included) {
+ if (aggregate.getAggregation(name) == null) {
+ throw new IllegalStateException("@" + name +
+ " was explicitly included but did not appear " +
+ "in the aggregate");
+ }
+ }
+ for (Aggregation a : aggregate.getAggregations()) {
+ if (!included.contains(a.getName())) {
+ throw new IllegalStateException("@" + a.getName() +
+ " was not explicitly included but appeared " +
+ "in the aggregate anyway");
+ }
+ }
+
+ if (!consumer.isRunning()) {
+ throw new IllegalStateException("consumer exited");
+ }
+ }
+
+ static void
+ testCleared(Consumer consumer, String ... aggregationNames)
+ throws DTraceException, InterruptedException
+ {
+ Aggregate aggregate;
+ AggregationRecord rec;
+ long value;
+ Long firstValue;
+ int n = 1;
+ Map <String, Long> firstValues = new HashMap <String, Long> ();
+ Set <String> cleared = new HashSet <String> ();
+
+ for (String name : aggregationNames) {
+ cleared.add(name);
+ }
+
+ do {
+ Thread.sleep(TICK);
+ aggregate = consumer.getAggregate(null, cleared);
+ } while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK));
+ n = 1;
+
+ do {
+ Thread.sleep(TICK * EXPECTED_TICKS);
+ aggregate = consumer.getAggregate(null, cleared);
+
+ for (Aggregation a : aggregate.getAggregations()) {
+ if (!firstValues.containsKey(a.getName())) {
+ rec = a.getRecord(Tuple.EMPTY);
+ value = rec.getValue().getValue().longValue();
+ firstValues.put(a.getName(), value);
+ }
+ }
+ } while (consumer.isRunning() && n++ < INTERVALS);
+
+ for (Aggregation a : aggregate.getAggregations()) {
+ rec = a.getRecord(Tuple.EMPTY);
+ value = rec.getValue().getValue().longValue();
+ firstValue = firstValues.get(a.getName());
+
+ if (cleared.contains(a.getName())) {
+ // last value should be about the same as first value
+ if (value > (firstValue * 2)) {
+ throw new IllegalStateException(
+ "@" + a.getName() + " should have " +
+ "been cleared but instead grew from " +
+ firstValue + " to " + value);
+ }
+ } else {
+ // last value should be about (INTERVALS * firstValue)
+ if (value < (firstValue * 2)) {
+ throw new IllegalStateException(
+ "@" + a.getName() + " should have " +
+ "accumulated a running total but " +
+ "instead went from " +
+ firstValue + " to " + value);
+ }
+ }
+ }
+
+ if (!consumer.isRunning()) {
+ throw new IllegalStateException("consumer exited");
+ }
+ }
+
+ static Integer includedStatus;
+ static Integer clearedStatus;
+
+ static void
+ startIncludedTest()
+ {
+ final Consumer consumer = new LocalConsumer();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStarted(ConsumerEvent e) {
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ testIncluded(consumer, ANONYMOUS_AGGREGATION);
+ includedStatus = 0;
+ } catch (Exception e) {
+ includedStatus = 1;
+ e.printStackTrace();
+ } finally {
+ consumer.abort();
+ }
+ }
+ }).start();
+ }
+ });
+
+ try {
+ consumer.open();
+ consumer.setOption(Option.aggrate, Option.millis(TICK));
+ consumer.compile(programString);
+ consumer.enable();
+ consumer.go();
+ } catch (Exception e) {
+ includedStatus = 1;
+ e.printStackTrace();
+ }
+ }
+
+ static void
+ startClearedTest()
+ {
+ final Consumer consumer = new LocalConsumer();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStarted(ConsumerEvent e) {
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ testCleared(consumer, ANONYMOUS_AGGREGATION);
+ clearedStatus = 0;
+ } catch (Exception e) {
+ clearedStatus = 1;
+ e.printStackTrace();
+ } finally {
+ consumer.abort();
+ }
+ }
+ }).start();
+ }
+ });
+
+ try {
+ consumer.open();
+ consumer.setOption(Option.aggrate, Option.millis(TICK));
+ consumer.compile(programString);
+ consumer.enable();
+ consumer.go();
+ } catch (Exception e) {
+ clearedStatus = 1;
+ e.printStackTrace();
+ }
+ }
+
+ public static void
+ main(String[] args)
+ {
+ startIncludedTest();
+
+ do {
+ try {
+ Thread.sleep(TICK);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ } while (includedStatus == null);
+
+ startClearedTest();
+
+ do {
+ try {
+ Thread.sleep(TICK);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ } while (clearedStatus == null);
+
+ if (includedStatus != 0 || clearedStatus != 0) {
+ System.out.println("Failure");
+ System.exit(1);
+ }
+
+ System.out.println("Success");
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMaxConsumers.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMaxConsumers.java
new file mode 100644
index 0000000..50eeac2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMaxConsumers.java
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression for 6506495 -DJAVA_DTRACE_MAX_CONSUMERS=N for any N &lt; 8
+ * is treated as if it were 8.
+ */
+public class TestMaxConsumers {
+ static final String MAX_CONSUMERS_PROPERTY_NAME =
+ "JAVA_DTRACE_MAX_CONSUMERS";
+
+ static Integer
+ getIntegerProperty(String name)
+ {
+ Integer value = null;
+ String property = System.getProperty(name);
+ if (property != null && property.length() != 0) {
+ try {
+ value = Integer.parseInt(property);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+ return value;
+ }
+
+ public static void
+ main(String[] args)
+ {
+ Integer property = getIntegerProperty(MAX_CONSUMERS_PROPERTY_NAME);
+ int max = (property == null ? 0 : property);
+ int n = (property == null ? 11 : (max < 1 ? 1 : max));
+
+ Consumer[] consumers = new Consumer[n];
+ try {
+ for (int i = 0; i < n; ++i) {
+ consumers[i] = new LocalConsumer();
+ consumers[i].open();
+ }
+ for (int i = 0; i < n; ++i) {
+ consumers[i].close();
+ }
+ for (int i = 0; i < n; ++i) {
+ consumers[i] = new LocalConsumer();
+ consumers[i].open();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ try {
+ Consumer consumer = new LocalConsumer();
+ consumer.open();
+ if (max > 0) {
+ System.out.println("Error: " + (max + 1) + " > " +
+ MAX_CONSUMERS_PROPERTY_NAME);
+ } else {
+ System.out.println("Success");
+ }
+ consumer.close();
+ } catch (Exception e) {
+ System.out.println("Success");
+ } finally {
+ for (int i = 0; i < n; ++i) {
+ consumers[i].close();
+ }
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMultiAggPrinta.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMultiAggPrinta.java
new file mode 100644
index 0000000..facdf7f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestMultiAggPrinta.java
@@ -0,0 +1,144 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression for multi-aggregation printa() corner cases.
+ */
+public class TestMultiAggPrinta {
+ static int exitStatus;
+
+ // Gets a string representation of the given PrintaRecord minus the
+ // timestamp of the aggregate snapshot, so that the output is
+ // comparable across multiple test runs.
+ static String
+ printaRecordString(PrintaRecord rec)
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append(PrintaRecord.class.getName());
+ buf.append("[aggregations = ");
+ buf.append(rec.getAggregations());
+ buf.append(", formattedStrings = ");
+ buf.append(rec.getFormattedStrings());
+ buf.append(", tuples = ");
+ buf.append(rec.getTuples());
+ buf.append(", output = ");
+ buf.append(rec.getOutput());
+ buf.append(']');
+ return buf.toString();
+ }
+
+ static String
+ probeDataString(ProbeData data)
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append(ProbeData.class.getName());
+ buf.append("[epid = ");
+ buf.append(data.getEnabledProbeID());
+ // Do not include cpu, since it can change across test runs
+ buf.append(", enabledProbeDescription = ");
+ buf.append(data.getEnabledProbeDescription());
+ buf.append(", flow = ");
+ buf.append(data.getFlow());
+ buf.append(", records = ");
+
+ List <Record> records = data.getRecords();
+ Record record;
+ Object value;
+ buf.append('[');
+ for (int i = 0; i < records.size(); ++i) {
+ if (i > 0) {
+ buf.append(", ");
+ }
+ record = records.get(i);
+ if (record instanceof ValueRecord) {
+ value = ((ValueRecord)record).getValue();
+ if (value instanceof String) {
+ buf.append("\"");
+ buf.append((String)value);
+ buf.append("\"");
+ } else {
+ buf.append(record);
+ }
+ } else if (record instanceof PrintaRecord) {
+ PrintaRecord printa = (PrintaRecord)record;
+ buf.append(printaRecordString(printa));
+ } else {
+ buf.append(record);
+ }
+ }
+ buf.append(']');
+ return buf.toString();
+ }
+
+ public static void
+ main(String[] args)
+ {
+ if (args.length != 1) {
+ System.err.println("usage: java TestMultiAggPrinta <script>");
+ System.exit(2);
+ }
+
+ final Consumer consumer = new LocalConsumer();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void dataReceived(DataEvent e) {
+ ProbeData data = e.getProbeData();
+ List <Record> records = data.getRecords();
+ for (Record r : records) {
+ if (r instanceof ExitRecord) {
+ ExitRecord exitRecord = (ExitRecord)r;
+ exitStatus = exitRecord.getStatus();
+ }
+ }
+ System.out.println(probeDataString(e.getProbeData()));
+ }
+ public void consumerStopped(ConsumerEvent e) {
+ consumer.close();
+ System.exit(exitStatus);
+ }
+ });
+
+ File file = new File(args[0]);
+ try {
+ consumer.open();
+ consumer.compile(file);
+ consumer.enable();
+ consumer.go();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeData.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeData.java
new file mode 100644
index 0000000..78a65f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeData.java
@@ -0,0 +1,110 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import java.util.*;
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression test verifies that ProbeData instances sort as expected
+ * with multiple enabled probe IDs and multiple records including byte
+ * array (sorted as unsigned bytes), stand-alone ufunc() action, and
+ * signed integer.
+ */
+public class TestProbeData {
+ public static final String PROGRAM =
+ "pid$target::fN:entry\n" +
+ "{\n" +
+ " tracemem(copyin(arg1, 6), 6);\n" +
+ " ufunc(arg0);\n" +
+ " trace((int)arg2);\n" +
+ "}" +
+ "" +
+ "pid$target::fN2:entry\n" +
+ "{\n" +
+ " tracemem(copyin(arg1, 6), 6);\n" +
+ " ufunc(arg0);\n" +
+ " trace((int)arg2);\n" +
+ "}";
+
+ static String
+ getString(ProbeData p)
+ {
+ StringBuilder buf = new StringBuilder();
+ buf.append("[probe ");
+ buf.append(p.getEnabledProbeID());
+ buf.append(' ');
+ ProbeDescription d = p.getEnabledProbeDescription();
+ buf.append("pid$target");
+ buf.append(':');
+ buf.append(d.getModule());
+ buf.append(':');
+ buf.append(d.getFunction());
+ buf.append(':');
+ buf.append(d.getName());
+ buf.append(' ');
+ buf.append(p.getRecords());
+ buf.append("]");
+ return buf.toString();
+ }
+
+ public static void
+ main(String[] args)
+ {
+ if (args.length != 1) {
+ System.err.println("usage: java TestProbedata <command>");
+ System.exit(2);
+ }
+
+ String command = args[0];
+ final Consumer consumer = new LocalConsumer();
+ final List <ProbeData> list = new ArrayList <ProbeData> ();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void dataReceived(DataEvent e) {
+ list.add(e.getProbeData());
+ }
+ public void consumerStopped(ConsumerEvent e) {
+ Collections.sort(list);
+ for (ProbeData p : list) {
+ System.out.println(getString(p));
+ System.out.println();
+ }
+ consumer.close();
+ }
+ });
+
+ try {
+ consumer.open();
+ consumer.createProcess(command);
+ consumer.compile(PROGRAM);
+ consumer.enable();
+ consumer.go();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeDescription.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeDescription.java
new file mode 100644
index 0000000..b9e9570
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestProbeDescription.java
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+import java.util.logging.*;
+
+/**
+ * Regression for 6399915 ProbeDescription single arg constructor should
+ * parse probe descriptions.
+ */
+public class TestProbeDescription {
+ public static void
+ main(String[] args)
+ {
+ ProbeDescription p = null;
+ int len = args.length;
+ if (len == 0) {
+ p = new ProbeDescription("syscall:::entry");
+ } else if (len == 1) {
+ p = new ProbeDescription(args[0]);
+ } else if (len == 2) {
+ p = new ProbeDescription(args[0], args[1]);
+ } else if (len == 3) {
+ p = new ProbeDescription(args[0], args[1], args[2]);
+ } else if (len == 4) {
+ p = new ProbeDescription(args[0], args[1], args[2], args[3]);
+ }
+ System.out.println(p);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStateMachine.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStateMachine.java
new file mode 100644
index 0000000..8875d06
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStateMachine.java
@@ -0,0 +1,627 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Regression test for the LocalConsumer state machine. Calls Consumer
+ * methods before and after open(), compile(), enable(), go(), stop(),
+ * and close() to verify that the calls succeed as expected or fail with
+ * the expected Java exception.
+ */
+public class TestStateMachine {
+ static Program program;
+
+ static void
+ exit(int status)
+ {
+ exit(status, null);
+ }
+
+ static void
+ exit(int status, String msg)
+ {
+ if (msg != null) {
+ System.out.println(msg);
+ }
+ System.out.flush();
+ System.err.flush();
+ System.exit(status);
+ }
+
+ static void
+ printState(Consumer consumer)
+ {
+ System.out.println("open: " + consumer.isOpen());
+ System.out.println("enabled: " + consumer.isEnabled());
+ System.out.println("closed: " + consumer.isClosed());
+ }
+
+ static void
+ beforeOpen(Consumer consumer)
+ {
+ System.out.println("before open");
+ printState(consumer);
+
+ // compile
+ try {
+ consumer.compile("syscall:::entry");
+ exit(1, "compile before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "compile before open");
+ }
+
+ // enable
+ try {
+ consumer.enable();
+ exit(1, "enable before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "enable before open");
+ }
+
+ // getOption, setOption, unsetOption
+ try {
+ consumer.getOption(Option.bufsize);
+ exit(1, "getOption before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getOption before open");
+ }
+ try {
+ consumer.setOption(Option.bufsize, Option.mb(1));
+ exit(1, "setOption before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "setOption before open");
+ }
+ try {
+ consumer.unsetOption(Option.quiet);
+ exit(1, "unsetOption before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "unsetOption before open");
+ }
+
+ // createProcess, grabProcess
+ try {
+ consumer.createProcess("date");
+ exit(1, "createProcess before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "createProcess before open");
+ }
+ try {
+ consumer.grabProcess(1);
+ exit(1, "grabProcess before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "grabProcess before open");
+ }
+
+ // listProbes
+ try {
+ consumer.listProbes(ProbeDescription.EMPTY);
+ exit(1, "listProbes before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "listProbes before open");
+ }
+
+ // getAggregate
+ try {
+ consumer.getAggregate();
+ exit(1, "getAggregate before open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getAggregate before open");
+ }
+
+ // getVersion
+ try {
+ consumer.getVersion(); // allowed
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getVersion before open");
+ }
+ }
+
+ static void
+ beforeCompile(Consumer consumer)
+ {
+ System.out.println("before compile");
+ printState(consumer);
+
+ // open
+ try {
+ consumer.open();
+ exit(1, "open after open");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "open after open");
+ }
+
+ // enable
+ try {
+ consumer.enable();
+ exit(1, "enable before compile");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "enable before compile");
+ }
+ }
+
+ static void
+ beforeEnable(Consumer consumer)
+ {
+ System.out.println("before enable");
+ printState(consumer);
+
+ // go
+ try {
+ consumer.go();
+ exit(1, "go before enable");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "go before enable");
+ }
+ }
+
+ static void
+ beforeGo(Consumer consumer)
+ {
+ System.out.println("before go");
+ printState(consumer);
+
+ // getAggregate
+ try {
+ consumer.getAggregate();
+ exit(1, "getAggregate before go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getAggregate before go");
+ }
+
+ // lookupKernelFunction, lookupUserFunction
+ try {
+ consumer.lookupKernelFunction(1);
+ exit(1, "lookupKernelFunction before go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "lookupKernelFunction before go");
+ }
+ try {
+ consumer.lookupUserFunction(1, 1);
+ exit(1, "lookupUserFunction before go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "lookupUserFunction before go");
+ }
+
+ // stop
+ try {
+ consumer.stop();
+ exit(1, "stop before go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "stop before go");
+ }
+ }
+
+ static void
+ afterGo(Consumer consumer, Program program)
+ {
+ System.out.println("after go");
+ printState(consumer);
+
+ // go
+ try {
+ consumer.go();
+ exit(1, "go after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "go after go");
+ }
+
+ // createProcess, grabProcess
+ try {
+ consumer.createProcess("date");
+ exit(1, "createProcess after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "createProcess after go");
+ }
+ try {
+ consumer.grabProcess(1);
+ exit(1, "grabProcess after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "grabProcess after go");
+ }
+
+ // listProbes
+ try {
+ consumer.listProbes(ProbeDescription.EMPTY);
+ exit(1, "listProbes after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "listProbes after go");
+ }
+
+ // compile
+ try {
+ consumer.compile("syscall:::entry");
+ exit(1, "compile after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "compile after go");
+ }
+
+ // enable
+ try {
+ consumer.enable();
+ exit(1, "enable after go");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "enable after go");
+ }
+
+ // getAggregate
+ try {
+ consumer.getAggregate();
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getAggregate after go");
+ }
+
+ // getProgramInfo
+ try {
+ consumer.getProgramInfo(program);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getProgramInfo after go");
+ }
+
+ // getOption, setOption, unsetOption
+ try {
+ consumer.getOption(Option.quiet);
+ consumer.setOption(Option.quiet);
+ consumer.unsetOption(Option.quiet);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "get, set, unset option after go");
+ }
+ }
+
+ static void
+ afterStop(Consumer consumer, Program program)
+ {
+ System.out.println("after stop");
+ printState(consumer);
+
+ // stop
+ try {
+ consumer.stop();
+ exit(1, "stop after stop");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "stop after stop");
+ }
+
+ // getAggregate
+ try {
+ consumer.getAggregate();
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getAggregate after stop");
+ }
+
+ // getProgramInfo
+ try {
+ consumer.getProgramInfo(program);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getProgramInfo after stop");
+ }
+
+ // getOption, setOption, unsetOption
+ try {
+ consumer.getOption(Option.quiet);
+ consumer.setOption(Option.quiet);
+ consumer.unsetOption(Option.quiet);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "get, set, unset option after stop");
+ }
+ }
+
+ static void
+ afterClose(Consumer consumer, Program program)
+ {
+ System.out.println("after close");
+ printState(consumer);
+
+ // open
+ try {
+ consumer.open();
+ exit(1, "open after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "open after close");
+ }
+
+ // compile
+ try {
+ consumer.compile("syscall:::entry");
+ exit(1, "compile after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "compile after close");
+ }
+
+ // enable
+ try {
+ consumer.enable();
+ exit(1, "enable after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "enable after close");
+ }
+
+ // getOption, setOption, unsetOption
+ try {
+ consumer.getOption(Option.bufsize);
+ exit(1, "getOption after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getOption after close");
+ }
+ try {
+ consumer.setOption(Option.bufsize, Option.mb(1));
+ exit(1, "setOption after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "setOption after close");
+ }
+ try {
+ consumer.unsetOption(Option.quiet);
+ exit(1, "unsetOption after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "unsetOption after close");
+ }
+
+ // createProcess, grabProcess
+ try {
+ consumer.createProcess("date");
+ exit(1, "createProcess after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "createProcess after close");
+ }
+ try {
+ consumer.grabProcess(1);
+ exit(1, "grabProcess after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "grabProcess after close");
+ }
+
+ // listProbes
+ try {
+ consumer.listProbes(ProbeDescription.EMPTY);
+ exit(1, "listProbes after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "listProbes after close");
+ }
+
+ // getAggregate
+ try {
+ consumer.getAggregate();
+ exit(1, "getAggregate after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getAggregate after close");
+ }
+
+ // getVersion
+ try {
+ consumer.getVersion(); // allowed
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getVersion after close");
+ }
+
+ // go
+ try {
+ consumer.go();
+ exit(1, "go after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "go after close");
+ }
+
+ // lookupKernelFunction, lookupUserFunction
+ try {
+ consumer.lookupKernelFunction(1);
+ exit(1, "lookupKernelFunction after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "lookupKernelFunction after close");
+ }
+ try {
+ consumer.lookupUserFunction(1, 1);
+ exit(1, "lookupUserFunction after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "lookupUserFunction after close");
+ }
+
+ // stop
+ try {
+ consumer.stop();
+ exit(1, "stop after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "stop after close");
+ }
+
+ // getProgramInfo
+ try {
+ consumer.getProgramInfo(program);
+ exit(1, "getProgramInfo after close");
+ } catch (IllegalStateException e) {
+ System.out.println(e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ exit(1, "getProgramInfo after close");
+ }
+ }
+
+ public static void
+ main(String[] args)
+ {
+ final Consumer consumer = new LocalConsumer();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ public void consumerStarted(ConsumerEvent e) {
+ System.out.println("consumerStarted, running: " +
+ consumer.isRunning());
+ afterGo(consumer, program);
+ }
+ public void consumerStopped(ConsumerEvent e) {
+ System.out.println("consumerStopped, running: " +
+ consumer.isRunning());
+ }
+ });
+
+ try {
+ beforeOpen(consumer);
+ consumer.open();
+ beforeCompile(consumer);
+ program = consumer.compile(
+ "syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ beforeEnable(consumer);
+ consumer.enable();
+ beforeGo(consumer);
+ System.out.println("before go, running: " + consumer.isRunning());
+ consumer.go();
+ // Avoid race, call afterGo() in ConsumerListener
+ try {
+ Thread.currentThread().sleep(300);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ consumer.stop();
+ System.out.println("after stop, running: " + consumer.isRunning());
+ afterStop(consumer, program);
+ consumer.close();
+ afterClose(consumer, program);
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStopLock.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStopLock.java
new file mode 100644
index 0000000..f37c9cf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestStopLock.java
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+import org.opensolaris.os.dtrace.*;
+
+/**
+ * Test for bug 6399888 stop() hangs if ConsumerListener calls
+ * synchronized Consumer method
+ */
+public class TestStopLock {
+ public static void
+ main(String[] args)
+ {
+ final Consumer consumer = new LocalConsumer();
+ consumer.addConsumerListener(new ConsumerAdapter() {
+ @Override
+ public void intervalBegan(ConsumerEvent e) {
+ consumer.isRunning();
+ }
+ });
+
+ try {
+ consumer.open();
+ consumer.compile("syscall:::entry { @[execname] = count(); } " +
+ "tick-101ms { printa(@); }");
+ consumer.enable();
+ consumer.go();
+ try {
+ Thread.currentThread().sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ consumer.stop();
+ consumer.close();
+ } catch (DTraceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.out.println("Successful");
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh
new file mode 100644
index 0000000..85c2c70
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh
@@ -0,0 +1,39 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6426129 abort() after close() throws
+# NoSuchElementException.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestAbort
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh.out
new file mode 100644
index 0000000..628d787
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Abort.ksh.out
@@ -0,0 +1 @@
+Successful
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh
new file mode 100644
index 0000000..99b232e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh
@@ -0,0 +1,41 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# All Serializable classes can be serializaed and deserialized,
+# also encoded in XML and decoded, and still remain equal and have
+# equal string values.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestBean TestBean.out
+rm -f TestBean.out
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh.out
new file mode 100644
index 0000000..cf24c67
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh.out
@@ -0,0 +1,722 @@
+ExitRecord:
+ serialized: 1
+ deserialized: 1
+ExitRecord:
+ encoded: 1
+ decoded: 1
+AggregationRecord:
+ serialized: org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]
+ deserialized: org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]
+AggregationRecord:
+ encoded: org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]
+ decoded: org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]
+Aggregation:
+ serialized: org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]
+ deserialized: org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]
+Aggregation:
+ encoded: org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]
+ decoded: org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]
+Tuple:
+ serialized: [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]
+ deserialized: [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]
+Tuple:
+ encoded: [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]
+ decoded: [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]
+ScalarRecord:
+ serialized: [1, 2, 3]
+ deserialized: [1, 2, 3]
+ScalarRecord:
+ encoded: [1, 2, 3]
+ decoded: [1, 2, 3]
+KernelStackRecord:
+ serialized:
+ Frame 1
+ Frame 2
+ Frame 3
+
+ deserialized:
+ Frame 1
+ Frame 2
+ Frame 3
+
+KernelStackRecord:
+ encoded:
+ Frame 1
+ Frame 2
+ Frame 3
+
+ decoded:
+ Frame 1
+ Frame 2
+ Frame 3
+
+LogDistribution:
+ serialized: org.opensolaris.os.dtrace.Distribution[buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = -4611686018427387904, max = -2305843009213693953, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2305843009213693952, max = -1152921504606846977, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1152921504606846976, max = -576460752303423489, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = -576460752303423488, max = -288230376151711745, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = -288230376151711744, max = -144115188075855873, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = -144115188075855872, max = -72057594037927937, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = -72057594037927936, max = -36028797018963969, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = -36028797018963968, max = -18014398509481985, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = -18014398509481984, max = -9007199254740993, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = -9007199254740992, max = -4503599627370497, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4503599627370496, max = -2251799813685249, frequency = 10], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2251799813685248, max = -1125899906842625, frequency = 11], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1125899906842624, max = -562949953421313, frequency = 12], org.opensolaris.os.dtrace.Distribution$Bucket[min = -562949953421312, max = -281474976710657, frequency = 13], org.opensolaris.os.dtrace.Distribution$Bucket[min = -281474976710656, max = -140737488355329, frequency = 14], org.opensolaris.os.dtrace.Distribution$Bucket[min = -140737488355328, max = -70368744177665, frequency = 15], org.opensolaris.os.dtrace.Distribution$Bucket[min = -70368744177664, max = -35184372088833, frequency = 16], org.opensolaris.os.dtrace.Distribution$Bucket[min = -35184372088832, max = -17592186044417, frequency = 17], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17592186044416, max = -8796093022209, frequency = 18], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8796093022208, max = -4398046511105, frequency = 19], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4398046511104, max = -2199023255553, frequency = 20], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2199023255552, max = -1099511627777, frequency = 21], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1099511627776, max = -549755813889, frequency = 22], org.opensolaris.os.dtrace.Distribution$Bucket[min = -549755813888, max = -274877906945, frequency = 23], org.opensolaris.os.dtrace.Distribution$Bucket[min = -274877906944, max = -137438953473, frequency = 24], org.opensolaris.os.dtrace.Distribution$Bucket[min = -137438953472, max = -68719476737, frequency = 25], org.opensolaris.os.dtrace.Distribution$Bucket[min = -68719476736, max = -34359738369, frequency = 26], org.opensolaris.os.dtrace.Distribution$Bucket[min = -34359738368, max = -17179869185, frequency = 27], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17179869184, max = -8589934593, frequency = 28], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8589934592, max = -4294967297, frequency = 29], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4294967296, max = -2147483649, frequency = 30], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2147483648, max = -1073741825, frequency = 31], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1073741824, max = -536870913, frequency = 32], org.opensolaris.os.dtrace.Distribution$Bucket[min = -536870912, max = -268435457, frequency = 33], org.opensolaris.os.dtrace.Distribution$Bucket[min = -268435456, max = -134217729, frequency = 34], org.opensolaris.os.dtrace.Distribution$Bucket[min = -134217728, max = -67108865, frequency = 35], org.opensolaris.os.dtrace.Distribution$Bucket[min = -67108864, max = -33554433, frequency = 36], org.opensolaris.os.dtrace.Distribution$Bucket[min = -33554432, max = -16777217, frequency = 37], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16777216, max = -8388609, frequency = 38], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8388608, max = -4194305, frequency = 39], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4194304, max = -2097153, frequency = 40], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2097152, max = -1048577, frequency = 41], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1048576, max = -524289, frequency = 42], org.opensolaris.os.dtrace.Distribution$Bucket[min = -524288, max = -262145, frequency = 43], org.opensolaris.os.dtrace.Distribution$Bucket[min = -262144, max = -131073, frequency = 44], org.opensolaris.os.dtrace.Distribution$Bucket[min = -131072, max = -65537, frequency = 45], org.opensolaris.os.dtrace.Distribution$Bucket[min = -65536, max = -32769, frequency = 46], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32768, max = -16385, frequency = 47], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16384, max = -8193, frequency = 48], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8192, max = -4097, frequency = 49], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4096, max = -2049, frequency = 50], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2048, max = -1025, frequency = 51], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1024, max = -513, frequency = 52], org.opensolaris.os.dtrace.Distribution$Bucket[min = -512, max = -257, frequency = 53], org.opensolaris.os.dtrace.Distribution$Bucket[min = -256, max = -129, frequency = 54], org.opensolaris.os.dtrace.Distribution$Bucket[min = -128, max = -65, frequency = 55], org.opensolaris.os.dtrace.Distribution$Bucket[min = -64, max = -33, frequency = 56], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32, max = -17, frequency = 57], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16, max = -9, frequency = 58], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8, max = -5, frequency = 59], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4, max = -3, frequency = 60], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2, max = -2, frequency = 61], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1, max = -1, frequency = 62], org.opensolaris.os.dtrace.Distribution$Bucket[min = 0, max = 0, frequency = 63], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 1, frequency = 64], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2, max = 3, frequency = 65], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4, max = 7, frequency = 66], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8, max = 15, frequency = 67], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16, max = 31, frequency = 68], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32, max = 63, frequency = 69], org.opensolaris.os.dtrace.Distribution$Bucket[min = 64, max = 127, frequency = 70], org.opensolaris.os.dtrace.Distribution$Bucket[min = 128, max = 255, frequency = 71], org.opensolaris.os.dtrace.Distribution$Bucket[min = 256, max = 511, frequency = 72], org.opensolaris.os.dtrace.Distribution$Bucket[min = 512, max = 1023, frequency = 73], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1024, max = 2047, frequency = 74], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2048, max = 4095, frequency = 75], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4096, max = 8191, frequency = 76], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8192, max = 16383, frequency = 77], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16384, max = 32767, frequency = 78], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32768, max = 65535, frequency = 79], org.opensolaris.os.dtrace.Distribution$Bucket[min = 65536, max = 131071, frequency = 80], org.opensolaris.os.dtrace.Distribution$Bucket[min = 131072, max = 262143, frequency = 81], org.opensolaris.os.dtrace.Distribution$Bucket[min = 262144, max = 524287, frequency = 82], org.opensolaris.os.dtrace.Distribution$Bucket[min = 524288, max = 1048575, frequency = 83], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1048576, max = 2097151, frequency = 84], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2097152, max = 4194303, frequency = 85], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4194304, max = 8388607, frequency = 86], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8388608, max = 16777215, frequency = 87], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16777216, max = 33554431, frequency = 88], org.opensolaris.os.dtrace.Distribution$Bucket[min = 33554432, max = 67108863, frequency = 89], org.opensolaris.os.dtrace.Distribution$Bucket[min = 67108864, max = 134217727, frequency = 90], org.opensolaris.os.dtrace.Distribution$Bucket[min = 134217728, max = 268435455, frequency = 91], org.opensolaris.os.dtrace.Distribution$Bucket[min = 268435456, max = 536870911, frequency = 92], org.opensolaris.os.dtrace.Distribution$Bucket[min = 536870912, max = 1073741823, frequency = 93], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1073741824, max = 2147483647, frequency = 94], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2147483648, max = 4294967295, frequency = 95], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4294967296, max = 8589934591, frequency = 96], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8589934592, max = 17179869183, frequency = 97], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17179869184, max = 34359738367, frequency = 98], org.opensolaris.os.dtrace.Distribution$Bucket[min = 34359738368, max = 68719476735, frequency = 99], org.opensolaris.os.dtrace.Distribution$Bucket[min = 68719476736, max = 137438953471, frequency = 100], org.opensolaris.os.dtrace.Distribution$Bucket[min = 137438953472, max = 274877906943, frequency = 101], org.opensolaris.os.dtrace.Distribution$Bucket[min = 274877906944, max = 549755813887, frequency = 102], org.opensolaris.os.dtrace.Distribution$Bucket[min = 549755813888, max = 1099511627775, frequency = 103], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1099511627776, max = 2199023255551, frequency = 104], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2199023255552, max = 4398046511103, frequency = 105], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4398046511104, max = 8796093022207, frequency = 106], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8796093022208, max = 17592186044415, frequency = 107], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17592186044416, max = 35184372088831, frequency = 108], org.opensolaris.os.dtrace.Distribution$Bucket[min = 35184372088832, max = 70368744177663, frequency = 109], org.opensolaris.os.dtrace.Distribution$Bucket[min = 70368744177664, max = 140737488355327, frequency = 110], org.opensolaris.os.dtrace.Distribution$Bucket[min = 140737488355328, max = 281474976710655, frequency = 111], org.opensolaris.os.dtrace.Distribution$Bucket[min = 281474976710656, max = 562949953421311, frequency = 112], org.opensolaris.os.dtrace.Distribution$Bucket[min = 562949953421312, max = 1125899906842623, frequency = 113], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1125899906842624, max = 2251799813685247, frequency = 114], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2251799813685248, max = 4503599627370495, frequency = 115], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4503599627370496, max = 9007199254740991, frequency = 116], org.opensolaris.os.dtrace.Distribution$Bucket[min = 9007199254740992, max = 18014398509481983, frequency = 117], org.opensolaris.os.dtrace.Distribution$Bucket[min = 18014398509481984, max = 36028797018963967, frequency = 118], org.opensolaris.os.dtrace.Distribution$Bucket[min = 36028797018963968, max = 72057594037927935, frequency = 119], org.opensolaris.os.dtrace.Distribution$Bucket[min = 72057594037927936, max = 144115188075855871, frequency = 120], org.opensolaris.os.dtrace.Distribution$Bucket[min = 144115188075855872, max = 288230376151711743, frequency = 121], org.opensolaris.os.dtrace.Distribution$Bucket[min = 288230376151711744, max = 576460752303423487, frequency = 122], org.opensolaris.os.dtrace.Distribution$Bucket[min = 576460752303423488, max = 1152921504606846975, frequency = 123], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1152921504606846976, max = 2305843009213693951, frequency = 124], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2305843009213693952, max = 4611686018427387903, frequency = 125], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4611686018427387904, max = 9223372036854775807, frequency = 126]], total = 8001.0]
+ deserialized: org.opensolaris.os.dtrace.Distribution[buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = -4611686018427387904, max = -2305843009213693953, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2305843009213693952, max = -1152921504606846977, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1152921504606846976, max = -576460752303423489, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = -576460752303423488, max = -288230376151711745, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = -288230376151711744, max = -144115188075855873, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = -144115188075855872, max = -72057594037927937, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = -72057594037927936, max = -36028797018963969, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = -36028797018963968, max = -18014398509481985, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = -18014398509481984, max = -9007199254740993, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = -9007199254740992, max = -4503599627370497, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4503599627370496, max = -2251799813685249, frequency = 10], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2251799813685248, max = -1125899906842625, frequency = 11], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1125899906842624, max = -562949953421313, frequency = 12], org.opensolaris.os.dtrace.Distribution$Bucket[min = -562949953421312, max = -281474976710657, frequency = 13], org.opensolaris.os.dtrace.Distribution$Bucket[min = -281474976710656, max = -140737488355329, frequency = 14], org.opensolaris.os.dtrace.Distribution$Bucket[min = -140737488355328, max = -70368744177665, frequency = 15], org.opensolaris.os.dtrace.Distribution$Bucket[min = -70368744177664, max = -35184372088833, frequency = 16], org.opensolaris.os.dtrace.Distribution$Bucket[min = -35184372088832, max = -17592186044417, frequency = 17], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17592186044416, max = -8796093022209, frequency = 18], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8796093022208, max = -4398046511105, frequency = 19], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4398046511104, max = -2199023255553, frequency = 20], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2199023255552, max = -1099511627777, frequency = 21], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1099511627776, max = -549755813889, frequency = 22], org.opensolaris.os.dtrace.Distribution$Bucket[min = -549755813888, max = -274877906945, frequency = 23], org.opensolaris.os.dtrace.Distribution$Bucket[min = -274877906944, max = -137438953473, frequency = 24], org.opensolaris.os.dtrace.Distribution$Bucket[min = -137438953472, max = -68719476737, frequency = 25], org.opensolaris.os.dtrace.Distribution$Bucket[min = -68719476736, max = -34359738369, frequency = 26], org.opensolaris.os.dtrace.Distribution$Bucket[min = -34359738368, max = -17179869185, frequency = 27], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17179869184, max = -8589934593, frequency = 28], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8589934592, max = -4294967297, frequency = 29], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4294967296, max = -2147483649, frequency = 30], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2147483648, max = -1073741825, frequency = 31], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1073741824, max = -536870913, frequency = 32], org.opensolaris.os.dtrace.Distribution$Bucket[min = -536870912, max = -268435457, frequency = 33], org.opensolaris.os.dtrace.Distribution$Bucket[min = -268435456, max = -134217729, frequency = 34], org.opensolaris.os.dtrace.Distribution$Bucket[min = -134217728, max = -67108865, frequency = 35], org.opensolaris.os.dtrace.Distribution$Bucket[min = -67108864, max = -33554433, frequency = 36], org.opensolaris.os.dtrace.Distribution$Bucket[min = -33554432, max = -16777217, frequency = 37], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16777216, max = -8388609, frequency = 38], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8388608, max = -4194305, frequency = 39], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4194304, max = -2097153, frequency = 40], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2097152, max = -1048577, frequency = 41], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1048576, max = -524289, frequency = 42], org.opensolaris.os.dtrace.Distribution$Bucket[min = -524288, max = -262145, frequency = 43], org.opensolaris.os.dtrace.Distribution$Bucket[min = -262144, max = -131073, frequency = 44], org.opensolaris.os.dtrace.Distribution$Bucket[min = -131072, max = -65537, frequency = 45], org.opensolaris.os.dtrace.Distribution$Bucket[min = -65536, max = -32769, frequency = 46], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32768, max = -16385, frequency = 47], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16384, max = -8193, frequency = 48], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8192, max = -4097, frequency = 49], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4096, max = -2049, frequency = 50], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2048, max = -1025, frequency = 51], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1024, max = -513, frequency = 52], org.opensolaris.os.dtrace.Distribution$Bucket[min = -512, max = -257, frequency = 53], org.opensolaris.os.dtrace.Distribution$Bucket[min = -256, max = -129, frequency = 54], org.opensolaris.os.dtrace.Distribution$Bucket[min = -128, max = -65, frequency = 55], org.opensolaris.os.dtrace.Distribution$Bucket[min = -64, max = -33, frequency = 56], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32, max = -17, frequency = 57], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16, max = -9, frequency = 58], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8, max = -5, frequency = 59], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4, max = -3, frequency = 60], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2, max = -2, frequency = 61], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1, max = -1, frequency = 62], org.opensolaris.os.dtrace.Distribution$Bucket[min = 0, max = 0, frequency = 63], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 1, frequency = 64], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2, max = 3, frequency = 65], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4, max = 7, frequency = 66], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8, max = 15, frequency = 67], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16, max = 31, frequency = 68], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32, max = 63, frequency = 69], org.opensolaris.os.dtrace.Distribution$Bucket[min = 64, max = 127, frequency = 70], org.opensolaris.os.dtrace.Distribution$Bucket[min = 128, max = 255, frequency = 71], org.opensolaris.os.dtrace.Distribution$Bucket[min = 256, max = 511, frequency = 72], org.opensolaris.os.dtrace.Distribution$Bucket[min = 512, max = 1023, frequency = 73], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1024, max = 2047, frequency = 74], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2048, max = 4095, frequency = 75], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4096, max = 8191, frequency = 76], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8192, max = 16383, frequency = 77], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16384, max = 32767, frequency = 78], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32768, max = 65535, frequency = 79], org.opensolaris.os.dtrace.Distribution$Bucket[min = 65536, max = 131071, frequency = 80], org.opensolaris.os.dtrace.Distribution$Bucket[min = 131072, max = 262143, frequency = 81], org.opensolaris.os.dtrace.Distribution$Bucket[min = 262144, max = 524287, frequency = 82], org.opensolaris.os.dtrace.Distribution$Bucket[min = 524288, max = 1048575, frequency = 83], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1048576, max = 2097151, frequency = 84], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2097152, max = 4194303, frequency = 85], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4194304, max = 8388607, frequency = 86], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8388608, max = 16777215, frequency = 87], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16777216, max = 33554431, frequency = 88], org.opensolaris.os.dtrace.Distribution$Bucket[min = 33554432, max = 67108863, frequency = 89], org.opensolaris.os.dtrace.Distribution$Bucket[min = 67108864, max = 134217727, frequency = 90], org.opensolaris.os.dtrace.Distribution$Bucket[min = 134217728, max = 268435455, frequency = 91], org.opensolaris.os.dtrace.Distribution$Bucket[min = 268435456, max = 536870911, frequency = 92], org.opensolaris.os.dtrace.Distribution$Bucket[min = 536870912, max = 1073741823, frequency = 93], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1073741824, max = 2147483647, frequency = 94], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2147483648, max = 4294967295, frequency = 95], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4294967296, max = 8589934591, frequency = 96], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8589934592, max = 17179869183, frequency = 97], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17179869184, max = 34359738367, frequency = 98], org.opensolaris.os.dtrace.Distribution$Bucket[min = 34359738368, max = 68719476735, frequency = 99], org.opensolaris.os.dtrace.Distribution$Bucket[min = 68719476736, max = 137438953471, frequency = 100], org.opensolaris.os.dtrace.Distribution$Bucket[min = 137438953472, max = 274877906943, frequency = 101], org.opensolaris.os.dtrace.Distribution$Bucket[min = 274877906944, max = 549755813887, frequency = 102], org.opensolaris.os.dtrace.Distribution$Bucket[min = 549755813888, max = 1099511627775, frequency = 103], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1099511627776, max = 2199023255551, frequency = 104], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2199023255552, max = 4398046511103, frequency = 105], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4398046511104, max = 8796093022207, frequency = 106], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8796093022208, max = 17592186044415, frequency = 107], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17592186044416, max = 35184372088831, frequency = 108], org.opensolaris.os.dtrace.Distribution$Bucket[min = 35184372088832, max = 70368744177663, frequency = 109], org.opensolaris.os.dtrace.Distribution$Bucket[min = 70368744177664, max = 140737488355327, frequency = 110], org.opensolaris.os.dtrace.Distribution$Bucket[min = 140737488355328, max = 281474976710655, frequency = 111], org.opensolaris.os.dtrace.Distribution$Bucket[min = 281474976710656, max = 562949953421311, frequency = 112], org.opensolaris.os.dtrace.Distribution$Bucket[min = 562949953421312, max = 1125899906842623, frequency = 113], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1125899906842624, max = 2251799813685247, frequency = 114], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2251799813685248, max = 4503599627370495, frequency = 115], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4503599627370496, max = 9007199254740991, frequency = 116], org.opensolaris.os.dtrace.Distribution$Bucket[min = 9007199254740992, max = 18014398509481983, frequency = 117], org.opensolaris.os.dtrace.Distribution$Bucket[min = 18014398509481984, max = 36028797018963967, frequency = 118], org.opensolaris.os.dtrace.Distribution$Bucket[min = 36028797018963968, max = 72057594037927935, frequency = 119], org.opensolaris.os.dtrace.Distribution$Bucket[min = 72057594037927936, max = 144115188075855871, frequency = 120], org.opensolaris.os.dtrace.Distribution$Bucket[min = 144115188075855872, max = 288230376151711743, frequency = 121], org.opensolaris.os.dtrace.Distribution$Bucket[min = 288230376151711744, max = 576460752303423487, frequency = 122], org.opensolaris.os.dtrace.Distribution$Bucket[min = 576460752303423488, max = 1152921504606846975, frequency = 123], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1152921504606846976, max = 2305843009213693951, frequency = 124], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2305843009213693952, max = 4611686018427387903, frequency = 125], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4611686018427387904, max = 9223372036854775807, frequency = 126]], total = 8001.0]
+LogDistribution:
+ encoded: org.opensolaris.os.dtrace.Distribution[buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = -4611686018427387904, max = -2305843009213693953, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2305843009213693952, max = -1152921504606846977, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1152921504606846976, max = -576460752303423489, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = -576460752303423488, max = -288230376151711745, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = -288230376151711744, max = -144115188075855873, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = -144115188075855872, max = -72057594037927937, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = -72057594037927936, max = -36028797018963969, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = -36028797018963968, max = -18014398509481985, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = -18014398509481984, max = -9007199254740993, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = -9007199254740992, max = -4503599627370497, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4503599627370496, max = -2251799813685249, frequency = 10], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2251799813685248, max = -1125899906842625, frequency = 11], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1125899906842624, max = -562949953421313, frequency = 12], org.opensolaris.os.dtrace.Distribution$Bucket[min = -562949953421312, max = -281474976710657, frequency = 13], org.opensolaris.os.dtrace.Distribution$Bucket[min = -281474976710656, max = -140737488355329, frequency = 14], org.opensolaris.os.dtrace.Distribution$Bucket[min = -140737488355328, max = -70368744177665, frequency = 15], org.opensolaris.os.dtrace.Distribution$Bucket[min = -70368744177664, max = -35184372088833, frequency = 16], org.opensolaris.os.dtrace.Distribution$Bucket[min = -35184372088832, max = -17592186044417, frequency = 17], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17592186044416, max = -8796093022209, frequency = 18], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8796093022208, max = -4398046511105, frequency = 19], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4398046511104, max = -2199023255553, frequency = 20], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2199023255552, max = -1099511627777, frequency = 21], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1099511627776, max = -549755813889, frequency = 22], org.opensolaris.os.dtrace.Distribution$Bucket[min = -549755813888, max = -274877906945, frequency = 23], org.opensolaris.os.dtrace.Distribution$Bucket[min = -274877906944, max = -137438953473, frequency = 24], org.opensolaris.os.dtrace.Distribution$Bucket[min = -137438953472, max = -68719476737, frequency = 25], org.opensolaris.os.dtrace.Distribution$Bucket[min = -68719476736, max = -34359738369, frequency = 26], org.opensolaris.os.dtrace.Distribution$Bucket[min = -34359738368, max = -17179869185, frequency = 27], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17179869184, max = -8589934593, frequency = 28], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8589934592, max = -4294967297, frequency = 29], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4294967296, max = -2147483649, frequency = 30], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2147483648, max = -1073741825, frequency = 31], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1073741824, max = -536870913, frequency = 32], org.opensolaris.os.dtrace.Distribution$Bucket[min = -536870912, max = -268435457, frequency = 33], org.opensolaris.os.dtrace.Distribution$Bucket[min = -268435456, max = -134217729, frequency = 34], org.opensolaris.os.dtrace.Distribution$Bucket[min = -134217728, max = -67108865, frequency = 35], org.opensolaris.os.dtrace.Distribution$Bucket[min = -67108864, max = -33554433, frequency = 36], org.opensolaris.os.dtrace.Distribution$Bucket[min = -33554432, max = -16777217, frequency = 37], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16777216, max = -8388609, frequency = 38], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8388608, max = -4194305, frequency = 39], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4194304, max = -2097153, frequency = 40], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2097152, max = -1048577, frequency = 41], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1048576, max = -524289, frequency = 42], org.opensolaris.os.dtrace.Distribution$Bucket[min = -524288, max = -262145, frequency = 43], org.opensolaris.os.dtrace.Distribution$Bucket[min = -262144, max = -131073, frequency = 44], org.opensolaris.os.dtrace.Distribution$Bucket[min = -131072, max = -65537, frequency = 45], org.opensolaris.os.dtrace.Distribution$Bucket[min = -65536, max = -32769, frequency = 46], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32768, max = -16385, frequency = 47], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16384, max = -8193, frequency = 48], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8192, max = -4097, frequency = 49], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4096, max = -2049, frequency = 50], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2048, max = -1025, frequency = 51], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1024, max = -513, frequency = 52], org.opensolaris.os.dtrace.Distribution$Bucket[min = -512, max = -257, frequency = 53], org.opensolaris.os.dtrace.Distribution$Bucket[min = -256, max = -129, frequency = 54], org.opensolaris.os.dtrace.Distribution$Bucket[min = -128, max = -65, frequency = 55], org.opensolaris.os.dtrace.Distribution$Bucket[min = -64, max = -33, frequency = 56], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32, max = -17, frequency = 57], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16, max = -9, frequency = 58], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8, max = -5, frequency = 59], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4, max = -3, frequency = 60], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2, max = -2, frequency = 61], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1, max = -1, frequency = 62], org.opensolaris.os.dtrace.Distribution$Bucket[min = 0, max = 0, frequency = 63], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 1, frequency = 64], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2, max = 3, frequency = 65], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4, max = 7, frequency = 66], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8, max = 15, frequency = 67], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16, max = 31, frequency = 68], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32, max = 63, frequency = 69], org.opensolaris.os.dtrace.Distribution$Bucket[min = 64, max = 127, frequency = 70], org.opensolaris.os.dtrace.Distribution$Bucket[min = 128, max = 255, frequency = 71], org.opensolaris.os.dtrace.Distribution$Bucket[min = 256, max = 511, frequency = 72], org.opensolaris.os.dtrace.Distribution$Bucket[min = 512, max = 1023, frequency = 73], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1024, max = 2047, frequency = 74], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2048, max = 4095, frequency = 75], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4096, max = 8191, frequency = 76], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8192, max = 16383, frequency = 77], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16384, max = 32767, frequency = 78], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32768, max = 65535, frequency = 79], org.opensolaris.os.dtrace.Distribution$Bucket[min = 65536, max = 131071, frequency = 80], org.opensolaris.os.dtrace.Distribution$Bucket[min = 131072, max = 262143, frequency = 81], org.opensolaris.os.dtrace.Distribution$Bucket[min = 262144, max = 524287, frequency = 82], org.opensolaris.os.dtrace.Distribution$Bucket[min = 524288, max = 1048575, frequency = 83], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1048576, max = 2097151, frequency = 84], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2097152, max = 4194303, frequency = 85], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4194304, max = 8388607, frequency = 86], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8388608, max = 16777215, frequency = 87], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16777216, max = 33554431, frequency = 88], org.opensolaris.os.dtrace.Distribution$Bucket[min = 33554432, max = 67108863, frequency = 89], org.opensolaris.os.dtrace.Distribution$Bucket[min = 67108864, max = 134217727, frequency = 90], org.opensolaris.os.dtrace.Distribution$Bucket[min = 134217728, max = 268435455, frequency = 91], org.opensolaris.os.dtrace.Distribution$Bucket[min = 268435456, max = 536870911, frequency = 92], org.opensolaris.os.dtrace.Distribution$Bucket[min = 536870912, max = 1073741823, frequency = 93], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1073741824, max = 2147483647, frequency = 94], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2147483648, max = 4294967295, frequency = 95], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4294967296, max = 8589934591, frequency = 96], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8589934592, max = 17179869183, frequency = 97], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17179869184, max = 34359738367, frequency = 98], org.opensolaris.os.dtrace.Distribution$Bucket[min = 34359738368, max = 68719476735, frequency = 99], org.opensolaris.os.dtrace.Distribution$Bucket[min = 68719476736, max = 137438953471, frequency = 100], org.opensolaris.os.dtrace.Distribution$Bucket[min = 137438953472, max = 274877906943, frequency = 101], org.opensolaris.os.dtrace.Distribution$Bucket[min = 274877906944, max = 549755813887, frequency = 102], org.opensolaris.os.dtrace.Distribution$Bucket[min = 549755813888, max = 1099511627775, frequency = 103], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1099511627776, max = 2199023255551, frequency = 104], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2199023255552, max = 4398046511103, frequency = 105], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4398046511104, max = 8796093022207, frequency = 106], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8796093022208, max = 17592186044415, frequency = 107], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17592186044416, max = 35184372088831, frequency = 108], org.opensolaris.os.dtrace.Distribution$Bucket[min = 35184372088832, max = 70368744177663, frequency = 109], org.opensolaris.os.dtrace.Distribution$Bucket[min = 70368744177664, max = 140737488355327, frequency = 110], org.opensolaris.os.dtrace.Distribution$Bucket[min = 140737488355328, max = 281474976710655, frequency = 111], org.opensolaris.os.dtrace.Distribution$Bucket[min = 281474976710656, max = 562949953421311, frequency = 112], org.opensolaris.os.dtrace.Distribution$Bucket[min = 562949953421312, max = 1125899906842623, frequency = 113], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1125899906842624, max = 2251799813685247, frequency = 114], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2251799813685248, max = 4503599627370495, frequency = 115], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4503599627370496, max = 9007199254740991, frequency = 116], org.opensolaris.os.dtrace.Distribution$Bucket[min = 9007199254740992, max = 18014398509481983, frequency = 117], org.opensolaris.os.dtrace.Distribution$Bucket[min = 18014398509481984, max = 36028797018963967, frequency = 118], org.opensolaris.os.dtrace.Distribution$Bucket[min = 36028797018963968, max = 72057594037927935, frequency = 119], org.opensolaris.os.dtrace.Distribution$Bucket[min = 72057594037927936, max = 144115188075855871, frequency = 120], org.opensolaris.os.dtrace.Distribution$Bucket[min = 144115188075855872, max = 288230376151711743, frequency = 121], org.opensolaris.os.dtrace.Distribution$Bucket[min = 288230376151711744, max = 576460752303423487, frequency = 122], org.opensolaris.os.dtrace.Distribution$Bucket[min = 576460752303423488, max = 1152921504606846975, frequency = 123], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1152921504606846976, max = 2305843009213693951, frequency = 124], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2305843009213693952, max = 4611686018427387903, frequency = 125], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4611686018427387904, max = 9223372036854775807, frequency = 126]], total = 8001.0]
+ decoded: org.opensolaris.os.dtrace.Distribution[buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = -4611686018427387904, max = -2305843009213693953, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2305843009213693952, max = -1152921504606846977, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1152921504606846976, max = -576460752303423489, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = -576460752303423488, max = -288230376151711745, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = -288230376151711744, max = -144115188075855873, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = -144115188075855872, max = -72057594037927937, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = -72057594037927936, max = -36028797018963969, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = -36028797018963968, max = -18014398509481985, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = -18014398509481984, max = -9007199254740993, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = -9007199254740992, max = -4503599627370497, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4503599627370496, max = -2251799813685249, frequency = 10], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2251799813685248, max = -1125899906842625, frequency = 11], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1125899906842624, max = -562949953421313, frequency = 12], org.opensolaris.os.dtrace.Distribution$Bucket[min = -562949953421312, max = -281474976710657, frequency = 13], org.opensolaris.os.dtrace.Distribution$Bucket[min = -281474976710656, max = -140737488355329, frequency = 14], org.opensolaris.os.dtrace.Distribution$Bucket[min = -140737488355328, max = -70368744177665, frequency = 15], org.opensolaris.os.dtrace.Distribution$Bucket[min = -70368744177664, max = -35184372088833, frequency = 16], org.opensolaris.os.dtrace.Distribution$Bucket[min = -35184372088832, max = -17592186044417, frequency = 17], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17592186044416, max = -8796093022209, frequency = 18], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8796093022208, max = -4398046511105, frequency = 19], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4398046511104, max = -2199023255553, frequency = 20], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2199023255552, max = -1099511627777, frequency = 21], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1099511627776, max = -549755813889, frequency = 22], org.opensolaris.os.dtrace.Distribution$Bucket[min = -549755813888, max = -274877906945, frequency = 23], org.opensolaris.os.dtrace.Distribution$Bucket[min = -274877906944, max = -137438953473, frequency = 24], org.opensolaris.os.dtrace.Distribution$Bucket[min = -137438953472, max = -68719476737, frequency = 25], org.opensolaris.os.dtrace.Distribution$Bucket[min = -68719476736, max = -34359738369, frequency = 26], org.opensolaris.os.dtrace.Distribution$Bucket[min = -34359738368, max = -17179869185, frequency = 27], org.opensolaris.os.dtrace.Distribution$Bucket[min = -17179869184, max = -8589934593, frequency = 28], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8589934592, max = -4294967297, frequency = 29], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4294967296, max = -2147483649, frequency = 30], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2147483648, max = -1073741825, frequency = 31], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1073741824, max = -536870913, frequency = 32], org.opensolaris.os.dtrace.Distribution$Bucket[min = -536870912, max = -268435457, frequency = 33], org.opensolaris.os.dtrace.Distribution$Bucket[min = -268435456, max = -134217729, frequency = 34], org.opensolaris.os.dtrace.Distribution$Bucket[min = -134217728, max = -67108865, frequency = 35], org.opensolaris.os.dtrace.Distribution$Bucket[min = -67108864, max = -33554433, frequency = 36], org.opensolaris.os.dtrace.Distribution$Bucket[min = -33554432, max = -16777217, frequency = 37], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16777216, max = -8388609, frequency = 38], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8388608, max = -4194305, frequency = 39], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4194304, max = -2097153, frequency = 40], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2097152, max = -1048577, frequency = 41], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1048576, max = -524289, frequency = 42], org.opensolaris.os.dtrace.Distribution$Bucket[min = -524288, max = -262145, frequency = 43], org.opensolaris.os.dtrace.Distribution$Bucket[min = -262144, max = -131073, frequency = 44], org.opensolaris.os.dtrace.Distribution$Bucket[min = -131072, max = -65537, frequency = 45], org.opensolaris.os.dtrace.Distribution$Bucket[min = -65536, max = -32769, frequency = 46], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32768, max = -16385, frequency = 47], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16384, max = -8193, frequency = 48], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8192, max = -4097, frequency = 49], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4096, max = -2049, frequency = 50], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2048, max = -1025, frequency = 51], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1024, max = -513, frequency = 52], org.opensolaris.os.dtrace.Distribution$Bucket[min = -512, max = -257, frequency = 53], org.opensolaris.os.dtrace.Distribution$Bucket[min = -256, max = -129, frequency = 54], org.opensolaris.os.dtrace.Distribution$Bucket[min = -128, max = -65, frequency = 55], org.opensolaris.os.dtrace.Distribution$Bucket[min = -64, max = -33, frequency = 56], org.opensolaris.os.dtrace.Distribution$Bucket[min = -32, max = -17, frequency = 57], org.opensolaris.os.dtrace.Distribution$Bucket[min = -16, max = -9, frequency = 58], org.opensolaris.os.dtrace.Distribution$Bucket[min = -8, max = -5, frequency = 59], org.opensolaris.os.dtrace.Distribution$Bucket[min = -4, max = -3, frequency = 60], org.opensolaris.os.dtrace.Distribution$Bucket[min = -2, max = -2, frequency = 61], org.opensolaris.os.dtrace.Distribution$Bucket[min = -1, max = -1, frequency = 62], org.opensolaris.os.dtrace.Distribution$Bucket[min = 0, max = 0, frequency = 63], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 1, frequency = 64], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2, max = 3, frequency = 65], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4, max = 7, frequency = 66], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8, max = 15, frequency = 67], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16, max = 31, frequency = 68], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32, max = 63, frequency = 69], org.opensolaris.os.dtrace.Distribution$Bucket[min = 64, max = 127, frequency = 70], org.opensolaris.os.dtrace.Distribution$Bucket[min = 128, max = 255, frequency = 71], org.opensolaris.os.dtrace.Distribution$Bucket[min = 256, max = 511, frequency = 72], org.opensolaris.os.dtrace.Distribution$Bucket[min = 512, max = 1023, frequency = 73], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1024, max = 2047, frequency = 74], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2048, max = 4095, frequency = 75], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4096, max = 8191, frequency = 76], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8192, max = 16383, frequency = 77], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16384, max = 32767, frequency = 78], org.opensolaris.os.dtrace.Distribution$Bucket[min = 32768, max = 65535, frequency = 79], org.opensolaris.os.dtrace.Distribution$Bucket[min = 65536, max = 131071, frequency = 80], org.opensolaris.os.dtrace.Distribution$Bucket[min = 131072, max = 262143, frequency = 81], org.opensolaris.os.dtrace.Distribution$Bucket[min = 262144, max = 524287, frequency = 82], org.opensolaris.os.dtrace.Distribution$Bucket[min = 524288, max = 1048575, frequency = 83], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1048576, max = 2097151, frequency = 84], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2097152, max = 4194303, frequency = 85], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4194304, max = 8388607, frequency = 86], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8388608, max = 16777215, frequency = 87], org.opensolaris.os.dtrace.Distribution$Bucket[min = 16777216, max = 33554431, frequency = 88], org.opensolaris.os.dtrace.Distribution$Bucket[min = 33554432, max = 67108863, frequency = 89], org.opensolaris.os.dtrace.Distribution$Bucket[min = 67108864, max = 134217727, frequency = 90], org.opensolaris.os.dtrace.Distribution$Bucket[min = 134217728, max = 268435455, frequency = 91], org.opensolaris.os.dtrace.Distribution$Bucket[min = 268435456, max = 536870911, frequency = 92], org.opensolaris.os.dtrace.Distribution$Bucket[min = 536870912, max = 1073741823, frequency = 93], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1073741824, max = 2147483647, frequency = 94], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2147483648, max = 4294967295, frequency = 95], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4294967296, max = 8589934591, frequency = 96], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8589934592, max = 17179869183, frequency = 97], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17179869184, max = 34359738367, frequency = 98], org.opensolaris.os.dtrace.Distribution$Bucket[min = 34359738368, max = 68719476735, frequency = 99], org.opensolaris.os.dtrace.Distribution$Bucket[min = 68719476736, max = 137438953471, frequency = 100], org.opensolaris.os.dtrace.Distribution$Bucket[min = 137438953472, max = 274877906943, frequency = 101], org.opensolaris.os.dtrace.Distribution$Bucket[min = 274877906944, max = 549755813887, frequency = 102], org.opensolaris.os.dtrace.Distribution$Bucket[min = 549755813888, max = 1099511627775, frequency = 103], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1099511627776, max = 2199023255551, frequency = 104], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2199023255552, max = 4398046511103, frequency = 105], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4398046511104, max = 8796093022207, frequency = 106], org.opensolaris.os.dtrace.Distribution$Bucket[min = 8796093022208, max = 17592186044415, frequency = 107], org.opensolaris.os.dtrace.Distribution$Bucket[min = 17592186044416, max = 35184372088831, frequency = 108], org.opensolaris.os.dtrace.Distribution$Bucket[min = 35184372088832, max = 70368744177663, frequency = 109], org.opensolaris.os.dtrace.Distribution$Bucket[min = 70368744177664, max = 140737488355327, frequency = 110], org.opensolaris.os.dtrace.Distribution$Bucket[min = 140737488355328, max = 281474976710655, frequency = 111], org.opensolaris.os.dtrace.Distribution$Bucket[min = 281474976710656, max = 562949953421311, frequency = 112], org.opensolaris.os.dtrace.Distribution$Bucket[min = 562949953421312, max = 1125899906842623, frequency = 113], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1125899906842624, max = 2251799813685247, frequency = 114], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2251799813685248, max = 4503599627370495, frequency = 115], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4503599627370496, max = 9007199254740991, frequency = 116], org.opensolaris.os.dtrace.Distribution$Bucket[min = 9007199254740992, max = 18014398509481983, frequency = 117], org.opensolaris.os.dtrace.Distribution$Bucket[min = 18014398509481984, max = 36028797018963967, frequency = 118], org.opensolaris.os.dtrace.Distribution$Bucket[min = 36028797018963968, max = 72057594037927935, frequency = 119], org.opensolaris.os.dtrace.Distribution$Bucket[min = 72057594037927936, max = 144115188075855871, frequency = 120], org.opensolaris.os.dtrace.Distribution$Bucket[min = 144115188075855872, max = 288230376151711743, frequency = 121], org.opensolaris.os.dtrace.Distribution$Bucket[min = 288230376151711744, max = 576460752303423487, frequency = 122], org.opensolaris.os.dtrace.Distribution$Bucket[min = 576460752303423488, max = 1152921504606846975, frequency = 123], org.opensolaris.os.dtrace.Distribution$Bucket[min = 1152921504606846976, max = 2305843009213693951, frequency = 124], org.opensolaris.os.dtrace.Distribution$Bucket[min = 2305843009213693952, max = 4611686018427387903, frequency = 125], org.opensolaris.os.dtrace.Distribution$Bucket[min = 4611686018427387904, max = 9223372036854775807, frequency = 126]], total = 8001.0]
+LinearDistribution:
+ serialized: class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]
+ deserialized: class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]
+LinearDistribution:
+ encoded: class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]
+ decoded: class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]
+Option:
+ serialized: org.opensolaris.os.dtrace.Option[name = aggrate, value = 1s]
+ deserialized: org.opensolaris.os.dtrace.Option[name = aggrate, value = 1s]
+Option:
+ encoded: org.opensolaris.os.dtrace.Option[name = aggrate, value = 1s]
+ decoded: org.opensolaris.os.dtrace.Option[name = aggrate, value = 1s]
+ProcessState:
+ serialized: org.opensolaris.os.dtrace.ProcessState[pid = 123456, state = UNDEAD, terminationSignal = 3, terminationSignalName = SIGSTOP, exitStatus = -2, message = Process stopped on dime]
+ deserialized: org.opensolaris.os.dtrace.ProcessState[pid = 123456, state = UNDEAD, terminationSignal = 3, terminationSignalName = SIGSTOP, exitStatus = -2, message = Process stopped on dime]
+ProcessState:
+ encoded: org.opensolaris.os.dtrace.ProcessState[pid = 123456, state = UNDEAD, terminationSignal = 3, terminationSignalName = SIGSTOP, exitStatus = -2, message = Process stopped on dime]
+ decoded: org.opensolaris.os.dtrace.ProcessState[pid = 123456, state = UNDEAD, terminationSignal = 3, terminationSignalName = SIGSTOP, exitStatus = -2, message = Process stopped on dime]
+ProbeDescription:
+ serialized: syscall::malloc:entry
+ deserialized: syscall::malloc:entry
+ProbeDescription:
+ encoded: syscall::malloc:entry
+ decoded: syscall::malloc:entry
+PrintaRecord:
+ serialized: org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output]
+ deserialized: org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output]
+PrintaRecord:
+ encoded: org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output]
+ decoded: org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output]
+PrintfRecord:
+ serialized: long formatted string
+ deserialized: long formatted string
+PrintfRecord:
+ encoded: long formatted string
+ decoded: long formatted string
+ProbeData:
+ serialized: org.opensolaris.os.dtrace.ProbeData[epid = 7, cpu = 1, enabledProbeDescription = syscall::malloc:entry, flow = org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3], records = [org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output], long formatted string,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, mod`func+0x4,
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+, 1]]
+ deserialized: org.opensolaris.os.dtrace.ProbeData[epid = 7, cpu = 1, enabledProbeDescription = syscall::malloc:entry, flow = org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3], records = [org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output], long formatted string,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, mod`func+0x4,
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+, 1]]
+ProbeData:
+ encoded: org.opensolaris.os.dtrace.ProbeData[epid = 7, cpu = 1, enabledProbeDescription = syscall::malloc:entry, flow = org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3], records = [org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output], long formatted string,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, mod`func+0x4,
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+, 1]]
+ decoded: org.opensolaris.os.dtrace.ProbeData[epid = 7, cpu = 1, enabledProbeDescription = syscall::malloc:entry, flow = org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3], records = [org.opensolaris.os.dtrace.PrintaRecord[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]]], formattedStrings = {[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!]=cat, [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]=cat}, tuples = [[
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+]], output = Yes, this is the formatted printa() output], long formatted string,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, mod`func+0x4,
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+, 1]]
+Aggregate:
+ serialized: org.opensolaris.os.dtrace.Aggregate[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = times, id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, dog, mouse, mouse, 67, 7], value = 9]]]]
+ deserialized: org.opensolaris.os.dtrace.Aggregate[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = times, id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, dog, mouse, mouse, 67, 7], value = 9]]]]
+Aggregate:
+ encoded: org.opensolaris.os.dtrace.Aggregate[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = times, id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, dog, mouse, mouse, 67, 7], value = 9]]]]
+ decoded: org.opensolaris.os.dtrace.Aggregate[snaptime = 1234567890, aggregations = [org.opensolaris.os.dtrace.Aggregation[name = counts, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+, shebang!], value = class org.opensolaris.os.dtrace.LinearDistribution[base = 1, step = 10, buckets = [org.opensolaris.os.dtrace.Distribution$Bucket[min = 1, max = 10, frequency = 0], org.opensolaris.os.dtrace.Distribution$Bucket[min = 11, max = 20, frequency = 1], org.opensolaris.os.dtrace.Distribution$Bucket[min = 21, max = 30, frequency = 2], org.opensolaris.os.dtrace.Distribution$Bucket[min = 31, max = 40, frequency = 3], org.opensolaris.os.dtrace.Distribution$Bucket[min = 41, max = 50, frequency = 4], org.opensolaris.os.dtrace.Distribution$Bucket[min = 51, max = 60, frequency = 5], org.opensolaris.os.dtrace.Distribution$Bucket[min = 61, max = 70, frequency = 6], org.opensolaris.os.dtrace.Distribution$Bucket[min = 71, max = 80, frequency = 7], org.opensolaris.os.dtrace.Distribution$Bucket[min = 81, max = 90, frequency = 8], org.opensolaris.os.dtrace.Distribution$Bucket[min = 91, max = 100, frequency = 9], org.opensolaris.os.dtrace.Distribution$Bucket[min = 101, max = 9223372036854775807, frequency = 0]], total = 45.0]], org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, 9,
+ has
+ nine
+ lives
+,
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 1 2 3 ...
+], value = 7]], org.opensolaris.os.dtrace.Aggregation[name = times, id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [cat, dog, mouse, mouse, 67, 7], value = 9]]]]
+UserStackRecord:
+ serialized:
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+
+ deserialized:
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+
+UserStackRecord:
+ encoded:
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+
+ decoded:
+ process ID: 123456
+ User Stack Frame 1
+ User Stack Frame 2
+ User Stack Frame 3
+
+AvgValue:
+ serialized: 5
+ deserialized: 5
+AvgValue:
+ encoded: 5
+ decoded: 5
+CountValue:
+ serialized: 9
+ deserialized: 9
+CountValue:
+ encoded: 9
+ decoded: 9
+SumValue:
+ serialized: 25
+ deserialized: 25
+SumValue:
+ encoded: 25
+ decoded: 25
+MinValue:
+ serialized: 101
+ deserialized: 101
+MinValue:
+ encoded: 101
+ decoded: 101
+MaxValue:
+ serialized: 101
+ deserialized: 101
+MaxValue:
+ encoded: 101
+ decoded: 101
+Error:
+ serialized: org.opensolaris.os.dtrace.Error[probeDescription = syscall::malloc:entry, epid = 8, cpu = 3, action = 1, offset = 20, fault = DTRACEFLT_BADALIGN, address = -1, defaultMessage = error on enabled probe ID 8 (ID 256: syscall::malloc:entry): Bad alignment (0x33ef) in action #1 at DIF offset 20]
+ deserialized: org.opensolaris.os.dtrace.Error[probeDescription = syscall::malloc:entry, epid = 8, cpu = 3, action = 1, offset = 20, fault = DTRACEFLT_BADALIGN, address = -1, defaultMessage = error on enabled probe ID 8 (ID 256: syscall::malloc:entry): Bad alignment (0x33ef) in action #1 at DIF offset 20]
+Error:
+ encoded: org.opensolaris.os.dtrace.Error[probeDescription = syscall::malloc:entry, epid = 8, cpu = 3, action = 1, offset = 20, fault = DTRACEFLT_BADALIGN, address = -1, defaultMessage = error on enabled probe ID 8 (ID 256: syscall::malloc:entry): Bad alignment (0x33ef) in action #1 at DIF offset 20]
+ decoded: org.opensolaris.os.dtrace.Error[probeDescription = syscall::malloc:entry, epid = 8, cpu = 3, action = 1, offset = 20, fault = DTRACEFLT_BADALIGN, address = -1, defaultMessage = error on enabled probe ID 8 (ID 256: syscall::malloc:entry): Bad alignment (0x33ef) in action #1 at DIF offset 20]
+Drop:
+ serialized: org.opensolaris.os.dtrace.Drop[cpu = 2, kind = Speculation (busy), count = 72, total = 1041, defaultMessage = Guess we dropped stuff all over the place.]
+ deserialized: org.opensolaris.os.dtrace.Drop[cpu = 2, kind = Speculation (busy), count = 72, total = 1041, defaultMessage = Guess we dropped stuff all over the place.]
+Drop:
+ encoded: org.opensolaris.os.dtrace.Drop[cpu = 2, kind = Speculation (busy), count = 72, total = 1041, defaultMessage = Guess we dropped stuff all over the place.]
+ decoded: org.opensolaris.os.dtrace.Drop[cpu = 2, kind = Speculation (busy), count = 72, total = 1041, defaultMessage = Guess we dropped stuff all over the place.]
+InterfaceAttributes:
+ serialized: Unstable / Evolving / ISA
+ deserialized: Unstable / Evolving / ISA
+InterfaceAttributes:
+ encoded: Unstable / Evolving / ISA
+ decoded: Unstable / Evolving / ISA
+ProgramInfo:
+ serialized: org.opensolaris.os.dtrace.ProgramInfo[minimumProbeAttributes = Unstable / Evolving / ISA, minimumStatementAttributes = Unstable / Evolving / ISA, matchingProbeCount = 256]
+ deserialized: org.opensolaris.os.dtrace.ProgramInfo[minimumProbeAttributes = Unstable / Evolving / ISA, minimumStatementAttributes = Unstable / Evolving / ISA, matchingProbeCount = 256]
+ProgramInfo:
+ encoded: org.opensolaris.os.dtrace.ProgramInfo[minimumProbeAttributes = Unstable / Evolving / ISA, minimumStatementAttributes = Unstable / Evolving / ISA, matchingProbeCount = 256]
+ decoded: org.opensolaris.os.dtrace.ProgramInfo[minimumProbeAttributes = Unstable / Evolving / ISA, minimumStatementAttributes = Unstable / Evolving / ISA, matchingProbeCount = 256]
+ProbeInfo:
+ serialized: org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]
+ deserialized: org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]
+ProbeInfo:
+ encoded: org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]
+ decoded: org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]
+Probe:
+ serialized: org.opensolaris.os.dtrace.Probe[description = syscall::malloc:entry, info = org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]]
+ deserialized: org.opensolaris.os.dtrace.Probe[description = syscall::malloc:entry, info = org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]]
+Probe:
+ encoded: org.opensolaris.os.dtrace.Probe[description = syscall::malloc:entry, info = org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]]
+ decoded: org.opensolaris.os.dtrace.Probe[description = syscall::malloc:entry, info = org.opensolaris.os.dtrace.ProbeInfo[probeAttributes = Unstable / Evolving / ISA, argumentAttributes = Unstable / Evolving / ISA]]
+Flow:
+ serialized: org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3]
+ deserialized: org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3]
+Flow:
+ encoded: org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3]
+ decoded: org.opensolaris.os.dtrace.Flow[kind = RETURN, depth = 3]
+KernelSymbolRecord:
+ serialized: mod`func+0x4
+ deserialized: mod`func+0x4
+KernelSymbolRecord:
+ encoded: mod`func+0x4
+ decoded: mod`func+0x4
+UserSymbolRecord:
+ serialized: mod`func+0x4
+ deserialized: mod`func+0x4
+UserSymbolRecord:
+ encoded: mod`func+0x4
+ decoded: mod`func+0x4
+UserSymbolRecord$Value:
+ serialized: org.opensolaris.os.dtrace.UserSymbolRecord$Value[processID = 7, address = -1]
+ deserialized: org.opensolaris.os.dtrace.UserSymbolRecord$Value[processID = 7, address = -1]
+UserSymbolRecord$Value:
+ encoded: org.opensolaris.os.dtrace.UserSymbolRecord$Value[processID = 7, address = -1]
+ decoded: org.opensolaris.os.dtrace.UserSymbolRecord$Value[processID = 7, address = -1]
+Program:
+ serialized: org.opensolaris.os.dtrace.Program[contents = syscall:::entry { @[execname] = count(); }, info = null]
+ deserialized: org.opensolaris.os.dtrace.Program[contents = syscall:::entry { @[execname] = count(); }, info = null]
+Program$File:
+ serialized: org.opensolaris.os.dtrace.Program$File[super = org.opensolaris.os.dtrace.Program[contents = syscall:::entry { @[execname] = count(); }, info = null], file = TestBean.out]
+ deserialized: org.opensolaris.os.dtrace.Program$File[super = org.opensolaris.os.dtrace.Program[contents = syscall:::entry { @[execname] = count(); }, info = null], file = TestBean.out]
+StddevValue:
+ serialized: 37
+ deserialized: 37
+StddevValue:
+ encoded: 37
+ decoded: 37
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh
new file mode 100644
index 0000000..299755c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6419880 close() hangs running consumer.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestClose
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh.out
new file mode 100644
index 0000000..628d787
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Close.ksh.out
@@ -0,0 +1 @@
+Successful
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh
new file mode 100644
index 0000000..a03de95
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6521523 aggregation drops can hang the Java DTrace API.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestDrop 3
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh.out
new file mode 100644
index 0000000..266c4d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Drop.ksh.out
@@ -0,0 +1 @@
+Lock released
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh
new file mode 100644
index 0000000..df1c11f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh
@@ -0,0 +1,40 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Consumer enable() correctly handles multiple programs,
+# recognizing programs that have already been enabled or that were
+# compiled by another consumer.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestEnable
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh.out
new file mode 100644
index 0000000..a13fb70
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Enable.ksh.out
@@ -0,0 +1,6 @@
+java.lang.IllegalStateException: Not all compiled probes are enabled. Compiled description dtrace:::END not enabled.
+java.lang.IllegalStateException: program already enabled
+java.lang.IllegalStateException: program already enabled
+java.lang.IllegalStateException: Not all compiled probes are enabled. Compiled description syscall:::return not enabled.
+java.lang.IllegalStateException: program already enabled
+java.lang.IllegalArgumentException: program not compiled by this consumer
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.c
new file mode 100644
index 0000000..0e6291f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.c
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+
+typedef void f(int x);
+
+static void
+f1(int i)
+{
+ printf("%d\n", i);
+}
+
+static void
+f2(f func, int i)
+{
+ func(i);
+}
+
+int
+main()
+{
+ f2(f1, 3);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh
new file mode 100644
index 0000000..e1ffbdf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh
@@ -0,0 +1,39 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6413280 lookupKernelFunction() and
+# lookupUserFunction() truncate last character.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestFunctionLookup ./tst.FunctionLookup.exe
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out
new file mode 100644
index 0000000..d42e9b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out
@@ -0,0 +1,3 @@
+genunix`cv_wakeup
+3
+tst.FunctionLookup.exe`f1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh
new file mode 100644
index 0000000..2fdd5a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+############################################################################
+# ASSERTION:
+# getAggregate() can explicitly specify the anonymous aggregation
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestGetAggregate
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh
new file mode 100644
index 0000000..992fcb5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh
@@ -0,0 +1,47 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6506495 -DJAVA_DTRACE_MAX_CONSUMERS=N for any N < 8 is
+# treated as if it were 8.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=-1 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=0 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=1 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=2 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=7 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=8 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=9 -cp test.jar TestMaxConsumers
+java -DJAVA_DTRACE_MAX_CONSUMERS=19 -cp test.jar TestMaxConsumers
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh.out
new file mode 100644
index 0000000..f68fc4e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MaxConsumers.ksh.out
@@ -0,0 +1,17 @@
+Success
+JAVA_DTRACE_MAX_CONSUMERS=-1
+Success
+JAVA_DTRACE_MAX_CONSUMERS=0
+Success
+JAVA_DTRACE_MAX_CONSUMERS=1
+Success
+JAVA_DTRACE_MAX_CONSUMERS=2
+Success
+JAVA_DTRACE_MAX_CONSUMERS=7
+Success
+JAVA_DTRACE_MAX_CONSUMERS=8
+Success
+JAVA_DTRACE_MAX_CONSUMERS=9
+Success
+JAVA_DTRACE_MAX_CONSUMERS=19
+Success
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh
new file mode 100644
index 0000000..6bb864a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Regression for multi-aggregation printa() corner cases.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestMultiAggPrinta tst.printa.d
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh.out
new file mode 100644
index 0000000..8b8fd6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.MultiAggPrinta.ksh.out
@@ -0,0 +1,78 @@
+org.opensolaris.os.dtrace.ProbeData[epid = 1, enabledProbeDescription = dtrace:::BEGIN, flow = null, records = [org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = , id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 1]]], formattedStrings = {[]=
+ 1
+}, tuples = [[]], output =
+ 1
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = , id = 1, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 1]]], formattedStrings = {[]=count: 1
+}, tuples = [[]], output = count: 1
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {[]= }, tuples = [[]], output = ], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3]]], formattedStrings = {[1, 3]=
+ 1 3 3
+, [1, 2]= 1 2 1
+}, tuples = [[1, 3], [1, 2]], output =
+ 1 3 3
+ 1 2 1
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=
+ 2 3 0 4
+, [1, 3]= 1 3 3 0
+, [1, 2]= 1 2 1 2
+}, tuples = [[2, 3], [1, 2], [1, 3]], output =
+ 2 3 0 4
+ 1 2 1 2
+ 1 3 3 0
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = c, id = 4, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 3]], org.opensolaris.os.dtrace.Aggregation[name = d, id = 5, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 4]]], formattedStrings = {[]=3 4
+}, tuples = [[]], output = 3 4
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = c, id = 4, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 3]], org.opensolaris.os.dtrace.Aggregation[name = d, id = 5, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 4]]], formattedStrings = {[]=3 4
+}, tuples = [[]], output = 3 4
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = c, id = 4, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [], value = 3]]], formattedStrings = {[]=3
+}, tuples = [[]], output = 3
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=[2, 3] 0 4
+, [1, 3]=[1, 3] 3 0
+, [1, 2]=[1, 2] 1 2
+}, tuples = [[2, 3], [1, 2], [1, 3]], output = [2, 3] 0 4
+[1, 2] 1 2
+[1, 3] 3 0
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=[2, 3] 0 4
+, [1, 3]=[1, 3] 3 0
+, [1, 2]=[1, 2] 1 2
+}, tuples = [[2, 3], [1, 3], [1, 2]], output = [2, 3] 0 4
+[1, 3] 3 0
+[1, 2] 1 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=[2, 3] 0 4
+, [1, 3]=[1, 3] 3 0
+, [1, 2]=[1, 2] 1 2
+}, tuples = [[2, 3], [1, 3], [1, 2]], output = [2, 3] 0 4
+[1, 3] 3 0
+[1, 2] 1 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=0 4 [2, 3]
+, [1, 3]=3 0 [1, 3]
+, [1, 2]=1 2 [1, 2]
+}, tuples = [[2, 3], [1, 3], [1, 2]], output = 0 4 [2, 3]
+3 0 [1, 3]
+1 2 [1, 2]
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {[2, 3]=[2, 3]
+, [1, 3]=[1, 3]
+, [1, 2]=[1, 2]
+}, tuples = [[2, 3], [1, 3], [1, 2]], output = [2, 3]
+[1, 3]
+[1, 2]
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {}, tuples = [], output = [2]
+[1]
+[1]
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {}, tuples = [], output = [2] 0 4
+[1] 3 0
+[1] 1 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {}, tuples = [], output = 0 4
+3 0
+1 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {}, tuples = [], output = 0 4 4
+3 0 0
+1 2 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [], formattedStrings = {}, tuples = [], output = [2] 0 4 4
+[1] 3 0 0
+[1] 1 2 2
+], org.opensolaris.os.dtrace.PrintaRecord[aggregations = [org.opensolaris.os.dtrace.Aggregation[name = a, id = 2, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 1], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 3], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 0]], org.opensolaris.os.dtrace.Aggregation[name = b, id = 3, records = [org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 2], value = 2], org.opensolaris.os.dtrace.AggregationRecord[tuple = [1, 3], value = 0], org.opensolaris.os.dtrace.AggregationRecord[tuple = [2, 3], value = 4]]], formattedStrings = {[2, 3]=[2, 3] 0 4 4
+, [1, 3]=[1, 3] 3 0 0
+, [1, 2]=[1, 2] 1 2 2
+}, tuples = [[2, 3], [1, 3], [1, 2]], output = [2, 3] 0 4 4
+[1, 3] 3 0 0
+[1, 2] 1 2 2
+], 0]
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.c
new file mode 100644
index 0000000..0833912
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.c
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+typedef void f(char *);
+
+static void
+f_a(char *a)
+{
+}
+
+static void
+f_b(char *a)
+{
+}
+
+static void
+f_c(char *a)
+{
+}
+
+static void
+f_d(char *a)
+{
+}
+
+static void
+f_e(char *a)
+{
+}
+
+static void
+fN(f func, char *a, int i)
+{
+ func(a);
+}
+
+static void
+fN2(f func, char *a, int i)
+{
+ func(a);
+}
+
+int
+main()
+{
+ /*
+ * Avoid length of 1, 2, 4, or 8 bytes so DTrace will treat the data as
+ * a byte array.
+ */
+ char a[] = {(char)-7, (char)201, (char)0, (char)0, (char)28, (char)1};
+ char b[] = {(char)84, (char)69, (char)0, (char)0, (char)28, (char)0};
+ char c[] = {(char)84, (char)69, (char)0, (char)0, (char)28, (char)1};
+ char d[] = {(char)-7, (char)201, (char)0, (char)0, (char)29, (char)0};
+ char e[] = {(char)84, (char)69, (char)0, (char)0, (char)28, (char)0};
+
+ fN(f_a, a, 1);
+ fN(f_b, b, 0);
+ fN(f_d, d, 102);
+ fN2(f_e, e, -2);
+ fN(f_c, c, 0);
+ fN(f_a, a, -1);
+ fN(f_d, d, 101);
+ fN(f_e, e, -2);
+ fN(f_e, e, 2);
+ fN2(f_e, e, 2);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh
new file mode 100644
index 0000000..97f4945
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# ProbeData instances sort as expected with multiple enabled probe
+# IDs and multiple records including byte array (sorted as
+# unsigned bytes), stand-alone ufunc() action, and signed integer.
+#
+############################################################################
+
+java -cp test.jar TestProbeData ./tst.ProbeData.exe
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh.out
new file mode 100644
index 0000000..6789514
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeData.ksh.out
@@ -0,0 +1,50 @@
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 0 TE....
+, tst.ProbeData.exe`f_b , 0]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 0 TE....
+, tst.ProbeData.exe`f_e , -2]]
+
+[probe 2 pid$target:tst.ProbeData.exe:fN2:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 0 TE....
+, tst.ProbeData.exe`f_e , -2]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 0 TE....
+, tst.ProbeData.exe`f_e , 2]]
+
+[probe 2 pid$target:tst.ProbeData.exe:fN2:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 0 TE....
+, tst.ProbeData.exe`f_e , 2]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 54 45 0 0 1c 1 TE....
+, tst.ProbeData.exe`f_c , 0]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: f9 c9 0 0 1c 1 ......
+, tst.ProbeData.exe`f_a , -1]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: f9 c9 0 0 1c 1 ......
+, tst.ProbeData.exe`f_a , 1]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: f9 c9 0 0 1d 0 ......
+, tst.ProbeData.exe`f_d , 101]]
+
+[probe 1 pid$target:tst.ProbeData.exe:fN:entry [
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: f9 c9 0 0 1d 0 ......
+, tst.ProbeData.exe`f_d , 102]]
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh
new file mode 100644
index 0000000..bee1cca
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh
@@ -0,0 +1,45 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# ProbeDescription constructors function as expected.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestProbeDescription syscall:::entry
+java -cp test.jar TestProbeDescription BEGIN
+java -cp test.jar TestProbeDescription isdigit entry
+java -cp test.jar TestProbeDescription genunix isdigit entry
+java -cp test.jar TestProbeDescription fbt genunix isdigit entry
+java -cp test.jar TestProbeDescription fbt:genunix:isdigit:entry
+java -cp test.jar TestProbeDescription syscall::entry
+java -cp test.jar TestProbeDescription syscall:entry
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh.out
new file mode 100644
index 0000000..326018a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.ProbeDescription.ksh.out
@@ -0,0 +1,8 @@
+syscall:::entry
+:::BEGIN
+::isdigit:entry
+:genunix:isdigit:entry
+fbt:genunix:isdigit:entry
+fbt:genunix:isdigit:entry
+:syscall::entry
+::syscall:entry
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh
new file mode 100644
index 0000000..638ce7a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh
@@ -0,0 +1,40 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Consumer state machine prevents illegal calls, allows legal
+# ones; consumer behaves predictably when methods called out of
+# order.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestStateMachine
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh.out
new file mode 100644
index 0000000..5ddb528
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StateMachine.ksh.out
@@ -0,0 +1,70 @@
+before open
+open: false
+enabled: false
+closed: false
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+java.lang.IllegalStateException: consumer not open
+before compile
+open: true
+enabled: false
+closed: false
+java.lang.IllegalStateException: consumer already open
+java.lang.IllegalStateException: no compiled program
+before enable
+open: true
+enabled: false
+closed: false
+java.lang.IllegalStateException: Not all compiled probes are enabled. Compiled description syscall:::entry { @[execname] = count(); } tick-101ms { printa(@); } not enabled.
+before go
+open: true
+enabled: true
+closed: false
+java.lang.IllegalStateException: go() not called
+java.lang.IllegalStateException: go() not called
+java.lang.IllegalStateException: go() not called
+java.lang.IllegalStateException: go() not called
+before go, running: false
+consumerStarted, running: true
+after go
+open: true
+enabled: false
+closed: false
+java.lang.IllegalStateException: go() already called
+java.lang.IllegalStateException: go() already called
+java.lang.IllegalStateException: go() already called
+java.lang.IllegalStateException: go() already called
+java.lang.IllegalStateException: go() already called
+java.lang.IllegalStateException: go() already called
+consumerStopped, running: false
+after stop, running: false
+after stop
+open: true
+enabled: false
+closed: false
+java.lang.IllegalStateException: consumer already stopped
+after close
+open: false
+enabled: false
+closed: true
+java.lang.IllegalStateException: cannot reopen a closed consumer
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
+java.lang.IllegalStateException: consumer closed
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh
new file mode 100644
index 0000000..4637a7ad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh
@@ -0,0 +1,39 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Fixed bug 6399888 stop() hangs if ConsumerListener calls
+# synchronized Consumer method.
+#
+# SECTION: Java API
+#
+############################################################################
+
+java -cp test.jar TestStopLock
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh.out
new file mode 100644
index 0000000..628d787
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.StopLock.ksh.out
@@ -0,0 +1 @@
+Successful
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d
new file mode 100644
index 0000000..574a9ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * printa() test with/without tuple, with multiple aggregations and
+ * mismatched format strings, and sorting options.
+ *
+ * SECTION: Aggregations/Aggregations; Output Formatting, printa()
+ *
+ * NOTES: This test attempts to cover all multi-agg printa() corner cases.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @ = count();
+ @a[1, 2] = sum(1);
+ @b[1, 2] = sum(2);
+ @a[1, 3] = sum(3);
+ @b[2, 3] = sum(4);
+ @c = sum(3);
+ @d = sum(4);
+ setopt("aggsortpos", "1");
+ setopt("aggsortrev");
+ printa(@);
+ printa("count: %@d\n", @);
+ printa(" ", @);
+ printa(@a);
+ printa(@a, @b);
+ printa("%@d %@d\n", @c, @d);
+ printa("%@d %@d\n", @c, @d);
+ printa("%@d\n", @c, @d);
+
+ printa("[%d, %d] %@d %@d\n", @a, @b);
+ setopt("aggsortkey");
+ printa("[%d, %d] %@d %@d\n", @a, @b);
+ setopt("aggsortpos", "0");
+ setopt("aggsortkeypos", "1");
+ printa("[%d, %d] %@d %@d\n", @a, @b);
+
+ printa("%@d %@d [%d, %d]\n", @a, @b);
+ printa("[%d, %d]\n", @a, @b);
+ printa("[%d]\n", @a, @b);
+ printa("[%d] %@d %@d\n", @a, @b);
+ printa("%@d %@d\n", @a, @b);
+ printa("%@d %@d %@d\n", @a, @b);
+ printa("[%d] %@d %@d %@d\n", @a, @b);
+ printa("[%d, %d] %@d %@d %@d\n", @a, @b);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d.out
new file mode 100644
index 0000000..10b90b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.printa.d.out
@@ -0,0 +1,47 @@
+
+ 1
+count: 1
+
+ 1 3 3
+ 1 2 1
+
+ 2 3 0 4
+ 1 2 1 2
+ 1 3 3 0
+3 4
+3 4
+3
+[2, 3] 0 4
+[1, 2] 1 2
+[1, 3] 3 0
+[2, 3] 0 4
+[1, 3] 3 0
+[1, 2] 1 2
+[2, 3] 0 4
+[1, 3] 3 0
+[1, 2] 1 2
+0 4 [2, 3]
+3 0 [1, 3]
+1 2 [1, 2]
+[2, 3]
+[1, 3]
+[1, 2]
+[2]
+[1]
+[1]
+[2] 0 4
+[1] 3 0
+[1] 1 2
+0 4
+3 0
+1 2
+0 4 4
+3 0 0
+1 2 2
+[2] 0 4 4
+[1] 3 0 0
+[1] 1 2 2
+[2, 3] 0 4 4
+[1, 3] 3 0 0
+[1, 2] 1 2 2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NL.char.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NL.char.d
new file mode 100644
index 0000000..9c0280c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NL.char.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Newlines may not be embedded in character constants..
+ *
+ * SECTION: Lexer
+ */
+
+
+BEGIN
+{
+
+ h = '
+ ';
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NULL.char.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NULL.char.d
new file mode 100644
index 0000000..aef5dab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_CHR_NULL.char.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Char constants may not be empty
+ *
+ * SECTION: Lexer
+ */
+
+
+BEGIN
+{
+
+ h = '';
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_DIGIT.InvalidDigit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_DIGIT.InvalidDigit.d
new file mode 100644
index 0000000..4fac03b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_DIGIT.InvalidDigit.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: If an integer representation contains an invalid digit
+ * a D_INT_DIGIT is thrown.
+ *
+ * SECTION: Errtags/D_INT_DIGIT
+ */
+
+BEGIN
+{
+ 0128;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_OFLOW.BigInt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_OFLOW.BigInt.d
new file mode 100644
index 0000000..1ec8be8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_INT_OFLOW.BigInt.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Using an integer constant that cannot be represented in any of the
+ * builtin integral types throws a D_INT_OFLOW error.
+ *
+ * SECTION: Errtags/D_INT_OFLOW
+ */
+
+BEGIN
+{
+ 0x12345678123456781;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_STR_NL.string.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_STR_NL.string.d
new file mode 100644
index 0000000..68b4cd4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_STR_NL.string.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Newlines may not be embedded in string literals.
+ *
+ * SECTION: Lexer
+ */
+
+
+BEGIN
+{
+
+ h = "hello
+
+ there";
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace1.d
new file mode 100644
index 0000000..ae6dc6c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace1.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of extra curly braces.
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ trace(epid);
+}
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace2.d
new file mode 100644
index 0000000..196f7d7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brace2.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: * Test detection of missing curly braces.
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ trace(epid);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack1.d
new file mode 100644
index 0000000..8e4c97d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack1.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of extra square brackets
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ trace(args[0]]);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack2.d
new file mode 100644
index 0000000..307bd08
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack2.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of missing square brackets
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ args[0
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack3.d
new file mode 100644
index 0000000..2d66828
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.brack3.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of missing square brackets
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+/args[0/
+{
+ trace(epid);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren1.d
new file mode 100644
index 0000000..812dbb7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren1.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of extra parentheses
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ trace(epid));
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren2.d
new file mode 100644
index 0000000..078d08c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren2.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of missing parentheses
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+{
+ rand(
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren3.d
new file mode 100644
index 0000000..38cdb7e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/err.D_SYNTAX.paren3.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test detection of missing parentheses
+ *
+ * SECTION: Lexer
+ */
+
+BEGIN
+/rand(/
+{
+ trace(epid);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/tst.D_MACRO_OFLOW.ParIntOvflow.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/tst.D_MACRO_OFLOW.ParIntOvflow.d.ksh
new file mode 100644
index 0000000..ad124ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/lexer/tst.D_MACRO_OFLOW.ParIntOvflow.d.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION:
+# If a macro argument results in an integer overflow, a D_MACRO_OFLOW is
+# thrown.
+#
+# SECTION: Errtags/D_MACRO_OFLOW
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -n 'BEGIN { $1; }' 0x12345678123456781
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ exit 0
+fi
+
+echo dtrace failed
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.nodivide.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.nodivide.d
new file mode 100644
index 0000000..b11d282
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.nodivide.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 25);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.notfactor.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.notfactor.d
new file mode 100644
index 0000000..c8af7d9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTOREVEN.notfactor.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 30);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORMATCH.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORMATCH.d
new file mode 100644
index 0000000..0404b4ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORMATCH.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 10);
+ @ = llquantize(0, 3, 0, 10, 81);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORNSTEPS.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORNSTEPS.d
new file mode 100644
index 0000000..fd6b0e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORNSTEPS.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 7);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORSMALL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORSMALL.d
new file mode 100644
index 0000000..7074f5f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORSMALL.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 1, 0, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORTYPE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORTYPE.d
new file mode 100644
index 0000000..ea39c7e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORTYPE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ this->doogle = 10;
+ @ = llquantize(0, this->doogle, 0, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORVAL.d
new file mode 100644
index 0000000..a1ad20f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_FACTORVAL.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 65537, 0, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHMATCH.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHMATCH.d
new file mode 100644
index 0000000..46bf0e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHMATCH.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 10);
+ @ = llquantize(0, 10, 0, 11, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHTYPE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHTYPE.d
new file mode 100644
index 0000000..fee786d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHTYPE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ this->doogle = 10;
+ @ = llquantize(0, 10, 0, this->doogle, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHVAL.d
new file mode 100644
index 0000000..531ab0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_HIGHVAL.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, -1, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWMATCH.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWMATCH.d
new file mode 100644
index 0000000..126429a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWMATCH.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 10);
+ @ = llquantize(0, 10, 1, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWTYPE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWTYPE.d
new file mode 100644
index 0000000..2a9b2ef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWTYPE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ this->doogle = 0;
+ @ = llquantize(0, 10, this->doogle, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWVAL.d
new file mode 100644
index 0000000..e1045d8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_LOWVAL.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, -1, 10, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGRANGE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGRANGE.d
new file mode 100644
index 0000000..9852c1a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGRANGE.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 10, 0, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGTOOBIG.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGTOOBIG.d
new file mode 100644
index 0000000..c707630
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_MAGTOOBIG.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 100, 10);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPMATCH.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPMATCH.d
new file mode 100644
index 0000000..77b4d8a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPMATCH.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(0, 10, 0, 10, 10);
+ @ = llquantize(0, 10, 0, 10, 100);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPTYPE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPTYPE.d
new file mode 100644
index 0000000..4eb9b2f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPTYPE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ this->doogle = 10;
+ @ = llquantize(0, 10, 0, 10, this->doogle);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPVAL.d
new file mode 100644
index 0000000..3855beb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/err.D_LLQUANT_NSTEPVAL.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ @ = llquantize(123, 10, 0, 10, 123456);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d
new file mode 100644
index 0000000..e3a6ff1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tick-1ms
+/i++ <= 100/
+{
+ @two = llquantize(i, 2, 0, 6, 2);
+ @three = llquantize(i, 3, 0, 1, 9);
+ @four = llquantize(i, 4, 0, 1, 4);
+ @five = llquantize(i, 5, 0, 1, 25);
+ @six = llquantize(i, 6, 0, 3, 12);
+ @seven = llquantize(i, 7, 0, 1, 7);
+ @eight = llquantize(i, 8, 0, 1, 16);
+ @nine = llquantize(i, 9, 0, 1, 9);
+ @ten = llquantize(i, 10, 0, 1, 10);
+}
+
+tick-1ms
+/i > 100/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d.out
new file mode 100644
index 0000000..1b207bf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.bases.d.out
@@ -0,0 +1,177 @@
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 |@ 2
+ 4 |@@ 4
+ 8 |@@@ 8
+ 16 |@@@@@@ 16
+ 32 |@@@@@@@@@@@@@ 32
+ 64 |@@@@@@@@@@@@@@@ 38
+ >= 128 | 0
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ >= 9 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 93
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 |@@ 4
+ 8 |@@ 4
+ 12 |@@ 4
+ >= 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 86
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ 9 | 1
+ 10 | 1
+ 11 | 1
+ 12 | 1
+ 13 | 1
+ 14 | 1
+ 15 | 1
+ 16 | 1
+ 17 | 1
+ 18 | 1
+ 19 | 1
+ 20 | 1
+ 21 | 1
+ 22 | 1
+ 23 | 1
+ 24 | 1
+ >= 25 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 77
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 |@ 3
+ 9 |@ 3
+ 12 |@ 3
+ 15 |@ 3
+ 18 |@ 3
+ 21 |@ 3
+ 24 |@ 3
+ 27 |@ 3
+ 30 |@ 3
+ 33 |@ 3
+ 36 |@@@@@@@ 18
+ 54 |@@@@@@@ 18
+ 72 |@@@@@@@ 18
+ 90 |@@@@@ 12
+ 108 | 0
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 |@@@ 7
+ 14 |@@@ 7
+ 21 |@@@ 7
+ 28 |@@@ 7
+ 35 |@@@ 7
+ 42 |@@@ 7
+ >= 49 |@@@@@@@@@@@@@@@@@@@@@ 53
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 |@@ 4
+ 12 |@@ 4
+ 16 |@@ 4
+ 20 |@@ 4
+ 24 |@@ 4
+ 28 |@@ 4
+ 32 |@@ 4
+ 36 |@@ 4
+ 40 |@@ 4
+ 44 |@@ 4
+ 48 |@@ 4
+ 52 |@@ 4
+ 56 |@@ 4
+ 60 |@@ 4
+ >= 64 |@@@@@@@@@@@@@@@ 38
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ 9 |@@@@ 9
+ 18 |@@@@ 9
+ 27 |@@@@ 9
+ 36 |@@@@ 9
+ 45 |@@@@ 9
+ 54 |@@@@ 9
+ 63 |@@@@ 9
+ 72 |@@@@ 9
+ >= 81 |@@@@@@@@ 21
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ 9 | 1
+ 10 |@@@@ 10
+ 20 |@@@@ 10
+ 30 |@@@@ 10
+ 40 |@@@@ 10
+ 50 |@@@@ 10
+ 60 |@@@@ 10
+ 70 |@@@@ 10
+ 80 |@@@@ 10
+ 90 |@@@@ 10
+ >= 100 |@ 2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d
new file mode 100644
index 0000000..57b6ed8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tick-1ms
+/i++ <= 100/
+{
+ @ = llquantize(i, 10, 0, 10, 10);
+}
+
+tick-1ms
+/i > 100/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d.out
new file mode 100644
index 0000000..9a7b288
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.basic.d.out
@@ -0,0 +1,25 @@
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ 9 | 1
+ 10 |@@@@ 10
+ 20 |@@@@ 10
+ 30 |@@@@ 10
+ 40 |@@@@ 10
+ 50 |@@@@ 10
+ 60 |@@@@ 10
+ 70 |@@@@ 10
+ 80 |@@@@ 10
+ 90 |@@@@ 10
+ 100 |@ 2
+ 200 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d
new file mode 100644
index 0000000..b18c688
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = 7;
+ b = 13;
+ val = (-a * b) + a;
+}
+
+tick-1ms
+{
+ incr = val % b;
+ val += a;
+}
+
+tick-1ms
+/val == 0/
+{
+ val += a;
+}
+
+tick-1ms
+/incr != 0/
+{
+ i++;
+ @llquanty[i] = llquantize(1, 10, 0, 10, 10, incr);
+}
+
+tick-1ms
+/incr == 0/
+{
+ printf("Ordering of llquantize() with some negative weights:\n");
+ printa(@llquanty);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d.out
new file mode 100644
index 0000000..ac0f3cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negorder.d.out
@@ -0,0 +1,148 @@
+Ordering of llquantize() with some negative weights:
+
+ 2
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -12
+ 2 | 0
+
+ 4
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -11
+ 2 | 0
+
+ 6
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -10
+ 2 | 0
+
+ 8
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -9
+ 2 | 0
+
+ 10
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -8
+ 2 | 0
+
+ 12
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -7
+ 2 | 0
+
+ 1
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -6
+ 2 | 0
+
+ 3
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -5
+ 2 | 0
+
+ 5
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -4
+ 2 | 0
+
+ 7
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -3
+ 2 | 0
+
+ 9
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -2
+ 2 | 0
+
+ 11
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -1
+ 2 | 0
+
+ 14
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+ 16
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2
+ 2 | 0
+
+ 18
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3
+ 2 | 0
+
+ 20
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4
+ 2 | 0
+
+ 22
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ 2 | 0
+
+ 24
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+ 2 | 0
+
+ 13
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7
+ 2 | 0
+
+ 15
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8
+ 2 | 0
+
+ 17
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9
+ 2 | 0
+
+ 19
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 10
+ 2 | 0
+
+ 21
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11
+ 2 | 0
+
+ 23
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12
+ 2 | 0
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d
new file mode 100644
index 0000000..c74d019
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tick-1ms
+/i++ <= 100/
+{
+ @ = llquantize(i, 10, 0, 10, 10, 50 - i);
+}
+
+tick-1ms
+/i > 100/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d.out
new file mode 100644
index 0000000..04b0d5e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.negvalue.d.out
@@ -0,0 +1,25 @@
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 49
+ 2 | 48
+ 3 | 47
+ 4 | 46
+ 5 | 45
+ 6 | 44
+ 7 | 43
+ 8 | 42
+ 9 | 41
+ 10 |@@@ 355
+ 20 |@@ 255
+ 30 |@ 155
+ 40 | 55
+ 50 | -45
+ 60 @| -145
+ 70 @@| -245
+ 80 @@@| -345
+ 90 @@@| -445
+ 100 @| -101
+ 200 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d
new file mode 100644
index 0000000..7097ba7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tick-1ms
+/i++ <= 100/
+{
+ @ = llquantize(i, 10, 0, 10, 10);
+}
+
+tick-1ms
+/i > 100/
+{
+ normalize(@, 10);
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d.out
new file mode 100644
index 0000000..3b1f41b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.normal.d.out
@@ -0,0 +1,26 @@
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 0
+ 2 | 0
+ 3 | 0
+ 4 | 0
+ 5 | 0
+ 6 | 0
+ 7 | 0
+ 8 | 0
+ 9 | 0
+ 10 |@@@@ 1
+ 20 |@@@@ 1
+ 30 |@@@@ 1
+ 40 |@@@@ 1
+ 50 |@@@@ 1
+ 60 |@@@@ 1
+ 70 |@@@@ 1
+ 80 |@@@@ 1
+ 90 |@@@@ 1
+ 100 |@ 0
+ 200 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d
new file mode 100644
index 0000000..e2882b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @["Screven"] = llquantize(0, 10, 1, 2, 20, 25);
+ @["Katz"] = llquantize(1, 10, 1, 2, 20, -100);
+ @["Kurian"] = llquantize(7, 10, 1, 2, 20, 15);
+ @["Rozwat"] = llquantize(49, 10, 1, 2, 20, 15);
+ @["Fowler"] = llquantize(343, 10, 1, 2, 20, 150);
+
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d.out
new file mode 100644
index 0000000..c6736c6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.range.d.out
@@ -0,0 +1,29 @@
+
+ Katz
+ value ------------- Distribution ------------- count
+ < 10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100
+ 10 | 0
+
+ Kurian
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 10 | 0
+
+ Screven
+ value ------------- Distribution ------------- count
+ < 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 25
+ 10 | 0
+
+ Rozwat
+ value ------------- Distribution ------------- count
+ 40 | 0
+ 45 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 15
+ 50 | 0
+
+ Fowler
+ value ------------- Distribution ------------- count
+ 250 | 0
+ 300 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 150
+ 350 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d
new file mode 100644
index 0000000..f00659e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tick-1ms
+/i++ <= 100/
+{
+ @ = llquantize(i, 10, 0, 10, 20);
+ @hunid = llquantize(i * 10, 10, 0, 10, 100);
+ @large = llquantize(i * 100, 10, 0, 10, 1000);
+}
+
+tick-1ms
+/i > 100/
+{
+ exit(0);
+}
+
+END
+{
+ printf("20 steps:\n");
+ printa(@);
+
+ printf("100 steps:\n");
+ printa(@hunid);
+
+ printf("1000 steps:\n");
+ printa(@large);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d.out
new file mode 100644
index 0000000..0888551
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.steps.d.out
@@ -0,0 +1,2033 @@
+20 steps:
+
+
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 | 1
+ 2 | 1
+ 3 | 1
+ 4 | 1
+ 5 | 1
+ 6 | 1
+ 7 | 1
+ 8 | 1
+ 9 | 1
+ 10 |@@ 5
+ 15 |@@ 5
+ 20 |@@ 5
+ 25 |@@ 5
+ 30 |@@ 5
+ 35 |@@ 5
+ 40 |@@ 5
+ 45 |@@ 5
+ 50 |@@ 5
+ 55 |@@ 5
+ 60 |@@ 5
+ 65 |@@ 5
+ 70 |@@ 5
+ 75 |@@ 5
+ 80 |@@ 5
+ 85 |@@ 5
+ 90 |@@ 5
+ 95 |@@ 5
+ 100 |@ 2
+ 150 | 0
+
+100 steps:
+
+
+ value ------------- Distribution ------------- count
+ 9 | 0
+ 10 | 1
+ 11 | 0
+ 12 | 0
+ 13 | 0
+ 14 | 0
+ 15 | 0
+ 16 | 0
+ 17 | 0
+ 18 | 0
+ 19 | 0
+ 20 | 1
+ 21 | 0
+ 22 | 0
+ 23 | 0
+ 24 | 0
+ 25 | 0
+ 26 | 0
+ 27 | 0
+ 28 | 0
+ 29 | 0
+ 30 | 1
+ 31 | 0
+ 32 | 0
+ 33 | 0
+ 34 | 0
+ 35 | 0
+ 36 | 0
+ 37 | 0
+ 38 | 0
+ 39 | 0
+ 40 | 1
+ 41 | 0
+ 42 | 0
+ 43 | 0
+ 44 | 0
+ 45 | 0
+ 46 | 0
+ 47 | 0
+ 48 | 0
+ 49 | 0
+ 50 | 1
+ 51 | 0
+ 52 | 0
+ 53 | 0
+ 54 | 0
+ 55 | 0
+ 56 | 0
+ 57 | 0
+ 58 | 0
+ 59 | 0
+ 60 | 1
+ 61 | 0
+ 62 | 0
+ 63 | 0
+ 64 | 0
+ 65 | 0
+ 66 | 0
+ 67 | 0
+ 68 | 0
+ 69 | 0
+ 70 | 1
+ 71 | 0
+ 72 | 0
+ 73 | 0
+ 74 | 0
+ 75 | 0
+ 76 | 0
+ 77 | 0
+ 78 | 0
+ 79 | 0
+ 80 | 1
+ 81 | 0
+ 82 | 0
+ 83 | 0
+ 84 | 0
+ 85 | 0
+ 86 | 0
+ 87 | 0
+ 88 | 0
+ 89 | 0
+ 90 | 1
+ 91 | 0
+ 92 | 0
+ 93 | 0
+ 94 | 0
+ 95 | 0
+ 96 | 0
+ 97 | 0
+ 98 | 0
+ 99 | 0
+ 100 | 1
+ 110 | 1
+ 120 | 1
+ 130 | 1
+ 140 | 1
+ 150 | 1
+ 160 | 1
+ 170 | 1
+ 180 | 1
+ 190 | 1
+ 200 | 1
+ 210 | 1
+ 220 | 1
+ 230 | 1
+ 240 | 1
+ 250 | 1
+ 260 | 1
+ 270 | 1
+ 280 | 1
+ 290 | 1
+ 300 | 1
+ 310 | 1
+ 320 | 1
+ 330 | 1
+ 340 | 1
+ 350 | 1
+ 360 | 1
+ 370 | 1
+ 380 | 1
+ 390 | 1
+ 400 | 1
+ 410 | 1
+ 420 | 1
+ 430 | 1
+ 440 | 1
+ 450 | 1
+ 460 | 1
+ 470 | 1
+ 480 | 1
+ 490 | 1
+ 500 | 1
+ 510 | 1
+ 520 | 1
+ 530 | 1
+ 540 | 1
+ 550 | 1
+ 560 | 1
+ 570 | 1
+ 580 | 1
+ 590 | 1
+ 600 | 1
+ 610 | 1
+ 620 | 1
+ 630 | 1
+ 640 | 1
+ 650 | 1
+ 660 | 1
+ 670 | 1
+ 680 | 1
+ 690 | 1
+ 700 | 1
+ 710 | 1
+ 720 | 1
+ 730 | 1
+ 740 | 1
+ 750 | 1
+ 760 | 1
+ 770 | 1
+ 780 | 1
+ 790 | 1
+ 800 | 1
+ 810 | 1
+ 820 | 1
+ 830 | 1
+ 840 | 1
+ 850 | 1
+ 860 | 1
+ 870 | 1
+ 880 | 1
+ 890 | 1
+ 900 | 1
+ 910 | 1
+ 920 | 1
+ 930 | 1
+ 940 | 1
+ 950 | 1
+ 960 | 1
+ 970 | 1
+ 980 | 1
+ 990 | 1
+ 1000 |@ 2
+ 1100 | 0
+
+1000 steps:
+
+
+ value ------------- Distribution ------------- count
+ 99 | 0
+ 100 | 1
+ 101 | 0
+ 102 | 0
+ 103 | 0
+ 104 | 0
+ 105 | 0
+ 106 | 0
+ 107 | 0
+ 108 | 0
+ 109 | 0
+ 110 | 0
+ 111 | 0
+ 112 | 0
+ 113 | 0
+ 114 | 0
+ 115 | 0
+ 116 | 0
+ 117 | 0
+ 118 | 0
+ 119 | 0
+ 120 | 0
+ 121 | 0
+ 122 | 0
+ 123 | 0
+ 124 | 0
+ 125 | 0
+ 126 | 0
+ 127 | 0
+ 128 | 0
+ 129 | 0
+ 130 | 0
+ 131 | 0
+ 132 | 0
+ 133 | 0
+ 134 | 0
+ 135 | 0
+ 136 | 0
+ 137 | 0
+ 138 | 0
+ 139 | 0
+ 140 | 0
+ 141 | 0
+ 142 | 0
+ 143 | 0
+ 144 | 0
+ 145 | 0
+ 146 | 0
+ 147 | 0
+ 148 | 0
+ 149 | 0
+ 150 | 0
+ 151 | 0
+ 152 | 0
+ 153 | 0
+ 154 | 0
+ 155 | 0
+ 156 | 0
+ 157 | 0
+ 158 | 0
+ 159 | 0
+ 160 | 0
+ 161 | 0
+ 162 | 0
+ 163 | 0
+ 164 | 0
+ 165 | 0
+ 166 | 0
+ 167 | 0
+ 168 | 0
+ 169 | 0
+ 170 | 0
+ 171 | 0
+ 172 | 0
+ 173 | 0
+ 174 | 0
+ 175 | 0
+ 176 | 0
+ 177 | 0
+ 178 | 0
+ 179 | 0
+ 180 | 0
+ 181 | 0
+ 182 | 0
+ 183 | 0
+ 184 | 0
+ 185 | 0
+ 186 | 0
+ 187 | 0
+ 188 | 0
+ 189 | 0
+ 190 | 0
+ 191 | 0
+ 192 | 0
+ 193 | 0
+ 194 | 0
+ 195 | 0
+ 196 | 0
+ 197 | 0
+ 198 | 0
+ 199 | 0
+ 200 | 1
+ 201 | 0
+ 202 | 0
+ 203 | 0
+ 204 | 0
+ 205 | 0
+ 206 | 0
+ 207 | 0
+ 208 | 0
+ 209 | 0
+ 210 | 0
+ 211 | 0
+ 212 | 0
+ 213 | 0
+ 214 | 0
+ 215 | 0
+ 216 | 0
+ 217 | 0
+ 218 | 0
+ 219 | 0
+ 220 | 0
+ 221 | 0
+ 222 | 0
+ 223 | 0
+ 224 | 0
+ 225 | 0
+ 226 | 0
+ 227 | 0
+ 228 | 0
+ 229 | 0
+ 230 | 0
+ 231 | 0
+ 232 | 0
+ 233 | 0
+ 234 | 0
+ 235 | 0
+ 236 | 0
+ 237 | 0
+ 238 | 0
+ 239 | 0
+ 240 | 0
+ 241 | 0
+ 242 | 0
+ 243 | 0
+ 244 | 0
+ 245 | 0
+ 246 | 0
+ 247 | 0
+ 248 | 0
+ 249 | 0
+ 250 | 0
+ 251 | 0
+ 252 | 0
+ 253 | 0
+ 254 | 0
+ 255 | 0
+ 256 | 0
+ 257 | 0
+ 258 | 0
+ 259 | 0
+ 260 | 0
+ 261 | 0
+ 262 | 0
+ 263 | 0
+ 264 | 0
+ 265 | 0
+ 266 | 0
+ 267 | 0
+ 268 | 0
+ 269 | 0
+ 270 | 0
+ 271 | 0
+ 272 | 0
+ 273 | 0
+ 274 | 0
+ 275 | 0
+ 276 | 0
+ 277 | 0
+ 278 | 0
+ 279 | 0
+ 280 | 0
+ 281 | 0
+ 282 | 0
+ 283 | 0
+ 284 | 0
+ 285 | 0
+ 286 | 0
+ 287 | 0
+ 288 | 0
+ 289 | 0
+ 290 | 0
+ 291 | 0
+ 292 | 0
+ 293 | 0
+ 294 | 0
+ 295 | 0
+ 296 | 0
+ 297 | 0
+ 298 | 0
+ 299 | 0
+ 300 | 1
+ 301 | 0
+ 302 | 0
+ 303 | 0
+ 304 | 0
+ 305 | 0
+ 306 | 0
+ 307 | 0
+ 308 | 0
+ 309 | 0
+ 310 | 0
+ 311 | 0
+ 312 | 0
+ 313 | 0
+ 314 | 0
+ 315 | 0
+ 316 | 0
+ 317 | 0
+ 318 | 0
+ 319 | 0
+ 320 | 0
+ 321 | 0
+ 322 | 0
+ 323 | 0
+ 324 | 0
+ 325 | 0
+ 326 | 0
+ 327 | 0
+ 328 | 0
+ 329 | 0
+ 330 | 0
+ 331 | 0
+ 332 | 0
+ 333 | 0
+ 334 | 0
+ 335 | 0
+ 336 | 0
+ 337 | 0
+ 338 | 0
+ 339 | 0
+ 340 | 0
+ 341 | 0
+ 342 | 0
+ 343 | 0
+ 344 | 0
+ 345 | 0
+ 346 | 0
+ 347 | 0
+ 348 | 0
+ 349 | 0
+ 350 | 0
+ 351 | 0
+ 352 | 0
+ 353 | 0
+ 354 | 0
+ 355 | 0
+ 356 | 0
+ 357 | 0
+ 358 | 0
+ 359 | 0
+ 360 | 0
+ 361 | 0
+ 362 | 0
+ 363 | 0
+ 364 | 0
+ 365 | 0
+ 366 | 0
+ 367 | 0
+ 368 | 0
+ 369 | 0
+ 370 | 0
+ 371 | 0
+ 372 | 0
+ 373 | 0
+ 374 | 0
+ 375 | 0
+ 376 | 0
+ 377 | 0
+ 378 | 0
+ 379 | 0
+ 380 | 0
+ 381 | 0
+ 382 | 0
+ 383 | 0
+ 384 | 0
+ 385 | 0
+ 386 | 0
+ 387 | 0
+ 388 | 0
+ 389 | 0
+ 390 | 0
+ 391 | 0
+ 392 | 0
+ 393 | 0
+ 394 | 0
+ 395 | 0
+ 396 | 0
+ 397 | 0
+ 398 | 0
+ 399 | 0
+ 400 | 1
+ 401 | 0
+ 402 | 0
+ 403 | 0
+ 404 | 0
+ 405 | 0
+ 406 | 0
+ 407 | 0
+ 408 | 0
+ 409 | 0
+ 410 | 0
+ 411 | 0
+ 412 | 0
+ 413 | 0
+ 414 | 0
+ 415 | 0
+ 416 | 0
+ 417 | 0
+ 418 | 0
+ 419 | 0
+ 420 | 0
+ 421 | 0
+ 422 | 0
+ 423 | 0
+ 424 | 0
+ 425 | 0
+ 426 | 0
+ 427 | 0
+ 428 | 0
+ 429 | 0
+ 430 | 0
+ 431 | 0
+ 432 | 0
+ 433 | 0
+ 434 | 0
+ 435 | 0
+ 436 | 0
+ 437 | 0
+ 438 | 0
+ 439 | 0
+ 440 | 0
+ 441 | 0
+ 442 | 0
+ 443 | 0
+ 444 | 0
+ 445 | 0
+ 446 | 0
+ 447 | 0
+ 448 | 0
+ 449 | 0
+ 450 | 0
+ 451 | 0
+ 452 | 0
+ 453 | 0
+ 454 | 0
+ 455 | 0
+ 456 | 0
+ 457 | 0
+ 458 | 0
+ 459 | 0
+ 460 | 0
+ 461 | 0
+ 462 | 0
+ 463 | 0
+ 464 | 0
+ 465 | 0
+ 466 | 0
+ 467 | 0
+ 468 | 0
+ 469 | 0
+ 470 | 0
+ 471 | 0
+ 472 | 0
+ 473 | 0
+ 474 | 0
+ 475 | 0
+ 476 | 0
+ 477 | 0
+ 478 | 0
+ 479 | 0
+ 480 | 0
+ 481 | 0
+ 482 | 0
+ 483 | 0
+ 484 | 0
+ 485 | 0
+ 486 | 0
+ 487 | 0
+ 488 | 0
+ 489 | 0
+ 490 | 0
+ 491 | 0
+ 492 | 0
+ 493 | 0
+ 494 | 0
+ 495 | 0
+ 496 | 0
+ 497 | 0
+ 498 | 0
+ 499 | 0
+ 500 | 1
+ 501 | 0
+ 502 | 0
+ 503 | 0
+ 504 | 0
+ 505 | 0
+ 506 | 0
+ 507 | 0
+ 508 | 0
+ 509 | 0
+ 510 | 0
+ 511 | 0
+ 512 | 0
+ 513 | 0
+ 514 | 0
+ 515 | 0
+ 516 | 0
+ 517 | 0
+ 518 | 0
+ 519 | 0
+ 520 | 0
+ 521 | 0
+ 522 | 0
+ 523 | 0
+ 524 | 0
+ 525 | 0
+ 526 | 0
+ 527 | 0
+ 528 | 0
+ 529 | 0
+ 530 | 0
+ 531 | 0
+ 532 | 0
+ 533 | 0
+ 534 | 0
+ 535 | 0
+ 536 | 0
+ 537 | 0
+ 538 | 0
+ 539 | 0
+ 540 | 0
+ 541 | 0
+ 542 | 0
+ 543 | 0
+ 544 | 0
+ 545 | 0
+ 546 | 0
+ 547 | 0
+ 548 | 0
+ 549 | 0
+ 550 | 0
+ 551 | 0
+ 552 | 0
+ 553 | 0
+ 554 | 0
+ 555 | 0
+ 556 | 0
+ 557 | 0
+ 558 | 0
+ 559 | 0
+ 560 | 0
+ 561 | 0
+ 562 | 0
+ 563 | 0
+ 564 | 0
+ 565 | 0
+ 566 | 0
+ 567 | 0
+ 568 | 0
+ 569 | 0
+ 570 | 0
+ 571 | 0
+ 572 | 0
+ 573 | 0
+ 574 | 0
+ 575 | 0
+ 576 | 0
+ 577 | 0
+ 578 | 0
+ 579 | 0
+ 580 | 0
+ 581 | 0
+ 582 | 0
+ 583 | 0
+ 584 | 0
+ 585 | 0
+ 586 | 0
+ 587 | 0
+ 588 | 0
+ 589 | 0
+ 590 | 0
+ 591 | 0
+ 592 | 0
+ 593 | 0
+ 594 | 0
+ 595 | 0
+ 596 | 0
+ 597 | 0
+ 598 | 0
+ 599 | 0
+ 600 | 1
+ 601 | 0
+ 602 | 0
+ 603 | 0
+ 604 | 0
+ 605 | 0
+ 606 | 0
+ 607 | 0
+ 608 | 0
+ 609 | 0
+ 610 | 0
+ 611 | 0
+ 612 | 0
+ 613 | 0
+ 614 | 0
+ 615 | 0
+ 616 | 0
+ 617 | 0
+ 618 | 0
+ 619 | 0
+ 620 | 0
+ 621 | 0
+ 622 | 0
+ 623 | 0
+ 624 | 0
+ 625 | 0
+ 626 | 0
+ 627 | 0
+ 628 | 0
+ 629 | 0
+ 630 | 0
+ 631 | 0
+ 632 | 0
+ 633 | 0
+ 634 | 0
+ 635 | 0
+ 636 | 0
+ 637 | 0
+ 638 | 0
+ 639 | 0
+ 640 | 0
+ 641 | 0
+ 642 | 0
+ 643 | 0
+ 644 | 0
+ 645 | 0
+ 646 | 0
+ 647 | 0
+ 648 | 0
+ 649 | 0
+ 650 | 0
+ 651 | 0
+ 652 | 0
+ 653 | 0
+ 654 | 0
+ 655 | 0
+ 656 | 0
+ 657 | 0
+ 658 | 0
+ 659 | 0
+ 660 | 0
+ 661 | 0
+ 662 | 0
+ 663 | 0
+ 664 | 0
+ 665 | 0
+ 666 | 0
+ 667 | 0
+ 668 | 0
+ 669 | 0
+ 670 | 0
+ 671 | 0
+ 672 | 0
+ 673 | 0
+ 674 | 0
+ 675 | 0
+ 676 | 0
+ 677 | 0
+ 678 | 0
+ 679 | 0
+ 680 | 0
+ 681 | 0
+ 682 | 0
+ 683 | 0
+ 684 | 0
+ 685 | 0
+ 686 | 0
+ 687 | 0
+ 688 | 0
+ 689 | 0
+ 690 | 0
+ 691 | 0
+ 692 | 0
+ 693 | 0
+ 694 | 0
+ 695 | 0
+ 696 | 0
+ 697 | 0
+ 698 | 0
+ 699 | 0
+ 700 | 1
+ 701 | 0
+ 702 | 0
+ 703 | 0
+ 704 | 0
+ 705 | 0
+ 706 | 0
+ 707 | 0
+ 708 | 0
+ 709 | 0
+ 710 | 0
+ 711 | 0
+ 712 | 0
+ 713 | 0
+ 714 | 0
+ 715 | 0
+ 716 | 0
+ 717 | 0
+ 718 | 0
+ 719 | 0
+ 720 | 0
+ 721 | 0
+ 722 | 0
+ 723 | 0
+ 724 | 0
+ 725 | 0
+ 726 | 0
+ 727 | 0
+ 728 | 0
+ 729 | 0
+ 730 | 0
+ 731 | 0
+ 732 | 0
+ 733 | 0
+ 734 | 0
+ 735 | 0
+ 736 | 0
+ 737 | 0
+ 738 | 0
+ 739 | 0
+ 740 | 0
+ 741 | 0
+ 742 | 0
+ 743 | 0
+ 744 | 0
+ 745 | 0
+ 746 | 0
+ 747 | 0
+ 748 | 0
+ 749 | 0
+ 750 | 0
+ 751 | 0
+ 752 | 0
+ 753 | 0
+ 754 | 0
+ 755 | 0
+ 756 | 0
+ 757 | 0
+ 758 | 0
+ 759 | 0
+ 760 | 0
+ 761 | 0
+ 762 | 0
+ 763 | 0
+ 764 | 0
+ 765 | 0
+ 766 | 0
+ 767 | 0
+ 768 | 0
+ 769 | 0
+ 770 | 0
+ 771 | 0
+ 772 | 0
+ 773 | 0
+ 774 | 0
+ 775 | 0
+ 776 | 0
+ 777 | 0
+ 778 | 0
+ 779 | 0
+ 780 | 0
+ 781 | 0
+ 782 | 0
+ 783 | 0
+ 784 | 0
+ 785 | 0
+ 786 | 0
+ 787 | 0
+ 788 | 0
+ 789 | 0
+ 790 | 0
+ 791 | 0
+ 792 | 0
+ 793 | 0
+ 794 | 0
+ 795 | 0
+ 796 | 0
+ 797 | 0
+ 798 | 0
+ 799 | 0
+ 800 | 1
+ 801 | 0
+ 802 | 0
+ 803 | 0
+ 804 | 0
+ 805 | 0
+ 806 | 0
+ 807 | 0
+ 808 | 0
+ 809 | 0
+ 810 | 0
+ 811 | 0
+ 812 | 0
+ 813 | 0
+ 814 | 0
+ 815 | 0
+ 816 | 0
+ 817 | 0
+ 818 | 0
+ 819 | 0
+ 820 | 0
+ 821 | 0
+ 822 | 0
+ 823 | 0
+ 824 | 0
+ 825 | 0
+ 826 | 0
+ 827 | 0
+ 828 | 0
+ 829 | 0
+ 830 | 0
+ 831 | 0
+ 832 | 0
+ 833 | 0
+ 834 | 0
+ 835 | 0
+ 836 | 0
+ 837 | 0
+ 838 | 0
+ 839 | 0
+ 840 | 0
+ 841 | 0
+ 842 | 0
+ 843 | 0
+ 844 | 0
+ 845 | 0
+ 846 | 0
+ 847 | 0
+ 848 | 0
+ 849 | 0
+ 850 | 0
+ 851 | 0
+ 852 | 0
+ 853 | 0
+ 854 | 0
+ 855 | 0
+ 856 | 0
+ 857 | 0
+ 858 | 0
+ 859 | 0
+ 860 | 0
+ 861 | 0
+ 862 | 0
+ 863 | 0
+ 864 | 0
+ 865 | 0
+ 866 | 0
+ 867 | 0
+ 868 | 0
+ 869 | 0
+ 870 | 0
+ 871 | 0
+ 872 | 0
+ 873 | 0
+ 874 | 0
+ 875 | 0
+ 876 | 0
+ 877 | 0
+ 878 | 0
+ 879 | 0
+ 880 | 0
+ 881 | 0
+ 882 | 0
+ 883 | 0
+ 884 | 0
+ 885 | 0
+ 886 | 0
+ 887 | 0
+ 888 | 0
+ 889 | 0
+ 890 | 0
+ 891 | 0
+ 892 | 0
+ 893 | 0
+ 894 | 0
+ 895 | 0
+ 896 | 0
+ 897 | 0
+ 898 | 0
+ 899 | 0
+ 900 | 1
+ 901 | 0
+ 902 | 0
+ 903 | 0
+ 904 | 0
+ 905 | 0
+ 906 | 0
+ 907 | 0
+ 908 | 0
+ 909 | 0
+ 910 | 0
+ 911 | 0
+ 912 | 0
+ 913 | 0
+ 914 | 0
+ 915 | 0
+ 916 | 0
+ 917 | 0
+ 918 | 0
+ 919 | 0
+ 920 | 0
+ 921 | 0
+ 922 | 0
+ 923 | 0
+ 924 | 0
+ 925 | 0
+ 926 | 0
+ 927 | 0
+ 928 | 0
+ 929 | 0
+ 930 | 0
+ 931 | 0
+ 932 | 0
+ 933 | 0
+ 934 | 0
+ 935 | 0
+ 936 | 0
+ 937 | 0
+ 938 | 0
+ 939 | 0
+ 940 | 0
+ 941 | 0
+ 942 | 0
+ 943 | 0
+ 944 | 0
+ 945 | 0
+ 946 | 0
+ 947 | 0
+ 948 | 0
+ 949 | 0
+ 950 | 0
+ 951 | 0
+ 952 | 0
+ 953 | 0
+ 954 | 0
+ 955 | 0
+ 956 | 0
+ 957 | 0
+ 958 | 0
+ 959 | 0
+ 960 | 0
+ 961 | 0
+ 962 | 0
+ 963 | 0
+ 964 | 0
+ 965 | 0
+ 966 | 0
+ 967 | 0
+ 968 | 0
+ 969 | 0
+ 970 | 0
+ 971 | 0
+ 972 | 0
+ 973 | 0
+ 974 | 0
+ 975 | 0
+ 976 | 0
+ 977 | 0
+ 978 | 0
+ 979 | 0
+ 980 | 0
+ 981 | 0
+ 982 | 0
+ 983 | 0
+ 984 | 0
+ 985 | 0
+ 986 | 0
+ 987 | 0
+ 988 | 0
+ 989 | 0
+ 990 | 0
+ 991 | 0
+ 992 | 0
+ 993 | 0
+ 994 | 0
+ 995 | 0
+ 996 | 0
+ 997 | 0
+ 998 | 0
+ 999 | 0
+ 1000 | 1
+ 1010 | 0
+ 1020 | 0
+ 1030 | 0
+ 1040 | 0
+ 1050 | 0
+ 1060 | 0
+ 1070 | 0
+ 1080 | 0
+ 1090 | 0
+ 1100 | 1
+ 1110 | 0
+ 1120 | 0
+ 1130 | 0
+ 1140 | 0
+ 1150 | 0
+ 1160 | 0
+ 1170 | 0
+ 1180 | 0
+ 1190 | 0
+ 1200 | 1
+ 1210 | 0
+ 1220 | 0
+ 1230 | 0
+ 1240 | 0
+ 1250 | 0
+ 1260 | 0
+ 1270 | 0
+ 1280 | 0
+ 1290 | 0
+ 1300 | 1
+ 1310 | 0
+ 1320 | 0
+ 1330 | 0
+ 1340 | 0
+ 1350 | 0
+ 1360 | 0
+ 1370 | 0
+ 1380 | 0
+ 1390 | 0
+ 1400 | 1
+ 1410 | 0
+ 1420 | 0
+ 1430 | 0
+ 1440 | 0
+ 1450 | 0
+ 1460 | 0
+ 1470 | 0
+ 1480 | 0
+ 1490 | 0
+ 1500 | 1
+ 1510 | 0
+ 1520 | 0
+ 1530 | 0
+ 1540 | 0
+ 1550 | 0
+ 1560 | 0
+ 1570 | 0
+ 1580 | 0
+ 1590 | 0
+ 1600 | 1
+ 1610 | 0
+ 1620 | 0
+ 1630 | 0
+ 1640 | 0
+ 1650 | 0
+ 1660 | 0
+ 1670 | 0
+ 1680 | 0
+ 1690 | 0
+ 1700 | 1
+ 1710 | 0
+ 1720 | 0
+ 1730 | 0
+ 1740 | 0
+ 1750 | 0
+ 1760 | 0
+ 1770 | 0
+ 1780 | 0
+ 1790 | 0
+ 1800 | 1
+ 1810 | 0
+ 1820 | 0
+ 1830 | 0
+ 1840 | 0
+ 1850 | 0
+ 1860 | 0
+ 1870 | 0
+ 1880 | 0
+ 1890 | 0
+ 1900 | 1
+ 1910 | 0
+ 1920 | 0
+ 1930 | 0
+ 1940 | 0
+ 1950 | 0
+ 1960 | 0
+ 1970 | 0
+ 1980 | 0
+ 1990 | 0
+ 2000 | 1
+ 2010 | 0
+ 2020 | 0
+ 2030 | 0
+ 2040 | 0
+ 2050 | 0
+ 2060 | 0
+ 2070 | 0
+ 2080 | 0
+ 2090 | 0
+ 2100 | 1
+ 2110 | 0
+ 2120 | 0
+ 2130 | 0
+ 2140 | 0
+ 2150 | 0
+ 2160 | 0
+ 2170 | 0
+ 2180 | 0
+ 2190 | 0
+ 2200 | 1
+ 2210 | 0
+ 2220 | 0
+ 2230 | 0
+ 2240 | 0
+ 2250 | 0
+ 2260 | 0
+ 2270 | 0
+ 2280 | 0
+ 2290 | 0
+ 2300 | 1
+ 2310 | 0
+ 2320 | 0
+ 2330 | 0
+ 2340 | 0
+ 2350 | 0
+ 2360 | 0
+ 2370 | 0
+ 2380 | 0
+ 2390 | 0
+ 2400 | 1
+ 2410 | 0
+ 2420 | 0
+ 2430 | 0
+ 2440 | 0
+ 2450 | 0
+ 2460 | 0
+ 2470 | 0
+ 2480 | 0
+ 2490 | 0
+ 2500 | 1
+ 2510 | 0
+ 2520 | 0
+ 2530 | 0
+ 2540 | 0
+ 2550 | 0
+ 2560 | 0
+ 2570 | 0
+ 2580 | 0
+ 2590 | 0
+ 2600 | 1
+ 2610 | 0
+ 2620 | 0
+ 2630 | 0
+ 2640 | 0
+ 2650 | 0
+ 2660 | 0
+ 2670 | 0
+ 2680 | 0
+ 2690 | 0
+ 2700 | 1
+ 2710 | 0
+ 2720 | 0
+ 2730 | 0
+ 2740 | 0
+ 2750 | 0
+ 2760 | 0
+ 2770 | 0
+ 2780 | 0
+ 2790 | 0
+ 2800 | 1
+ 2810 | 0
+ 2820 | 0
+ 2830 | 0
+ 2840 | 0
+ 2850 | 0
+ 2860 | 0
+ 2870 | 0
+ 2880 | 0
+ 2890 | 0
+ 2900 | 1
+ 2910 | 0
+ 2920 | 0
+ 2930 | 0
+ 2940 | 0
+ 2950 | 0
+ 2960 | 0
+ 2970 | 0
+ 2980 | 0
+ 2990 | 0
+ 3000 | 1
+ 3010 | 0
+ 3020 | 0
+ 3030 | 0
+ 3040 | 0
+ 3050 | 0
+ 3060 | 0
+ 3070 | 0
+ 3080 | 0
+ 3090 | 0
+ 3100 | 1
+ 3110 | 0
+ 3120 | 0
+ 3130 | 0
+ 3140 | 0
+ 3150 | 0
+ 3160 | 0
+ 3170 | 0
+ 3180 | 0
+ 3190 | 0
+ 3200 | 1
+ 3210 | 0
+ 3220 | 0
+ 3230 | 0
+ 3240 | 0
+ 3250 | 0
+ 3260 | 0
+ 3270 | 0
+ 3280 | 0
+ 3290 | 0
+ 3300 | 1
+ 3310 | 0
+ 3320 | 0
+ 3330 | 0
+ 3340 | 0
+ 3350 | 0
+ 3360 | 0
+ 3370 | 0
+ 3380 | 0
+ 3390 | 0
+ 3400 | 1
+ 3410 | 0
+ 3420 | 0
+ 3430 | 0
+ 3440 | 0
+ 3450 | 0
+ 3460 | 0
+ 3470 | 0
+ 3480 | 0
+ 3490 | 0
+ 3500 | 1
+ 3510 | 0
+ 3520 | 0
+ 3530 | 0
+ 3540 | 0
+ 3550 | 0
+ 3560 | 0
+ 3570 | 0
+ 3580 | 0
+ 3590 | 0
+ 3600 | 1
+ 3610 | 0
+ 3620 | 0
+ 3630 | 0
+ 3640 | 0
+ 3650 | 0
+ 3660 | 0
+ 3670 | 0
+ 3680 | 0
+ 3690 | 0
+ 3700 | 1
+ 3710 | 0
+ 3720 | 0
+ 3730 | 0
+ 3740 | 0
+ 3750 | 0
+ 3760 | 0
+ 3770 | 0
+ 3780 | 0
+ 3790 | 0
+ 3800 | 1
+ 3810 | 0
+ 3820 | 0
+ 3830 | 0
+ 3840 | 0
+ 3850 | 0
+ 3860 | 0
+ 3870 | 0
+ 3880 | 0
+ 3890 | 0
+ 3900 | 1
+ 3910 | 0
+ 3920 | 0
+ 3930 | 0
+ 3940 | 0
+ 3950 | 0
+ 3960 | 0
+ 3970 | 0
+ 3980 | 0
+ 3990 | 0
+ 4000 | 1
+ 4010 | 0
+ 4020 | 0
+ 4030 | 0
+ 4040 | 0
+ 4050 | 0
+ 4060 | 0
+ 4070 | 0
+ 4080 | 0
+ 4090 | 0
+ 4100 | 1
+ 4110 | 0
+ 4120 | 0
+ 4130 | 0
+ 4140 | 0
+ 4150 | 0
+ 4160 | 0
+ 4170 | 0
+ 4180 | 0
+ 4190 | 0
+ 4200 | 1
+ 4210 | 0
+ 4220 | 0
+ 4230 | 0
+ 4240 | 0
+ 4250 | 0
+ 4260 | 0
+ 4270 | 0
+ 4280 | 0
+ 4290 | 0
+ 4300 | 1
+ 4310 | 0
+ 4320 | 0
+ 4330 | 0
+ 4340 | 0
+ 4350 | 0
+ 4360 | 0
+ 4370 | 0
+ 4380 | 0
+ 4390 | 0
+ 4400 | 1
+ 4410 | 0
+ 4420 | 0
+ 4430 | 0
+ 4440 | 0
+ 4450 | 0
+ 4460 | 0
+ 4470 | 0
+ 4480 | 0
+ 4490 | 0
+ 4500 | 1
+ 4510 | 0
+ 4520 | 0
+ 4530 | 0
+ 4540 | 0
+ 4550 | 0
+ 4560 | 0
+ 4570 | 0
+ 4580 | 0
+ 4590 | 0
+ 4600 | 1
+ 4610 | 0
+ 4620 | 0
+ 4630 | 0
+ 4640 | 0
+ 4650 | 0
+ 4660 | 0
+ 4670 | 0
+ 4680 | 0
+ 4690 | 0
+ 4700 | 1
+ 4710 | 0
+ 4720 | 0
+ 4730 | 0
+ 4740 | 0
+ 4750 | 0
+ 4760 | 0
+ 4770 | 0
+ 4780 | 0
+ 4790 | 0
+ 4800 | 1
+ 4810 | 0
+ 4820 | 0
+ 4830 | 0
+ 4840 | 0
+ 4850 | 0
+ 4860 | 0
+ 4870 | 0
+ 4880 | 0
+ 4890 | 0
+ 4900 | 1
+ 4910 | 0
+ 4920 | 0
+ 4930 | 0
+ 4940 | 0
+ 4950 | 0
+ 4960 | 0
+ 4970 | 0
+ 4980 | 0
+ 4990 | 0
+ 5000 | 1
+ 5010 | 0
+ 5020 | 0
+ 5030 | 0
+ 5040 | 0
+ 5050 | 0
+ 5060 | 0
+ 5070 | 0
+ 5080 | 0
+ 5090 | 0
+ 5100 | 1
+ 5110 | 0
+ 5120 | 0
+ 5130 | 0
+ 5140 | 0
+ 5150 | 0
+ 5160 | 0
+ 5170 | 0
+ 5180 | 0
+ 5190 | 0
+ 5200 | 1
+ 5210 | 0
+ 5220 | 0
+ 5230 | 0
+ 5240 | 0
+ 5250 | 0
+ 5260 | 0
+ 5270 | 0
+ 5280 | 0
+ 5290 | 0
+ 5300 | 1
+ 5310 | 0
+ 5320 | 0
+ 5330 | 0
+ 5340 | 0
+ 5350 | 0
+ 5360 | 0
+ 5370 | 0
+ 5380 | 0
+ 5390 | 0
+ 5400 | 1
+ 5410 | 0
+ 5420 | 0
+ 5430 | 0
+ 5440 | 0
+ 5450 | 0
+ 5460 | 0
+ 5470 | 0
+ 5480 | 0
+ 5490 | 0
+ 5500 | 1
+ 5510 | 0
+ 5520 | 0
+ 5530 | 0
+ 5540 | 0
+ 5550 | 0
+ 5560 | 0
+ 5570 | 0
+ 5580 | 0
+ 5590 | 0
+ 5600 | 1
+ 5610 | 0
+ 5620 | 0
+ 5630 | 0
+ 5640 | 0
+ 5650 | 0
+ 5660 | 0
+ 5670 | 0
+ 5680 | 0
+ 5690 | 0
+ 5700 | 1
+ 5710 | 0
+ 5720 | 0
+ 5730 | 0
+ 5740 | 0
+ 5750 | 0
+ 5760 | 0
+ 5770 | 0
+ 5780 | 0
+ 5790 | 0
+ 5800 | 1
+ 5810 | 0
+ 5820 | 0
+ 5830 | 0
+ 5840 | 0
+ 5850 | 0
+ 5860 | 0
+ 5870 | 0
+ 5880 | 0
+ 5890 | 0
+ 5900 | 1
+ 5910 | 0
+ 5920 | 0
+ 5930 | 0
+ 5940 | 0
+ 5950 | 0
+ 5960 | 0
+ 5970 | 0
+ 5980 | 0
+ 5990 | 0
+ 6000 | 1
+ 6010 | 0
+ 6020 | 0
+ 6030 | 0
+ 6040 | 0
+ 6050 | 0
+ 6060 | 0
+ 6070 | 0
+ 6080 | 0
+ 6090 | 0
+ 6100 | 1
+ 6110 | 0
+ 6120 | 0
+ 6130 | 0
+ 6140 | 0
+ 6150 | 0
+ 6160 | 0
+ 6170 | 0
+ 6180 | 0
+ 6190 | 0
+ 6200 | 1
+ 6210 | 0
+ 6220 | 0
+ 6230 | 0
+ 6240 | 0
+ 6250 | 0
+ 6260 | 0
+ 6270 | 0
+ 6280 | 0
+ 6290 | 0
+ 6300 | 1
+ 6310 | 0
+ 6320 | 0
+ 6330 | 0
+ 6340 | 0
+ 6350 | 0
+ 6360 | 0
+ 6370 | 0
+ 6380 | 0
+ 6390 | 0
+ 6400 | 1
+ 6410 | 0
+ 6420 | 0
+ 6430 | 0
+ 6440 | 0
+ 6450 | 0
+ 6460 | 0
+ 6470 | 0
+ 6480 | 0
+ 6490 | 0
+ 6500 | 1
+ 6510 | 0
+ 6520 | 0
+ 6530 | 0
+ 6540 | 0
+ 6550 | 0
+ 6560 | 0
+ 6570 | 0
+ 6580 | 0
+ 6590 | 0
+ 6600 | 1
+ 6610 | 0
+ 6620 | 0
+ 6630 | 0
+ 6640 | 0
+ 6650 | 0
+ 6660 | 0
+ 6670 | 0
+ 6680 | 0
+ 6690 | 0
+ 6700 | 1
+ 6710 | 0
+ 6720 | 0
+ 6730 | 0
+ 6740 | 0
+ 6750 | 0
+ 6760 | 0
+ 6770 | 0
+ 6780 | 0
+ 6790 | 0
+ 6800 | 1
+ 6810 | 0
+ 6820 | 0
+ 6830 | 0
+ 6840 | 0
+ 6850 | 0
+ 6860 | 0
+ 6870 | 0
+ 6880 | 0
+ 6890 | 0
+ 6900 | 1
+ 6910 | 0
+ 6920 | 0
+ 6930 | 0
+ 6940 | 0
+ 6950 | 0
+ 6960 | 0
+ 6970 | 0
+ 6980 | 0
+ 6990 | 0
+ 7000 | 1
+ 7010 | 0
+ 7020 | 0
+ 7030 | 0
+ 7040 | 0
+ 7050 | 0
+ 7060 | 0
+ 7070 | 0
+ 7080 | 0
+ 7090 | 0
+ 7100 | 1
+ 7110 | 0
+ 7120 | 0
+ 7130 | 0
+ 7140 | 0
+ 7150 | 0
+ 7160 | 0
+ 7170 | 0
+ 7180 | 0
+ 7190 | 0
+ 7200 | 1
+ 7210 | 0
+ 7220 | 0
+ 7230 | 0
+ 7240 | 0
+ 7250 | 0
+ 7260 | 0
+ 7270 | 0
+ 7280 | 0
+ 7290 | 0
+ 7300 | 1
+ 7310 | 0
+ 7320 | 0
+ 7330 | 0
+ 7340 | 0
+ 7350 | 0
+ 7360 | 0
+ 7370 | 0
+ 7380 | 0
+ 7390 | 0
+ 7400 | 1
+ 7410 | 0
+ 7420 | 0
+ 7430 | 0
+ 7440 | 0
+ 7450 | 0
+ 7460 | 0
+ 7470 | 0
+ 7480 | 0
+ 7490 | 0
+ 7500 | 1
+ 7510 | 0
+ 7520 | 0
+ 7530 | 0
+ 7540 | 0
+ 7550 | 0
+ 7560 | 0
+ 7570 | 0
+ 7580 | 0
+ 7590 | 0
+ 7600 | 1
+ 7610 | 0
+ 7620 | 0
+ 7630 | 0
+ 7640 | 0
+ 7650 | 0
+ 7660 | 0
+ 7670 | 0
+ 7680 | 0
+ 7690 | 0
+ 7700 | 1
+ 7710 | 0
+ 7720 | 0
+ 7730 | 0
+ 7740 | 0
+ 7750 | 0
+ 7760 | 0
+ 7770 | 0
+ 7780 | 0
+ 7790 | 0
+ 7800 | 1
+ 7810 | 0
+ 7820 | 0
+ 7830 | 0
+ 7840 | 0
+ 7850 | 0
+ 7860 | 0
+ 7870 | 0
+ 7880 | 0
+ 7890 | 0
+ 7900 | 1
+ 7910 | 0
+ 7920 | 0
+ 7930 | 0
+ 7940 | 0
+ 7950 | 0
+ 7960 | 0
+ 7970 | 0
+ 7980 | 0
+ 7990 | 0
+ 8000 | 1
+ 8010 | 0
+ 8020 | 0
+ 8030 | 0
+ 8040 | 0
+ 8050 | 0
+ 8060 | 0
+ 8070 | 0
+ 8080 | 0
+ 8090 | 0
+ 8100 | 1
+ 8110 | 0
+ 8120 | 0
+ 8130 | 0
+ 8140 | 0
+ 8150 | 0
+ 8160 | 0
+ 8170 | 0
+ 8180 | 0
+ 8190 | 0
+ 8200 | 1
+ 8210 | 0
+ 8220 | 0
+ 8230 | 0
+ 8240 | 0
+ 8250 | 0
+ 8260 | 0
+ 8270 | 0
+ 8280 | 0
+ 8290 | 0
+ 8300 | 1
+ 8310 | 0
+ 8320 | 0
+ 8330 | 0
+ 8340 | 0
+ 8350 | 0
+ 8360 | 0
+ 8370 | 0
+ 8380 | 0
+ 8390 | 0
+ 8400 | 1
+ 8410 | 0
+ 8420 | 0
+ 8430 | 0
+ 8440 | 0
+ 8450 | 0
+ 8460 | 0
+ 8470 | 0
+ 8480 | 0
+ 8490 | 0
+ 8500 | 1
+ 8510 | 0
+ 8520 | 0
+ 8530 | 0
+ 8540 | 0
+ 8550 | 0
+ 8560 | 0
+ 8570 | 0
+ 8580 | 0
+ 8590 | 0
+ 8600 | 1
+ 8610 | 0
+ 8620 | 0
+ 8630 | 0
+ 8640 | 0
+ 8650 | 0
+ 8660 | 0
+ 8670 | 0
+ 8680 | 0
+ 8690 | 0
+ 8700 | 1
+ 8710 | 0
+ 8720 | 0
+ 8730 | 0
+ 8740 | 0
+ 8750 | 0
+ 8760 | 0
+ 8770 | 0
+ 8780 | 0
+ 8790 | 0
+ 8800 | 1
+ 8810 | 0
+ 8820 | 0
+ 8830 | 0
+ 8840 | 0
+ 8850 | 0
+ 8860 | 0
+ 8870 | 0
+ 8880 | 0
+ 8890 | 0
+ 8900 | 1
+ 8910 | 0
+ 8920 | 0
+ 8930 | 0
+ 8940 | 0
+ 8950 | 0
+ 8960 | 0
+ 8970 | 0
+ 8980 | 0
+ 8990 | 0
+ 9000 | 1
+ 9010 | 0
+ 9020 | 0
+ 9030 | 0
+ 9040 | 0
+ 9050 | 0
+ 9060 | 0
+ 9070 | 0
+ 9080 | 0
+ 9090 | 0
+ 9100 | 1
+ 9110 | 0
+ 9120 | 0
+ 9130 | 0
+ 9140 | 0
+ 9150 | 0
+ 9160 | 0
+ 9170 | 0
+ 9180 | 0
+ 9190 | 0
+ 9200 | 1
+ 9210 | 0
+ 9220 | 0
+ 9230 | 0
+ 9240 | 0
+ 9250 | 0
+ 9260 | 0
+ 9270 | 0
+ 9280 | 0
+ 9290 | 0
+ 9300 | 1
+ 9310 | 0
+ 9320 | 0
+ 9330 | 0
+ 9340 | 0
+ 9350 | 0
+ 9360 | 0
+ 9370 | 0
+ 9380 | 0
+ 9390 | 0
+ 9400 | 1
+ 9410 | 0
+ 9420 | 0
+ 9430 | 0
+ 9440 | 0
+ 9450 | 0
+ 9460 | 0
+ 9470 | 0
+ 9480 | 0
+ 9490 | 0
+ 9500 | 1
+ 9510 | 0
+ 9520 | 0
+ 9530 | 0
+ 9540 | 0
+ 9550 | 0
+ 9560 | 0
+ 9570 | 0
+ 9580 | 0
+ 9590 | 0
+ 9600 | 1
+ 9610 | 0
+ 9620 | 0
+ 9630 | 0
+ 9640 | 0
+ 9650 | 0
+ 9660 | 0
+ 9670 | 0
+ 9680 | 0
+ 9690 | 0
+ 9700 | 1
+ 9710 | 0
+ 9720 | 0
+ 9730 | 0
+ 9740 | 0
+ 9750 | 0
+ 9760 | 0
+ 9770 | 0
+ 9780 | 0
+ 9790 | 0
+ 9800 | 1
+ 9810 | 0
+ 9820 | 0
+ 9830 | 0
+ 9840 | 0
+ 9850 | 0
+ 9860 | 0
+ 9870 | 0
+ 9880 | 0
+ 9890 | 0
+ 9900 | 1
+ 9910 | 0
+ 9920 | 0
+ 9930 | 0
+ 9940 | 0
+ 9950 | 0
+ 9960 | 0
+ 9970 | 0
+ 9980 | 0
+ 9990 | 0
+ 10000 | 1
+ 10100 | 1
+ 10200 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d
new file mode 100644
index 0000000..e3db030
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+int i;
+
+tick-10ms
+/i < 100/
+{
+ @[i] = llquantize(i, 10, 1, 2, 10, 150);
+ @[i] = llquantize(i + 1, 10, 1, 2, 10, 150);
+ @[i] = llquantize(i + 2, 10, 1, 2, 10, 150);
+ @[i] = llquantize(i + 3, 10, 1, 2, 10, 150);
+ i++;
+}
+
+tick-10ms
+/i == 100/
+{
+ exit(0);
+}
+
+END
+{
+ trunc(@, 5);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d.out
new file mode 100644
index 0000000..941c626
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/tst.trunc.d.out
@@ -0,0 +1,34 @@
+
+ 95
+ value ------------- Distribution ------------- count
+ 80 | 0
+ 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 600
+ 100 | 0
+
+ 96
+ value ------------- Distribution ------------- count
+ 80 | 0
+ 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 600
+ 100 | 0
+
+ 97
+ value ------------- Distribution ------------- count
+ 80 | 0
+ 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 450
+ 100 |@@@@@@@@@@ 150
+ 200 | 0
+
+ 98
+ value ------------- Distribution ------------- count
+ 80 | 0
+ 90 |@@@@@@@@@@@@@@@@@@@@ 300
+ 100 |@@@@@@@@@@@@@@@@@@@@ 300
+ 200 | 0
+
+ 99
+ value ------------- Distribution ------------- count
+ 80 | 0
+ 90 |@@@@@@@@@@ 150
+ 100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 450
+ 200 | 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mdb/tst.dtracedcmd.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mdb/tst.dtracedcmd.ksh
new file mode 100644
index 0000000..561f854
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mdb/tst.dtracedcmd.ksh
@@ -0,0 +1,85 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This script primarily tests that the ::dtrace dcmd is not dumping
+# core. We don't try to make sense of the output of the dcmd nor
+# do we check to see if any output is produced. We merely see if
+# mdb fails with a fatal failure.
+#
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ syscall:::entry
+ {
+ @[probefunc] = count();
+ }
+EOF
+}
+
+mdbdoit()
+{
+ mdb -k <<EOF
+ ::walk dtrace_state | ::dtrace
+EOF
+ status=$?
+ kill $script
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+script &
+script=$!
+timeout=15
+
+#
+# Sleep while the above script fires into life. To guard against dtrace dying
+# and us sleeping forever we allow 15 secs for this to happen. This should be
+# enough for even the slowest systems.
+#
+while [ ! -f $dtraceout ]; do
+ sleep 1
+ timeout=$(($timeout-1))
+ if [ $timeout -eq 0 ]; then
+ echo "dtrace failed to start. Exiting."
+ exit 1
+ fi
+done
+
+mdbdoit
+
+rm $dtraceout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.icmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.icmp.ksh
new file mode 100644
index 0000000..b1cac20
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.icmp.ksh
@@ -0,0 +1,79 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that several of the the mib:::icmp* probes fire and fire
+# with a valid args[0].
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ mib:::icmpInEchos
+ {
+ in = args[0];
+ }
+
+ mib:::icmpOutEchoReps
+ {
+ reps = args[0];
+ }
+
+ mib:::icmpOutMsgs
+ {
+ msgs = args[0];
+ }
+
+ profile:::tick-10msec
+ /in && reps && msgs/
+ {
+ exit(0);
+ }
+EOF
+}
+
+pinger()
+{
+ while true; do
+ ping -A inet localhost
+ /usr/bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+pinger &
+pinger=$!
+script
+status=$?
+
+kill $pinger
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.tcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.tcp.ksh
new file mode 100644
index 0000000..ee602e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.tcp.ksh
@@ -0,0 +1,155 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that several of the the mib:::tcp* probes fire and fire
+# with a valid args[0].
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+timeout=15
+port=2000
+
+if [ -f $dtraceout ]; then
+ rm -f $dtraceout
+fi
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ mib:::tcpActiveOpens
+ {
+ opens = args[0];
+ }
+
+ mib:::tcpOutDataBytes
+ {
+ bytes = args[0];
+ }
+
+ mib:::tcpOutDataSegs
+ {
+ segs = args[0];
+ }
+
+ profile:::tick-10msec
+ /opens && bytes && segs/
+ {
+ exit(0);
+ }
+
+ profile:::tick-1s
+ /n++ >= 10/
+ {
+ exit(1);
+ }
+EOF
+}
+
+server()
+{
+ perl /dev/stdin /dev/stdout << EOF
+ use strict;
+ use Socket;
+
+ socket(S, AF_INET, SOCK_STREAM, getprotobyname('tcp'))
+ or die "socket() failed: \$!";
+
+ setsockopt(S, SOL_SOCKET, SO_REUSEADDR, 1)
+ or die "setsockopt() failed: \$!";
+
+ my \$addr = sockaddr_in($port, INADDR_ANY);
+ bind(S, \$addr) or die "bind() failed: \$!";
+ listen(S, SOMAXCONN) or die "listen() failed: \$!";
+
+ while (1) {
+ next unless my \$raddr = accept(SESSION, S);
+
+ while (<SESSION>) {
+ }
+
+ close SESSION;
+ }
+EOF
+}
+
+client()
+{
+ perl /dev/stdin /dev/stdout <<EOF
+ use strict;
+ use Socket;
+
+ my \$peer = sockaddr_in($port, INADDR_ANY);
+
+ socket(S, AF_INET, SOCK_STREAM, getprotobyname('tcp'))
+ or die "socket() failed: \$!";
+
+ connect(S, \$peer) or die "connect failed: \$!";
+
+ for (my \$i = 0; \$i < 10; \$i++) {
+ send(S, "There!", 0) or die "send() failed: \$!";
+ sleep (1);
+ }
+EOF
+}
+
+script &
+dtrace_pid=$!
+
+#
+# Sleep while the above script fires into life. To guard against dtrace dying
+# and us sleeping forever we allow 15 secs for this to happen. This should be
+# enough for even the slowest systems.
+#
+while [ ! -f $dtraceout ]; do
+ sleep 1
+ timeout=$(($timeout-1))
+ if [ $timeout -eq 0 ]; then
+ echo "dtrace failed to start. Exiting."
+ exit 1
+ fi
+done
+
+server &
+server_pid=$!
+sleep 2
+client &
+client_pid=$!
+
+wait $dtrace_pid
+status=$?
+
+kill $server_pid
+kill $client_pid
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.udp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.udp.ksh
new file mode 100644
index 0000000..a492124
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/mib/tst.udp.ksh
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that several of the the mib:::udp* probes fire and fire
+# with a valid args[0].
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ mib:::udpHCOutDatagrams
+ {
+ out = args[0];
+ }
+
+ mib:::udpHCInDatagrams
+ {
+ in = args[0];
+ }
+
+ profile:::tick-10msec
+ /in && out/
+ {
+ exit(0);
+ }
+EOF
+}
+
+rupper()
+{
+ while true; do
+ rup localhost
+ /usr/bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+rupper &
+rupper=$!
+script
+status=$?
+
+kill $rupper
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/err.D_PRAGMA_OPTSET.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/err.D_PRAGMA_OPTSET.d
new file mode 100644
index 0000000..5238e3f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/err.D_PRAGMA_OPTSET.d
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet=please
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.badopt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.badopt.d
new file mode 100644
index 0000000..868b756
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.badopt.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ setopt("Nixon");
+ setopt("Harding");
+ setopt("Hoover");
+ setopt("Bush");
+ setopt("quiet", "hell no");
+ setopt("aggrate", "0.5hz");
+ setopt("bufsize", "1m");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d
new file mode 100644
index 0000000..0755271
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet=yes
+#pragma D option quiet=YES
+#pragma D option quiet=true
+#pragma D option quiet=enable
+#pragma D option quiet=enabled
+#pragma D option quiet=on
+#pragma D option quiet=set
+#pragma D option quiet=SeT
+
+#pragma D option flowindent=no
+#pragma D option flowindent=NO
+#pragma D option flowindent=false
+#pragma D option flowindent=disable
+#pragma D option flowindent=disabled
+#pragma D option flowindent=off
+#pragma D option flowindent=UnSeT
+
+BEGIN
+{
+ printf(".lived eht si paTmetsyS, lived eht si paTmetsyS\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d.out
new file mode 100644
index 0000000..2554be5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.boolopt.d.out
@@ -0,0 +1,2 @@
+.lived eht si paTmetsyS, lived eht si paTmetsyS
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d
new file mode 100644
index 0000000..cb98d73
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+#pragma D option switchrate=1ms
+#pragma D option aggrate=1ms
+
+tick-100ms
+{
+ i++;
+}
+
+tick-100ms
+/i > 1/
+{
+ setopt("quiet", "no");
+ setopt("quiet");
+ setopt("quiet");
+ setopt("quiet", "yes");
+ @["abc"] = count();
+ printa("%@d\n", @);
+}
+
+tick-100ms
+/i == 5/
+{
+ setopt("switchrate", "5sec");
+ setopt("aggrate", "5sec");
+}
+
+tick-100ms
+/i == 31/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d.out
new file mode 100644
index 0000000..092a042
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.dynopt.d.out
@@ -0,0 +1,31 @@
+1
+2
+3
+4
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.enablerace.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.enablerace.ksh
new file mode 100644
index 0000000..b4d56bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.enablerace.ksh
@@ -0,0 +1,89 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script attempts to tease out a race when probes are initially enabled.
+#
+script()
+{
+ #
+ # Nauseatingly, the #defines below must be in the 0th column to
+ # satisfy the ancient cpp that -C defaults to.
+ #
+ $dtrace -C -s /dev/stdin <<EOF
+#define PROF1 profile:::profile-4000hz
+#define PROF4 PROF1, PROF1, PROF1, PROF1
+#define PROF16 PROF4, PROF4, PROF4, PROF4
+#define PROF64 PROF16, PROF16, PROF16, PROF16
+#define PROF256 PROF64, PROF64, PROF64, PROF64
+#define PROF512 PROF256, PROF256
+
+ PROF1
+ {
+ this->x = 0;
+ }
+
+ PROF512
+ {
+ this->x++;
+ }
+
+ PROF1
+ /this->x != 512/
+ {
+ printf("failed! x is %d (expected 512)", this->x);
+ exit(1);
+ }
+
+ tick-1sec
+ /secs++/
+ {
+ exit(0);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+let i=0
+
+while [ "$i" -lt 20 ]; do
+ script
+ status=$?
+
+ if [ "$status" -ne 0 ]; then
+ exit $status
+ fi
+
+ let i=i+1
+done
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.haslam.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.haslam.d
new file mode 100644
index 0000000..a0b437b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.haslam.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test for off-by-one error in the format lookup code
+ *
+ * SECTION: Aggregations/Aggregations; Misc
+ */
+
+/*
+ * A script from Jon Haslam that induced an off-by-one error in the
+ * format lookup code.
+ */
+BEGIN
+{
+ start = timestamp;
+ allocd = 0;
+ numallocs = 0;
+ numfrees = 0;
+ numtids = 0;
+}
+
+syscall:::entry
+{
+ @sys[tid] = sum(tid);
+}
+
+END
+{
+ printf("%s, %s, %s, %d numtids", "hhh", "jjj", "ggg", numtids );
+ printa(@sys);
+}
+
+tick-1sec
+/n++ == 5/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh
new file mode 100644
index 0000000..30a2ce4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh
@@ -0,0 +1,135 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+CC=/usr/bin/gcc
+CFLAGS=
+
+doit()
+{
+ file=$1
+ ofile=$2
+ errfile=$3
+ cfile=${TMPDIR:-/tmp}/inc.$$.$file.c
+ cofile=${TMPDIR:-/tmp}/inc.$$.$file
+ cat > $cfile <<EOF
+#include <sys/$file>
+void
+main()
+{}
+EOF
+ if $CC $CFLAGS -o $cofile $cfile >/dev/null 2>&1; then
+ $dtrace -xerrtags -C -s /dev/stdin \
+ >/dev/null 2>$errfile <<EOF
+#include <sys/$file>
+BEGIN
+{
+ exit(0);
+}
+EOF
+ if [ $? -ne 0 ]; then
+ echo $inc failed: `cat $errfile | head -1` > $ofile
+ else
+ echo $inc succeeded > $ofile
+ fi
+ rm -f $errfile
+ fi
+
+ rm -f $cofile $cfile 2>/dev/null
+}
+
+if [ ! -x $CC ]; then
+ echo "$0: bad compiler: $CC" >& 2
+ exit 1
+fi
+
+concurrency=`psrinfo | wc -l`
+let concurrency=concurrency*4
+let i=0
+
+files=/usr/include/sys/*.h
+
+#
+# There are a few files in /usr/include/sys that are known to be bad -- usually
+# because they include static globals (!) or function bodies (!!) in the header
+# file. Hopefully these remain sufficiently few that the O(#files * #badfiles)
+# algorithm, below, doesn't become a problem. (And yes, writing scripts in
+# something other than ksh1888 would probably be a good idea.) If this script
+# becomes a problem, kindly fix it by reducing the number of bad files! (That
+# is, fix it by fixing the broken file, not the broken script.)
+#
+badfiles="ctype.h eri_msg.h ser_sync.h sbpro.h neti.h hook_event.h \
+ bootconf.h bootstat.h dtrace.h dumphdr.h exacct_impl.h fasttrap.h \
+ kobj.h kobj_impl.h ksyms.h lockstat.h smedia.h stat.h utsname.h"
+
+for inc in $files; do
+ file=`basename $inc`
+ for bad in $badfiles; do
+ if [ "$file" = "$bad" ]; then
+ continue 2
+ fi
+ done
+
+ ofile=${TMPDIR:-/tmp}/inc.$file.$$.out
+ errfile=${TMPDIR:-/tmp}/inc.$file.$$.err
+ doit $file $ofile $errfile &
+ let i=i+1
+
+ if [ $i -eq $concurrency ]; then
+ #
+ # This isn't optimal -- it creates a highly fluctuating load
+ # as we wait for all work to complete -- but it's an easy
+ # way of parallelizing work.
+ #
+ wait
+ let i=0
+ fi
+done
+
+wait
+
+bigofile=${TMPDIR:-/tmp}/inc.$$.out
+
+for inc in $files; do
+ file=`basename $inc`
+ ofile=${TMPDIR:-/tmp}/inc.$file.$$.out
+
+ if [ -f $ofile ]; then
+ cat $ofile >> $bigofile
+ rm $ofile
+ fi
+done
+
+status=$(grep "failed:" $bigofile | wc -l)
+cat $bigofile
+rm -f $bigofile
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh
new file mode 100644
index 0000000..a5114f4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -ln 'syscall::*$1:entry' read | awk '{print $(NF-1),$NF}' | sort
+$dtrace -ln 'syscall::$1*:entry' read | awk '{print $(NF-1),$NF}' | sort
+$dtrace -ln 'syscall::re$1*:entry' ad | awk '{print $(NF-1),$NF}' | sort
+$dtrace -ln 'syscall::$1l*:entry' read | awk '{print $(NF-1),$NF}' | sort
+$dtrace -ln 'syscall::p$1[0-9][0-9]:entry' read | awk '{print $(NF-1),$NF}' | \
+ sort
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out
new file mode 100644
index 0000000..8a9ac6d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out
@@ -0,0 +1,15 @@
+FUNCTION NAME
+pread entry
+read entry
+FUNCTION NAME
+read entry
+readlink entry
+readv entry
+FUNCTION NAME
+read entry
+readlink entry
+readv entry
+FUNCTION NAME
+readlink entry
+FUNCTION NAME
+pread64 entry
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.roch.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.roch.d
new file mode 100644
index 0000000..67f4462
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.roch.d
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test for assertion failure in the ring buffer code
+ *
+ * SECTION: Buffers and Buffering/ring Policy; Misc
+ */
+
+#pragma ident "@(#)tst.roch.d 1.2 03/08/11 SMI"
+
+/*
+ * A script from Roch Bourbonnais that induced an assertion failure in the
+ * ring buffer code.
+ */
+#pragma D option strsize=16
+#pragma D option bufsize=10K
+#pragma D option bufpolicy=ring
+
+fbt:::entry
+/(self->done == 0) && (curthread->t_cpu->cpu_intr_actv == 0) /
+{
+ self->done = 1;
+ printf(" %u 0x%llX %d %d comm:%s csathr:%lld", timestamp,
+ (long long)curthread, pid, tid,
+ execname, (long long)stackdepth);
+ stack(20);
+}
+
+fbt:::return
+/(self->done == 0) && (curthread->t_cpu->cpu_intr_actv == 0) /
+{
+ self->done = 1;
+ printf(" %u 0x%llX %d %d comm:%s csathr:%lld", timestamp,
+ (long long) curthread, pid, tid,
+ execname, (long long) stackdepth);
+ stack(20);
+}
+
+fbt:::entry
+{
+ printf(" %u 0x%llX %d %d ", timestamp,
+ (long long)curthread, pid, tid);
+}
+
+fbt:::return
+{
+ printf(" %u 0x%llX %d %d tag:%d off:%d ", timestamp,
+ (long long)curthread, pid, tid, (int)arg1, (int)arg0);
+}
+
+mutex_enter:adaptive-acquire
+{
+ printf(" %u 0x%llX %d %d lock:0x%llX", timestamp,
+ (long long)curthread, pid, tid, arg0);
+}
+
+mutex_exit:adaptive-release
+{
+ printf(" %u 0x%llX %d %d lock:0x%llX", timestamp,
+ (long long) curthread, pid, tid, arg0);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh
new file mode 100644
index 0000000..197bd8d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh
@@ -0,0 +1,79 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+#
+# /usr/ccs/bin/nm execs a 64-bit version of itself. DTrace uses libproc
+# (which uses /proc) to find out when the traced process exits, but a
+# 32-bit process can't examine a 64-bit one with libproc. The
+# LD_NOEXEC_64 variable prevents nm from re-execing itself.
+#
+LD_NOEXEC_64=tomeeisrad $dtrace -F -s /dev/stdin -c \
+ '/usr/bin/nm /bin/ls' stat <<EOF
+
+pid\$target::\$1:entry
+{
+ self->start = vtimestamp;
+}
+
+pid\$target:::entry
+/self->start/
+{
+ trace(vtimestamp - self->start);
+}
+
+pid\$target:::return
+/self->start/
+{
+ trace(vtimestamp - self->start);
+}
+
+pid\$target::\$1:return
+/self->start/
+{
+ self->start = 0;
+ exit(0);
+}
+
+syscall:::
+/self->start/
+{
+ trace(vtimestamp - self->start);
+}
+
+fbt:::
+/self->start/
+{
+ trace(vtimestamp - self->start);
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGKEY.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGKEY.d
new file mode 100644
index 0000000..8074e6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGKEY.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @foo[123] = sum(123);
+ @bar = sum(456);
+
+ printa("%10d %@10d %@10d\n", @foo, @bar);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGPROTO.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGPROTO.d
new file mode 100644
index 0000000..dc65947
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/err.D_PRINTA_AGGPROTO.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @foo[123] = sum(123);
+ @bar["fooey"] = sum(456);
+
+ printa("%10d %@10d %@10d\n", @foo, @bar);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d
new file mode 100644
index 0000000..00588c6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d
@@ -0,0 +1,311 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option destructive
+#pragma D option quiet
+
+BEGIN
+/0/
+{
+ @agg996[996] = quantize(998);
+ @agg997[997] = count();
+ @agg998[998] = min(998);
+ @agg999[999] = lquantize(0, -10, 10, 1);
+}
+
+BEGIN
+{
+ @agg0[0] = sum(0);
+ @agg1[1] = sum(1);
+ @agg2[2] = sum(2);
+ @agg3[3] = sum(3);
+ @agg4[4] = sum(4);
+ @agg5[5] = sum(5);
+ @agg6[6] = sum(6);
+ @agg7[7] = sum(7);
+ @agg8[8] = sum(8);
+ @agg9[9] = sum(9);
+ @agg10[10] = sum(10);
+ @agg11[11] = sum(11);
+ @agg12[12] = sum(12);
+ @agg13[13] = sum(13);
+ @agg14[14] = sum(14);
+ @agg15[15] = sum(15);
+ @agg16[16] = sum(16);
+ @agg17[17] = sum(17);
+ @agg18[18] = sum(18);
+ @agg19[19] = sum(19);
+ @agg20[20] = sum(20);
+ @agg21[21] = sum(21);
+ @agg22[22] = sum(22);
+ @agg23[23] = sum(23);
+ @agg24[24] = sum(24);
+ @agg25[25] = sum(25);
+ @agg26[26] = sum(26);
+ @agg27[27] = sum(27);
+ @agg28[28] = sum(28);
+ @agg29[29] = sum(29);
+ @agg30[30] = sum(30);
+ @agg31[31] = sum(31);
+ @agg32[32] = sum(32);
+ @agg33[33] = sum(33);
+ @agg34[34] = sum(34);
+ @agg35[35] = sum(35);
+ @agg36[36] = sum(36);
+ @agg37[37] = sum(37);
+ @agg38[38] = sum(38);
+ @agg39[39] = sum(39);
+ @agg40[40] = sum(40);
+ @agg41[41] = sum(41);
+ @agg42[42] = sum(42);
+ @agg43[43] = sum(43);
+ @agg44[44] = sum(44);
+ @agg45[45] = sum(45);
+ @agg46[46] = sum(46);
+ @agg47[47] = sum(47);
+ @agg48[48] = sum(48);
+ @agg49[49] = sum(49);
+ @agg50[50] = sum(50);
+ @agg51[51] = sum(51);
+ @agg52[52] = sum(52);
+ @agg53[53] = sum(53);
+ @agg54[54] = sum(54);
+ @agg55[55] = sum(55);
+ @agg56[56] = sum(56);
+ @agg57[57] = sum(57);
+ @agg58[58] = sum(58);
+ @agg59[59] = sum(59);
+ @agg60[60] = sum(60);
+ @agg61[61] = sum(61);
+ @agg62[62] = sum(62);
+ @agg63[63] = sum(63);
+ @agg64[64] = sum(64);
+ @agg65[65] = sum(65);
+ @agg66[66] = sum(66);
+ @agg67[67] = sum(67);
+ @agg68[68] = sum(68);
+ @agg69[69] = sum(69);
+ @agg70[70] = sum(70);
+ @agg71[71] = sum(71);
+ @agg72[72] = sum(72);
+ @agg73[73] = sum(73);
+ @agg74[74] = sum(74);
+ @agg75[75] = sum(75);
+ @agg76[76] = sum(76);
+ @agg77[77] = sum(77);
+ @agg78[78] = sum(78);
+ @agg79[79] = sum(79);
+ @agg80[80] = sum(80);
+ @agg81[81] = sum(81);
+ @agg82[82] = sum(82);
+ @agg83[83] = sum(83);
+ @agg84[84] = sum(84);
+ @agg85[85] = sum(85);
+ @agg86[86] = sum(86);
+ @agg87[87] = sum(87);
+ @agg88[88] = sum(88);
+ @agg89[89] = sum(89);
+ @agg90[90] = sum(90);
+ @agg91[91] = sum(91);
+ @agg92[92] = sum(92);
+ @agg93[93] = sum(93);
+ @agg94[94] = sum(94);
+ @agg95[95] = sum(95);
+ @agg96[96] = sum(96);
+ @agg97[97] = sum(97);
+ @agg98[98] = sum(98);
+ @agg99[99] = sum(99);
+ @agg100[100] = sum(100);
+ @agg101[101] = sum(101);
+ @agg102[102] = sum(102);
+ @agg103[103] = sum(103);
+ @agg104[104] = sum(104);
+ @agg105[105] = sum(105);
+ @agg106[106] = sum(106);
+ @agg107[107] = sum(107);
+ @agg108[108] = sum(108);
+ @agg109[109] = sum(109);
+ @agg110[110] = sum(110);
+ @agg111[111] = sum(111);
+ @agg112[112] = sum(112);
+ @agg113[113] = sum(113);
+ @agg114[114] = sum(114);
+ @agg115[115] = sum(115);
+ @agg116[116] = sum(116);
+ @agg117[117] = sum(117);
+ @agg118[118] = sum(118);
+ @agg119[119] = sum(119);
+ @agg120[120] = sum(120);
+ @agg121[121] = sum(121);
+ @agg122[122] = sum(122);
+ @agg123[123] = sum(123);
+ @agg124[124] = sum(124);
+ @agg125[125] = sum(125);
+ @agg126[126] = sum(126);
+ @agg127[127] = sum(127);
+ @agg128[128] = sum(128);
+ @agg129[129] = sum(129);
+ @agg130[130] = sum(130);
+ @agg131[131] = sum(131);
+ @agg132[132] = sum(132);
+ @agg133[133] = sum(133);
+ @agg134[134] = sum(134);
+ @agg135[135] = sum(135);
+ @agg136[136] = sum(136);
+ @agg137[137] = sum(137);
+ @agg138[138] = sum(138);
+ @agg139[139] = sum(139);
+ @agg140[140] = sum(140);
+ @agg141[141] = sum(141);
+ @agg142[142] = sum(142);
+ @agg143[143] = sum(143);
+ @agg144[144] = sum(144);
+ @agg145[145] = sum(145);
+ @agg146[146] = sum(146);
+ @agg147[147] = sum(147);
+ @agg148[148] = sum(148);
+ @agg149[149] = sum(149);
+ @agg150[150] = sum(150);
+ @agg151[151] = sum(151);
+ @agg152[152] = sum(152);
+ @agg153[153] = sum(153);
+ @agg154[154] = sum(154);
+ @agg155[155] = sum(155);
+ @agg156[156] = sum(156);
+ @agg157[157] = sum(157);
+ @agg158[158] = sum(158);
+ @agg159[159] = sum(159);
+ @agg160[160] = sum(160);
+ @agg161[161] = sum(161);
+ @agg162[162] = sum(162);
+ @agg163[163] = sum(163);
+ @agg164[164] = sum(164);
+ @agg165[165] = sum(165);
+ @agg166[166] = sum(166);
+ @agg167[167] = sum(167);
+ @agg168[168] = sum(168);
+ @agg169[169] = sum(169);
+ @agg170[170] = sum(170);
+ @agg171[171] = sum(171);
+ @agg172[172] = sum(172);
+ @agg173[173] = sum(173);
+ @agg174[174] = sum(174);
+ @agg175[175] = sum(175);
+ @agg176[176] = sum(176);
+ @agg177[177] = sum(177);
+ @agg178[178] = sum(178);
+ @agg179[179] = sum(179);
+ @agg180[180] = sum(180);
+ @agg181[181] = sum(181);
+ @agg182[182] = sum(182);
+ @agg183[183] = sum(183);
+ @agg184[184] = sum(184);
+ @agg185[185] = sum(185);
+ @agg186[186] = sum(186);
+ @agg187[187] = sum(187);
+ @agg188[188] = sum(188);
+ @agg189[189] = sum(189);
+ @agg190[190] = sum(190);
+ @agg191[191] = sum(191);
+ @agg192[192] = sum(192);
+ @agg193[193] = sum(193);
+ @agg194[194] = sum(194);
+ @agg195[195] = sum(195);
+ @agg196[196] = sum(196);
+ @agg197[197] = sum(197);
+ @agg198[198] = sum(198);
+ @agg199[199] = sum(199);
+ @agg200[200] = sum(200);
+ @agg201[201] = sum(201);
+ @agg202[202] = sum(202);
+ @agg203[203] = sum(203);
+ @agg204[204] = sum(204);
+ @agg205[205] = sum(205);
+ @agg206[206] = sum(206);
+ @agg207[207] = sum(207);
+ @agg208[208] = sum(208);
+ @agg209[209] = sum(209);
+ @agg210[210] = sum(210);
+ @agg211[211] = sum(211);
+ @agg212[212] = sum(212);
+ @agg213[213] = sum(213);
+ @agg214[214] = sum(214);
+ @agg215[215] = sum(215);
+ @agg216[216] = sum(216);
+ @agg217[217] = sum(217);
+ @agg218[218] = sum(218);
+ @agg219[219] = sum(219);
+ @agg220[220] = sum(220);
+ @agg221[221] = sum(221);
+ @agg222[222] = sum(222);
+ @agg223[223] = sum(223);
+ @agg224[224] = sum(224);
+ @agg225[225] = sum(225);
+ @agg226[226] = sum(226);
+ @agg227[227] = sum(227);
+ @agg228[228] = sum(228);
+ @agg229[229] = sum(229);
+ @agg230[230] = sum(230);
+ @agg231[231] = sum(231);
+ @agg232[232] = sum(232);
+ @agg233[233] = sum(233);
+ @agg234[234] = sum(234);
+ @agg235[235] = sum(235);
+ @agg236[236] = sum(236);
+ @agg237[237] = sum(237);
+ @agg238[238] = sum(238);
+ @agg239[239] = sum(239);
+ @agg240[240] = sum(240);
+ @agg241[241] = sum(241);
+ @agg242[242] = sum(242);
+ @agg243[243] = sum(243);
+ @agg244[244] = sum(244);
+ @agg245[245] = sum(245);
+ @agg246[246] = sum(246);
+
+ printa("%8d %8@d %8@d\n", @agg0, @agg1);
+ printf("\n");
+
+ printa("%8d %8@d %8@d\n", @agg0, @agg996);
+ printf("\n");
+
+ printa("%4d %4@d %4@d %4@d %4@d %4@d %4@d %4@d %4@d %4@d %4@d %4@d\n",
+ @agg12, @agg3, @agg73, @agg997,
+ @agg9, @agg9, @agg4, @agg998,
+ @agg11, @agg23, @agg69);
+
+ printf("\n");
+
+ printa("%8d %8@d %8@d\n", @agg245, @agg246);
+ printf("\n");
+
+ printa("%8d %8@d %8@d\n", @agg999, @agg246);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d.out
new file mode 100644
index 0000000..e048d43
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.many.d.out
@@ -0,0 +1,265 @@
+ 0 0 0
+ 1 0 1
+
+ 0 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+
+ 69 0 0 0 0 0 0 0 0 0 0 69
+ 23 0 0 0 0 0 0 0 0 0 23 0
+ 11 0 0 0 0 0 0 0 0 11 0 0
+ 4 0 0 0 0 0 0 4 0 0 0 0
+ 9 0 0 0 0 9 9 0 0 0 0 0
+ 73 0 0 73 0 0 0 0 0 0 0 0
+ 3 0 3 0 0 0 0 0 0 0 0 0
+ 12 12 0 0 0 0 0 0 0 0 0 0
+
+ 246 0 246
+ 245 245 0
+
+ 246
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+ 246
+
+
+ 2 2
+ 5 5
+ 6 6
+ 7 7
+ 8 8
+ 10 10
+ 13 13
+ 14 14
+ 15 15
+ 16 16
+ 17 17
+ 18 18
+ 19 19
+ 20 20
+ 21 21
+ 22 22
+ 24 24
+ 25 25
+ 26 26
+ 27 27
+ 28 28
+ 29 29
+ 30 30
+ 31 31
+ 32 32
+ 33 33
+ 34 34
+ 35 35
+ 36 36
+ 37 37
+ 38 38
+ 39 39
+ 40 40
+ 41 41
+ 42 42
+ 43 43
+ 44 44
+ 45 45
+ 46 46
+ 47 47
+ 48 48
+ 49 49
+ 50 50
+ 51 51
+ 52 52
+ 53 53
+ 54 54
+ 55 55
+ 56 56
+ 57 57
+ 58 58
+ 59 59
+ 60 60
+ 61 61
+ 62 62
+ 63 63
+ 64 64
+ 65 65
+ 66 66
+ 67 67
+ 68 68
+ 70 70
+ 71 71
+ 72 72
+ 74 74
+ 75 75
+ 76 76
+ 77 77
+ 78 78
+ 79 79
+ 80 80
+ 81 81
+ 82 82
+ 83 83
+ 84 84
+ 85 85
+ 86 86
+ 87 87
+ 88 88
+ 89 89
+ 90 90
+ 91 91
+ 92 92
+ 93 93
+ 94 94
+ 95 95
+ 96 96
+ 97 97
+ 98 98
+ 99 99
+ 100 100
+ 101 101
+ 102 102
+ 103 103
+ 104 104
+ 105 105
+ 106 106
+ 107 107
+ 108 108
+ 109 109
+ 110 110
+ 111 111
+ 112 112
+ 113 113
+ 114 114
+ 115 115
+ 116 116
+ 117 117
+ 118 118
+ 119 119
+ 120 120
+ 121 121
+ 122 122
+ 123 123
+ 124 124
+ 125 125
+ 126 126
+ 127 127
+ 128 128
+ 129 129
+ 130 130
+ 131 131
+ 132 132
+ 133 133
+ 134 134
+ 135 135
+ 136 136
+ 137 137
+ 138 138
+ 139 139
+ 140 140
+ 141 141
+ 142 142
+ 143 143
+ 144 144
+ 145 145
+ 146 146
+ 147 147
+ 148 148
+ 149 149
+ 150 150
+ 151 151
+ 152 152
+ 153 153
+ 154 154
+ 155 155
+ 156 156
+ 157 157
+ 158 158
+ 159 159
+ 160 160
+ 161 161
+ 162 162
+ 163 163
+ 164 164
+ 165 165
+ 166 166
+ 167 167
+ 168 168
+ 169 169
+ 170 170
+ 171 171
+ 172 172
+ 173 173
+ 174 174
+ 175 175
+ 176 176
+ 177 177
+ 178 178
+ 179 179
+ 180 180
+ 181 181
+ 182 182
+ 183 183
+ 184 184
+ 185 185
+ 186 186
+ 187 187
+ 188 188
+ 189 189
+ 190 190
+ 191 191
+ 192 192
+ 193 193
+ 194 194
+ 195 195
+ 196 196
+ 197 197
+ 198 198
+ 199 199
+ 200 200
+ 201 201
+ 202 202
+ 203 203
+ 204 204
+ 205 205
+ 206 206
+ 207 207
+ 208 208
+ 209 209
+ 210 210
+ 211 211
+ 212 212
+ 213 213
+ 214 214
+ 215 215
+ 216 216
+ 217 217
+ 218 218
+ 219 219
+ 220 220
+ 221 221
+ 222 222
+ 223 223
+ 224 224
+ 225 225
+ 226 226
+ 227 227
+ 228 228
+ 229 229
+ 230 230
+ 231 231
+ 232 232
+ 233 233
+ 234 234
+ 235 235
+ 236 236
+ 237 237
+ 238 238
+ 239 239
+ 240 240
+ 241 241
+ 242 242
+ 243 243
+ 244 244
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d
new file mode 100644
index 0000000..0e67557
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @ = sum(90904);
+ printa("%@d %@d %@d\n", @, @, @);
+ printa("%@d %@d %@d\n", @);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d.out
new file mode 100644
index 0000000..b382c35
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.same.d.out
@@ -0,0 +1,3 @@
+90904 90904 90904
+90904 90904 90904
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d
new file mode 100644
index 0000000..7bfd9e5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+tick-1ms
+{
+ i++;
+ @a[i] = sum(100 - (i / 2));
+ @b[i] = sum(100 - (i / 4));
+ @c[i] = sum(100 - (i / 8));
+ @d[i] = sum(100 - (i / 16));
+}
+
+tick-1ms
+/i == 100/
+{
+ printa("%10d %@10d %@10d %@10d %@10d\n", @a, @b, @c, @d);
+ printa("%10d %@10d %@10d %@10d %@10d\n", @d, @c, @b, @a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d.out
new file mode 100644
index 0000000..8c79190
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sort.d.out
@@ -0,0 +1,201 @@
+ 100 50 75 88 94
+ 98 51 76 88 94
+ 99 51 76 88 94
+ 96 52 76 88 94
+ 97 52 76 88 94
+ 94 53 77 89 95
+ 95 53 77 89 95
+ 92 54 77 89 95
+ 93 54 77 89 95
+ 90 55 78 89 95
+ 91 55 78 89 95
+ 88 56 78 89 95
+ 89 56 78 89 95
+ 86 57 79 90 95
+ 87 57 79 90 95
+ 84 58 79 90 95
+ 85 58 79 90 95
+ 82 59 80 90 95
+ 83 59 80 90 95
+ 80 60 80 90 95
+ 81 60 80 90 95
+ 78 61 81 91 96
+ 79 61 81 91 96
+ 76 62 81 91 96
+ 77 62 81 91 96
+ 74 63 82 91 96
+ 75 63 82 91 96
+ 72 64 82 91 96
+ 73 64 82 91 96
+ 70 65 83 92 96
+ 71 65 83 92 96
+ 68 66 83 92 96
+ 69 66 83 92 96
+ 66 67 84 92 96
+ 67 67 84 92 96
+ 64 68 84 92 96
+ 65 68 84 92 96
+ 62 69 85 93 97
+ 63 69 85 93 97
+ 60 70 85 93 97
+ 61 70 85 93 97
+ 58 71 86 93 97
+ 59 71 86 93 97
+ 56 72 86 93 97
+ 57 72 86 93 97
+ 54 73 87 94 97
+ 55 73 87 94 97
+ 52 74 87 94 97
+ 53 74 87 94 97
+ 50 75 88 94 97
+ 51 75 88 94 97
+ 48 76 88 94 97
+ 49 76 88 94 97
+ 46 77 89 95 98
+ 47 77 89 95 98
+ 44 78 89 95 98
+ 45 78 89 95 98
+ 42 79 90 95 98
+ 43 79 90 95 98
+ 40 80 90 95 98
+ 41 80 90 95 98
+ 38 81 91 96 98
+ 39 81 91 96 98
+ 36 82 91 96 98
+ 37 82 91 96 98
+ 34 83 92 96 98
+ 35 83 92 96 98
+ 32 84 92 96 98
+ 33 84 92 96 98
+ 30 85 93 97 99
+ 31 85 93 97 99
+ 28 86 93 97 99
+ 29 86 93 97 99
+ 26 87 94 97 99
+ 27 87 94 97 99
+ 24 88 94 97 99
+ 25 88 94 97 99
+ 22 89 95 98 99
+ 23 89 95 98 99
+ 20 90 95 98 99
+ 21 90 95 98 99
+ 18 91 96 98 99
+ 19 91 96 98 99
+ 16 92 96 98 99
+ 17 92 96 98 99
+ 14 93 97 99 100
+ 15 93 97 99 100
+ 12 94 97 99 100
+ 13 94 97 99 100
+ 10 95 98 99 100
+ 11 95 98 99 100
+ 8 96 98 99 100
+ 9 96 98 99 100
+ 6 97 99 100 100
+ 7 97 99 100 100
+ 4 98 99 100 100
+ 5 98 99 100 100
+ 2 99 100 100 100
+ 3 99 100 100 100
+ 1 100 100 100 100
+ 100 94 88 75 50
+ 98 94 88 76 51
+ 99 94 88 76 51
+ 96 94 88 76 52
+ 97 94 88 76 52
+ 94 95 89 77 53
+ 95 95 89 77 53
+ 92 95 89 77 54
+ 93 95 89 77 54
+ 90 95 89 78 55
+ 91 95 89 78 55
+ 88 95 89 78 56
+ 89 95 89 78 56
+ 86 95 90 79 57
+ 87 95 90 79 57
+ 84 95 90 79 58
+ 85 95 90 79 58
+ 82 95 90 80 59
+ 83 95 90 80 59
+ 80 95 90 80 60
+ 81 95 90 80 60
+ 78 96 91 81 61
+ 79 96 91 81 61
+ 76 96 91 81 62
+ 77 96 91 81 62
+ 74 96 91 82 63
+ 75 96 91 82 63
+ 72 96 91 82 64
+ 73 96 91 82 64
+ 70 96 92 83 65
+ 71 96 92 83 65
+ 68 96 92 83 66
+ 69 96 92 83 66
+ 66 96 92 84 67
+ 67 96 92 84 67
+ 64 96 92 84 68
+ 65 96 92 84 68
+ 62 97 93 85 69
+ 63 97 93 85 69
+ 60 97 93 85 70
+ 61 97 93 85 70
+ 58 97 93 86 71
+ 59 97 93 86 71
+ 56 97 93 86 72
+ 57 97 93 86 72
+ 54 97 94 87 73
+ 55 97 94 87 73
+ 52 97 94 87 74
+ 53 97 94 87 74
+ 50 97 94 88 75
+ 51 97 94 88 75
+ 48 97 94 88 76
+ 49 97 94 88 76
+ 46 98 95 89 77
+ 47 98 95 89 77
+ 44 98 95 89 78
+ 45 98 95 89 78
+ 42 98 95 90 79
+ 43 98 95 90 79
+ 40 98 95 90 80
+ 41 98 95 90 80
+ 38 98 96 91 81
+ 39 98 96 91 81
+ 36 98 96 91 82
+ 37 98 96 91 82
+ 34 98 96 92 83
+ 35 98 96 92 83
+ 32 98 96 92 84
+ 33 98 96 92 84
+ 30 99 97 93 85
+ 31 99 97 93 85
+ 28 99 97 93 86
+ 29 99 97 93 86
+ 26 99 97 94 87
+ 27 99 97 94 87
+ 24 99 97 94 88
+ 25 99 97 94 88
+ 22 99 98 95 89
+ 23 99 98 95 89
+ 20 99 98 95 90
+ 21 99 98 95 90
+ 18 99 98 96 91
+ 19 99 98 96 91
+ 16 99 98 96 92
+ 17 99 98 96 92
+ 14 100 99 97 93
+ 15 100 99 97 93
+ 12 100 99 97 94
+ 13 100 99 97 94
+ 10 100 99 98 95
+ 11 100 99 98 95
+ 8 100 99 98 96
+ 9 100 99 98 96
+ 6 100 100 99 97
+ 7 100 100 99 97
+ 4 100 100 99 98
+ 5 100 100 99 98
+ 2 100 100 100 99
+ 3 100 100 100 99
+ 1 100 100 100 100
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d
new file mode 100644
index 0000000..ddb297f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ j = 0;
+}
+
+tick-1ms
+/i < 100/
+{
+ i++;
+ @a[i] = sum(i);
+ @b[i] = sum((25 + i) % 100);
+ @c[i] = sum((50 + i) % 100);
+ @d[i] = sum((75 + i) % 100);
+}
+
+tick-1ms
+/i == 100 && j < 10/
+{
+ printf("Sorted at position %d:\n", j);
+ setopt("aggsortpos", lltostr(j));
+ printa("%9d %@9d %@9d %@9d %@9d %@9d %@9d\n", @a, @b, @c, @a, @d, @a);
+ printf("\n");
+ j++;
+}
+
+tick-1ms
+/i == 100 && j == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d.out
new file mode 100644
index 0000000..ce17539
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.sortpos.d.out
@@ -0,0 +1,1021 @@
+Sorted at position 0:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 1:
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+
+Sorted at position 2:
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+
+Sorted at position 3:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 4:
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+
+Sorted at position 5:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 6:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 7:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 8:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+Sorted at position 9:
+ 1 1 26 51 1 76 1
+ 2 2 27 52 2 77 2
+ 3 3 28 53 3 78 3
+ 4 4 29 54 4 79 4
+ 5 5 30 55 5 80 5
+ 6 6 31 56 6 81 6
+ 7 7 32 57 7 82 7
+ 8 8 33 58 8 83 8
+ 9 9 34 59 9 84 9
+ 10 10 35 60 10 85 10
+ 11 11 36 61 11 86 11
+ 12 12 37 62 12 87 12
+ 13 13 38 63 13 88 13
+ 14 14 39 64 14 89 14
+ 15 15 40 65 15 90 15
+ 16 16 41 66 16 91 16
+ 17 17 42 67 17 92 17
+ 18 18 43 68 18 93 18
+ 19 19 44 69 19 94 19
+ 20 20 45 70 20 95 20
+ 21 21 46 71 21 96 21
+ 22 22 47 72 22 97 22
+ 23 23 48 73 23 98 23
+ 24 24 49 74 24 99 24
+ 25 25 50 75 25 0 25
+ 26 26 51 76 26 1 26
+ 27 27 52 77 27 2 27
+ 28 28 53 78 28 3 28
+ 29 29 54 79 29 4 29
+ 30 30 55 80 30 5 30
+ 31 31 56 81 31 6 31
+ 32 32 57 82 32 7 32
+ 33 33 58 83 33 8 33
+ 34 34 59 84 34 9 34
+ 35 35 60 85 35 10 35
+ 36 36 61 86 36 11 36
+ 37 37 62 87 37 12 37
+ 38 38 63 88 38 13 38
+ 39 39 64 89 39 14 39
+ 40 40 65 90 40 15 40
+ 41 41 66 91 41 16 41
+ 42 42 67 92 42 17 42
+ 43 43 68 93 43 18 43
+ 44 44 69 94 44 19 44
+ 45 45 70 95 45 20 45
+ 46 46 71 96 46 21 46
+ 47 47 72 97 47 22 47
+ 48 48 73 98 48 23 48
+ 49 49 74 99 49 24 49
+ 50 50 75 0 50 25 50
+ 51 51 76 1 51 26 51
+ 52 52 77 2 52 27 52
+ 53 53 78 3 53 28 53
+ 54 54 79 4 54 29 54
+ 55 55 80 5 55 30 55
+ 56 56 81 6 56 31 56
+ 57 57 82 7 57 32 57
+ 58 58 83 8 58 33 58
+ 59 59 84 9 59 34 59
+ 60 60 85 10 60 35 60
+ 61 61 86 11 61 36 61
+ 62 62 87 12 62 37 62
+ 63 63 88 13 63 38 63
+ 64 64 89 14 64 39 64
+ 65 65 90 15 65 40 65
+ 66 66 91 16 66 41 66
+ 67 67 92 17 67 42 67
+ 68 68 93 18 68 43 68
+ 69 69 94 19 69 44 69
+ 70 70 95 20 70 45 70
+ 71 71 96 21 71 46 71
+ 72 72 97 22 72 47 72
+ 73 73 98 23 73 48 73
+ 74 74 99 24 74 49 74
+ 75 75 0 25 75 50 75
+ 76 76 1 26 76 51 76
+ 77 77 2 27 77 52 77
+ 78 78 3 28 78 53 78
+ 79 79 4 29 79 54 79
+ 80 80 5 30 80 55 80
+ 81 81 6 31 81 56 81
+ 82 82 7 32 82 57 82
+ 83 83 8 33 83 58 83
+ 84 84 9 34 84 59 84
+ 85 85 10 35 85 60 85
+ 86 86 11 36 86 61 86
+ 87 87 12 37 87 62 87
+ 88 88 13 38 88 63 88
+ 89 89 14 39 89 64 89
+ 90 90 15 40 90 65 90
+ 91 91 16 41 91 66 91
+ 92 92 17 42 92 67 92
+ 93 93 18 43 93 68 93
+ 94 94 19 44 94 69 94
+ 95 95 20 45 95 70 95
+ 96 96 21 46 96 71 96
+ 97 97 22 47 97 72 97
+ 98 98 23 48 98 73 98
+ 99 99 24 49 99 74 99
+ 100 100 25 50 100 75 100
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d
new file mode 100644
index 0000000..ebb916a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @one["foo", 789, "bar", curthread] = sum(123);
+ @two["foo", 789, "bar", curthread] = sum(456);
+ printa("%10s %10d %10s %@10d %@10d\n", @one, @two);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d.out
new file mode 100644
index 0000000..002f5aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.tuplecompat.d.out
@@ -0,0 +1,2 @@
+ foo 789 bar 123 456
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d
new file mode 100644
index 0000000..5a57b2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+/0/
+{
+ @bop[345] = quantize(0);
+ @baz[345] = lquantize(0, -10, 10, 1);
+}
+
+BEGIN
+{
+ @foo[123] = sum(123);
+ @bar[456] = sum(456);
+
+ @foo[789] = sum(789);
+ @bar[789] = sum(789);
+
+ printa("%10d %@10d %@10d\n", @foo, @bar);
+ printa("%10d %@10d %@10d %@10d\n", @foo, @bar, @bop);
+ printa("%10d %@10d %@10d %@10d %@10d\n", @foo, @bar, @bop, @baz);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d.out
new file mode 100644
index 0000000..dde9e41
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero.d.out
@@ -0,0 +1,55 @@
+ 456 0 456
+ 123 123 0
+ 789 789 789
+ 456 0 456
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 123 123 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 789 789 789
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 456 0 456
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+ 123 123 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+ 789 789 789
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d
new file mode 100644
index 0000000..79e756b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ @bop[345] = quantize(0, 0);
+ @baz[345] = lquantize(0, -10, 10, 1, 0);
+}
+
+BEGIN
+{
+ @foo[123] = sum(123);
+ @bar[456] = sum(456);
+
+ @foo[789] = sum(789);
+ @bar[789] = sum(789);
+
+ printa("%10d %@10d %@10d\n", @foo, @bar);
+ printa("%10d %@10d %@10d %@10d\n", @foo, @bar, @bop);
+ printa("%10d %@10d %@10d %@10d %@10d\n", @foo, @bar, @bop, @baz);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d.out
new file mode 100644
index 0000000..9b28d8e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero2.d.out
@@ -0,0 +1,72 @@
+ 456 0 456
+ 123 123 0
+ 789 789 789
+ 345 0 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 456 0 456
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 123 123 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 789 789 789
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ 345 0 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+ 456 0 456
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+ 123 123 0
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+ 789 789 789
+ value ------------- Distribution ------------- count
+ -1 | 0
+ 0 | 0
+ 1 | 0
+
+ value ------------- Distribution ------------- count
+ < -10 | 0
+ -10 | 0
+ -9 | 0
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d
new file mode 100644
index 0000000..bc17bc9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+/0/
+{
+ @bop[345] = quantize(0, 0);
+ @baz[345] = lquantize(0, -10, 10, 1, 0);
+}
+
+BEGIN
+{
+ printa(@bop);
+ printa(@baz);
+ printa("%@10d %@10d\n", @bop, @baz);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d.out
new file mode 100644
index 0000000..b28b04f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/multiaggs/tst.zero3.d.out
@@ -0,0 +1,3 @@
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.c
new file mode 100644
index 0000000..6194c58
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.c
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <strings.h>
+#include <rpc/rpc.h>
+
+#include "rpcsvc/nfs4_prot.h"
+
+int nfs4_skip_bytes;
+
+/*
+ * The waiting() function returns the value passed in, until something
+ * external modifies it. In this case, the D script tst.call.d will
+ * modify the value of *a, and thus break the while loop in dotest().
+ *
+ * This serves the purpose of not making the RPC calls until tst.call.d
+ * is active. Thus, the probes in tst.call.d can fire as a result of
+ * the RPC call in dotest().
+ */
+
+int
+waiting(volatile int *a)
+{
+ return (*a);
+}
+
+int
+dotest(void)
+{
+ CLIENT *client;
+ AUTH *auth;
+ COMPOUND4args args;
+ COMPOUND4res res;
+ enum clnt_stat status;
+ struct timeval timeout;
+ nfs_argop4 arg[1];
+ char *tag = "dtrace test";
+ volatile int a = 0;
+
+ while (waiting(&a) == 0)
+ continue;
+
+ timeout.tv_sec = 30;
+ timeout.tv_usec = 0;
+
+ client = clnt_create("localhost", NFS4_PROGRAM, NFS_V4, "tcp");
+ if (client == NULL) {
+ clnt_pcreateerror("test");
+ return (1);
+ }
+ auth = authsys_create_default();
+ client->cl_auth = auth;
+ args.minorversion = 0;
+ args.tag.utf8string_len = strlen(tag);
+ args.tag.utf8string_val = tag;
+ args.argarray.argarray_len = sizeof (arg) / sizeof (nfs_argop4);
+ args.argarray.argarray_val = arg;
+
+ arg[0].argop = OP_PUTROOTFH;
+ /* no need to manipulate nfs_argop4_u */
+
+ bzero(&res, sizeof (res));
+
+ status = clnt_call(client, NFSPROC4_COMPOUND,
+ xdr_COMPOUND4args, (caddr_t)&args,
+ xdr_COMPOUND4res, (caddr_t)&res,
+ timeout);
+ if (status != RPC_SUCCESS) {
+ clnt_perror(client, "test");
+ return (2);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ char shareline[BUFSIZ], unshareline[BUFSIZ];
+ int rc;
+
+ (void) snprintf(shareline, sizeof (shareline),
+ "mkdir /tmp/nfsv4test.%d ; share /tmp/nfsv4test.%d", getpid(),
+ getpid());
+ (void) snprintf(unshareline, sizeof (unshareline),
+ "unshare /tmp/nfsv4test.%d ; rmdir /tmp/nfsv4test.%d", getpid(),
+ getpid());
+
+ (void) system(shareline);
+ rc = dotest();
+ (void) system(unshareline);
+
+ return (rc);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.d
new file mode 100644
index 0000000..15cf8bc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure nfs provider probes are firing
+ *
+ * SECTION: nfs4 provider
+ */
+
+#pragma D option destructive
+#pragma D option quiet
+
+pid$1:a.out:waiting:entry
+{
+ this->value = (int *)alloca(sizeof (int));
+ *this->value = 1;
+ copyout(this->value, arg0, sizeof (int));
+}
+
+nfsv4:::compound-start
+{
+ cstart++;
+}
+
+nfsv4:::op-putrootfh-start
+{
+ opstart++;
+}
+
+nfsv4:::op-putrootfh-done
+{
+ opdone++;
+}
+
+nfsv4:::compound-done
+/cstart && opstart && opdone/
+{
+ exit(0);
+}
+
+tick-1s
+/tick++ == 3/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.c
new file mode 100644
index 0000000..bd89fff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.c
@@ -0,0 +1,441 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <strings.h>
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <rpcsvc/mount.h>
+
+#include "rpcsvc/nfs_prot.h"
+
+char sharedpath[MAXPATHLEN];
+fhandle3 *rootfh;
+
+/*
+ * The waiting() function returns the value passed in, until something
+ * external modifies it. In this case, the D script tst.call.d will
+ * modify the value of *a, and thus break the while loop in dotest().
+ *
+ * This serves the purpose of not making the RPC calls until tst.call.d
+ * is active. Thus, the probes in tst.call.d can fire as a result of
+ * the RPC call in dotest().
+ */
+
+int
+waiting(volatile int *a)
+{
+ return (*a);
+}
+
+static void
+getattr_arginit(void *argp)
+{
+ GETATTR3args *args = argp;
+
+ args->object.data.data_len = rootfh->fhandle3_len;
+ args->object.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+setattr_arginit(void *argp)
+{
+ SETATTR3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->object.data.data_len = rootfh->fhandle3_len;
+ args->object.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+lookup_arginit(void *argp)
+{
+ LOOKUP3args *args = argp;
+
+ args->what.name = "giant-skunk";
+ args->what.dir.data.data_len = rootfh->fhandle3_len;
+ args->what.dir.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+access_arginit(void *argp)
+{
+ ACCESS3args *args = argp;
+
+ args->object.data.data_len = rootfh->fhandle3_len;
+ args->object.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+commit_arginit(void *argp)
+{
+ COMMIT3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->file.data.data_len = rootfh->fhandle3_len;
+ args->file.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+create_arginit(void *argp)
+{
+ CREATE3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->where.name = "pinky-blue";
+ args->where.dir.data.data_len = rootfh->fhandle3_len;
+ args->where.dir.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+fsinfo_arginit(void *argp)
+{
+ FSINFO3args *args = argp;
+
+ args->fsroot.data.data_len = rootfh->fhandle3_len;
+ args->fsroot.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+fsstat_arginit(void *argp)
+{
+ FSSTAT3args *args = argp;
+
+ args->fsroot.data.data_len = rootfh->fhandle3_len;
+ args->fsroot.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+link_arginit(void *argp)
+{
+ LINK3args *args = argp;
+
+ args->file.data.data_len = rootfh->fhandle3_len;
+ args->file.data.data_val = rootfh->fhandle3_val;
+ args->link.dir.data.data_len = rootfh->fhandle3_len;
+ args->link.dir.data.data_val = rootfh->fhandle3_val;
+ args->link.name = "samf";
+}
+
+static void
+mkdir_arginit(void *argp)
+{
+ MKDIR3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->where.dir.data.data_len = rootfh->fhandle3_len;
+ args->where.dir.data.data_val = rootfh->fhandle3_val;
+ args->where.name = "cookie";
+}
+
+static void
+mknod_arginit(void *argp)
+{
+ MKNOD3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->where.dir.data.data_len = rootfh->fhandle3_len;
+ args->where.dir.data.data_val = rootfh->fhandle3_val;
+ args->where.name = "pookie";
+}
+
+static void
+null_arginit(void *argp)
+{
+}
+
+static void
+pathconf_arginit(void *argp)
+{
+ PATHCONF3args *args = argp;
+
+ args->object.data.data_len = rootfh->fhandle3_len;
+ args->object.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+read_arginit(void *argp)
+{
+ READ3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->file.data.data_len = rootfh->fhandle3_len;
+ args->file.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+readdir_arginit(void *argp)
+{
+ READDIR3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->dir.data.data_len = rootfh->fhandle3_len;
+ args->dir.data.data_val = rootfh->fhandle3_val;
+ args->count = 1024;
+}
+
+static void
+readdirplus_arginit(void *argp)
+{
+ READDIRPLUS3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->dir.data.data_len = rootfh->fhandle3_len;
+ args->dir.data.data_val = rootfh->fhandle3_val;
+ args->dircount = 1024;
+ args->maxcount = 1024;
+}
+
+static void
+readlink_arginit(void *argp)
+{
+ READLINK3args *args = argp;
+
+ args->symlink.data.data_len = rootfh->fhandle3_len;
+ args->symlink.data.data_val = rootfh->fhandle3_val;
+}
+
+static void
+remove_arginit(void *argp)
+{
+ REMOVE3args *args = argp;
+
+ args->object.dir.data.data_len = rootfh->fhandle3_len;
+ args->object.dir.data.data_val = rootfh->fhandle3_val;
+ args->object.name = "antelope";
+}
+
+static void
+rename_arginit(void *argp)
+{
+ RENAME3args *args = argp;
+
+ args->from.dir.data.data_len = rootfh->fhandle3_len;
+ args->from.dir.data.data_val = rootfh->fhandle3_val;
+ args->from.name = "walter";
+ args->to.dir.data.data_len = rootfh->fhandle3_len;
+ args->to.dir.data.data_val = rootfh->fhandle3_val;
+ args->to.name = "wendy";
+}
+
+static void
+rmdir_arginit(void *argp)
+{
+ RMDIR3args *args = argp;
+
+ args->object.dir.data.data_len = rootfh->fhandle3_len;
+ args->object.dir.data.data_val = rootfh->fhandle3_val;
+ args->object.name = "bunny";
+}
+
+static void
+symlink_arginit(void *argp)
+{
+ SYMLINK3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->where.dir.data.data_len = rootfh->fhandle3_len;
+ args->where.dir.data.data_val = rootfh->fhandle3_val;
+ args->where.name = "parlor";
+ args->symlink.symlink_data = "interior";
+}
+
+static void
+write_arginit(void *argp)
+{
+ WRITE3args *args = argp;
+
+ bzero(args, sizeof (*args));
+ args->file.data.data_len = rootfh->fhandle3_len;
+ args->file.data.data_val = rootfh->fhandle3_val;
+}
+
+typedef void (*call3_arginit_t)(void *);
+
+typedef struct {
+ call3_arginit_t arginit;
+ rpcproc_t proc;
+ xdrproc_t xdrargs;
+ size_t argsize;
+ xdrproc_t xdrres;
+ size_t ressize;
+} call3_test_t;
+call3_test_t call3_tests[] = {
+ {getattr_arginit, NFSPROC3_GETATTR, xdr_GETATTR3args,
+ sizeof (GETATTR3args), xdr_GETATTR3res, sizeof (GETATTR3res)},
+ {setattr_arginit, NFSPROC3_SETATTR, xdr_SETATTR3args,
+ sizeof (SETATTR3args), xdr_SETATTR3res, sizeof (SETATTR3res)},
+ {lookup_arginit, NFSPROC3_LOOKUP, xdr_LOOKUP3args,
+ sizeof (LOOKUP3args), xdr_LOOKUP3res, sizeof (LOOKUP3res)},
+ {access_arginit, NFSPROC3_ACCESS, xdr_ACCESS3args,
+ sizeof (ACCESS3args), xdr_ACCESS3res, sizeof (ACCESS3res)},
+ {commit_arginit, NFSPROC3_COMMIT, xdr_COMMIT3args,
+ sizeof (COMMIT3args), xdr_COMMIT3res, sizeof (COMMIT3res)},
+ {create_arginit, NFSPROC3_CREATE, xdr_CREATE3args,
+ sizeof (CREATE3args), xdr_CREATE3res, sizeof (CREATE3res)},
+ {fsinfo_arginit, NFSPROC3_FSINFO, xdr_FSINFO3args,
+ sizeof (FSINFO3args), xdr_FSINFO3res, sizeof (FSINFO3res)},
+ {fsstat_arginit, NFSPROC3_FSSTAT, xdr_FSSTAT3args,
+ sizeof (FSSTAT3args), xdr_FSSTAT3res, sizeof (FSSTAT3res)},
+ {link_arginit, NFSPROC3_LINK, xdr_LINK3args,
+ sizeof (LINK3args), xdr_LINK3res, sizeof (LINK3res)},
+ {mkdir_arginit, NFSPROC3_MKDIR, xdr_MKDIR3args,
+ sizeof (MKDIR3args), xdr_MKDIR3res, sizeof (MKDIR3res)},
+ {mknod_arginit, NFSPROC3_MKNOD, xdr_MKNOD3args,
+ sizeof (MKNOD3args), xdr_MKNOD3res, sizeof (MKNOD3res)},
+ /*
+ * NULL proc is special. Rather than special case its zero-sized
+ * args/results, we give it a small nonzero size, so as to not
+ * make realloc() do the wrong thing.
+ */
+ {null_arginit, NFSPROC3_NULL, xdr_void, sizeof (int), xdr_void,
+ sizeof (int)},
+ {pathconf_arginit, NFSPROC3_PATHCONF, xdr_PATHCONF3args,
+ sizeof (PATHCONF3args), xdr_PATHCONF3res, sizeof (PATHCONF3res)},
+ {read_arginit, NFSPROC3_READ, xdr_READ3args,
+ sizeof (READ3args), xdr_READ3res, sizeof (READ3res)},
+ {readdir_arginit, NFSPROC3_READDIR, xdr_READDIR3args,
+ sizeof (READDIR3args), xdr_READDIR3res, sizeof (READDIR3res)},
+ {readdirplus_arginit, NFSPROC3_READDIRPLUS, xdr_READDIRPLUS3args,
+ sizeof (READDIRPLUS3args), xdr_READDIRPLUS3res,
+ sizeof (READDIRPLUS3res)},
+ {readlink_arginit, NFSPROC3_READLINK, xdr_READLINK3args,
+ sizeof (READLINK3args), xdr_READLINK3res, sizeof (READLINK3res)},
+ {remove_arginit, NFSPROC3_REMOVE, xdr_REMOVE3args,
+ sizeof (REMOVE3args), xdr_REMOVE3res, sizeof (REMOVE3res)},
+ {rename_arginit, NFSPROC3_RENAME, xdr_RENAME3args,
+ sizeof (RENAME3args), xdr_RENAME3res, sizeof (RENAME3res)},
+ {rmdir_arginit, NFSPROC3_RMDIR, xdr_RMDIR3args,
+ sizeof (RMDIR3args), xdr_RMDIR3res, sizeof (RMDIR3res)},
+ {symlink_arginit, NFSPROC3_SYMLINK, xdr_SYMLINK3args,
+ sizeof (SYMLINK3args), xdr_SYMLINK3res, sizeof (SYMLINK3res)},
+ {write_arginit, NFSPROC3_WRITE, xdr_WRITE3args,
+ sizeof (WRITE3args), xdr_WRITE3res, sizeof (WRITE3res)},
+ {NULL}
+};
+
+int
+dotest(void)
+{
+ CLIENT *client, *mountclient;
+ AUTH *auth;
+ struct timeval timeout;
+ caddr_t args, res;
+ enum clnt_stat status;
+ rpcproc_t proc;
+ call3_test_t *test;
+ void *argbuf = NULL;
+ void *resbuf = NULL;
+ struct mountres3 mountres3;
+ char *sp;
+ volatile int a = 0;
+
+ while (waiting(&a) == 0)
+ continue;
+
+ timeout.tv_sec = 30;
+ timeout.tv_usec = 0;
+
+ mountclient = clnt_create("localhost", MOUNTPROG, MOUNTVERS3, "tcp");
+ if (mountclient == NULL) {
+ clnt_pcreateerror("clnt_create mount");
+ return (1);
+ }
+ auth = authsys_create_default();
+ mountclient->cl_auth = auth;
+ sp = sharedpath;
+ bzero(&mountres3, sizeof (mountres3));
+ status = clnt_call(mountclient, MOUNTPROC_MNT,
+ xdr_dirpath, (char *)&sp,
+ xdr_mountres3, (char *)&mountres3,
+ timeout);
+ if (status != RPC_SUCCESS) {
+ clnt_perror(mountclient, "mnt");
+ return (1);
+ }
+ if (mountres3.fhs_status != 0) {
+ fprintf(stderr, "MOUNTPROG/MOUNTVERS3 failed %d\n",
+ mountres3.fhs_status);
+ return (1);
+ }
+ rootfh = &mountres3.mountres3_u.mountinfo.fhandle;
+
+ client = clnt_create("localhost", NFS3_PROGRAM, NFS_V3, "tcp");
+ if (client == NULL) {
+ clnt_pcreateerror("clnt_create");
+ return (1);
+ }
+ client->cl_auth = auth;
+
+ for (test = call3_tests; test->arginit; ++test) {
+ argbuf = realloc(argbuf, test->argsize);
+ resbuf = realloc(resbuf, test->ressize);
+ if ((argbuf == NULL) || (resbuf == NULL)) {
+ perror("realloc() failed");
+ return (1);
+ }
+ (test->arginit)(argbuf);
+ bzero(resbuf, test->ressize);
+ status = clnt_call(client, test->proc,
+ test->xdrargs, argbuf,
+ test->xdrres, resbuf,
+ timeout);
+ if (status != RPC_SUCCESS)
+ clnt_perror(client, "call");
+ }
+
+ status = clnt_call(mountclient, MOUNTPROC_UMNT,
+ xdr_dirpath, (char *)&sp,
+ xdr_void, NULL,
+ timeout);
+ if (status != RPC_SUCCESS)
+ clnt_perror(mountclient, "umnt");
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ char shareline[BUFSIZ], unshareline[BUFSIZ];
+ int rc;
+
+ (void) snprintf(sharedpath, sizeof (sharedpath),
+ "/tmp/nfsv3test.%d", getpid());
+ (void) snprintf(shareline, sizeof (shareline),
+ "mkdir %s ; share %s", sharedpath, sharedpath);
+ (void) snprintf(unshareline, sizeof (unshareline),
+ "unshare %s ; rmdir %s", sharedpath, sharedpath);
+
+ (void) system(shareline);
+ rc = dotest();
+ (void) system(unshareline);
+
+ return (rc);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.d
new file mode 100644
index 0000000..b635b16
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.d
@@ -0,0 +1,91 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure nfsv3 provider probes are firing, and that the
+ * arguments are properly visible.
+ *
+ * SECTION: nfs3 provider
+ */
+
+#pragma D option destructive
+#pragma D option quiet
+
+pid$1:a.out:waiting:entry
+{
+ this->value = (int *)alloca(sizeof (int));
+ *this->value = 1;
+ copyout(this->value, arg0, sizeof (int));
+}
+
+nfsv3:::op-getattr-start
+{
+ printf("ci_local: %s\n", args[0]->ci_local);
+ printf("ci_remote: %s\n", args[0]->ci_remote);
+ printf("ci_protocol: %s\n", args[0]->ci_protocol);
+
+ printf("noi_xid: %d\n", args[1]->noi_xid);
+ printf("noi_cred->cr_uid: %d\n", args[1]->noi_cred->cr_uid);
+ printf("noi_curpath: %s\n", args[1]->noi_curpath);
+
+ printf("fh3_flags: %d\n", args[2]->object.fh3_flags);
+}
+
+nfsv3:::op-getattr-done
+{
+ printf("ci_local: %s\n", args[0]->ci_local);
+ printf("ci_remote: %s\n", args[0]->ci_remote);
+ printf("ci_protocol: %s\n", args[0]->ci_protocol);
+
+ printf("noi_xid: %d\n", args[1]->noi_xid);
+ printf("noi_cred->cr_uid: %d\n", args[1]->noi_cred->cr_uid);
+ printf("noi_curpath: %s\n", args[1]->noi_curpath);
+
+ printf("status: %d\n", args[2]->status);
+}
+
+nfsv3:::*-done
+/seen[probename] == 0/
+{
+ ++numberseen;
+ seen[probename] = 1;
+ printf("%d ops seen, latest op is %s\n", numberseen, probename);
+}
+
+nfsv3:::*-done
+/numberseen == 22/
+{
+ exit(0);
+}
+
+tick-1s
+/tick++ == 10/
+{
+ printf("%d nfsv3 ops seen; should be 22\n", numberseen);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_BITFIELD.bitfield.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_BITFIELD.bitfield.d
new file mode 100644
index 0000000..cc48846
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_BITFIELD.bitfield.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test invocation of offsetof() with a member that is a bit-field.
+ * This should fail at compile time.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+struct foo {
+ int a:1;
+ int b:3;
+};
+
+BEGIN
+{
+ trace(offsetof(struct foo, b));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.badtype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.badtype.d
new file mode 100644
index 0000000..4e8a885
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.badtype.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test invocation of offsetof() with an invalid type.
+ * This should fail at compile time.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+BEGIN
+{
+ trace(offsetof(struct no_such_type, x));
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.notsou.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.notsou.d
new file mode 100644
index 0000000..8420953
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_OFFSETOF_TYPE.notsou.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ *
+ * Test invocation of offsetof() with a type that is not a struct or union.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+BEGIN
+{
+ trace(offsetof(int, x));
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.OffsetofNULL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.OffsetofNULL.d
new file mode 100644
index 0000000..5a341a3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.OffsetofNULL.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Querying the offsetof an non-member variable of a struct throws
+ * a D_UNKNOWN error.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+
+struct record {
+ int a;
+ int b;
+ int c : 4;
+};
+
+BEGIN
+{
+ printf("offsetof (struct record, NULL): %d\n",
+ offsetof (struct record, NULL));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.badmemb.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.badmemb.d
new file mode 100644
index 0000000..caf0a1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/err.D_UNKNOWN.badmemb.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test invocation of offsetof() with an invalid member.
+ * This should fail at compile time.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+BEGIN
+{
+ trace(offsetof(vnode_t, v_no_such_member));
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofAlias.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofAlias.d
new file mode 100644
index 0000000..c7494d2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofAlias.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test invocation of offsetof() with a struct type alias.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+typedef struct record {
+ char c;
+ int x;
+ int y;
+} record_t;
+
+BEGIN
+{
+ printf("offsetof(record_t, c) = %d\n", offsetof(record_t, c));
+ printf("offsetof(record_t, x) = %d\n", offsetof(record_t, x));
+ printf("offsetof(record_t, y) = %d\n", offsetof(record_t, y));
+ exit(0);
+}
+
+END
+/(8 != offsetof(record_t, y)) || (4 != offsetof(record_t, x)) ||
+ (0 != offsetof(record_t, c))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofArith.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofArith.d
new file mode 100644
index 0000000..7e2b330
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofArith.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: offsetof can be used anywhere in a D program that an integer
+ * constant can be used.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+typedef struct record {
+ char c;
+ int x;
+ int y;
+} record_t;
+
+BEGIN
+{
+
+ add = offsetof(record_t, c) + offsetof(record_t, x) +
+ offsetof(record_t, y);
+ sub = offsetof(record_t, y) - offsetof(record_t, x);
+ mul = offsetof(record_t, x) * offsetof(record_t, c);
+ div = offsetof(record_t, y) / offsetof(record_t, x);
+
+ printf("offsetof(record_t, c) = %d\n", offsetof(record_t, c));
+ printf("offsetof(record_t, x) = %d\n", offsetof(record_t, x));
+ printf("offsetof(record_t, y) = %d\n", offsetof(record_t, y));
+
+ printf("Addition of offsets (c+x+y)= %d\n", add);
+ printf("Subtraction of offsets (y-x)= %d\n", sub);
+ printf("Multiplication of offsets (x*c) = %d\n", mul);
+ printf("Division of offsets (y/x) = %d\n", div);
+
+ exit(0);
+}
+
+END
+/(8 != offsetof(record_t, y)) || (4 != offsetof(record_t, x)) ||
+ (0 != offsetof(record_t, c)) || (12 != add) || (4 != sub) || (0 != mul)
+ || (2 != div)/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofUnion.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofUnion.d
new file mode 100644
index 0000000..de1a5fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.OffsetofUnion.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test invocation of offsetof() with a union type alias.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int x;
+ int y;
+ char c;
+};
+
+BEGIN
+{
+ printf("offsetof(record, x) = %d\n", offsetof(union D`record, x));
+ printf("offsetof(record, y) = %d\n", offsetof(union D`record, y));
+ printf("offsetof(record, c) = %d\n", offsetof(union D`record, c));
+ exit(0);
+}
+
+END
+/(0 != offsetof(union D`record, y)) && (0 != offsetof(union D`record, x)) &&
+ (0 != offsetof(union D`record, c))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d
new file mode 100644
index 0000000..60b8863
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test invocation of offsetof() with a struct type.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+struct s {
+ int x;
+ int y;
+};
+
+BEGIN
+{
+ printf("offsetof(s, y) = %d\n", offsetof(struct D`s, y));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d.out
new file mode 100644
index 0000000..04b666e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.struct.d.out
@@ -0,0 +1,2 @@
+offsetof(s, y) = 4
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d
new file mode 100644
index 0000000..1b37c4c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test invocation of offsetof() with a union type.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+union s {
+ int x;
+ int y;
+};
+
+BEGIN
+{
+ printf("offsetof(s, y) = %d\n", offsetof(union D`s, y));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d.out
new file mode 100644
index 0000000..e3918be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/offsetof/tst.union.d.out
@@ -0,0 +1,2 @@
+offsetof(s, y) = 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d
new file mode 100644
index 0000000..cd37519
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the ternary operator. Test left-hand side true, right-hand side true,
+ * and multiple nested instances of the ternary operator.
+ *
+ * SECTION: Types, Operators, and Expressions/Conditional Expressions
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = 0;
+ printf("x is %s\n", x == 0 ? "zero" : "one");
+ x = 1;
+ printf("x is %s\n", x == 0 ? "zero" : "one");
+ x = 2;
+ printf("x is %s\n", x == 0 ? "zero" : x == 1 ? "one" : "two");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d.out
new file mode 100644
index 0000000..ec30800
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/operators/tst.ternary.d.out
@@ -0,0 +1,4 @@
+x is zero
+x is one
+x is two
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.d
new file mode 100644
index 0000000..a3fa24f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: can't specify a bogus library name
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid$1:libbmc_sucks.so.1::entry
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badproc1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badproc1.d
new file mode 100644
index 0000000..3f3ca22
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badproc1.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that we don't grab bogus process IDs.
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pidgin:::entry
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_BADPID.badproc2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_BADPID.badproc2.d
new file mode 100644
index 0000000..8e01b06
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_BADPID.badproc2.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure we can't grab pid 0
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid0:::entry
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.d
new file mode 100644
index 0000000..dabcd9c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+pid$1:::
+{
+}
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe
new file mode 100644
index 0000000..7a6d6f2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.d
new file mode 100644
index 0000000..f1c44e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Can't specify a bogus function name (if the module is specified)
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ * NOTES:
+ *
+ */
+
+pid$1:a.out:ahl_r00lz:entry
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.d
new file mode 100644
index 0000000..dd90530
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test that the '-' function doesn't work with random modules
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid$1:libc:-:800
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.d
new file mode 100644
index 0000000..6acf8aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that you can't enable "all" '-' function probes
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid$1::-:
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.d
new file mode 100644
index 0000000..829c002
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Only entry, return and offsets are valid names
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid$1:a.out:main:beginning
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.d
new file mode 100644
index 0000000..36bf9d6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that you can't glob the probe name with the '-' function
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ */
+
+pid$1::-:10*
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.d
new file mode 100644
index 0000000..60e5a8c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Can't have an offset that's outside of a function
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ * NOTES: If _exit(2) becomes _way_ more complex this could fail...
+ *
+ */
+
+pid$1::_exit:100
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.addprobes.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.addprobes.ksh
new file mode 100644
index 0000000..6c269ca
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.addprobes.ksh
@@ -0,0 +1,61 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This test verifies that it's possible to add new pid probes to an existing
+# pid provider.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+sleep 60 &
+pid=$!
+
+$dtrace -n pid$pid:libc::entry -n 'tick-1s{exit(0);}'
+status=$?
+
+if [ $status -gt 0 ]; then
+ exit $status;
+fi
+
+$dtrace -n pid$pid:libc::return -n 'tick-1s{exit(0);}'
+status=$?
+
+if [ $status -gt 0 ]; then
+ exit $status;
+fi
+
+kill $pid
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.c
new file mode 100644
index 0000000..23bbab2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.c
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <unistd.h>
+
+int
+go(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6,
+ int arg7, int arg8, int arg9)
+{
+ return (arg1);
+}
+
+static void
+handle(int sig)
+{
+ go(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ (void) signal(SIGUSR1, handle);
+ for (;;)
+ getpid();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.d
new file mode 100644
index 0000000..a3ad6c9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.args1.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that all 10 arguments are what we expect them to be.
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the first call to getpid(2).
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ i = 0;
+ raise(SIGUSR1);
+ /*
+ * Wait half a second after raising the signal.
+ */
+ timeout = timestamp + 500000000;
+}
+
+pid$1:a.out:go:entry
+/arg0 == 0 && arg1 == 1 && arg2 == 2 && arg3 == 3 && arg4 == 4 &&
+arg5 == 5 && arg6 == 6 && arg7 == 7 && arg8 == 8 && arg9 == 9/
+{
+ exit(0);
+}
+
+pid$1:a.out:go:entry
+{
+ printf("wrong args: %d %d %d %d %d %d %d %d %d %d", arg0, arg1, arg2,
+ arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+ exit(1);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.d
new file mode 100644
index 0000000..d3d568e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that we can trace every instruction safely
+ *
+ * SECTION: pid provider
+ *
+ */
+
+BEGIN
+{
+ /*
+ * Let's just do this for 2 seconds.
+ */
+ timeout = timestamp + 2000000000;
+}
+
+pid$1:a.out::
+{}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe
new file mode 100644
index 0000000..07e8458
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe
@@ -0,0 +1,29 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+while true; do env > /dev/null; done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d
new file mode 100644
index 0000000..e0fada8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: the stack() action should be empty for all pid probes
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ /*
+ * Monitor the program for two seconds.
+ */
+ timeout = timestamp + 1000000000 * 2;
+}
+
+pid$1:::return
+{
+ @[stack()] = sum(0);
+}
+
+pid$1:a.out::
+{
+ @[stack()] = sum(0);
+}
+
+pid$1:::entry
+{
+ @[stack()] = sum(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d.out
new file mode 100644
index 0000000..2304a61
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.d.out
@@ -0,0 +1,3 @@
+
+
+ 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe
new file mode 100644
index 0000000..a8bc8cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe
@@ -0,0 +1,29 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+exec find / > /dev/null 2>&1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.c
new file mode 100644
index 0000000..450c6aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.c
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+volatile double c = 1.2;
+
+int
+main(int argc, char **argv)
+{
+ double a = 1.56;
+ double b = (double)argc;
+
+ for (;;) {
+ c *= a;
+ c += b;
+ (void) usleep(1000);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.d
new file mode 100644
index 0000000..4e11ee3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.float.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure we can work on processes that use the FPU
+ *
+ * SECTION: pid provider
+ */
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+pid$1:a.out:main:
+{}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c
new file mode 100644
index 0000000..8c27723
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+int
+waiting(volatile int *a)
+{
+ return (*a);
+}
+
+int
+go(void)
+{
+ int i, j, total = 0;
+
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 10; j++) {
+ total += i * j;
+ }
+ }
+
+ return (total);
+}
+
+int
+main(int argc, char **argv)
+{
+ volatile int a = 0;
+
+ while (waiting(&a) == 0)
+ continue;
+
+ (void) fork();
+ (void) go();
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.d
new file mode 100644
index 0000000..f1b1197
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.d
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: make sure fork(2) is okay
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->value = (int *)alloca(sizeof (int));
+ *this->value = 1;
+ copyout(this->value, arg0, sizeof (int));
+}
+
+proc:::create
+/pid == $1/
+{
+ child = args[0]->pr_pid;
+ trace(pid);
+}
+
+pid$1:a.out:go:
+/pid == child/
+{
+ trace("wrong pid");
+ exit(1);
+}
+
+proc:::exit
+/pid == $1 || pid == child/
+{
+ out++;
+ trace(pid);
+}
+
+proc:::exit
+/out == 2/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c
new file mode 100644
index 0000000..69df472
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <spawn.h>
+#include <signal.h>
+#include <stdio.h>
+
+void
+go(void)
+{
+ pid_t pid;
+
+ (void) posix_spawn(&pid, "/bin/ls", NULL, NULL, NULL, NULL);
+
+ (void) waitpid(pid, NULL, 0);
+}
+
+void
+intr(int sig)
+{
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = intr;
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ (void) sigaction(SIGUSR1, &sa, NULL);
+
+ for (;;) {
+ go();
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.d
new file mode 100644
index 0000000..f119098
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that we can trace every instruction safely for gcc
+ * compiled apps.
+ *
+ * SECTION: pid provider
+ *
+ */
+
+BEGIN
+{
+ /*
+ * Let's just do this for 2 seconds.
+ */
+ timeout = timestamp + 2000000000;
+}
+
+pid$1:a.out::
+{}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh
new file mode 100644
index 0000000..587878c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh
@@ -0,0 +1,41 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+#
+# Make sure we kill a process if the dtrace(1M) command fails.
+#
+
+rc=`$dtrace -c date -n jarod 2>/dev/null | /usr/bin/wc -l`
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.main.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.main.ksh
new file mode 100644
index 0000000..b3b9960
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.main.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+#
+# Make sure we can trace main:entry properly -- this was problematic because
+# we also set a breakpoint on the same spot in libdtrace.
+#
+
+$dtrace -c date -s /dev/stdin <<EOF
+ BEGIN
+ {
+ status = 1;
+ }
+
+ pid\$target::main:entry
+ {
+ status = 0;
+ }
+
+ END
+ {
+ exit(status);
+ }
+EOF
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.manypids.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.manypids.ksh
new file mode 100644
index 0000000..869339b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.manypids.ksh
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+set -A pids
+
+for lib in `ls -1 /lib/lib*.so.1 | grep -v ld.so.1`; do
+ preload=$lib:${preload}
+done
+
+export LD_PRELOAD=$preload
+
+let numkids=100
+let i=0
+
+tmpfile=/tmp/dtest.$$
+
+while [ "$i" -lt "$numkids" ]; do
+ sleep 500 &
+ pids[$i]=$!
+ let i=i+1
+done
+
+export LD_PRELOAD=
+
+let i=0
+
+echo "tick-1sec\n{\n\texit(0);\n}\n" > $tmpfile
+
+while [ "$i" -lt "$numkids" ]; do
+ echo "pid${pids[$i]}::malloc:entry\n{}\n" >> $tmpfile
+ let i=i+1
+done
+
+$dtrace -s $tmpfile
+status=$?
+
+rm $tmpfile
+pkill sleep
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh
new file mode 100644
index 0000000..35f0391
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh
@@ -0,0 +1,62 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -wZq -x switchrate=100ms -s /dev/stdin <<EOF
+pid*:date::
+{
+ printf("%s:%s\n", probefunc, probename);
+}
+
+tick-1s
+/i++ > 5/
+{
+ exit(0);
+}
+
+tick-1s
+/(i % 2) == 0/
+{
+ system("dtrace -c date -ln 'pid\$target::main:entry' >/dev/null");
+}
+
+tick-1s
+/(i % 2) == 1/
+{
+ system("dtrace -c date -ln 'pid\$target::main:return' >/dev/null");
+}
+EOF
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh.out
new file mode 100644
index 0000000..b2742c4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.newprobes.ksh.out
@@ -0,0 +1,7 @@
+main:return
+main:entry
+main:return
+main:entry
+main:return
+main:entry
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh
new file mode 100644
index 0000000..326fd1a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+#
+# Let's see if we can successfully specify a module using partial
+# matches as well as the full module name. We'll use 'libc.so.1'
+# (and therefore 'libc' and 'libc.so') as it's definitely there.
+#
+
+for lib in libc libc.so libc.so.1 'lib[c]*'; do
+ sleep 60 &
+ pid=$!
+ dtrace -n "pid$pid:$lib::entry" -n 'tick-2s{exit(0);}'
+ status=$?
+
+ kill $pid
+
+ if [ $status -gt 0 ]; then
+ exit $status
+ fi
+done
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh
new file mode 100644
index 0000000..7b0824e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that specifying a glob in a pid provider name
+# (e.g., p*d$target) works.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=${TMPDIR:-/tmp}/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main
+
+main: main.o
+ cc -o main main.o
+
+main.o: main.c
+ cc -c main.c
+EOF
+
+cat > main.c <<EOF
+void
+go(void)
+{
+}
+
+int
+main(int argc, char **argv)
+{
+ go();
+
+ return (0);
+}
+EOF
+
+make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+cat > main.d <<'EOF'
+p*d$target::go:entry
+{
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+}
+EOF
+
+script() {
+ $dtrace -q -s ./main.d -c ./main
+}
+
+script
+status=$?
+
+cd /tmp
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh
new file mode 100644
index 0000000..8951cb3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh
@@ -0,0 +1,131 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that probes will be picked up after a dlopen(3C)
+# when the pid provider is specified as a glob (e.g., p*d$target.)
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=${TMPDIR:-/tmp}/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main altlib.so
+
+main: main.o
+ cc -o main main.o
+
+main.o: main.c
+ cc -c main.c
+
+altlib.so: altlib.o
+ cc -z defs -G -o altlib.so altlib.o -lc
+
+altlib.o: altlib.c
+ cc -c altlib.c
+EOF
+
+cat > altlib.c <<EOF
+void
+go(void)
+{
+}
+EOF
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+
+void
+go(void)
+{
+}
+
+int
+main(int argc, char **argv)
+{
+ void *alt;
+ void *alt_go;
+
+ go();
+
+ if ((alt = dlopen("./altlib.so", RTLD_LAZY | RTLD_LOCAL))
+ == NULL) {
+ printf("dlopen of altlib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ if ((alt_go = dlsym(alt, "go")) == NULL) {
+ printf("failed to lookup 'go' in altlib.so\n");
+ return (1);
+ }
+
+ ((void (*)(void))alt_go)();
+
+ return (0);
+}
+EOF
+
+make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+cat > main.d <<'EOF'
+p*d$target::go:entry
+{
+ @foo[probemod, probefunc, probename] = count();
+}
+
+END
+{
+ printa("%s:%s:%s %@u\n",@foo);
+}
+EOF
+
+script() {
+ $dtrace -q -s ./main.d -c ./main
+}
+
+script
+status=$?
+
+cd /tmp
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh.out
new file mode 100644
index 0000000..824d898
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh.out
@@ -0,0 +1,3 @@
+altlib.so:go:entry 1
+main:go:entry 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh
new file mode 100644
index 0000000..49e362b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh
@@ -0,0 +1,102 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that a regex in the provider name will match
+# USDT probes as well as pid probes (e.g., p*d$target matches both
+# pid$target and pyramid$target.)
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=${TMPDIR:-/tmp}/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+ all: main
+
+main: main.o prov.o
+ cc -o main main.o prov.o
+
+main.o: main.c prov.h
+ cc -c main.c
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+prov.o: prov.d main.o
+ $dtrace -G -32 -s prov.d main.o
+EOF
+
+cat > prov.d <<EOF
+provider pyramid {
+ probe entry();
+};
+EOF
+
+cat > main.c <<EOF
+#include <sys/sdt.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ PYRAMID_ENTRY();
+}
+EOF
+
+make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+cat > main.d <<'EOF'
+p*d$target::main:entry
+{
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+}
+EOF
+
+script() {
+ $dtrace -q -s ./main.d -c ./main
+}
+
+script
+status=$?
+
+cd /tmp
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh.out
new file mode 100644
index 0000000..5a8938f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh.out
@@ -0,0 +1,3 @@
+main:main:entry
+main:main:entry
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh
new file mode 100644
index 0000000..865b9bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh
@@ -0,0 +1,154 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that USDT probes will be picked up after a dlopen(3C)
+# when a regex in the provider name matches both USDT probes and pid probes
+# (e.g., p*d$target matches both pid$target and pyramid$target.)
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=${TMPDIR:-/tmp}/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main altlib.so
+
+main: main.o provmain.o
+ cc -o main main.o provmain.o
+
+main.o: main.c prov.h
+ cc -c main.c
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+provmain.o: prov.d main.o
+ $dtrace -G -32 -o provmain.o -s prov.d main.o
+
+altlib.so: altlib.o provalt.o
+ cc -z defs -G -o altlib.so altlib.o provalt.o -lc
+
+altlib.o: altlib.c prov.h
+ cc -c altlib.c
+
+provalt.o: prov.d altlib.o
+ $dtrace -G -32 -o provalt.o -s prov.d altlib.o
+EOF
+
+cat > prov.d <<EOF
+provider pyramid {
+ probe entry();
+};
+EOF
+
+cat > altlib.c <<EOF
+#include <sys/sdt.h>
+#include "prov.h"
+
+void
+go(void)
+{
+ PYRAMID_ENTRY();
+}
+EOF
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/sdt.h>
+#include "prov.h"
+
+void
+go(void)
+{
+ PYRAMID_ENTRY();
+}
+
+int
+main(int argc, char **argv)
+{
+ void *alt;
+ void *alt_go;
+
+ go();
+
+ if ((alt = dlopen("./altlib.so", RTLD_LAZY | RTLD_LOCAL))
+ == NULL) {
+ printf("dlopen of altlib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ if ((alt_go = dlsym(alt, "go")) == NULL) {
+ printf("failed to lookup 'go' in altlib.so\n");
+ return (1);
+ }
+
+ ((void (*)(void))alt_go)();
+
+ return (0);
+}
+EOF
+
+make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+cat > main.d <<'EOF'
+p*d$target::go:entry
+{
+ @foo[probemod, probefunc, probename] = count();
+}
+
+END
+{
+ printa("%s:%s:%s %@u\n",@foo);
+}
+EOF
+
+script() {
+ $dtrace -q -s ./main.d -c ./main
+}
+
+script
+status=$?
+
+cd /tmp
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh.out
new file mode 100644
index 0000000..f471538
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh.out
@@ -0,0 +1,3 @@
+altlib.so:go:entry 2
+main:go:entry 2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.c
new file mode 100644
index 0000000..cfb88a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.c
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * The canonical name should be 'go' since we prefer symbol names with fewer
+ * leading underscores.
+ */
+
+int a = 100;
+
+int
+help(void)
+{
+ return (a);
+}
+
+int
+go(void)
+{
+ return (help() + 1);
+}
+
+static void
+handle(int sig)
+{
+ go();
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ (void) signal(SIGUSR1, handle);
+ for (;;)
+ getpid();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.d
new file mode 100644
index 0000000..0305d09
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret1.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that we get the right return value from non-leaf returns
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the first call to getpid(2).
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ i = 0;
+ raise(SIGUSR1);
+ /*
+ * Wait half a second after raising the signal.
+ */
+ timeout = timestamp + 500000000;
+}
+
+pid$1:a.out:go:return
+/arg1 == 101/
+{
+ exit(0);
+}
+
+pid$1:a.out:go:return
+{
+ printf("wrong return value: %d", arg1);
+ exit(1);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.c
new file mode 100644
index 0000000..b64aa05
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.c
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * The canonical name should be 'go' since we prefer symbol names with fewer
+ * leading underscores.
+ */
+
+int a = 100;
+
+int
+go(void)
+{
+ return (a);
+}
+
+static void
+handle(int sig)
+{
+ go();
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ (void) signal(SIGUSR1, handle);
+ for (;;)
+ getpid();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.d
new file mode 100644
index 0000000..0232948
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.ret2.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that we get the right return value from leaf returns
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the first call to getpid(2).
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ i = 0;
+ raise(SIGUSR1);
+ /*
+ * Wait half a second after raising the signal.
+ */
+ timeout = timestamp + 500000000;
+}
+
+pid$1:a.out:go:return
+/arg1 == 100/
+{
+ exit(0);
+}
+
+pid$1:a.out:go:return
+{
+ printf("wrong return value: %d", arg1);
+ exit(1);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.c
new file mode 100644
index 0000000..76fa711
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.c
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+int
+waiting(volatile int *a)
+{
+ return (*a);
+}
+
+int
+go(void)
+{
+ int i, j, total = 0;
+
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 10; j++) {
+ total += i * j;
+ }
+ }
+
+ return (total);
+}
+
+int
+main(int argc, char **argv)
+{
+ volatile int a = 0;
+
+ while (waiting(&a) == 0)
+ continue;
+
+ if (vfork() == 0) {
+ int ret = go();
+ (void) _exit(ret);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.d
new file mode 100644
index 0000000..b31bb7f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.vfork.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: make sure probes called from a vfork(2) child fire in the parent
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->value = (int *)alloca(sizeof (int));
+ *this->value = 1;
+ copyout(this->value, arg0, sizeof (int));
+}
+
+proc:::create
+/pid == $1/
+{
+ child = args[0]->pr_pid;
+}
+
+pid$1:a.out:go:
+/child != pid/
+{
+ printf("wrong pid (%d %d)", pid, child);
+ exit(1);
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.c
new file mode 100644
index 0000000..1418f2a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.c
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * The canonical name should be 'go' since we prefer symbol names with fewer
+ * leading underscores.
+ */
+
+#pragma weak _go = go
+
+int
+go(int a)
+{
+ return (a + 1);
+}
+
+static void
+handle(int sig)
+{
+ _go(1);
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ (void) signal(SIGUSR1, handle);
+ for (;;)
+ getpid();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.d
new file mode 100644
index 0000000..458eada
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak1.d
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: test that we prefer symbols with fewer underscores
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the first call to getpid(2).
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ i = 0;
+ raise(SIGUSR1);
+ /*
+ * Wait half a second after raising the signal.
+ */
+ timeout = timestamp + 500000000;
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/probefunc == "go"/
+{
+ i++;
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/probefunc == "_go"/
+{
+ trace("resolved to '_go' rather than 'go'");
+ exit(1);
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/i == 2/
+{
+ exit(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.c
new file mode 100644
index 0000000..8dabbe6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.c
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * The canonical name should be 'go' since we prefer symbol names with fewer
+ * leading underscores.
+ */
+
+#pragma weak _go = go
+
+static int
+go(int a)
+{
+ return (a + 1);
+}
+
+static void
+handle(int sig)
+{
+ _go(1);
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ (void) signal(SIGUSR1, handle);
+ for (;;)
+ getpid();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.d
new file mode 100644
index 0000000..e3688b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.weak2.d
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: check that we prefer weak symbols to local ones
+ *
+ * SECTION: pid provider
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the first call to getpid(2).
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ i = 0;
+ raise(SIGUSR1);
+ /*
+ * Wait half a second after raising the signal.
+ */
+ timeout = timestamp + 500000000;
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/probefunc == "_go"/
+{
+ i++;
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/probefunc == "go"/
+{
+ trace("resolved to '_go' rather than 'go'");
+ exit(1);
+}
+
+pid$1:a.out:go:entry,
+pid$1:a.out:_go:entry
+/i == 2/
+{
+ exit(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.d
new file mode 100644
index 0000000..6fc9f2f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: make sure the plockstat probes are present in libc.
+ */
+
+plockstat$1:libc.so.1::
+{}
+
+profile:::tick-1
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe
new file mode 100644
index 0000000..221e8b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe
@@ -0,0 +1,29 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 100000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.d
new file mode 100644
index 0000000..5f755b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: make sure the plockstat probes are present in libc.
+ */
+
+plockstat$1:libc::
+{}
+
+profile:::tick-1
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe
new file mode 100644
index 0000000..221e8b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe
@@ -0,0 +1,29 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 100000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d
new file mode 100644
index 0000000..ab4106d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.BadAlign.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: This test reproduces the alignment error.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = (int *) 64;
+ y = *x;
+ trace(y);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.ArrayVar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.ArrayVar.d
new file mode 100644
index 0000000..b683208
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.ArrayVar.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Trying to access the address of a user defined array variable should throw
+ * a D_ADDROF_VAR error.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Address Spaces
+ */
+
+#pragma D option quiet
+
+int a[5];
+int *p;
+
+BEGIN
+{
+ p = &a;
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.DynamicVar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.DynamicVar.d
new file mode 100644
index 0000000..028a30a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.DynamicVar.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Trying to access the address of a user defined dynamic variable should throw
+ * a D_ADDROF_VAR error.
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ * SECTION: Pointers and Arrays/Pointers to Dtrace Objects
+ */
+
+#pragma D option quiet
+
+int i;
+int *p;
+
+BEGIN
+{
+ i = 10;
+ p = &i;
+
+ printf("Integer: %d, Pointer: %d\n", i, *p);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.agg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.agg.d
new file mode 100644
index 0000000..8b59262
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_ADDROF_VAR.agg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test that the & operator fails with D_ADDROF_VAR if its operand
+ * is a dynamic variable such as an aggregation.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ * SECTION: Pointers and Arrays/Pointers to Dtrace Objects
+ */
+
+BEGIN
+{
+ @a = count();
+ trace(&@a);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_NONPTR.noptr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_NONPTR.noptr.d
new file mode 100644
index 0000000..96d25b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_NONPTR.noptr.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Can not dereference non-pointers
+ *
+ * SECTION: Pointers and Arrays/Pointer Safety
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int x;
+
+BEGIN
+{
+ b = *x;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_VOID.VoidPointerDeref.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_VOID.VoidPointerDeref.d
new file mode 100644
index 0000000..f2fa5b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_DEREF_VOID.VoidPointerDeref.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Cannot dereference a void * pointer.
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ */
+
+#pragma D option quiet
+
+void *p;
+
+int array[3];
+
+BEGIN
+{
+ array[0] = 234;
+ array[1] = 334;
+ array[2] = 434;
+
+ p = &array[0];
+
+ printf("array[0]: %d, p: %d\n", array[0], *p);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_ARRFUN.ArrayAssignment.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_ARRFUN.ArrayAssignment.d
new file mode 100644
index 0000000..94814a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_ARRFUN.ArrayAssignment.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Arrays may not be assigned as a whole in D.
+ *
+ * SECTION: Pointers and Arrays/Pointer and Array Relationship
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array1[3];
+int array2[3];
+
+BEGIN
+{
+ array1[0] = 200;
+ array1[1] = 400;
+ array1[2] = 600;
+
+ array2[0] = 300;
+ array2[1] = 500;
+ array2[2] = 700;
+
+ array2 = array1;
+
+ printf("array1[0]: %d\tarray2[0]: %d\n", array1[0], array2[0]);
+ printf("array1[1]: %d\tarray2[1]: %d\n", array1[1], array2[1]);
+ printf("array1[2]: %d\tarray2[2]: %d\n", array1[2], array2[2]);
+
+ exit(0);
+
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_INCOMPAT.VoidPointerArith.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_INCOMPAT.VoidPointerArith.d
new file mode 100644
index 0000000..e81c2bd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_INCOMPAT.VoidPointerArith.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * May not apply pointer arithmetic to an object of type void *
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ */
+
+#pragma D option quiet
+
+void *p;
+
+BEGIN
+{
+ printf("p: %d\n", (int) p);
+ printf("p+1: %d\n", (int) (p+1));
+ printf("p+2: %d\n", (int) (p+2));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_LVAL.AddressChange.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_LVAL.AddressChange.d
new file mode 100644
index 0000000..9828240
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_LVAL.AddressChange.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: D pointers do not allow invalid address changes.
+ *
+ * SECTION: Pointers and Arrays/Pointer Safety
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ &`kmem_flags = (int *) 0x185ede4;
+ printf("Address of kmem_flags: %d\n", (int) kmemAddress);
+ printf("Value of kmem_flags: %d\n", `kmem_flags);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.NonPointerAccess.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.NonPointerAccess.d
new file mode 100644
index 0000000..6f25327
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.NonPointerAccess.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Accessing the members of a struct using the pointer notation using a
+ * nonpointer variable throws a D_OP_PTR error.
+ *
+ * SECTION: Structs and Unions/Pointers to Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myinput_struct f;
+
+BEGIN
+{
+ f.i = 10;
+ f.c = 'c';
+
+ printf("f->i: %d\tf->c: %c\n", f->i, f->c);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.badpointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.badpointer.d
new file mode 100644
index 0000000..b1524e5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_PTR.badpointer.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * -> can only be used with pointer operands.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Address Spaces
+ */
+
+#pragma D option quiet
+
+struct teststruct {
+ int a;
+ int b;
+};
+
+struct teststruct xyz;
+
+BEGIN
+{
+ xyz->a = 1;
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.BadPointerAccess.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.BadPointerAccess.d
new file mode 100644
index 0000000..7563577
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.BadPointerAccess.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Accessing a pointer to a struct like a non pointer throws a D_OP_SOU.
+ *
+ * SECTION: Structs and Unions/Pointers to Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myinput_struct *f;
+BEGIN
+{
+ f.i = 10;
+ f.c = 'c';
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.badpointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.badpointer.d
new file mode 100644
index 0000000..1b351f3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.D_OP_SOU.badpointer.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * -> can only be used with pointer to structs and unions.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Address Spaces
+ */
+
+#pragma D option quiet
+
+int *abc;
+
+BEGIN
+{
+ abc->a = 1;
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress1.d
new file mode 100644
index 0000000..9c9d2f0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress1.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: D pointers do not allow invalid pointer accesses.
+ *
+ * SECTION: Pointers and Arrays/Pointer Safety
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ kmemAddress = &`kmem_flags;
+ *kmemAddress = 20;
+ printf("Address of kmem_flags: %d\n", (int) kmemAddress);
+ printf("Value of kmem_flags: %d\n", `kmem_flags);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d
new file mode 100644
index 0000000..324f401
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress2.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: D pointers do not allow invalid pointer accesses.
+ *
+ * SECTION: Pointers and Arrays/Pointer Safety
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = (int *)alloca(sizeof (int));
+ trace(x);
+ y = (int *) (x - 3300778156056);
+ *y = 3;
+ trace(*y);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d
new file mode 100644
index 0000000..39bd114
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress3.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: D pointers do not allow invalid pointer accesses.
+ *
+ * SECTION: Pointers and Arrays/Pointer Safety
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ y = (int *) (-33007);
+ *y = 3;
+ trace(*y);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d
new file mode 100644
index 0000000..9d6b144
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress4.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Demonstrating valid memory access.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = (int *)alloca(sizeof (int));
+ printf("Address x: %x\n", (int) x);
+ y = (int *) (x - 2);
+ *y = 3;
+ printf("Address y: %x\tValue: %d\n", (int) y, *y);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d
new file mode 100644
index 0000000..64b7728
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/err.InvalidAddress5.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using integer arithmetic providing a non-aligned memory address will throw
+ * a runtime error.
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ *
+ * NOTES:
+ * This test doesn't apply to x86; for the time being, we're working
+ * around this with the preprocessor.
+ */
+
+#pragma D option quiet
+
+int array[3];
+uintptr_t uptr;
+int *p;
+int *q;
+int *r;
+
+BEGIN
+{
+#ifdef __i386
+ exit(1);
+#else
+ array[0] = 20;
+ array[1] = 40;
+ array[2] = 80;
+
+ uptr = (uintptr_t) &array[0];
+
+ p = (int *) (uptr);
+ q = (int *) (uptr + 2);
+ r = (int *) (uptr + 3);
+
+ printf("array[0]: %d\t*p: %d\n", array[0], *p);
+ printf("array[1]: %d\t*q: %d\n", array[1], *q);
+ printf("array[2]: %d\t*r: %d\n", array[2], *r);
+
+ exit(0);
+#endif
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer1.d
new file mode 100644
index 0000000..fb9db75
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer1.d
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Declare arrays of different data types and verify that the
+ * addresses of the individual elements differ by an amount equal to the number
+ * elements separating them multiplied by the size of each element.
+ *
+ * SECTION: Pointers and Arrays/Array Declarations and Storage;
+ * Pointers and Arrays/Pointer Arithmetic
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+char char_array[5];
+short short_array[5];
+int int_array[5];
+long long_array[5];
+long long long_long_array[5];
+int8_t int8_array[5];
+int16_t int16_array[5];
+int32_t int32_array[5];
+int64_t int64_array[5];
+intptr_t intptr_array[5];
+uint8_t uint8_array[5];
+uint16_t uint16_array[5];
+uint32_t uint32_array[5];
+uint64_t uint64_array[5];
+uintptr_t uintptr_array[5];
+
+/*
+float float_array[5];
+double double_array[5];
+long double long_double_array[5];
+
+string string_array[5];
+*/
+
+struct record {
+ char ch;
+ int in;
+} struct_array[5];
+
+struct {
+ char ch;
+ int in;
+} anon_struct_array[5];
+
+union record {
+ char ch;
+ int in;
+} union_array[5];
+
+union {
+ char ch;
+ int in;
+} anon_union_array[5];
+
+enum colors {
+ RED,
+ GREEN,
+ BLUE
+} enum_array[5];
+
+BEGIN
+{
+ char_var0 = &char_array[0]; char_var2 = &char_array[2];
+ short_var0 = &short_array[0]; short_var3 = &short_array[3];
+ int_var3 = &int_array[3]; int_var5 = &int_array[5];
+
+ long_var0 = &long_array[0]; long_var4 = &long_array[4];
+ long_long_var0 = &long_long_array[0];
+ long_long_var2 = &long_long_array[2];
+ int8_var3 = &int8_array[3]; int8_var5 = &int8_array[5];
+
+ int16_var0 = &int16_array[0]; int16_var4 = &int16_array[4];
+ int32_var0 = &int32_array[0]; int32_var3 = &int32_array[3];
+ int64_var0 = &int64_array[0]; int64_var1 = &int64_array[1];
+
+ uintptr_var0 = &uintptr_array[0]; uintptr_var2 = &uintptr_array[2];
+ struct_var0 = &struct_array[0]; struct_var2 = &struct_array[2];
+ anon_struct_var3 = &anon_struct_array[3];
+ anon_struct_var5 = &anon_struct_array[5];
+
+ union_var0 = &union_array[0]; union_var3 = &union_array[3];
+ anon_union_var0 = &anon_union_array[0];
+ anon_union_var4 = &anon_union_array[4];
+ enum_var0 = &enum_array[0]; enum_var2 = &enum_array[2];
+
+ printf("char_var2 - char_var0: %d\n",
+ (int) char_var2 - (int) char_var0);
+ printf("short_var3 - short_var0: %d\n",
+ (int) short_var3 - (int) short_var0);
+ printf("int_var5 - int_var3: %d\n", (int) int_var5 - (int) int_var3);
+
+ printf("long_var4 - long_var0: %d\n",
+ (int) long_var4 - (int) long_var0);
+ printf("long_long_var2 - long_long_var0: %d\n",
+ (int) long_long_var2 - (int) long_long_var0);
+ printf("int8_var5 - int8_var3: %d\n",
+ (int) int8_var5 - (int) int8_var3);
+
+ printf("int16_var4 - int16_var0: %d\n",
+ (int) int16_var4 - (int) int16_var0);
+ printf("int32_var3 - int32_var0: %d\n",
+ (int) int32_var3 - (int) int32_var0);
+ printf("int64_var1 - int64_var0: %d\n",
+ (int) int64_var1 - (int) int64_var0);
+
+ printf("uintptr_var2 - uintptr_var0: %d\n",
+ (int) uintptr_var2 - (int) uintptr_var0);
+ printf("struct_var2 - struct_var0: %d\n",
+ (int) struct_var2 - (int) struct_var0);
+ printf("anon_struct_var5 - anon_struct_var3: %d\n",
+ (int) anon_struct_var5 - (int) anon_struct_var3);
+
+ printf("union_var3 - union_var0: %d\n",
+ (int) union_var3 - (int) union_var0);
+ printf("anon_union_var4 - anon_union_var0: %d\n",
+ (int) anon_union_var4 - (int) anon_union_var0);
+ printf("enum_var2 - enum_var0: %d\n",
+ (int) enum_var2 - (int) enum_var0);
+ exit(0);
+}
+
+END
+/(2 != ((int) char_var2 - (int) char_var0)) ||
+ (6 != ((int) short_var3 - (int) short_var0)) ||
+ (8 != ((int) int_var5 - (int) int_var3)) ||
+ ((32 != ((int) long_var4 - (int) long_var0)) &&
+ (16 != ((int) long_var4 - (int) long_var0))) ||
+ (16 != ((int) long_long_var2 - (int) long_long_var0)) ||
+ (2 != ((int) int8_var5 - (int) int8_var3))
+ || (8 != ((int) int16_var4 - (int) int16_var0)) ||
+ (12 != ((int) int32_var3 - (int) int32_var0)) ||
+ (8 != ((int) int64_var1 - (int) int64_var0)) ||
+ ((16 != ((int) uintptr_var2 - (int) uintptr_var0))
+ && (8 != ((int) uintptr_var2 - (int) uintptr_var0))) ||
+ (16 != ((int) struct_var2 - (int) struct_var0)) ||
+ (16 != ((int) anon_struct_var5 - (int) anon_struct_var3))
+ || (12 != ((int) union_var3 - (int) union_var0)) ||
+ (16 != ((int) anon_union_var4 - (int) anon_union_var0)) ||
+ (8 != ((int) enum_var2 - (int) enum_var0))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer2.d
new file mode 100644
index 0000000..bf64539
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer2.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: D permits the use of array [] index notation with both pointer
+ * variables and array variables.
+ *
+ * SECTION: Pointers and Arrays/Pointer and Array Relationship
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array[5];
+BEGIN
+{
+ array[0] = 100;
+ array[1] = 200;
+ array[2] = 300;
+ array[3] = 400;
+ array[4] = 500;
+
+ p = &array[0];
+
+ printf("array[0]: %d\tp[0]: %d\n", array[0], p[0]);
+ printf("array[1]: %d\tp[1]: %d\n", array[1], p[1]);
+ printf("array[2]: %d\tp[2]: %d\n", array[2], p[2]);
+ printf("array[3]: %d\tp[3]: %d\n", array[3], p[3]);
+ printf("array[4]: %d\tp[4]: %d\n", array[4], p[4]);
+
+ exit(0);
+
+}
+
+END
+/(array[0] != p[0]) || (array[1] != p[1]) || (array[2] != p[2]) ||
+ (array[3] != p[3]) || (array[4] != p[4])/
+{
+ printf("Error");
+ exit(1);
+}
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer3.d
new file mode 100644
index 0000000..a0be130
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ArrayPointer3.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: In D, the an array variable can be assigned to a pointer.
+ *
+ * SECTION: Pointers and Arrays/Pointer and Array Relationship
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array[5];
+int *p;
+
+BEGIN
+{
+ array[0] = 100;
+ array[1] = 200;
+ array[2] = 300;
+ array[3] = 400;
+ array[4] = 500;
+
+ p = array;
+
+ printf("array[0]: %d\tp[0]: %d\n", array[0], p[0]);
+ printf("array[1]: %d\tp[1]: %d\n", array[1], p[1]);
+ printf("array[2]: %d\tp[2]: %d\n", array[2], p[2]);
+ printf("array[3]: %d\tp[3]: %d\n", array[3], p[3]);
+ printf("array[4]: %d\tp[4]: %d\n", array[4], p[4]);
+
+ exit(0);
+
+}
+
+END
+/(array[0] != p[0]) || (array[1] != p[1]) || (array[2] != p[2]) ||
+ (array[3] != p[3]) || (array[4] != p[4])/
+{
+ printf("Error");
+ exit(1);
+}
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.GlobalVar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.GlobalVar.d
new file mode 100644
index 0000000..8b7f36e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.GlobalVar.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Pointer declarations are global.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ kmemAddress = &`kmem_flags;
+ kmemValue = *kmemAddress;
+ printf("Address of kmem_flags: %x\n", (int) kmemAddress);
+ printf("Value of kmem_flags: %d\n", kmemValue);
+}
+
+profile:::tick-1sec
+/(i < 1) && (&`kmem_flags == kmemAddress) && (*kmemAddress == kmemValue)/
+{
+ exit(1);
+}
+
+END
+/(&`kmem_flags == kmemAddress) && (*kmemAddress == kmemValue)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.IntegerArithmetic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.IntegerArithmetic1.d
new file mode 100644
index 0000000..99cbd7e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.IntegerArithmetic1.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Integer arithmetic can be performed on pointers by casting to uintptr_t.
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array[3];
+uintptr_t uptr;
+int *p;
+int *q;
+int *r;
+
+BEGIN
+{
+ array[0] = 20;
+ array[1] = 40;
+ array[2] = 80;
+
+ uptr = (uintptr_t) &array[0];
+
+ p = (int *) (uptr);
+ q = (int *) (uptr + 4);
+ r = (int *) (uptr + 8);
+
+ printf("array[0]: %d\t*p: %d\n", array[0], *p);
+ printf("array[1]: %d\t*q: %d\n", array[1], *q);
+ printf("array[2]: %d\t*r: %d\n", array[2], *r);
+
+ exit(0);
+}
+
+END
+/(20 != *p) || (40 != *q) || (80 != *r)/
+{
+ printf("Error");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic1.d
new file mode 100644
index 0000000..3a96832
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic1.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Pointer arithmetic implicitly adjusts the underlying address by
+ * multiplying or dividing the operands by the size of the type referenced
+ * by the pointer.
+ *
+ * SECTION: Pointers and Arrays/Pointer Arithmetic
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int *x;
+
+BEGIN
+{
+ printf("x: %x\n", (int) x);
+ printf("x + 1: %x\n", (int) (x+1));
+ printf("x + 2: %x\n", (int) (x+2));
+ exit(0);
+}
+
+END
+/(0 != (int) x) || (4 != (int) (x+1)) || (8 != (int) (x+2))/
+{
+ printf("Error");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic2.d
new file mode 100644
index 0000000..ac55eb4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic2.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * D pointers can be used to refer to consecutive storage locations like
+ * arrays.
+ *
+ * SECTION: Pointers and Arrays/Pointer and Array Relationship
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array[5];
+BEGIN
+{
+ array[0] = 100;
+ array[1] = 200;
+ array[2] = 300;
+ array[3] = 400;
+ array[4] = 500;
+
+ p = &array[0];
+
+ printf("array[0]: %d\t*p: %d\n", array[0], *p);
+ printf("array[1]: %d\t*(p+1): %d\n", array[1], *(p+1));
+ printf("array[2]: %d\t*(p+2): %d\n", array[2], *(p+2));
+ printf("array[3]: %d\t*(p+3): %d\n", array[3], *(p+3));
+ printf("array[4]: %d\t*(p+4): %d\n", array[4], *(p+4));
+
+ exit(0);
+
+}
+
+END
+/(array[0] != *p) || (array[1] != *(p+1)) || (array[2] != *(p+2))
+ || (array[3] != *(p+3)) || (array[4] != *(p+4))/
+{
+ printf("Error");
+ exit(1);
+}
+
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic3.d
new file mode 100644
index 0000000..a4f4bfc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerArithmetic3.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Pointer arithmetic implicitly adjusts the underlying address by
+ * multiplying or dividing the operands by the size of the type referenced
+ * by the pointer.
+ *
+ * SECTION: Pointers and Arrays/Pointer Arithmetic
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int *x;
+int *y;
+int a[5];
+
+BEGIN
+{
+ x = &a[0];
+ y = &a[2];
+
+ printf("y-x: %x\n", (int) (y-x));
+ exit(0);
+}
+
+END
+/(2 != (int) (y-x)) /
+{
+ printf("Error");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerAssignment.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerAssignment.d
new file mode 100644
index 0000000..3a49686
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.PointerAssignment.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Pointers assignment simply copies over the pointer address in the
+ * variable on the right hand side into the variable on the left hand side.
+ *
+ * SECTION: Pointers and Arrays/Pointer and Array Relationship
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+int array[3];
+int *ptr1;
+int *ptr2;
+
+BEGIN
+{
+ array[0] = 200;
+ array[1] = 400;
+ array[2] = 600;
+
+ ptr1 = array;
+ ptr2 = ptr1;
+
+ ptr2[0] = 400;
+ ptr2[1] = 800;
+ ptr2[2] = 1200;
+
+ printf("array[0]: %d\tptr2[0]: %d\n", array[0], ptr2[0]);
+ printf("array[1]: %d\tptr2[1]: %d\n", array[1], ptr2[1]);
+ printf("array[2]: %d\tptr2[2]: %d\n", array[2], ptr2[2]);
+
+ exit(0);
+
+}
+
+END
+/(array[0] != 400) || (array[1] != 800) || (array[2] != 1200)/
+{
+ printf("Error");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer1.d
new file mode 100644
index 0000000..5d9db38
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer1.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Demonstrating valid memory access.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = (int *)alloca(sizeof (int));
+ printf("Address x: %x\n", (int) x);
+ y = (int *) (x);
+ *y = 3;
+ printf("Address y: %x\tValue: %d\n", (int) y, *y);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer2.d
new file mode 100644
index 0000000..26d698a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.ValidPointer2.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Demonstrating valid memory access.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = (int *)alloca(sizeof (int));
+ printf("Address x: %x\n", (int) x);
+ y = (int *) (x + 2);
+ *y = 3;
+ printf("Address y: %x\tValue: %d\n", (int) y, *y);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.VoidCast.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.VoidCast.d
new file mode 100644
index 0000000..296fdf4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.VoidCast.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Can dereference a void * pointer only by casting it to another type.
+ *
+ * SECTION: Pointers and Arrays/Generic Pointers
+ */
+
+#pragma D option quiet
+
+void *p;
+
+int array[3];
+
+BEGIN
+{
+ array[0] = 234;
+ array[1] = 334;
+ array[2] = 434;
+
+ p = &array[0];
+ newp = (int *) p;
+
+ printf("array[0]: %d, newp: %d\n", array[0], *newp);
+ exit(0);
+}
+
+END
+/234 != *newp/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic1.d
new file mode 100644
index 0000000..bf3154a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic1.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Pointers can be stored in variables.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ kmemAddress = &`kmem_flags;
+ kmemValue = *kmemAddress;
+ printf("Address of kmem_flags: %x\n", (int) kmemAddress);
+ printf("Value of kmem_flags: %d\n", kmemValue);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic2.d
new file mode 100644
index 0000000..6b72b63
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pointers/tst.basic2.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Pointers can be stored in associative arrays.
+ *
+ * SECTION: Pointers and Arrays/Pointers and Addresses
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ assoc_array["kmemAddress"] = &`kmem_flags;
+ kmemValue = *(assoc_array["kmemAddress"]);
+ printf("Address of kmem_flags: %x\n", (int) assoc_array["kmemAddress"]);
+ printf("Value of kmem_flags: %d\n", kmemValue);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGERR.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGERR.d
new file mode 100644
index 0000000..863ddc8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGERR.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify pragma errors
+ *
+ * SECTION: Pragmas
+ */
+
+
+#pragma D error "this is an error message"
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_DEPEND.main.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_DEPEND.main.d
new file mode 100644
index 0000000..0b5a340
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_DEPEND.main.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * It isn't permitted for a main program to contain a depends_on imperative.
+ */
+
+#pragma D depends_on library net.d
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_INVAL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_INVAL.d
new file mode 100644
index 0000000..c6fd147
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_INVAL.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify invalid attributes
+ *
+ * SECTION: Pragmas;
+ * Stabilty/Interface Attributes
+ */
+
+
+inline int foo
+
+#pragma D attributes incorrect_attr foo
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_MALFORM.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_MALFORM.d
new file mode 100644
index 0000000..7f0ba23
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_MALFORM.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify malformed pragma argument list
+ *
+ * SECTION: Pragmas
+ */
+
+
+#pragma D attributes incorrect_attr
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_UNUSED.UnusedPragma.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_UNUSED.UnusedPragma.d
new file mode 100644
index 0000000..da2336b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.D_PRAGMA_UNUSED.UnusedPragma.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Unused pragmas throw error D_PRAGMA_UNUSED
+ *
+ * SECTION: Errtags/D_PRAGMA_UNUSED
+ *
+ */
+
+void func(int, int);
+
+#pragma D option quiet
+#pragma D attributes Stable/Stable/Common func;
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.circlibdep.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.circlibdep.ksh
new file mode 100644
index 0000000..6fbace8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.circlibdep.ksh
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+libdir=${TMPDIR:-/tmp}/libdep.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdir
+ cat > $libdir/liba.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+EOF
+ cat > $libdir/libb.$$.d <<EOF
+#pragma D depends_on library libc.$$.d
+EOF
+ cat > $libdir/libc.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdir -e
+
+status=$?
+rm -rf $libdir
+return $status
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.invalidlibdep.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.invalidlibdep.ksh
new file mode 100644
index 0000000..b05ae3d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/err.invalidlibdep.ksh
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+libdir=${TMPDIR:-/tmp}/libdep.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdir
+ cat > $libdir/liba.$$.d <<EOF
+#pragma D depends_on library libnotthere.$$.d
+EOF
+ cat > $libdir/libb.$$.d <<EOF
+#pragma D depends_on library libc.$$.d
+EOF
+ cat > $libdir/libc.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdir -e
+
+status=$?
+rm -rf $libdir
+return $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libchain.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libchain.ksh
new file mode 100644
index 0000000..7c92243
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libchain.ksh
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+libdir=${TMPDIR:-/tmp}/libdep.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdir
+ cat > $libdir/liba.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+
+inline int foo = bar;
+EOF
+ cat > $libdir/libb.$$.d <<EOF
+#pragma D depends_on module doogle_knows_all_probes
+
+inline int bar = 0xd0061e;
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdir -e
+
+status=$?
+rm -rf $libdir
+return $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdep.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdep.ksh
new file mode 100644
index 0000000..38b3460
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdep.ksh
@@ -0,0 +1,66 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+libdir=${TMPDIR:-/tmp}/libdep.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdir
+ cat > $libdir/liba.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+#pragma D depends_on library libc.$$.d
+#pragma D depends_on library libd.$$.d
+EOF
+ cat > $libdir/libb.$$.d <<EOF
+#pragma D depends_on library libc.$$.d
+EOF
+ cat > $libdir/libc.$$.d <<EOF
+EOF
+ cat > $libdir/libd.$$.d <<EOF
+EOF
+ cat > $libdir/libe.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+ cat > $libdir/libf.$$.d <<EOF
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdir -e
+
+status=$?
+rm -rf $libdir
+return $status
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepfullyconnected.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepfullyconnected.ksh
new file mode 100644
index 0000000..e95de69
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepfullyconnected.ksh
@@ -0,0 +1,100 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that we can generate the correct ordering for
+# a given dependency specification. All files either have a dependency
+# on another file or are the dependent of another file. In this way we
+# guarantee consistent ordering as no nodes in the dependency graph will
+# be isolated.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+tmpfile=/tmp/libdeporder.$$
+libdir=${TMPDIR:-/tmp}/libdep.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdir
+ cat > $libdir/liba.$$.d <<EOF
+#pragma D depends_on library libd.$$.d
+EOF
+ cat > $libdir/libb.$$.d <<EOF
+EOF
+ cat > $libdir/libc.$$.d <<EOF
+#pragma D depends_on library libe.$$.d
+EOF
+ cat > $libdir/libd.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+EOF
+ cat > $libdir/libe.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+}
+
+
+setup_libs
+
+DTRACE_DEBUG=1 $dtrace -L$libdir -e >$tmpfile 2>&1
+
+perl /dev/stdin $tmpfile <<EOF
+
+ @order = qw(libc libe liba libd libb);
+
+ while (<>) {
+ if (\$_ =~ /lib[a-e]\.[0-9]+.d/) {
+ \$pos = length \$_;
+ for (\$i=0; \$i<=1;\$i++) {
+ \$pos = rindex(\$_, "/", \$pos);
+ \$pos--;
+ }
+
+ push(@new, substr(\$_, \$pos+2, 4));
+ next;
+ }
+ next;
+ }
+
+ exit 1 if @new != @order;
+
+ while (@new) {
+ exit 1 if pop(@new) ne pop(@order);
+ }
+
+ exit 0;
+EOF
+
+
+status=$?
+rm -rf $libdir
+rm $tmpfile
+return $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
new file mode 100644
index 0000000..ced6584
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
@@ -0,0 +1,76 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Test to catch that we properly look for libraries dependencies in
+# our full library parth
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+libdira=${TMPDIR:-/tmp}/libdepa.$$
+libdirb=${TMPDIR:-/tmp}/libdepb.$$
+libdirc=${TMPDIR:-/tmp}/libdepc.$$
+dtrace=$1
+
+setup_libs()
+{
+ mkdir $libdira
+ mkdir $libdirb
+ mkdir $libdirc
+ cat > $libdira/liba.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+#pragma D depends_on library libc.$$.d
+#pragma D depends_on library libd.$$.d
+EOF
+ cat > $libdirb/libb.$$.d <<EOF
+#pragma D depends_on library libc.$$.d
+EOF
+ cat > $libdirb/libc.$$.d <<EOF
+EOF
+ cat > $libdirb/libd.$$.d <<EOF
+EOF
+ cat > $libdirc/libe.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+ cat > $libdirc/libf.$$.d <<EOF
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdira -L$libdirb -L$libdirc -e
+
+status=$?
+rm -rf $libdira
+rm -rf $libdirb
+rm -rf $libdirc
+return $status
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_PRED_SCALAR.NonScalarPred.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_PRED_SCALAR.NonScalarPred.d
new file mode 100644
index 0000000..5f02b7a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_PRED_SCALAR.NonScalarPred.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Predicate result must be of scalar type.
+ *
+ * SECTION: Errtags/ D_PRED_SCALAR
+ *
+ */
+
+#pragma D option quiet
+int a[4];
+
+BEGIN
+/a/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.invalid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.invalid.d
new file mode 100644
index 0000000..391d425
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.invalid.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple if,then operation test.
+ * Call invalid conditions and make sure it gives compilation error.
+ *
+ * SECTION: Program Structure/Predicates
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile-1
+/i < != > 10/
+{
+ i++;
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.operr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.operr.d
new file mode 100644
index 0000000..8ffab27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/err.D_SYNTAX.operr.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple if,then operations test.
+ * Call impossible conditions and make sure compilation fails.
+ *
+ * SECTION: Program Structure/Predicates
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile-1
+/i != 0 && >= 5 || <= 10/
+{
+ i++;
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.argsnotcached.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.argsnotcached.d
new file mode 100644
index 0000000..f461c5d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.argsnotcached.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+int schedules;
+int executes;
+
+/*
+ * This script is a bit naughty: it's assuming the implementation of the
+ * VM system's page scanning. If this implementation changes -- either by
+ * changing the function that scans pages or by making that scanning
+ * multithreaded -- this script will break.
+ */
+fbt::timeout:entry
+/args[0] == (void *)&genunix`schedpaging/
+{
+ schedules++;
+}
+
+fbt::schedpaging:entry
+/executes == 10/
+{
+ printf("%d schedules, %d executes\n", schedules, executes);
+ exit(executes == schedules ? 0 : 1);
+}
+
+fbt::schedpaging:entry
+{
+ executes++;
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d
new file mode 100644
index 0000000..9b43b61
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple if,then operations test.
+ * Call simple expressions and make sure test satisfy conditions.
+ * Match expected output in tst.basics.d.out
+ *
+ * SECTION: Program Structure/Predicates
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i < 10/
+{
+ i++;
+ trace(i);
+}
+
+tick-10ms
+/i == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d.out
new file mode 100644
index 0000000..2a5b99a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.basics.d.out
@@ -0,0 +1 @@
+12345678910
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d
new file mode 100644
index 0000000..d08543f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d
@@ -0,0 +1,126 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Complex operations and if,then test.
+ * Call 'n' permutation and combination of operations over if,then.
+ * Match expected output in tst.complex.d.out
+ *
+ * SECTION: Program Structure/Predicates
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ j = 0;
+}
+
+tick-10ms
+/i < 10/
+{
+ i++;
+ j++;
+ printf("\n\n%d\n------\n", i);
+}
+
+tick-10ms
+/i == 5 || i == 10/
+{
+ printf("i == 5 (or) i == 10\n");
+}
+
+tick-10ms
+/i <= 5/
+{
+ printf("i <= 5\n");
+}
+
+tick-10ms
+/j >= 5/
+{
+ printf("j >= 5\n");
+}
+
+tick-10ms
+/j >= 5 || i <= 5/
+{
+ printf("i >= 5 || j >= 5\n");
+}
+
+tick-10ms
+/j >= 5 && i <= 5/
+{
+ printf("j >= 5 && i <= 55\n");
+}
+
+tick-10ms
+/i < 5/
+{
+ printf("i < 5\n");
+}
+
+tick-10ms
+/i == 2 || j == 2/
+{
+ printf("i == 2 (or) j == 2\n");
+}
+
+tick-10ms
+/i == 2 && j == 2/
+{
+ printf("i == 2 (and) j == 2\n");
+}
+
+tick-10ms
+/j != 10/
+{
+ printf("j != 10\n");
+}
+
+tick-10ms
+/j == 5 || i == 2/
+{
+ printf("j == 5 || i == 2\n");
+}
+
+tick-10ms
+/j == 5 && i == 2/
+{
+ printf("j == 5 && i == 2\n");
+}
+
+tick-10ms
+/i == 10/
+{
+ printf("i == 10\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d.out
new file mode 100644
index 0000000..5f16dbd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.complex.d.out
@@ -0,0 +1,83 @@
+
+
+1
+------
+i <= 5
+i >= 5 || j >= 5
+i < 5
+j != 10
+
+
+2
+------
+i <= 5
+i >= 5 || j >= 5
+i < 5
+i == 2 (or) j == 2
+i == 2 (and) j == 2
+j != 10
+j == 5 || i == 2
+
+
+3
+------
+i <= 5
+i >= 5 || j >= 5
+i < 5
+j != 10
+
+
+4
+------
+i <= 5
+i >= 5 || j >= 5
+i < 5
+j != 10
+
+
+5
+------
+i == 5 (or) i == 10
+i <= 5
+j >= 5
+i >= 5 || j >= 5
+j >= 5 && i <= 55
+j != 10
+j == 5 || i == 2
+
+
+6
+------
+j >= 5
+i >= 5 || j >= 5
+j != 10
+
+
+7
+------
+j >= 5
+i >= 5 || j >= 5
+j != 10
+
+
+8
+------
+j >= 5
+i >= 5 || j >= 5
+j != 10
+
+
+9
+------
+j >= 5
+i >= 5 || j >= 5
+j != 10
+
+
+10
+------
+i == 5 (or) i == 10
+j >= 5
+i >= 5 || j >= 5
+i == 10
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh
new file mode 100644
index 0000000..f06edcb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/predicates/tst.predcache.ksh
@@ -0,0 +1,197 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+unload()
+{
+ #
+ # Get the list of services whose processes have USDT probes. Ideally
+ # it would be possible to unload the fasttrap provider while USDT
+ # probes exist -- once that fix is integrated, this hack can go away
+ # We create two lists -- one of regular SMF services and one of legacy
+ # services -- since each must be enabled and disabled using a specific
+ # mechanism.
+ #
+ pids=$(dtrace -l | \
+ perl -ne 'print "$1\n" if (/^\s*\S+\s+\S*\D(\d+)\s+/);' | \
+ sort | uniq | tr '\n' ',')
+
+ ctids=$(ps -p $pids -o ctid | tail +2 | sort | uniq)
+ svcs=
+ lrcs=
+
+ for ct in $ctids
+ do
+ line=$(svcs -o fmri,ctid | grep " $ct\$")
+ svc=$(echo $line | cut -d' ' -f1)
+
+ if [[ $(svcs -Ho STA $svc) == "LRC" ]]; then
+ lrc=$(svcs -Ho SVC $svc | tr _ '?')
+ lrcs="$lrcs $lrc"
+ else
+ svcs="$svcs $svc"
+ fi
+ done
+
+ for svc in $svcs
+ do
+ svcadm disable -ts $svc
+ done
+
+ for lrc in $lrcs
+ do
+ #
+ # Does it seem a little paternalistic that lsvcrun requires
+ # this environment variable to be set? I'd say so...
+ #
+ SMF_RESTARTER=svc:/system/svc/restarter:default \
+ /lib/svc/bin/lsvcrun $lrc stop
+ done
+
+ modunload -i 0
+ modunload -i 0
+ modunload -i 0
+ modinfo | grep dtrace
+ success=$?
+
+ for svc in $svcs
+ do
+ svcadm enable -ts $svc
+ done
+
+ for lrc in $lrcs
+ do
+ SMF_RESTARTER=svc:/system/svc/restarter:default \
+ /lib/svc/bin/lsvcrun $lrc start
+ done
+
+ if [ ! $success ]; then
+ echo $tst: could not unload dtrace
+ exit 1
+ fi
+}
+
+script1()
+{
+ $dtrace -s /dev/stdin <<EOF
+ syscall:::entry
+ /pid != $ppid/
+ {
+ @a[probefunc] = count();
+ }
+
+ tick-1sec
+ /i++ == 5/
+ {
+ exit(0);
+ }
+EOF
+}
+
+script2()
+{
+ $dtrace -s /dev/stdin <<EOF
+
+ #pragma D option statusrate=1ms
+
+ syscall:::entry
+ /pid == $ppid/
+ {
+ ttl++;
+ }
+
+ tick-1sec
+ /i++ == 5/
+ {
+ exit(2);
+ }
+
+ END
+ /ttl/
+ {
+ printf("success; ttl is %d", ttl);
+ exit(0);
+ }
+
+ END
+ /ttl == 0/
+ {
+ printf("error -- total should be non-zero");
+ exit(1);
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+ppid=$$
+dtrace=$1
+
+unload
+script1 &
+child=$!
+
+let waited=0
+
+while [ "$waited" -lt 5 ]; do
+ seconds=`date +%S`
+
+ if [ "$seconds" -ne "$last" ]; then
+ last=$seconds
+ let waited=waited+1
+ fi
+done
+
+wait $child
+status=$?
+
+if [ "$status" -ne 0 ]; then
+ echo $tst: first dtrace failed
+ exit $status
+fi
+
+unload
+script2 &
+child=$!
+
+let waited=0
+
+while [ "$waited" -lt 10 ]; do
+ seconds=`date +%S`
+
+ if [ "$seconds" -ne "$last" ]; then
+ last=$seconds
+ let waited=waited+1
+ fi
+done
+
+wait $child
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_IDENT_UNDEF.afterprobe.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_IDENT_UNDEF.afterprobe.d
new file mode 100644
index 0000000..ac63b43
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_IDENT_UNDEF.afterprobe.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ *
+ * Declare 'ifdef' statements after probe clause definition and
+ * attempt to print the value before that.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
+#if !defined (FLAG)
+#define VALUE 5
+#endif
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_PRAGCTL_INVAL.tabdefine.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_PRAGCTL_INVAL.tabdefine.d
new file mode 100644
index 0000000..e79ad2e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_PRAGCTL_INVAL.tabdefine.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call #define statement not in first column, just after a tab.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+ #define VALUE 5
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The VALUE is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_SYNTAX.withoutpound.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_SYNTAX.withoutpound.d
new file mode 100644
index 0000000..aac2bcf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.D_SYNTAX.withoutpound.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Just call a 'define' statement without '#'
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+define VALUE 5
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.defincomp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.defincomp.d
new file mode 100644
index 0000000..750ce6d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.defincomp.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a incomplete #define statement
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#define
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefelsenotendif.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefelsenotendif.d
new file mode 100644
index 0000000..6ad696a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefelsenotendif.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call ifdef statement without endif statement.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG)
+#define RETURN 5
+#else
+#define RETURN 10
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", RETURN);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefincomp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefincomp.d
new file mode 100644
index 0000000..37c637c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefincomp.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call a 'if !defined' incomplete statement.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined
+#define VALUE 5
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefnotendif.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefnotendif.d
new file mode 100644
index 0000000..09fdb17
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.ifdefnotendif.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call a complete '!ifdefine' statement but without 'endif' statement.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG)
+#define VALUE 5
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.incompelse.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.incompelse.d
new file mode 100644
index 0000000..ee92f69
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.incompelse.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Just call a #else statement
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#else
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.mulelse.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.mulelse.d
new file mode 100644
index 0000000..958f4e2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/err.mulelse.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Attempt to declare a multiple else 'ifdef' declarations.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#else
+#define VALUE 15
+#else
+#define VALUE 20
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d
new file mode 100644
index 0000000..a17ee0e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple test to test 'if defined' 'defined' 'else' 'endif'
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d.out
new file mode 100644
index 0000000..2bde5e9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifdef.d.out
@@ -0,0 +1,2 @@
+The value is 10
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d
new file mode 100644
index 0000000..b40cf01
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple test for 'ifndef'.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#ifndef FLAG
+#define FLAG
+#endif
+
+#if defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d.out
new file mode 100644
index 0000000..d51d19f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifndef.d.out
@@ -0,0 +1,2 @@
+The value is 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d
new file mode 100644
index 0000000..345a82f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple if !defined, define, else and endif test
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d.out
new file mode 100644
index 0000000..d51d19f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.ifnotdef.d.out
@@ -0,0 +1,2 @@
+The value is 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d
new file mode 100644
index 0000000..c8ea348
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple !defined, logical 'and' (&&) test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG) && !defined(STATUS)
+#define VALUE 0
+#else
+#define VALUE 1
+#endif
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d.out
new file mode 100644
index 0000000..350295c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicaland.d.out
@@ -0,0 +1,2 @@
+The value is 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d
new file mode 100644
index 0000000..63637d3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple !defined logical-or(||) and logical-and(&&) test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG) || !defined(STATUS) && !defined(STATE)
+#define VALUE 0
+#else
+#define VALUE 1
+#endif
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d.out
new file mode 100644
index 0000000..350295c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalandor.d.out
@@ -0,0 +1,2 @@
+The value is 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d
new file mode 100644
index 0000000..b99ee1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * if !defined (logical-or) usage.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG) || !defined(STATUS)
+#define VALUE 0
+#else
+#define VALUE 1
+#endif
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d.out
new file mode 100644
index 0000000..350295c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.logicalor.d.out
@@ -0,0 +1,2 @@
+The value is 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d
new file mode 100644
index 0000000..9bca2cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * if !defined multiple logical-and(&&) usage.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG) && !defined(STATUS) && !defined(STATE)
+#define VALUE 0
+#else
+#define VALUE 1
+#endif
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d.out
new file mode 100644
index 0000000..350295c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.muland.d.out
@@ -0,0 +1,2 @@
+The value is 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d
new file mode 100644
index 0000000..1d0c4d9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple multiple ifdefined logical-or(||) test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if !defined (FLAG) || !defined(STATUS) || !defined(STATE)
+#define VALUE 0
+#else
+#define VALUE 1
+#endif
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d.out
new file mode 100644
index 0000000..350295c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.mulor.d.out
@@ -0,0 +1,2 @@
+The value is 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d
new file mode 100644
index 0000000..1d21d47
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple #define test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#define value 5
+
+
+#pragma D option quiet
+
+tick-10ms
+/value == 5/
+{
+ printf("The value is %d\n", value);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d.out
new file mode 100644
index 0000000..d51d19f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.precondi.d.out
@@ -0,0 +1,2 @@
+The value is 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.predicatedeclare.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.predicatedeclare.d
new file mode 100644
index 0000000..db5e94b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.predicatedeclare.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Attempt to declare 'ifdef' statement inbetween probe declaration
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+#if !defined (FLAG)
+#define VALUE 5
+#endif
+{
+
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d
new file mode 100644
index 0000000..044e5a1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple #define and predicates test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#define MAXVAL 10 * 15
+
+
+#pragma D option quiet
+
+tick-10ms
+/MAXVAL > 5/
+{
+ printf("The value is %d\n", MAXVAL);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d.out
new file mode 100644
index 0000000..7ae4979
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexp.d.out
@@ -0,0 +1,2 @@
+The value is 150
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d
new file mode 100644
index 0000000..d917d33
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple ifdefined, define, else, endif test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#if defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d.out
new file mode 100644
index 0000000..2bde5e9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpelse.d.out
@@ -0,0 +1,2 @@
+The value is 10
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d
new file mode 100644
index 0000000..b0ae395
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple define, if defined, define and endif tests.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#define FLAG 1
+#if defined (FLAG)
+#define VALUE 5
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d.out
new file mode 100644
index 0000000..d51d19f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpif.d.out
@@ -0,0 +1,2 @@
+The value is 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d
new file mode 100644
index 0000000..c6210d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple define, if defined, else, endif test.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+#define FLAG 1
+#if defined (FLAG)
+#define VALUE 5
+#else
+#define VALUE 10
+#endif
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d.out
new file mode 100644
index 0000000..d51d19f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.preexpifelse.d.out
@@ -0,0 +1,2 @@
+The value is 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.withinprobe.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.withinprobe.d
new file mode 100644
index 0000000..83a2445
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/preprocessor/tst.withinprobe.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a 'ifdef' section inside a probe clause.
+ *
+ * SECTION: Program Structure/Use of the C Preprocessor
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+
+#if !defined (FLAG)
+#define VALUE 5
+#endif
+
+ printf("The value is %d\n", VALUE);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_DYN.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_DYN.bad.d
new file mode 100644
index 0000000..892b445
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_DYN.bad.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print(*curpsinfo);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d
new file mode 100644
index 0000000..902f072
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PRINT_VOID.bad.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print((void)`p0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d
new file mode 100644
index 0000000..a1d3be1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/err.D_PROTO_LEN.bad.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+BEGIN
+{
+ print();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d
new file mode 100644
index 0000000..9650bf7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct bar {
+ int alpha;
+} bar_t;
+
+typedef struct foo {
+ int a[3];
+ char b[30];
+ bar_t c[2];
+ char d[3];
+} foo_t;
+
+BEGIN
+{
+ this->f = (foo_t *)alloca(sizeof (foo_t));
+
+ this->f->a[0] = 1;
+ this->f->a[1] = 2;
+ this->f->a[2] = 3;
+ this->f->b[0] = 'a';
+ this->f->b[1] = 'b';
+ this->f->b[2] = 0;
+ this->f->c[0].alpha = 5;
+ this->f->c[1].alpha = 6;
+ this->f->c[2].alpha = 7;
+ this->f->d[0] = 4;
+ this->f->d[1] = 0;
+ this->f->d[2] = 0;
+
+ print(this->f->a);
+ print(this->f->b);
+ print(this->f->c);
+ print(*this->f);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out
new file mode 100644
index 0000000..0702d4b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.array.d.out
@@ -0,0 +1,23 @@
+int [3] [ 0x1, 0x2, 0x3 ]
+char [30] "ab"
+bar_t [2] [
+ bar_t {
+ int alpha = 0x5
+ },
+ bar_t {
+ int alpha = 0x6
+ }
+]
+foo_t {
+ int [3] a = [ 0x1, 0x2, 0x3 ]
+ char [30] b = [ "ab" ]
+ bar_t [2] c = [
+ bar_t {
+ int alpha = 0x5
+ },
+ bar_t {
+ int alpha = 0x6
+ }
+ ]
+ char [3] d = [ '\004', '\0', '\0' ]
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d
new file mode 100644
index 0000000..ff77bb0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct forward forward_t;
+
+typedef struct foo {
+ int a:4;
+ int b:7;
+ int c:1;
+ int d:2;
+} foo_t;
+
+BEGIN
+{
+ this->s = (foo_t *)alloca(sizeof (foo_t));
+
+ this->s->a = 1;
+ this->s->b = 5;
+ this->s->c = 0;
+ this->s->d = 2;
+
+ print(*this->s);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out
new file mode 100644
index 0000000..309444d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.bitfield.d.out
@@ -0,0 +1,6 @@
+foo_t {
+ int a :4 = 0x1
+ int b :7 = 0x5
+ int c :1 = 0
+ int d :2 = 0x2
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d
new file mode 100644
index 0000000..559dab1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = (int)'a';
+
+ printf("\n");
+
+ print((char)'a');
+ print((int)-1);
+ print((unsigned int)23);
+ print((short)456);
+ print((unsigned short)789);
+ print((long)1234);
+ print((ulong_t)56789);
+ print((void *)0x1234);
+ print("hello");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out
new file mode 100644
index 0000000..f7e4076
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.primitive.d.out
@@ -0,0 +1,11 @@
+
+char 'a'
+int 0xffffffff
+unsigned int 0x17
+short 0x1c8
+unsigned short 0x315
+long 0x4d2
+ulong_t 0xddd5
+void * 0x1234
+string "hello"
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d
new file mode 100644
index 0000000..2fb1c41
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#pragma D option quiet
+
+typedef struct forward forward_t;
+
+typedef struct foo {
+ int a;
+ void *b;
+ struct {
+ uint64_t alpha;
+ uint64_t beta;
+ } c;
+ ushort_t d;
+ int e;
+ forward_t *f;
+ void (*g)();
+} foo_t;
+
+BEGIN
+{
+ this->s = (foo_t *)alloca(sizeof (foo_t));
+
+ this->s->a = 1;
+ this->s->b = (void *)2;
+ this->s->c.alpha = 3;
+ this->s->c.beta = 4;
+ this->s->d = 5;
+ this->s->e = 6;
+ this->s->f = (void *)7;
+ this->s->g = (void *)8;
+
+ print(*this->s);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out
new file mode 100644
index 0000000..b7b2108
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/print/tst.struct.d.out
@@ -0,0 +1,12 @@
+foo_t {
+ int a = 0x1
+ void *b = 0x2
+ struct c = {
+ uint64_t alpha = 0x3
+ uint64_t beta = 0x4
+ }
+ ushort_t d = 0x5
+ int e = 0x6
+ forward_t *f = 0x7
+ int (*)() g = 0x8
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badagg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badagg.d
new file mode 100644
index 0000000..817d9ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badagg.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invokes printa() with a bad aggregation argument.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+BEGIN
+{
+ printa("%d", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badfmt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badfmt.d
new file mode 100644
index 0000000..5a41982
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badfmt.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invokes printa() with a bad format string.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+BEGIN
+{
+ printa(123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badval.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badval.d
new file mode 100644
index 0000000..e8663ab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_AGGARG.badval.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invokes printa() with an argument that does not match the aggregation
+ * convertion.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+BEGIN
+{
+ printa("%@d\n", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_PROTO.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_PROTO.bad.d
new file mode 100644
index 0000000..8e202f6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTA_PROTO.bad.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invokes printa() with a bad aggregation argument.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+BEGIN
+{
+ printa("%d");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.jstack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.jstack.d
new file mode 100644
index 0000000..09b4b27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.jstack.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[jstack()] = count();
+
+ printa("%p\n", @);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.stack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.stack.d
new file mode 100644
index 0000000..8815ad6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.stack.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[stack()] = count();
+
+ printa("%p\n", @);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.ustack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.ustack.d
new file mode 100644
index 0000000..bce1b67
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/err.D_PRINTF_ARG_TYPE.ustack.d
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[ustack()] = count();
+
+ printa("%p\n", @);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d
new file mode 100644
index 0000000..f535387
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test the basic formatting of all the supported kinds of aggregations.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = avg(1);
+ @b = count();
+ @c = lquantize(1, 1, 10);
+ @d = max(1);
+ @e = min(1);
+ @f = sum(1);
+ @g = quantize(1);
+ @h = stddev(1);
+
+ printa("@a = %@u\n", @a);
+ printa("@b = %@u\n", @b);
+ printa("@c = %@d\n", @c);
+ printa("@d = %@u\n", @d);
+ printa("@e = %@u\n", @e);
+ printa("@f = %@u\n", @f);
+ printa("@g = %@d\n", @g);
+ printa("@h = %@d\n", @h);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out
new file mode 100644
index 0000000..ddad213
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out
@@ -0,0 +1,19 @@
+@a = 1
+@b = 1
+@c =
+ value ------------- Distribution ------------- count
+ < 1 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+@d = 1
+@e = 1
+@f = 1
+@g =
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1
+ 2 | 0
+
+@h = 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d
new file mode 100644
index 0000000..50011e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the printa() default output format.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = count();
+ printa(@a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d.out
new file mode 100644
index 0000000..7cf6701
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.def.d.out
@@ -0,0 +1,3 @@
+
+ 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d
new file mode 100644
index 0000000..f3379c9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ /*
+ * Yes, this works. But is it useful? And is it useful to someone
+ * other than jwadams and/or dep?
+ */
+ @[10, 100] = sum(1);
+ @[-10, 200] = sum(2);
+
+ printa("-->%-*d<--\n", @);
+ printa("-->%*d<--\n", @);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d.out
new file mode 100644
index 0000000..f6c53eb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.dynwidth.d.out
@@ -0,0 +1,5 @@
+-->100 <--
+-->200 <--
+--> 100<--
+-->200 <--
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d
new file mode 100644
index 0000000..8f8cd41
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the printa() format string in its simplest form.
+ *
+ * SECTION: Output Formatting/printa()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = count();
+ printa("%@u", @a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d.out
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.fmt.d.out
@@ -0,0 +1 @@
+1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh
new file mode 100644
index 0000000..7d8bd39
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh
@@ -0,0 +1,83 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+void
+thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog(void)
+{
+ while (1)
+ ;
+}
+
+int
+main(int argc, char *argv[])
+{
+ thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog();
+}
+EOF
+
+cc -o test test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ profile:::profile-1001hz
+ /pid == \$target/
+ {
+ @[arg1] = count();
+ }
+
+ tick-1s
+ /n++ > 10/
+ {
+ printa("%A %@d\n", @);
+ exit(0);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.many.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.many.d
new file mode 100644
index 0000000..5bd3eae
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.many.d
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=32m
+#pragma D option bufpolicy=fill
+#pragma D option destructive
+#pragma D option quiet
+
+BEGIN
+/0 == 1/
+{
+ @ = count();
+}
+
+BEGIN
+{
+ freopen("/dev/null");
+}
+
+profile-4000hz
+{
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+ printa(@);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d
new file mode 100644
index 0000000..c9fae84
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of many aggregation results in the same format string.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a = count();
+ printa("%@u %@u %@u %@u %@u %@u %@u\n", @a);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d.out
new file mode 100644
index 0000000..f08b797
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.manyval.d.out
@@ -0,0 +1,2 @@
+1 1 1 1 1 1 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.stack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.stack.d
new file mode 100644
index 0000000..88dbb1a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.stack.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ @[stack()] = count();
+ @[ustack()] = count();
+ @[jstack()] = count();
+
+ printa("%k\n", @);
+ printa("%-20k\n", @);
+ printa("%60k\n", @);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d
new file mode 100644
index 0000000..0eea887
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of tuple arguments in the printa() format.
+ *
+ * SECTION: Output Formatting/printa()
+ *
+ * NOTES:
+ * We confirm that we can consume fewer arguments than in the tuple, all
+ * the way up to the exact number.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ @a[1, 2, 3, 4, 5] = count();
+ printf("\n");
+
+ printa("%@u: -\n", @a);
+ printa("%@u: %d\n", @a);
+ printa("%@u: %d %d\n", @a);
+ printa("%@u: %d %d %d\n", @a);
+ printa("%@u: %d %d %d %d\n", @a);
+ printa("%@u: %d %d %d %d %d\n", @a);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d.out
new file mode 100644
index 0000000..928119c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.tuple.d.out
@@ -0,0 +1,8 @@
+
+1: -
+1: 1
+1: 1 2
+1: 1 2 3
+1: 1 2 3 4
+1: 1 2 3 4 5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh
new file mode 100644
index 0000000..69bf46b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+# The output files assumes the timezone is US/Pacific
+export TZ=America/Los_Angeles
+
+$dtrace -s /dev/stdin <<EOF
+#pragma D option quiet
+#pragma D option destructive
+
+BEGIN
+{
+ @foo = min(1075064400 * (hrtime_t)1000000000);
+ @bar = max(walltimestamp);
+ printa("%@T\n", @foo);
+ printa("%@Y\n", @foo);
+
+ freopen("/dev/null");
+ printa("%@T\n", @bar);
+ printa("%@Y\n", @bar);
+
+ exit(0);
+}
+EOF
+
+if [ $? -ne 0 ]; then
+ print -u2 "dtrace failed"
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh.out
new file mode 100644
index 0000000..7462cf8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh.out
@@ -0,0 +1,2 @@
+Sun, 25 Jan 2004 13:00:00 PST
+2004 Jan 25 13:00:00
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_AGG_CONV.aggfmt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_AGG_CONV.aggfmt.d
new file mode 100644
index 0000000..9cac625
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_AGG_CONV.aggfmt.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a bad aggregation format.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("hello %@d", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.toomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.toomany.d
new file mode 100644
index 0000000..de87e8d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.toomany.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with too many arguments.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("x = %d y = %d\n", 123, 456, 789);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.widths.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.widths.d
new file mode 100644
index 0000000..9381280
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_EXTRA.widths.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Negative test to test variety of fixed width formats.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ x = 0;
+
+ printf("%?d\n", x++, 1);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_FMT.badfmt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_FMT.badfmt.d
new file mode 100644
index 0000000..bf4dc72
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_FMT.badfmt.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a bad format string arg.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf(123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_PROTO.novalue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_PROTO.novalue.d
new file mode 100644
index 0000000..68f8cf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_PROTO.novalue.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a missing value argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%s");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.aggarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.aggarg.d
new file mode 100644
index 0000000..99bb039
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.aggarg.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test printf() with a bad aggregation arg.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ @a = count();
+ printf("hello %d %d", 123, @a);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.recursive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.recursive.d
new file mode 100644
index 0000000..3b94ba7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_ARG_TYPE.recursive.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid recursive printf test.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+ printf("%s\n", printf("test"));
+
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.noprec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.noprec.d
new file mode 100644
index 0000000..ba8a1a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.noprec.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a missing dynamic precision argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%s %.*d\n", "foo");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.nowidth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.nowidth.d
new file mode 100644
index 0000000..4d72c81
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_PROTO.nowidth.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a missing dynamic width argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%s %*d\n", "foo");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badprec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badprec.d
new file mode 100644
index 0000000..64cf912
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badprec.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a dynamic precision argument of non-integer type.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%.*d\n", "foo", 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badwidth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badwidth.d
new file mode 100644
index 0000000..badc95e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PRINTF_DYN_TYPE.badwidth.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tet dynamic width argument of non-integer type.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%*d\n", "foo", 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PROTO_LEN.toofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PROTO_LEN.toofew.d
new file mode 100644
index 0000000..32c877ba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_PROTO_LEN.toofew.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with too few arguments.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv1.d
new file mode 100644
index 0000000..7add331
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv1.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the unsupported %n$ conversion syntax.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%3$d", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv2.d
new file mode 100644
index 0000000..5cc32e2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv2.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an incomplete conversion.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%3", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv3.d
new file mode 100644
index 0000000..0dedea3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/err.D_SYNTAX.badconv3.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an undefined conversion.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ printf("%Z", 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d
new file mode 100644
index 0000000..8d4bb81
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the basics of all the format conversions in the printf dictionary.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ * NOTES:
+ * floats and wchar_t strings missing
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = (int)'a';
+
+ printf("\n");
+
+ printf("%%a = %a\n", &`kmem_alloc);
+ printf("%%c = %c\n", i);
+ printf("%%d = %d\n", i);
+ printf("%%hd = %hd\n", (short)i);
+ printf("%%hi = %hi\n", (short)i);
+ printf("%%ho = %ho\n", (ushort_t)i);
+ printf("%%hu = %hu\n", (ushort_t)i);
+ printf("%%hx = %hx\n", (ushort_t)i);
+ printf("%%hX = %hX\n", (ushort_t)i);
+ printf("%%i = %i\n", i);
+ printf("%%lc = %lc\n", i);
+ printf("%%ld = %ld\n", (long)i);
+ printf("%%li = %li\n", (long)i);
+ printf("%%lo = %lo\n", (ulong_t)i);
+ printf("%%lu = %lu\n", (ulong_t)i);
+ printf("%%lx = %lx\n", (ulong_t)i);
+ printf("%%lX = %lX\n", (ulong_t)i);
+ printf("%%o = %o\n", (uint_t)i);
+ printf("%%p = %p\n", (void *)i);
+ printf("%%s = %s\n", "hello");
+ printf("%%u = %u\n", (uint_t)i);
+ printf("%%wc = %wc\n", i);
+ printf("%%x = %x\n", (uint_t)i);
+ printf("%%X = %X\n", (uint_t)i);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out
new file mode 100644
index 0000000..55c1222
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.basics.d.out
@@ -0,0 +1,26 @@
+
+%a = genunix`kmem_alloc
+%c = a
+%d = 97
+%hd = 97
+%hi = 97
+%ho = 141
+%hu = 97
+%hx = 61
+%hX = 61
+%i = 97
+%lc = a
+%ld = 97
+%li = 97
+%lo = 141
+%lu = 97
+%lx = 61
+%lX = 61
+%o = 141
+%p = 61
+%s = hello
+%u = 97
+%wc = a
+%x = 61
+%X = 61
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d
new file mode 100644
index 0000000..0b65315
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test all of the various formatting flags (except %' because that
+ * requires locale support).
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ printf("# %#8x\n", 0x123);
+ printf("0 %08x\n", 0x123);
+ printf("- %-8x\n", 0x123);
+ printf("+ %+8d\n", 123);
+ printf(" % 8d\n", 123);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d.out
new file mode 100644
index 0000000..4e5344e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.flags.d.out
@@ -0,0 +1,7 @@
+
+# 0x123
+0 00000123
+- 123
++ +123
+ 123
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d
new file mode 100644
index 0000000..d58f6cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple printf() test.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("hello");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d.out
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.hello.d.out
@@ -0,0 +1 @@
+hello
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d
new file mode 100644
index 0000000..d15236ba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with simple integer arguments, using a variety of
+ * sizes and thereby exercise the automatic size extension feature.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n%d\n", (char)0x1234567890abcdef);
+ printf("%d\n", (short)0x1234567890abcdef);
+ printf("%d\n", (int)0x1234567890abcdef);
+ printf("%d\n", (long long)0x1234567890abcdef);
+
+ printf("\n%d\n", (unsigned char)0x1234567890abcdef);
+ printf("%d\n", (unsigned short)0x1234567890abcdef);
+ printf("%d\n", (unsigned int)0x1234567890abcdef);
+ printf("%d\n", (unsigned long long)0x1234567890abcdef);
+
+ printf("\n%u\n", (char)0x1234567890abcdef);
+ printf("%u\n", (short)0x1234567890abcdef);
+ printf("%u\n", (int)0x1234567890abcdef);
+ printf("%u\n", (long long)0x1234567890abcdef);
+
+ printf("\n%u\n", (unsigned char)0x1234567890abcdef);
+ printf("%u\n", (unsigned short)0x1234567890abcdef);
+ printf("%u\n", (unsigned int)0x1234567890abcdef);
+ printf("%u\n", (unsigned long long)0x1234567890abcdef);
+
+ printf("\n%x\n", (unsigned char)0x1234567890abcdef);
+ printf("%x\n", (unsigned short)0x1234567890abcdef);
+ printf("%x\n", (unsigned int)0x1234567890abcdef);
+ printf("%x\n", (unsigned long long)0x1234567890abcdef);
+
+ printf("\n%x\n", (char)0x1234567890abcdef);
+ printf("%x\n", (short)0x1234567890abcdef);
+ printf("%x\n", (int)0x1234567890abcdef);
+ printf("%x\n", (long long)0x1234567890abcdef);
+
+ printf("\n%o\n", (unsigned char)0x1234567890abcdef);
+ printf("%o\n", (unsigned short)0x1234567890abcdef);
+ printf("%o\n", (unsigned int)0x1234567890abcdef);
+ printf("%o\n", (unsigned long long)0x1234567890abcdef);
+
+ printf("\n%o\n", (char)0x1234567890abcdef);
+ printf("%o\n", (short)0x1234567890abcdef);
+ printf("%o\n", (int)0x1234567890abcdef);
+ printf("%o\n", (long long)0x1234567890abcdef);
+
+ printf("\n%p\n", (void *)0x12345678);
+ printf("%p\n", (int *)0x90abcdef);
+ printf("%p\n", (uintptr_t)0x67890abc);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out
new file mode 100644
index 0000000..4d2bb11
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.ints.d.out
@@ -0,0 +1,45 @@
+
+239
+52719
+-1867788817
+1311768467294899695
+
+239
+52719
+2427178479
+1311768467294899695
+
+239
+52719
+2427178479
+1311768467294899695
+
+239
+52719
+2427178479
+1311768467294899695
+
+ef
+cdef
+90abcdef
+1234567890abcdef
+
+ef
+cdef
+90abcdef
+1234567890abcdef
+
+357
+146757
+22052746757
+110642547422052746757
+
+357
+146757
+22052746757
+110642547422052746757
+
+12345678
+90abcdef
+67890abc
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d
new file mode 100644
index 0000000..2bfff9f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a variety of fixed and dynamic format precisions.
+ *
+ * SECTION: Output Formatting/printf()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ x = 0;
+
+ printf("%.0s\n", "hello");
+ printf("%.1s\n", "hello");
+ printf("%.2s\n", "hello");
+ printf("%.3s\n", "hello");
+ printf("%.4s\n", "hello");
+ printf("%.5s\n", "hello");
+
+ printf("%.*s\n", x++, "hello");
+ printf("%.*s\n", x++, "hello");
+ printf("%.*s\n", x++, "hello");
+ printf("%.*s\n", x++, "hello");
+ printf("%.*s\n", x++, "hello");
+ printf("%.*s\n", x++, "hello");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d.out
new file mode 100644
index 0000000..11a969d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.precs.d.out
@@ -0,0 +1,14 @@
+
+hello
+h
+he
+hel
+hell
+hello
+hello
+h
+he
+hel
+hell
+hello
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d
new file mode 100644
index 0000000..3fe0bac
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test %f format printing.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+float f;
+double d;
+
+BEGIN
+{
+ printf("\n");
+
+ printf("%%f = %f\n", f);
+ printf("%%f = %f\n", d);
+
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d.out
new file mode 100644
index 0000000..4d4b864
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.print-f.d.out
@@ -0,0 +1,4 @@
+
+%f = 0.000000
+%f = 0.000000
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh
new file mode 100644
index 0000000..6d36957
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+# The output files assumes the timezone is US/Pacific
+export TZ=America/Los_Angeles
+
+$dtrace -s /dev/stdin <<EOF
+#pragma D option quiet
+
+inline uint64_t NANOSEC = 1000000000;
+
+BEGIN
+{
+ printf("%T\n%T\n%T", (uint64_t)0, (uint64_t)1062609821 * NANOSEC,
+ (uint64_t)0x7fffffff * NANOSEC);
+ exit(0);
+}
+EOF
+
+if [ $? -ne 0 ]; then
+ print -u2 "dtrace failed"
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh.out
new file mode 100644
index 0000000..51c8437
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh.out
@@ -0,0 +1,3 @@
+Wed, 31 Dec 1970 16:00:00 PST
+Wed, 03 Sep 2003 10:23:41 PDT
+Mon, 18 Jan 2038 19:14:07 PST
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh
new file mode 100644
index 0000000..b8ea2ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+# The output files assumes the timezone is US/Pacific
+export TZ=America/Los_Angeles
+
+$dtrace -s /dev/stdin <<EOF
+#pragma D option quiet
+
+inline uint64_t NANOSEC = 1000000000;
+
+BEGIN
+{
+ printf("%Y\n%Y\n%Y", (uint64_t)0, (uint64_t)1062609821 * NANOSEC,
+ (uint64_t)0x7fffffff * NANOSEC);
+ exit(0);
+}
+EOF
+
+if [ $? -ne 0 ]; then
+ print -u2 "dtrace failed"
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh.out
new file mode 100644
index 0000000..ae8d82f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh.out
@@ -0,0 +1,3 @@
+1969 Dec 31 16:00:00
+2003 Sep 3 10:23:41
+2038 Jan 18 19:14:07
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d
new file mode 100644
index 0000000..ca7e1a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test 'uint' continously; like kinda stress.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+uint64_t ts;
+
+BEGIN
+{
+ ts = 53114233149441;
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ printf("%u\n", ts);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d.out
new file mode 100644
index 0000000..ce33b72
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printcont.d.out
@@ -0,0 +1,16 @@
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+53114233149441
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d
new file mode 100644
index 0000000..7aaee2a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test %e, %E format printing.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+float f;
+double d;
+
+BEGIN
+{
+ printf("\n");
+
+ printf("%%e = %e\n", f);
+ printf("%%E = %E\n", f);
+
+ printf("%%e = %e\n", d);
+ printf("%%E = %E\n", d);
+
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d.out
new file mode 100644
index 0000000..3fa96bc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printeE.d.out
@@ -0,0 +1,6 @@
+
+%e = 0.000000e+00
+%E = 0.000000E+00
+%e = 0.000000e+00
+%E = 0.000000E+00
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d
new file mode 100644
index 0000000..9e7e019
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test %g, %G format printing.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+float f;
+double d;
+
+BEGIN
+{
+ printf("\n");
+
+ printf("%%g = %g\n", f);
+ printf("%%g = %g\n", d);
+
+ printf("%%G = %G\n", f);
+ printf("%%G = %G\n", d);
+
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d.out
new file mode 100644
index 0000000..e4175e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printgG.d.out
@@ -0,0 +1,6 @@
+
+%g = 0
+%g = 0
+%G = 0
+%G = 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d
new file mode 100644
index 0000000..deb4f81
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a fixed string and no actual tracing arguments.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("hello world from BEGIN");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d.out
new file mode 100644
index 0000000..cb7c7e9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.rawfmt.d.out
@@ -0,0 +1 @@
+hello world from BEGIN
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d
new file mode 100644
index 0000000..a740413
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test printf() with a simple string argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sysname = %s", `utsname.sysname);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out
new file mode 100644
index 0000000..ba31981
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out
@@ -0,0 +1 @@
+sysname = SunOS
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d
new file mode 100644
index 0000000..32bc682
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with a simple string argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("symbol = %a", &`kmem_alloc);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out
new file mode 100644
index 0000000..5ed9d8e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out
@@ -0,0 +1 @@
+symbol = kernel`kmem_alloc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d
new file mode 100644
index 0000000..caa326e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test printf() with simple unsigned integer arguments.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ printf("%u\n", (uchar_t)123);
+ printf("%u\n", (ushort_t)123);
+ printf("%u\n", (ulong_t)123);
+ printf("%u\n", (u_longlong_t)123);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d.out
new file mode 100644
index 0000000..d800e91
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.uints.d.out
@@ -0,0 +1,6 @@
+
+123
+123
+123
+123
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d
new file mode 100644
index 0000000..21595c0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a variety of fixed and dynamic format widths.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ x = 0;
+
+ printf("%0d\n", 1);
+ printf("%1d\n", 1);
+ printf("%2d\n", 1);
+ printf("%3d\n", 1);
+ printf("%4d\n", 1);
+ printf("%5d\n", 1);
+
+ printf("%*d\n", x++, 1);
+ printf("%*d\n", x++, 1);
+ printf("%*d\n", x++, 1);
+ printf("%*d\n", x++, 1);
+ printf("%*d\n", x++, 1);
+ printf("%*d\n", x++, 1);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d.out
new file mode 100644
index 0000000..39fc7a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths.d.out
@@ -0,0 +1,14 @@
+
+1
+1
+ 1
+ 1
+ 1
+ 1
+1
+1
+ 1
+ 1
+ 1
+ 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths1.d
new file mode 100644
index 0000000..b5410ab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.widths1.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Try to print charecter wide width using '?'
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ x = 0;
+
+ printf("%?d\n", x++);
+ printf("%?d\n", x++);
+ printf("%?d\n", x++);
+ printf("%?d\n", x++);
+ printf("%?d\n", x++);
+ printf("%?d\n", x++);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d
new file mode 100644
index 0000000..b6745e1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a variety of fixed and dynamic format widths combined with precisions.
+ *
+ * SECTION: Output Formatting/printf()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\n");
+ x = 0;
+
+ printf("%0.0s\n", "hello");
+ printf("%1.1s\n", "hello");
+ printf("%2.2s\n", "hello");
+ printf("%3.3s\n", "hello");
+ printf("%4.4s\n", "hello");
+ printf("%5.5s\n", "hello");
+ printf("%6.6s\n", "hello");
+ printf("%7.7s\n", "hello");
+ printf("%8.8s\n", "hello");
+ printf("%9.9s\n", "hello");
+
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+ printf("%*.*s\n", x, x++, "hello");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d.out
new file mode 100644
index 0000000..2f1fd9d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.wp.d.out
@@ -0,0 +1,22 @@
+
+hello
+h
+he
+hel
+hell
+hello
+ hello
+ hello
+ hello
+ hello
+hello
+h
+he
+hel
+hell
+hello
+ hello
+ hello
+ hello
+ hello
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh
new file mode 100644
index 0000000..ae4934c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh
@@ -0,0 +1,82 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+/usr/sbin/dtrace -q -s /dev/stdin <<"EOF"
+
+BEGIN {
+ errorcount = 0;
+ expected_errorcount = 23;
+}
+
+BEGIN { trace(mutex_owned(&`pidlock)); }
+BEGIN { trace(mutex_owner(&`pidlock)); }
+BEGIN { trace(mutex_type_adaptive(&`pidlock)); }
+BEGIN { trace(mutex_type_spin(&`pidlock)); }
+
+BEGIN { trace(rw_read_held(&`ksyms_lock)); }
+BEGIN { trace(rw_write_held(&`ksyms_lock)); }
+BEGIN { trace(rw_iswriter(&`ksyms_lock)); }
+
+BEGIN { x = alloca(10); bcopy(`initname, x, 10); trace(stringof(x)); }
+/* We have no reliable way to test msgsize */
+
+BEGIN { trace(strlen(`initname)); }
+BEGIN { trace(strchr(`initname, 0x69)); }
+BEGIN { trace(strrchr(`initname, 0x69)); }
+BEGIN { trace(strstr("/sbin/init/foo", `initname)); }
+BEGIN { trace(strstr(`initname, "in")); }
+BEGIN { trace(strtok(`initname, "/")); }
+BEGIN { trace(strtok(NULL, "/")); }
+BEGIN { trace(strtok("foo/bar", `initname)); }
+BEGIN { trace(strtok(NULL, `initname)); }
+BEGIN { trace(substr(`initname, 2, 3)); }
+
+BEGIN { trace(ddi_pathname(`top_devinfo, 1)); }
+BEGIN { trace(strjoin(`initname, "foo")); }
+BEGIN { trace(strjoin("foo", `initname)); }
+BEGIN { trace(dirname(`initname)); }
+BEGIN { trace(cleanpath(`initname)); }
+
+ERROR {
+ errorcount++;
+}
+
+BEGIN /errorcount == expected_errorcount/ {
+ trace("test passed");
+ exit(0);
+}
+
+BEGIN /errorcount != expected_errorcount/ {
+ printf("fail: expected %d. saw %d.", expected_errorcount, errorcount);
+ exit(1);
+}
+EOF
+
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.op_access.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.op_access.ksh
new file mode 100644
index 0000000..08964c4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.op_access.ksh
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+/usr/sbin/dtrace -q -s /dev/stdin <<"EOF"
+BEGIN {
+ errorcount = 0;
+ expected_errorcount = 7;
+}
+
+/* BYREF */
+BEGIN { trace(`utsname); }
+BEGIN { trace(`kmem_flags); }
+
+/* DIF_OP_SCMP */
+BEGIN /`initname == "/sbin/init"/ { trace("bad"); }
+
+/* DIF_OP_COPYS */
+BEGIN { p = `p0; trace(p); }
+
+/* DIF_OP_STTS */
+BEGIN { self->p = `p0; trace(self->p); }
+
+/* DIF_OP_STGAA */
+BEGIN { a[stringof(`initname)] = 42; trace(a["/sbin/init"]); }
+
+/* DIF_OP_STTAA */
+BEGIN { self->a[stringof(`initname)] = 42; trace(self->a["/sbin/init"]); }
+
+ERROR {
+ errorcount++;
+}
+
+BEGIN /errorcount == expected_errorcount/ {
+ trace("pass");
+ exit(0);
+}
+
+BEGIN /errorcount != expected_errorcount/ {
+ printf("fail: expected %d. saw %d.", expected_errorcount, errorcount);
+ exit(1);
+}
+EOF
+
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.unpriv_funcs.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.unpriv_funcs.ksh
new file mode 100644
index 0000000..c9da0ce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.unpriv_funcs.ksh
@@ -0,0 +1,79 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# Affirmative test of less privileged user operation. We do so by running
+# this test case as root, then as a less privileged user. The output should
+# be exactly the same.
+#
+
+script()
+{
+ cat <<"EOF"
+
+ BEGIN { trace("trace\n"); }
+ BEGIN { printf("%s\n", "printf"); }
+ BEGIN { printf("strlen(\"strlen\") = %d\n", strlen("strlen")); }
+ BEGIN { x = alloca(10);
+ bcopy("alloca\n", x, 7);
+ trace(stringof(x)); }
+
+ BEGIN { printf("index(\"index\", \"x\") = %d\n",
+ index("index", "x")); }
+ BEGIN { printf("strchr(\"strchr\", \'t\') = %s\n",
+ strchr("strchr", 't')); }
+
+ BEGIN { printf("strtok(\"strtok\", \"t\") = %s\n",
+ strtok("strtok", "t")); }
+ BEGIN { printf("strtok(NULL, \"t\") = %s\n",
+ strtok(NULL, "t")); }
+ BEGIN { printf("strtok(NULL, \"t\") = %s\n",
+ strtok(NULL, "t")); }
+ BEGIN { printf("substr(\"substr\", 2, 2) = %s\n",
+ substr("substr", 2, 2)); }
+ BEGIN { trace(strjoin("str", "join\n")); }
+ BEGIN { trace(basename("dirname/basename")); trace("/"); }
+ BEGIN { trace(dirname("dirname/basename")); }
+
+ BEGIN { exit(0); }
+ ERROR { exit(1); }
+EOF
+}
+
+privout=/tmp/$$.priv_output
+unprivout=/tmp/$$.unpriv_output
+
+script | /usr/sbin/dtrace -q -s /dev/stdin > $privout
+ppriv -s A=basic,dtrace_user $$
+script | /usr/sbin/dtrace -q -s /dev/stdin > $unprivout
+
+diff $privout $unprivout
+res=$?
+
+/bin/rm -f $privout $unprivout
+
+exit $res
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probeqtn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probeqtn.d
new file mode 100644
index 0000000..3560427
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probeqtn.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call probes with mismatch "?" and make sure it results in compilation
+ * error
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i;
+BEGIN
+{
+ i = 0;
+}
+
+syscall::?lwp?:entry
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probestar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probestar.d
new file mode 100644
index 0000000..6103f48
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.probestar.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call an undefined probe with matching character "*" and make
+ * sure it results in compilation error.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+no_such_dtrace_probe*
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.tickstar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.tickstar.d
new file mode 100644
index 0000000..391b18c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_PDESC_ZERO.tickstar.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call a probe with matching charecters "*" but does not have
+ * any matching probes.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i;
+BEGIN
+{
+ i = 0;
+}
+
+syscall::*tick*:entry
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.assign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.assign.d
new file mode 100644
index 0000000..e4f7dcb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.assign.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a predicate with no spaces and make sure it results in
+ * compilation error.
+
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i = 0;
+
+profile-1
+/i == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declare.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declare.d
new file mode 100644
index 0000000..30aa266
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declare.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare variables inside probe clause and make sure it results
+ * in compilation error.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+{
+ int i = 0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declarein.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declarein.d
new file mode 100644
index 0000000..9ef8590
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.declarein.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a Variable in between definition and first brace, and make
+ * sure it results in compilation error.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+int i;
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.lbraces.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.lbraces.d
new file mode 100644
index 0000000..b4a4315
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.lbraces.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a probe with one missing braces.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+{
+ exit(0);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.probespec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.probespec.d
new file mode 100644
index 0000000..67c4487
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.probespec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Try Declaring Datatypes and variables next to profile declaration and
+ * Make sure it results in compilation error.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1:int i
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.rbraces.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.rbraces.d
new file mode 100644
index 0000000..4f889d5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.rbraces.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a probe with one missing braces.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.recdec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.recdec.d
new file mode 100644
index 0000000..5db21ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/err.D_SYNTAX.recdec.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a probe clause within another probe clause.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+{
+ tick-10ms
+{
+}
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.basic1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.basic1.d
new file mode 100644
index 0000000..df2b114
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.basic1.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple probe clause test; just a empty probe.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.check.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.check.d
new file mode 100644
index 0000000..d3f2535
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.check.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a Variable in BEGIN and use that in another probe.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i;
+BEGIN
+{
+ i = 0;
+}
+
+tick-10ms
+/i == 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declare.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declare.d
new file mode 100644
index 0000000..845b3fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declare.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declaration of variable outside probe clause
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i;
+tick-10ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declareafter.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declareafter.d
new file mode 100644
index 0000000..1c1e2ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.declareafter.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declaration of a variable after probe clause definition.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ exit(0);
+}
+int i;
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.emptyprobe.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.emptyprobe.d
new file mode 100644
index 0000000..e23a8db
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.emptyprobe.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Multiple probe clause declarations.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+}
+tick-10ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragma.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragma.d
new file mode 100644
index 0000000..035079d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragma.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Test to Declare pragma in right place.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-10ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaaftertab.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaaftertab.d
new file mode 100644
index 0000000..be725f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaaftertab.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare pragma after a tab and make sure it results in compilation error.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+ #pragma D option quiet
+
+tick-10ms
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmainside.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmainside.d
new file mode 100644
index 0000000..e602a41
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmainside.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare pragma inside probe clause.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+
+tick-10ms
+{
+#pragma D option quiet
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaoutside.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaoutside.d
new file mode 100644
index 0000000..7d2ea61
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.pragmaoutside.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare pragma outside probe clause.
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+
+tick-10ms
+{
+ exit(0);
+}
+#pragma D option quiet
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.probestar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.probestar.d
new file mode 100644
index 0000000..3f54321
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/probes/tst.probestar.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call matching probe clauses with given name using "*"
+ *
+ * SECTION: Program Structure/Probe Clauses and Declarations
+ *
+ */
+
+
+#pragma D option quiet
+
+int i;
+BEGIN
+{
+ i = 0;
+}
+
+syscall::*lwp*:entry
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.create.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.create.ksh
new file mode 100644
index 0000000..6b21eb8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.create.ksh
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::create probe fires with the proper
+# arguments.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::create
+ /args[0]->p_pptr->p_pid == $child && pid == $child/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.discard.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.discard.ksh
new file mode 100644
index 0000000..5595c24
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.discard.ksh
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::signal-discard probe fires correctly
+# and with the correct arguments.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::signal-discard
+ /args[1]->pr_pid == $child &&
+ args[1]->pr_psargs == "$longsleep" && args[2] == SIGHUP/
+ {
+ exit(0);
+ }
+EOF
+}
+
+killer()
+{
+ while true; do
+ sleep 1
+ /usr/bin/kill -HUP $child
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+longsleep="/usr/bin/sleep 10000"
+
+/usr/bin/nohup $longsleep &
+child=$!
+
+killer &
+killer=$!
+script
+status=$?
+
+kill $child
+kill $killer
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh
new file mode 100644
index 0000000..a4ad572
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh
@@ -0,0 +1,73 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::exec probe fires, followed by the
+# proc:::exec-success probe (in a successful exec(2)).
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exec
+ /curpsinfo->pr_ppid == $child && args[0] == "/bin/sleep"/
+ {
+ self->exec = 1;
+ }
+
+ proc:::exec-success
+ /self->exec/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh
new file mode 100644
index 0000000..995eb05
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script is identical to tst.execfail.ksh -- but it additionally checks
+# that errno is set to ENOENT in the case that an interpreter can't be
+# found.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exec
+ /curpsinfo->pr_ppid == $child && args[0] == "$badexec"/
+ {
+ self->exec = 1;
+ }
+
+ proc:::exec-failure
+ /self->exec && args[0] == ENOENT/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /bin/sleep 1
+ $badexec
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+badexec=/tmp/execfail.ENOENT.ksh.$$
+dtrace=$1
+
+cat > $badexec <<EOF
+#!/this_is_a_bogus_interpreter
+EOF
+
+chmod +x $badexec
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+kill $child
+rm $badexec
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh
new file mode 100644
index 0000000..7fb3faa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh
@@ -0,0 +1,86 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that -- if a exec(2) fails -- the proc:::exec probe fires,
+# followed by the proc:::exec-success probe (in a successful exec(2)). To
+# circumvent any potential shell cleverness, this script generates exec
+# failure by generating a file with a bogus interpreter. (It seems unlikely
+# that a shell -- regardless of how clever it claims to be -- would bother to
+# validate the interpreter before exec'ing.)
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exec
+ /curpsinfo->pr_ppid == $child && args[0] == "$badexec"/
+ {
+ self->exec = 1;
+ }
+
+ proc:::exec-failure
+ /self->exec/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /bin/sleep 1
+ $badexec
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+badexec=/tmp/execfail.ksh.$$
+dtrace=$1
+
+cat > $badexec <<EOF
+#!/this_is_a_bogus_interpreter
+EOF
+
+chmod +x $badexec
+
+sleeper &
+child=$!
+script
+status=$?
+
+kill $child
+rm $badexec
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh
new file mode 100644
index 0000000..867e4ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh
@@ -0,0 +1,92 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::exit probe fires with the correct argument
+# when the process core dumps. The problematic bit here is making sure that
+# a process _can_ dump core -- if core dumps are disabled on both a global
+# and per-process basis, this test will fail. Rather than having this test
+# muck with coreadm(1M) settings, it will fail explicitly in this case and
+# provide a hint as to the problem. In general, machines should never be
+# running with both per-process and global core dumps disabled -- so this
+# should be a non-issue in practice.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exit
+ /curpsinfo->pr_ppid == $child &&
+ execargs == "$longsleep" && args[0] == CLD_DUMPED/
+ {
+ exit(0);
+ }
+
+ proc:::exit
+ /curpsinfo->pr_ppid == $child &&
+ execargs == "$longsleep" && args[0] != CLD_DUMPED/
+ {
+ printf("Child process could did dump core.");
+ exit(1);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ $longsleep &
+ /bin/sleep 1
+ kill -SEGV $!
+ done
+ /bin/rm -f $corefile
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+longsleep="/bin/sleep 10000"
+corefile=/tmp/sleep.core
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+#pstop $child
+#pkill -P $child
+kill $child
+#prun $child
+
+/bin/rm -f $corefile
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitexit.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitexit.ksh
new file mode 100644
index 0000000..0d71b15
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitexit.ksh
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::exit probe fires with the correct argument
+# when the process explicitly exits.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exit
+ /curpsinfo->pr_ppid == $child && args[0] == CLD_EXITED/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitkilled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitkilled.ksh
new file mode 100644
index 0000000..8040ade
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitkilled.ksh
@@ -0,0 +1,75 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::exit probe fires with the correct argument
+# when the process is killed.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::exit
+ /curpsinfo->pr_ppid == $child &&
+ curpsinfo->pr_psargs == "$longsleep" && args[0] == CLD_KILLED/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ $longsleep &
+ /usr/bin/sleep 1
+ kill -9 $!
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+longsleep="/usr/bin/sleep 10000"
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+pstop $child
+pkill -P $child
+kill $child
+prun $child
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.signal.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.signal.ksh
new file mode 100644
index 0000000..cd3c791
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.signal.ksh
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the proc:::signal-send and proc:::signal-handle
+# probes fire correctly and with the correct arguments.
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::signal-send
+ /execname == "kill" && curpsinfo->pr_ppid == $child &&
+ args[1]->pr_psargs == "$longsleep" && args[2] == SIGUSR1/
+ {
+ /*
+ * This is guaranteed to not race with signal-handle.
+ */
+ target = args[1]->pr_pid;
+ }
+
+ proc:::signal-handle
+ /target == pid && args[0] == SIGUSR1/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ $longsleep &
+ sleep 1
+ /usr/bin/kill -USR1 $!
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+longsleep="/usr/bin/sleep 10000"
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+pstop $child
+pkill -P $child
+kill $child
+prun $child
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.c
new file mode 100644
index 0000000..c9cc434
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.c
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <signal.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#define NANOSEC 1000000000
+
+int
+main(int argc, char **argv)
+{
+ struct sigevent ev;
+ struct itimerspec ts;
+ sigset_t set;
+ timer_t tid;
+ char *cmd = argv[0];
+ int sig;
+
+ ev.sigev_notify = SIGEV_SIGNAL;
+ ev.sigev_signo = SIGUSR1;
+
+ if (timer_create(CLOCK_REALTIME, &ev, &tid) == -1) {
+ (void) fprintf(stderr, "%s: cannot create CLOCK_HIGHRES "
+ "timer: %s\n", cmd, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ (void) sigemptyset(&set);
+ (void) sigaddset(&set, SIGUSR1);
+ (void) sigprocmask(SIG_BLOCK, &set, NULL);
+
+ ts.it_value.tv_sec = 1;
+ ts.it_value.tv_nsec = 0;
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = NANOSEC / 2;
+
+ if (timer_settime(tid, TIMER_RELTIME, &ts, NULL) == -1) {
+ (void) fprintf(stderr, "%s: timer_settime() failed: %s\n",
+ cmd, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ do {
+ (void) sigwait(&set, &sig);
+ } while(sig != SIGUSR1);
+
+ /*NOTREACHED*/
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d
new file mode 100644
index 0000000..bb82819
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option destructive
+
+proc:::signal-send
+/args[1]->p_pid == $1 && args[2] == SIGUSR1/
+{
+ sent = 1;
+}
+
+proc:::signal-clear
+/pid == $1 && args[0] == SIGUSR1 && sent/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.startexit.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.startexit.ksh
new file mode 100644
index 0000000..4291738
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.startexit.ksh
@@ -0,0 +1,89 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script tests that the firing order of probes in a process is:
+#
+# 1. proc:::start
+# 2. proc:::lwp-start
+# 3. proc:::lwp-exit
+# 4. proc:::exit
+#
+# If this fails, the script will run indefinitely; it relies on the harness
+# to time it out.
+#
+script()
+{
+ $dtrace -s /dev/stdin <<EOF
+ proc:::start
+ /curpsinfo->pr_ppid == $child/
+ {
+ self->start = 1;
+ }
+
+ proc:::lwp-start
+ /self->start/
+ {
+ self->lwp_start = 1;
+ }
+
+ proc:::lwp-exit
+ /self->lwp_start/
+ {
+ self->lwp_exit = 1;
+ }
+
+ proc:::exit
+ /self->lwp_exit == 1/
+ {
+ exit(0);
+ }
+EOF
+}
+
+sleeper()
+{
+ while true; do
+ /usr/bin/sleep 1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+sleeper &
+child=$!
+
+script
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZERO.profile.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZERO.profile.d
new file mode 100644
index 0000000..e4e031b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZERO.profile.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * profile without valid value keyword just call with 'n'.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-n
+{
+ printf("This test should fail\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonens.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonens.d
new file mode 100644
index 0000000..3ed28b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonens.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-'ns' less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1ns
+{
+ printf("Calls 'ns' less than 200 micro seconds\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonensec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonensec.d
new file mode 100644
index 0000000..7b4df19
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROonensec.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-1nsec; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1nsec
+{
+ printf("Call profile-1nsec; less than 200 micro seconds\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneus.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneus.d
new file mode 100644
index 0000000..6a64a3a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneus.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-us; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1us
+{
+ printf(" Calling profile-us less than 200 micro seconds should fail\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneusec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneusec.d
new file mode 100644
index 0000000..b6b80be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/err.D_PDESC_ZEROoneusec.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * profile-usec; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1usec
+{
+ printf("profile-usec; less than 200 micro seconds \n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d
new file mode 100644
index 0000000..26a40b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Either one of arg0 (or) arg1 should be 0 and non-zero.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1
+/(arg0 != 0 && arg1 == 0) || (arg0 == 0 && arg1 != 0)/
+{
+ printf("Test passed; either arg0/arg1 is zero\n");
+ exit(0);
+}
+
+tick-1
+/(arg0 == 0 && arg1 == 0) || (arg0 != 0 && arg1 != 0)/
+{
+ printf("Test failed; either arg0 (or) arg1 should be non zero\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d.out
new file mode 100644
index 0000000..0bd3353
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.argtest.d.out
@@ -0,0 +1,2 @@
+Test passed; either arg0/arg1 is zero
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d
new file mode 100644
index 0000000..df8bf98
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * profile-n simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1
+{
+ printf("This test is a simple profile-n provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d.out
new file mode 100644
index 0000000..09005bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.basic.d.out
@@ -0,0 +1,2 @@
+This test is a simple profile-n provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.func.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.func.ksh
new file mode 100644
index 0000000..358d362
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.func.ksh
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg0 != 0/
+ {
+ @[func(arg0)] = count();
+ }
+
+ tick-100ms
+ /i++ == 50/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ /usr/bin/date > /dev/null
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# This is gutsy -- we're assuming that mutex_enter(9F) will show up in the
+# output. This is most likely _not_ to show up in the output if the
+# platform does not support arbitrary resolution interval timers -- but
+# the above script was stress-tested down to 100 hertz and still ran
+# successfully on all platforms, so one is hopeful that this test will pass
+# even in that case.
+#
+script | tee /dev/fd/2 | grep mutex_enter > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.mod.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.mod.ksh
new file mode 100644
index 0000000..4652ff3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.mod.ksh
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg0 != 0/
+ {
+ @[mod(arg0)] = count();
+ }
+
+ tick-100ms
+ /i++ == 20/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ /usr/bin/date > /dev/null
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# The only thing we can be sure of is that some module named "unix" (or
+# "genunix") did some work -- so that's all we'll check.
+#
+script | tee /dev/fd/2 | grep unix > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d
new file mode 100644
index 0000000..ba69def
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-hz test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-100hz
+{
+ printf("This test is a simple profile-hz provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d.out
new file mode 100644
index 0000000..711f635
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilehz.d.out
@@ -0,0 +1 @@
+This test is a simple profile-hz provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d
new file mode 100644
index 0000000..7ec573e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-ms simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1ms
+{
+ printf("This test is a simple profile-ms provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d.out
new file mode 100644
index 0000000..1fe17e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilems.d.out
@@ -0,0 +1 @@
+This test is a simple profile-ms provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d
new file mode 100644
index 0000000..80451e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-msec simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1msec
+{
+ printf("This test is a simple profile-msec provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d.out
new file mode 100644
index 0000000..c3fb4a3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilemsec.d.out
@@ -0,0 +1 @@
+This test is a simple profile-msec provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d
new file mode 100644
index 0000000..37b2090
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * profile-<number> simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-100
+{
+ printf("This test is a simple profile implicit hz test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d.out
new file mode 100644
index 0000000..c9409ce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilenhz.d.out
@@ -0,0 +1 @@
+This test is a simple profile implicit hz test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d
new file mode 100644
index 0000000..72f95ad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-2000000000ns simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-2000000000ns
+{
+ printf("This test is a simple profile-ns provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d.out
new file mode 100644
index 0000000..86251d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilens.d.out
@@ -0,0 +1 @@
+This test is a simple profile-ns provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d
new file mode 100644
index 0000000..d0236e9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-nsec simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-2000000000nsec
+{
+ printf("This test is a simple profile-nsec provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d.out
new file mode 100644
index 0000000..890b769
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilensec.d.out
@@ -0,0 +1 @@
+This test is a simple profile-nsec provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d
new file mode 100644
index 0000000..65201fc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-s simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1s
+{
+ printf("This test is a simple profile-s provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d.out
new file mode 100644
index 0000000..03a0cf2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profiles.d.out
@@ -0,0 +1 @@
+This test is a simple profile-s provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d
new file mode 100644
index 0000000..3e52ac5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-sec simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-1sec
+{
+ printf("This test is a simple profile-sec provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d.out
new file mode 100644
index 0000000..9091592
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profilesec.d.out
@@ -0,0 +1 @@
+This test is a simple profile-sec provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d
new file mode 100644
index 0000000..32ab415
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-us simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-200us
+{
+ printf("This test is a simple profile-us provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d.out
new file mode 100644
index 0000000..aa27064
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileus.d.out
@@ -0,0 +1 @@
+This test is a simple profile-us provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d
new file mode 100644
index 0000000..78df000
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple profile-usec simple test.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+profile-200usec
+{
+ printf("This test is a simple profile-usec provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d.out
new file mode 100644
index 0000000..96dfef1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.profileusec.d.out
@@ -0,0 +1 @@
+This test is a simple profile-usec provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.sym.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.sym.ksh
new file mode 100644
index 0000000..218a651
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.sym.ksh
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg0 != 0/
+ {
+ @[sym(arg0)] = count();
+ }
+
+ tick-100ms
+ /i++ == 50/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ /usr/bin/date > /dev/null
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# This is the same gutsy test as that found in the func() test; see that
+# test for the rationale.
+#
+script | tee /dev/fd/2 | grep mutex_enter > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh
new file mode 100644
index 0000000..69c0f84
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufunc.ksh
@@ -0,0 +1,71 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg1 != 0/
+ {
+ @[ufunc(arg1)] = count();
+ }
+
+ tick-100ms
+ /i++ == 20/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ let i=i+1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# The only thing we can be sure of here is that we caught some function in
+# ksh doing work. (This actually goes one step further and assumes that we
+# catch some non-static function in ksh.)
+#
+script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.c
new file mode 100644
index 0000000..96d78a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.c
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+typedef void f(int x);
+
+static void
+f_a(int i)
+{
+}
+
+static void
+f_b(int i)
+{
+}
+
+static void
+f_c(int i)
+{
+}
+
+static void
+f_d(int i)
+{
+}
+
+static void
+f_e(int i)
+{
+}
+
+static void
+fN(f func, int i)
+{
+ func(i);
+}
+
+int
+main()
+{
+ fN(f_a, 1);
+ fN(f_b, 2);
+ fN(f_c, 3);
+ fN(f_d, 4);
+ fN(f_e, 5);
+ fN(f_a, 11);
+ fN(f_c, 13);
+ fN(f_d, 14);
+ fN(f_a, 101);
+ fN(f_c, 103);
+ fN(f_c, 1003);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh
new file mode 100644
index 0000000..4689355
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh
@@ -0,0 +1,66 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# ufunc() values sort as expected
+#
+# SECTION: Aggregations, Printing Aggregations
+#
+# NOTES: Assumes that the order of user function addresses will follow
+# the function declaration order.
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -c ./tst.ufuncsort.exe -s /dev/stdin <<EOF
+
+
+ #pragma D option quiet
+ #pragma D option aggsortkey
+
+ pid\$target::fN:entry
+ {
+ @[ufunc(arg0)] = count();
+ }
+EOF
+
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh.out
new file mode 100644
index 0000000..a364322
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.ufuncsort.ksh.out
@@ -0,0 +1,6 @@
+
+ tst.ufuncsort.exe`f_a 3
+ tst.ufuncsort.exe`f_b 1
+ tst.ufuncsort.exe`f_c 4
+ tst.ufuncsort.exe`f_d 2
+ tst.ufuncsort.exe`f_e 1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh
new file mode 100644
index 0000000..6ca823f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.umod.ksh
@@ -0,0 +1,69 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg1 != 0/
+ {
+ @[umod(arg1)] = count();
+ }
+
+ tick-100ms
+ /i++ == 20/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ let i=i+1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# The only thing we can be sure of here is that ksh is doing some work.
+#
+script | tee /dev/fd/2 | grep -w ksh > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh
new file mode 100644
index 0000000..b1a3ab9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/profile-n/tst.usym.ksh
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ profile-1234hz
+ /arg1 != 0/
+ {
+ @[usym(arg1)] = count();
+ }
+
+ tick-100ms
+ /i++ == 20/
+ {
+ exit(0);
+ }
+EOF
+}
+
+spinny()
+{
+ while true; do
+ let i=i+1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spinny &
+child=$!
+
+#
+# This test is essentially the same as that in the ufunc test; see that
+# test for the rationale.
+#
+script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null
+status=$?
+
+kill $child
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_INVAL.wrongdec4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_INVAL.wrongdec4.d
new file mode 100644
index 0000000..0a7aa14
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_INVAL.wrongdec4.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * call profile<provider name>; called with no "::::".
+ * should fail with compilation error.
+ *
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile::::tick-1sec
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.nonprofile.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.nonprofile.d
new file mode 100644
index 0000000..1356a89
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.nonprofile.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test;
+ * Call user created provider. Make sure it gives compilation error.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::test
+/i < 3/
+{
+ i++;
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec1.d
new file mode 100644
index 0000000..e06edee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec1.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * call profile::<provider name>; called with two "::".
+ * should fail with compilation error.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile::tick-1sec
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec2.d
new file mode 100644
index 0000000..ea8909c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec2.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * call profile:<provider name>; called with one ":".
+ * should fail with compilation error.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:tick-1sec
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec3.d
new file mode 100644
index 0000000..edea0b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/err.D_PDESC_ZERO.wrongdec3.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * call profile<provider name>; called with no ":".
+ * should fail with compilation error.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profiletick-1sec
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d
new file mode 100644
index 0000000..6b6e526
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test;
+ * Call same profile provider two times
+ * Match expected output in tst.basics.d.out
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 3/
+{
+ i++;
+ trace(i);
+}
+
+profile:::tick-1sec
+/i == 3/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d.out
new file mode 100644
index 0000000..190a180
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.basics.d.out
@@ -0,0 +1 @@
+123
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginexit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginexit.d
new file mode 100644
index 0000000..202abe6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginexit.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("shouldn't be here...");
+ here++;
+}
+
+END
+{
+ exit(here);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d
new file mode 100644
index 0000000..99989d9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probeprov, probemod, probefunc, probename' from
+ * BEGIN
+ * Match the output from tst.beginprof.d.out
+ *
+ * SECTION: profile Provider/profile-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%s %s %s %s", probeprov, probemod, probefunc, probename);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d.out
new file mode 100644
index 0000000..d28a057
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.beginprof.d.out
@@ -0,0 +1 @@
+dtrace BEGIN
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d
new file mode 100644
index 0000000..bd24ca0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probeprov, probemod, probefunc, probename' at once.
+ * Match expected output in tst.probattrs.d.out
+ *
+ *
+ * SECTION: profile Provider/tick-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ printf("%s %s %s %s", probeprov, probemod, probefunc, probename);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d.out
new file mode 100644
index 0000000..2a13979
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probattrs.d.out
@@ -0,0 +1 @@
+profile tick-1sec
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d
new file mode 100644
index 0000000..fa7c47c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probefunc' field i.e. Current probe description's function
+ * field.
+ * Match expected output in tst.probefunc.d.out
+ *
+ * SECTION: profile Provider/tick-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ printf("probe funct = %s", probefunc);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d.out
new file mode 100644
index 0000000..de191dd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probefunc.d.out
@@ -0,0 +1 @@
+probe funct =
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d
new file mode 100644
index 0000000..89fd8b2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probemod' field i.e. Current probe description's module
+ * field.
+ * Match expected output in tst.probemod.d.out
+ *
+ * SECTION: profile Provider/tick-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ printf("probe description module field = %s", probemod);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d.out
new file mode 100644
index 0000000..1c95a77
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probemod.d.out
@@ -0,0 +1 @@
+probe description module field =
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d
new file mode 100644
index 0000000..c58097f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probename' field i.e. Current probe description's name
+ * field.
+ * Match expected output in tst.probename.d.out
+ *
+ * SECTION: profile Provider/tick-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ printf("probe name = %s", probename);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d.out
new file mode 100644
index 0000000..e5ff3e0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probename.d.out
@@ -0,0 +1 @@
+probe name = tick-1sec
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d
new file mode 100644
index 0000000..3c3ccef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * print the 'probeprov' field i.e. Current probe description's provider
+ * field.
+ * Match expected output in tst.probeprov.d.out
+ *
+ * SECTION: profile Provider/tick-n probes;
+ * Variables/Built-in Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ printf("probe description provider = %s", probeprov);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d.out
new file mode 100644
index 0000000..d8ca594
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.probprov.d.out
@@ -0,0 +1 @@
+probe description provider = profile
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d
new file mode 100644
index 0000000..9ab438a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * Call simple profile with END profile.
+ * Match expected output in tst.profend.d.out
+ *
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ i++;
+ trace(i);
+ exit(0);
+}
+
+dtrace:::END
+{
+ printf("\nI'm at END");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d.out
new file mode 100644
index 0000000..42e3005
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profend.d.out
@@ -0,0 +1,2 @@
+1
+I'm at END
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d
new file mode 100644
index 0000000..884053f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test;
+ * Call simple profile
+ * Match expected output in tst.profexit.d.out
+ *
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ i++;
+ trace(i);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d.out
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.profexit.d.out
@@ -0,0 +1 @@
+1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d
new file mode 100644
index 0000000..ec7053d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * Call simple profile with trace() in END profile
+ * Match expected output in tst.trace.d.out
+ *
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+{
+ i++;
+ exit(0);
+}
+
+dtrace:::END
+{
+ trace(i);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d.out
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.trace.d.out
@@ -0,0 +1 @@
+1
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d
new file mode 100644
index 0000000..352ed0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Simple profile provider test.
+ * Call two different profile provider
+ * Match expected output in tst.twoprof.d.out
+ *
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 3/
+{
+ i++;
+ trace(i);
+}
+
+profile:::tick-100msec
+/i == 3/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d.out
new file mode 100644
index 0000000..190a180
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/providers/tst.twoprof.d.out
@@ -0,0 +1 @@
+123
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c
new file mode 100644
index 0000000..e391083
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.c
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#include <signal.h>
+
+int
+main(int argc, char **argv)
+{
+ sigset_t ss;
+
+ (void) sigemptyset(&ss);
+ (void) sigaddset(&ss, SIGINT);
+ (void) sigprocmask(SIG_BLOCK, &ss, NULL);
+
+ do {
+ (void) getpid();
+ (void) sigpending(&ss);
+ } while (!sigismember(&ss, SIGINT));
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d
new file mode 100644
index 0000000..cdc7154
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise1.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for raise
+ *
+ * SECTION: Actions and Subroutines/raise()
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the process to call getpid().
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:entry
+/pid == $1/
+{
+ trace("raised");
+ raise(SIGINT);
+ /*
+ * Wait no more than half a second for the process to die.
+ */
+ timeout = timestamp + 500000000;
+}
+
+syscall::exit:entry
+{
+ exit(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c
new file mode 100644
index 0000000..9089283
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.c
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+static void
+handle(int sig)
+{
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = handle;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ (void) sigaction(SIGINT, &sa, NULL);
+
+ for (;;) {
+ (void) getpid();
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d
new file mode 100644
index 0000000..4f68a0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise2.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for raise
+ *
+ * SECTION: Actions and Subroutines/raise()
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the process to call getpid().
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:return
+/pid == $1/
+{
+ trace("raised");
+ raise(SIGINT);
+ /*
+ * Wait no more than half a second for the process to die.
+ */
+ timeout = timestamp + 500000000;
+}
+
+syscall::exit:entry
+{
+ exit(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c
new file mode 100644
index 0000000..9089283
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.c
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+static void
+handle(int sig)
+{
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = handle;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ (void) sigaction(SIGINT, &sa, NULL);
+
+ for (;;) {
+ (void) getpid();
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d
new file mode 100644
index 0000000..cdc7154
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/raise/tst.raise3.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for raise
+ *
+ * SECTION: Actions and Subroutines/raise()
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the process to call getpid().
+ */
+ timeout = timestamp + 1000000000;
+}
+
+syscall::getpid:entry
+/pid == $1/
+{
+ trace("raised");
+ raise(SIGINT);
+ /*
+ * Wait no more than half a second for the process to die.
+ */
+ timeout = timestamp + 500000000;
+}
+
+syscall::exit:entry
+{
+ exit(0);
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d
new file mode 100644
index 0000000..513cd31
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * If the aggregation rate is set properly, there should be no aggregation
+ * drops.
+ *
+ * SECTION: Aggregations/Minimizing drops;
+ * Options and Tunables/aggrate;
+ * Options and Tunables/aggsize
+ */
+
+/*
+ * We rely on the fact that at least 30 bytes must be stored per aggregation
+ * iteration, but that no more than 300 bytes are stored per iteration.
+ * We are going to let this run for ten seconds. If the aggregation rate
+ * is being set properly, there should be no aggregation drops. Note that
+ * this test (regrettably) may be scheduling sensitive -- but it should only
+ * fail on the most pathological systems.
+ */
+#pragma D option aggsize=300
+#pragma D option aggrate=10msec
+#pragma D option quiet
+
+int n;
+
+tick-100msec
+/n < 100/
+{
+ @a[n++] = sum(n);
+}
+
+tick-100msec
+/n == 100/
+{
+ exit(0);
+}
+
+END
+{
+ printa("%10d\n", @a);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d.out
new file mode 100644
index 0000000..c45f929
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.aggrate.d.out
@@ -0,0 +1,101 @@
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.statusrate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.statusrate.d
new file mode 100644
index 0000000..43c23bf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.statusrate.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test of statusrate option.
+ *
+ * SECTION: Options and Tunables/statusrate
+ */
+
+/*
+ * Tests the statusrate option, by checking that the time delta between
+ * exit() and END is at least as long as mandated by the statusrate.
+ */
+
+#pragma D option statusrate=10sec
+
+inline uint64_t NANOSEC = 1000000000;
+
+tick-1sec
+/n++ > 5/
+{
+ exit(2);
+ ts = timestamp;
+}
+
+END
+/(this->delta = timestamp - ts) > 2 * NANOSEC/
+{
+ exit(0);
+}
+
+END
+/this->delta <= 2 * NANOSEC/
+{
+ printf("delta between exit() and END (%u nanos) too small",
+ this->delta);
+ exit(1);
+}
+
+END
+/this->delta > 20 * NANOSEC/
+{
+ printf("delta between exit() and END (%u nanos) too large",
+ this->delta);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d
new file mode 100644
index 0000000..691b31c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * If the switch rate is set properly, there should be no drops.
+ *
+ * SECTION: Buffers and Buffering/switch Policy;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/switchrate
+ */
+
+/*
+ * We rely on the fact that at least 8 bytes must be stored per iteration
+ * (EPID plus data), but that no more than 40 bytes are stored per iteration.
+ * We are going to let this run for ten seconds. If the switch rate
+ * is being set properly, there should be no drops. Note that this test
+ * (regrettably) may be scheduling sensitive -- but it should only fail on
+ * the most pathological systems.
+ */
+#pragma D option bufsize=40
+#pragma D option switchrate=10msec
+#pragma D option quiet
+
+int n;
+
+tick-100msec
+/n < 100/
+{
+ printf("%10d\n", n++);
+}
+
+tick-100msec
+/n == 100/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d.out
new file mode 100644
index 0000000..c45f929
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/rates/tst.switchrate.d.out
@@ -0,0 +1,101 @@
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.basename.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.basename.d
new file mode 100644
index 0000000..3def964
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.basename.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::entry
+/on/
+{
+ trace(basename((char *)rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(basename((char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.caller.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.caller.d
new file mode 100644
index 0000000..b9777c1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.caller.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Make sure that the caller variable is safe to use at every fbt probe
+ * point.
+ *
+ * SECTION: Variables/Built-in Variables;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ trace(caller);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.cleanpath.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.cleanpath.d
new file mode 100644
index 0000000..729f320
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.cleanpath.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(cleanpath((char *)rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(cleanpath((char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d
new file mode 100644
index 0000000..7426d19
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin.d
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * We set our buffer size absurdly low to prevent a flood of errors that we
+ * don't care about. We set our statusrate to be infinitely short to cause
+ * lots of activity by the DTrace process.
+ *
+ * SECTION: Actions and Subroutines/copyin();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+
+#pragma D option bufsize=16
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=1nsec
+
+syscall:::entry
+{
+ n++;
+ trace(copyin(rand(), 1));
+}
+
+syscall:::entry
+{
+ trace(copyin(rand() | 1, 1));
+}
+
+syscall:::entry
+{
+ trace(copyin(NULL, 1));
+}
+
+dtrace:::ERROR
+{
+ err++;
+}
+
+tick-1sec
+/sec++ == 10/
+{
+ exit(2);
+}
+
+END
+/n == 0 || err == 0/
+{
+ exit(1);
+}
+
+END
+/n != 0 && err != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin2.d
new file mode 100644
index 0000000..aef0944
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.copyin2.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Test that there is no value of 'size' which can be passed to copyin
+ * to cause mischief. The somewhat odd order of operations ensures
+ * that we test both size = 0 and size = 0xfff...fff
+ */
+#include <sys/types.h>
+
+
+#if defined(_LP64)
+#define MAX_BITS 63
+size_t size;
+#else
+#define MAX_BITS 31
+size_t size;
+#endif
+
+syscall:::
+/pid == $pid/
+{
+ printf("size = 0x%lx\n", (ulong_t)size);
+}
+
+syscall:::
+/pid == $pid/
+{
+ tracemem(copyin(curthread->t_procp->p_user.u_envp, size), 10);
+}
+
+syscall:::
+/pid == $pid && size > (1 << MAX_BITS)/
+{
+ exit(0);
+}
+
+syscall:::
+/pid == $pid/
+{
+ size = (size << 1ULL) | 1ULL;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ddi_pathname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ddi_pathname.d
new file mode 100644
index 0000000..7427568
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ddi_pathname.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(ddi_pathname((struct dev_info *)rand(), rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(ddi_pathname((struct dev_info *)arg1, rand()));
+}
+
+tick-1sec
+/n++ == 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.dirname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.dirname.d
new file mode 100644
index 0000000..791d9b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.dirname.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(dirname((char *)rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(dirname((char *)arg1));
+}
+
+tick-1sec
+/n++ == 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.errno.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.errno.d
new file mode 100644
index 0000000..d3f238b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.errno.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect errno at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[errno] = count();
+}
+
+profile-4999hz
+{
+ @a[errno] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.execname.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.execname.d
new file mode 100644
index 0000000..cd9ca21
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.execname.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect execname at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[execname] = count();
+}
+
+profile-4999hz
+{
+ @a[execname] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.gid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.gid.d
new file mode 100644
index 0000000..f8f90e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.gid.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect gid at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[gid] = count();
+}
+
+profile-4999hz
+{
+ @a[gid] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.hton.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.hton.d
new file mode 100644
index 0000000..d573bfd1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.hton.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(htons(0x1122));
+}
+
+fbt:::
+/on/
+{
+ trace(htonl(0x11223344));
+}
+
+fbt:::
+/on/
+{
+ trace(htonll(0x1122334455667788));
+}
+
+fbt:::
+/on/
+{
+ trace(ntohs(0x1122));
+}
+
+fbt:::
+/on/
+{
+ trace(ntohl(0x11223344));
+}
+
+fbt:::
+/on/
+{
+ trace(ntohll(0x1122334455667788));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.index.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.index.d
new file mode 100644
index 0000000..22b0b5b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.index.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(index((char *)rand(), (char *)(rand() ^ vtimestamp)));
+}
+
+fbt:::
+/on/
+{
+ trace(rindex((char *)rand(), (char *)(rand() ^ vtimestamp,
+ timestamp)));
+}
+
+fbt:::entry
+/on/
+{
+ trace(index((char *)arg0, (char *)arg1, rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(rindex((char *)arg0, (char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgdsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgdsize.d
new file mode 100644
index 0000000..c4e7c34
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgdsize.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Make sure that the msgdsize safe to use at every fbt probe
+ *
+ * SECTION: Actions and Subroutines/msgdsize();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(msgdsize((mblk_t *)rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(msgdsize((mblk_t *)arg1));
+}
+
+tick-1sec
+/n++ == 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgsize.d
new file mode 100644
index 0000000..42aebe4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.msgsize.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Make sure that the msgsize safe to use at every fbt probe
+ *
+ * SECTION: Actions and Subroutines/msgsize();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(msgsize((mblk_t *)rand()));
+}
+
+fbt:::
+/on/
+{
+ trace(msgdsize((mblk_t *)rand()));
+}
+
+tick-1sec
+/n++ == 20/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.null.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.null.d
new file mode 100644
index 0000000..cafa3af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.null.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * trace with NULL argument - generate a bunch of errors
+ *
+ * SECTION: Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+/*
+ * We set our buffer size absurdly low to prevent a flood of errors that we
+ * don't care about.
+ */
+
+#pragma D option bufsize=16
+#pragma D option bufpolicy=ring
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ n++;
+ trace(*(int *)NULL);
+}
+
+dtrace:::ERROR
+{
+ err++;
+}
+
+tick-1sec
+/sec++ == 10/
+{
+ exit(2);
+}
+
+END
+/n == 0 || err == 0/
+{
+ exit(1);
+}
+
+END
+/n != 0 && err != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.pid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.pid.d
new file mode 100644
index 0000000..2b7a92e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.pid.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect pid at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[pid] = count();
+}
+
+profile-4999hz
+{
+ @a[pid] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ppid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ppid.d
new file mode 100644
index 0000000..faf07dc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ppid.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect ppid at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[ppid] = count();
+}
+
+profile-4999hz
+{
+ @a[ppid] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.progenyof.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.progenyof.d
new file mode 100644
index 0000000..d488fe2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.progenyof.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * trace progenyof() at every fbt probe point.
+ *
+ * SECTION: Actions and Subroutines/progenyof();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ trace(progenyof(rand()));
+}
+
+profile-4999hz
+{
+ trace(progenyof(rand()));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.random.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.random.d
new file mode 100644
index 0000000..8d157ef
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.random.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * trace rand() at every fbt probe point.
+ *
+ * SECTION: Actions and Subroutines/rand();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy
+ */
+
+/*
+ * We set our buffer size absurdly low to prevent a flood of errors that we
+ * don't care about.
+ */
+
+#pragma D option bufsize=16
+#pragma D option bufpolicy=ring
+
+fbt:::
+{
+ n++;
+ trace(*(int *)rand());
+}
+
+dtrace:::ERROR
+{
+ err++;
+}
+
+tick-1sec
+/sec++ == 10/
+{
+ exit(2);
+}
+
+END
+/n == 0 || err == 0/
+{
+ exit(1);
+}
+
+END
+/n != 0 && err != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d
new file mode 100644
index 0000000..c1fcd85
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ @[rw_read_held((struct rwlock *)&`unp_global_rwlock)] = count();
+ @[rw_read_held((struct rwlock *)rand())] = count();
+}
+
+fbt:::
+/on/
+{
+ @[rw_write_held((struct rwlock *)&`unp_global_rwlock)] = count();
+ @[rw_write_held((struct rwlock *)rand())] = count();
+}
+
+fbt:::
+/on/
+{
+ @[rw_iswriter((struct rwlock *)&`unp_global_rwlock)] = count();
+ @[rw_iswriter((struct rwlock *)rand())] = count();
+}
+
+tick-1sec
+/n++ == 20/
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.shortstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.shortstr.d
new file mode 100644
index 0000000..188f705
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.shortstr.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option strsize=16
+
+BEGIN
+{
+ this->str = ",,,Carrots,,Barley,Oatmeal,,,,,,,,,,,,,,,,,,Beans,";
+}
+
+BEGIN
+{
+ strtok(this->str, ",");
+}
+
+BEGIN
+{
+ this->str = ",,,,,,,,,,,,,,,,,,,,,,Carrots,";
+ strtok(this->str, ",");
+}
+
+BEGIN
+{
+ strtok(this->str, "a");
+}
+
+BEGIN
+{
+ printf("%s\n", substr(this->str, 1, 40));
+}
+
+BEGIN
+{
+ printf("%s\n", strjoin(this->str, this->str));
+}
+
+BEGIN
+{
+ this->str1 = ".........................................";
+ printf("%d\n", index(this->str, this->str1));
+}
+
+BEGIN
+{
+ printf("%d\n", rindex(this->str, this->str1));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stack.d
new file mode 100644
index 0000000..57588b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stack.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call stack() at every fbt probe point.
+ *
+ * SECTION: Actions and Subroutines/stack();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ stack();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stackdepth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stackdepth.d
new file mode 100644
index 0000000..a39387f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stackdepth.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test that the stackdepth variable is safe to use at every fbt probe
+ * point.
+ *
+ * SECTION: Variables/Built-in Variables;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ trace(stackdepth);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stddev.d
new file mode 100644
index 0000000..927930d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stddev.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call stddev() at every fbt probe point.
+ *
+ * SECTION: Actions and Subroutines/stddev();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ @a = stddev(1);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strchr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strchr.d
new file mode 100644
index 0000000..bc95c48
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strchr.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(strchr((char *)(rand() ^ timestamp), rand()));
+}
+
+fbt:::
+/on/
+{
+ trace(strrchr((char *)(rand() ^ timestamp), rand()));
+}
+
+fbt:::entry
+/on/
+{
+ trace(strchr((char *)arg0, '!'));
+}
+
+fbt:::entry
+/on/
+{
+ trace(strrchr((char *)arg0, '!'));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strjoin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strjoin.d
new file mode 100644
index 0000000..5ed2935
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strjoin.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(strjoin((char *)rand(), (char *)(rand() ^ vtimestamp)));
+}
+
+fbt:::entry
+/on/
+{
+ trace(strjoin((char *)arg0, (char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strstr.d
new file mode 100644
index 0000000..025e547
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strstr.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(strstr((char *)rand(), (char *)(rand() ^ vtimestamp)));
+}
+
+fbt:::entry
+/on/
+{
+ trace(strstr((char *)arg0, (char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strtok.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strtok.d
new file mode 100644
index 0000000..1027d2e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.strtok.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(strtok((char *)rand(), (char *)(rand() ^ vtimestamp)));
+}
+
+fbt:::entry
+/on/
+{
+ trace(strtok((char *)arg0, (char *)arg1));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.substr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.substr.d
new file mode 100644
index 0000000..d5ed9a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.substr.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ on = (timestamp / 1000000000) & 1;
+}
+
+fbt:::
+/on/
+{
+ trace(substr((char *)rand(), rand() ^ vtimestamp));
+}
+
+fbt:::
+/on/
+{
+ trace(substr((char *)rand(), -rand() ^ vtimestamp));
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ucaller.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ucaller.d
new file mode 100644
index 0000000..524c88b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ucaller.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect ucaller at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[ucaller] = count();
+}
+
+profile-4999hz
+{
+ @a[ucaller] = count();
+}
+
+tick-1sec
+/n++ == 30/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uid.d
new file mode 100644
index 0000000..b546457
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uid.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect uid at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[uid] = count();
+}
+
+profile-4999hz
+{
+ @a[uid] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.unalign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.unalign.d
new file mode 100644
index 0000000..e996cbd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.unalign.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * We set our buffer size absurdly low to prevent a flood of errors that we
+ * don't care about. Note that this test (unlike some other safety tests)
+ * doesn't check the error count -- some architectures have no notion of
+ * alignment.
+ */
+#pragma D option bufsize=16
+#pragma D option bufpolicy=ring
+
+fbt:::
+{
+ n++;
+ trace(*(int *)(rand() | 1));
+}
+
+tick-1sec
+/sec++ == 10/
+{
+ exit(2);
+}
+
+END
+/n == 0/
+{
+ exit(1);
+}
+
+END
+/n != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uregs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uregs.d
new file mode 100644
index 0000000..b13434d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.uregs.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Trace uregs[0] at every fbt probe point.
+ * SECTION: Variables/Built-in Variables;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ trace(uregs[0]);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustack.d
new file mode 100644
index 0000000..a286382
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustack.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call ustack() at every fbt probe point.
+ *
+ * SECTION: Actions and Subroutines/ustack();
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ ustack();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustackdepth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustackdepth.d
new file mode 100644
index 0000000..942913c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.ustackdepth.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test that the ustackdepth variable is safe to use at every fbt probe
+ * point.
+ *
+ * SECTION: Variables/Built-in Variables;
+ * Options and Tunables/bufsize;
+ * Options and Tunables/bufpolicy;
+ * Options and Tunables/statusrate
+ */
+
+#pragma D option bufsize=1000
+#pragma D option bufpolicy=ring
+#pragma D option statusrate=10ms
+
+fbt:::
+{
+ trace(ustackdepth);
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.vahole.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.vahole.d
new file mode 100644
index 0000000..2ef40a5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.vahole.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -Cs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * We set our buffer size absurdly low to prevent a flood of errors that we
+ * don't care about.
+ */
+#pragma D option bufsize=16
+#pragma D option bufpolicy=ring
+
+fbt:::
+{
+ n++;
+#ifdef __sparc
+ trace(*(int *)0x8000000000000000 ^ rand());
+#else
+ trace(*(int *)(`kernelbase - 1));
+#endif
+}
+
+dtrace:::ERROR
+{
+ err++;
+}
+
+tick-1sec
+/sec++ == 10/
+{
+ exit(2);
+}
+
+END
+/n == 0 || err == 0/
+{
+ exit(1);
+}
+
+END
+/n != 0 && err != 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.violentdeath.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.violentdeath.ksh
new file mode 100644
index 0000000..879774a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.violentdeath.ksh
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+script()
+{
+ $dtrace -x bufpolicy=ring -x bufsize=1k -s /dev/stdin <<EOF
+ fbt:::
+ {}
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+let i=0
+
+while [ "$i" -lt 10 ]; do
+ script &
+ child=$!
+ sleep 1
+ kill -9 $child
+ let i=i+1
+done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.zonename.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.zonename.d
new file mode 100644
index 0000000..5fc025f95
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.zonename.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * collect zonename at every fbt probe and at every firing of a
+ * high-frequency profile probe
+ */
+
+fbt:::
+{
+ @a[zonename] = count();
+}
+
+profile-4999hz
+{
+ @a[zonename] = count();
+}
+
+tick-1sec
+/n++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_ARR_LOCAL.thisarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_ARR_LOCAL.thisarray.d
new file mode 100644
index 0000000..289d164
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_ARR_LOCAL.thisarray.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Use 'this' variables in associative array.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+this int y;
+this int z;
+this int res;
+
+BEGIN
+{
+ this->x[this->y, this->z] = 123;
+ this->res = this->x[this->y, this->z]++;
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.selfthis.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.selfthis.d
new file mode 100644
index 0000000..eda1151
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.selfthis.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declare a variable and assign inappropriate value.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+self this int x;
+
+BEGIN
+{
+ x = "dummy";
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.thisself.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.thisself.d
new file mode 100644
index 0000000..f9c596b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_CLASS.thisself.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Multiple storage declarations.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+this self int x;
+
+BEGIN
+{
+ x = "dummy";
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_IDRED.errval.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_IDRED.errval.d
new file mode 100644
index 0000000..3130fbf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_DECL_IDRED.errval.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declare a variable with different data types.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+int x;
+char x;
+double x;
+long x;
+
+BEGIN
+{
+ x = 123;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dec.err.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dec.err.d
new file mode 100644
index 0000000..4261e07
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dec.err.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a variable and assign inappropriate value.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+int x;
+
+BEGIN
+{
+ x = "dummy";
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupgtype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupgtype.d
new file mode 100644
index 0000000..71f9c0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupgtype.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test assigning a variable two different incompatible types.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+BEGIN
+{
+ x = `kmem_flags;
+ x = *`rootvp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupltype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupltype.d
new file mode 100644
index 0000000..c316441
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupltype.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test assigning a variable two different incompatible types.
+ *
+ * SECTION: Variables/Clause-Local Variables
+ *
+ */
+
+BEGIN
+{
+ this->x = `kmem_flags;
+ this->x = *`rootvp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupttype.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupttype.d
new file mode 100644
index 0000000..23f26f7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_OP_INCOMPAT.dupttype.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test assigning a variable two different incompatible types.
+ * Test assigning a variable two different incompatible types.
+ *
+ * SECTION: Variables/Thread-Local Variables
+ *
+ */
+
+BEGIN
+{
+ self->x = `kmem_flags;
+ self->x = *`rootvp;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_SYNTAX.declare.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_SYNTAX.declare.d
new file mode 100644
index 0000000..246236a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/err.D_SYNTAX.declare.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a variable Inside Begin and make sure compilation fails.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+BEGIN
+{
+ int x = 123;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d
new file mode 100644
index 0000000..5561631
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Global variables defined once, is visible in every clause of
+ * D program
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+#pragma D option quiet
+
+int x;
+
+BEGIN
+{
+ x = 123;
+}
+
+profile:::tick-1sec
+{
+ printf("The value of x is %d\n", x);
+}
+
+profile:::tick-100msec
+{
+ printf("The value of x is %d\n", x);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d.out
new file mode 100644
index 0000000..2b8999e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.basicvar.d.out
@@ -0,0 +1,2 @@
+The value of x is 123
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.localvar.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.localvar.d
new file mode 100644
index 0000000..9a89a04
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.localvar.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Assign a value to a variable in a local clause.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+}
+int i;
+
+profile:::tick-1sec
+{
+ i = 0;
+}
+
+profile:::tick-100msec
+{
+ printf("The value of int i is %d\n", i);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.misc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.misc.d
new file mode 100644
index 0000000..3b6eb7a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.misc.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the different kinds of integer scalar references. In particular, we
+ * test accessing a kernel executable scalar, kernel scoped scalar, DTrace
+ * scalar first ref that forces creation (both global and TLS), and DTrace
+ * scalar subsequent reference (both global and TLS).
+ *
+ * SECTION: Variables/External Variables
+ *
+ */
+
+BEGIN
+{
+ printf("\nkmem_flags = 0x%x\n", `kmem_flags);
+ printf("ufs`ufs_allow_shared_writes = %d\n",
+ ufs`ufs_allow_shared_writes);
+ x = 123;
+ printf("x = %u\n", x);
+ self->x = 456;
+ printf("self->x = %u\n", self->x);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.self.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.self.d
new file mode 100644
index 0000000..514f385
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.self.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declare self a variable and assign appropriate value.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+self x;
+
+BEGIN
+{
+ x = "dummy";
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray.d
new file mode 100644
index 0000000..410e8de
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a self variable and assign appropriate value.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+
+self int y;
+self int z;
+self int res;
+
+BEGIN
+{
+ self->x[self->y, self->z] = 123;
+ self->res = self->x[self->y, self->z]++;
+ printf("The result = %d\n", self->res);
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray2.d
new file mode 100644
index 0000000..2fd69c6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfarray2.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+#pragma D option destructive
+#pragma D option dynvarsize=1m
+
+struct bar {
+ int pid;
+ kthread_t *curthread;
+};
+
+self struct bar foo[int];
+
+syscall:::entry
+/!self->foo[0].pid/
+{
+ self->foo[0].pid = pid;
+ self->foo[0].curthread = curthread;
+}
+
+syscall:::entry
+/self->foo[0].pid != pid/
+{
+ printf("expected %d, found %d (found curthread %p, curthread is %p)\n",
+ pid, self->foo[0].pid, self->foo[0].curthread, curthread);
+ exit(1);
+}
+
+tick-100hz
+{
+ system("date > /dev/null")
+}
+
+tick-1sec
+/i++ == 10/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfthis.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfthis.d
new file mode 100644
index 0000000..7bbfaf7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.selfthis.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Declare a this variable and assign value of self variable to it.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+self int x;
+this int y;
+
+BEGIN
+{
+ this->x = 123;
+ self->y = this->x;
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.this.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.this.d
new file mode 100644
index 0000000..01ea89f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.this.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple 'this' declaration.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+this x;
+
+BEGIN
+{
+ x = "dummy";
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.thisself.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.thisself.d
new file mode 100644
index 0000000..925dff2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scalars/tst.thisself.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declare a self value and assign value of 'this' variable to that.
+ *
+ * SECTION: Variables/Scalar Variables
+ *
+ */
+self int x;
+this int y;
+
+BEGIN
+{
+ self->x = 123;
+ this->y = self->x;
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.enqueue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.enqueue.d
new file mode 100644
index 0000000..77105c1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.enqueue.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option switchrate=100hz
+#pragma D option destructive
+
+sched:::enqueue
+/pid == 0 && args[1]->pr_pid == $pid/
+{
+ self->one = 1;
+}
+
+sched:::enqueue
+/self->one && args[2]->cpu_id >= 0 && args[2]->cpu_id <= `max_cpuid/
+{
+ self->two = 1;
+}
+
+sched:::enqueue
+/self->two && args[0]->pr_lwpid > 0/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.oncpu.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.oncpu.d
new file mode 100644
index 0000000..2571767
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.oncpu.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option switchrate=100hz
+#pragma D option destructive
+
+sched:::on-cpu
+/pid == $pid/
+{
+ self->on++;
+}
+
+sched:::off-cpu
+/pid == $pid && self->on/
+{
+ self->off++;
+}
+
+sched:::off-cpu
+/self->on > 50 && self->off > 50/
+{
+ exit(0);
+}
+
+profile:::tick-1sec
+/n++ > 10/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.stackdepth.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.stackdepth.d
new file mode 100644
index 0000000..b425127
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sched/tst.stackdepth.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option switchrate=100hz
+
+sched:::on-cpu
+/stackdepth > 0/
+{
+ exit(0);
+}
+
+tick-1s
+/i++ == 3/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d
new file mode 100644
index 0000000..27d969e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Try to print arguments not provided.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ print("The arguments are %d %d\n", $1, $2);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d
new file mode 100644
index 0000000..5bf4675
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Try to update a read-only macro.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ $pid++;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d
new file mode 100644
index 0000000..649cbdb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Try to assign value to Macro.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ pid = 1;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.concat.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.concat.d
new file mode 100644
index 0000000..00a2996
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.concat.d
@@ -0,0 +1,45 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Try to concat macro with user variables in provider description
+ * section.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+/i = 123$pid/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.desc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.desc.d
new file mode 100644
index 0000000..3dfa2b2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.desc.d
@@ -0,0 +1,49 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Try to call providers using macro variables.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+/i = 123$pid/
+{
+ exit(0);
+}
+
+pid$pid
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d
new file mode 100644
index 0000000..28b251c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt to print invalid arguments.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ print("The arguments are %d %d\n", $-1);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d
new file mode 100644
index 0000000..d9711d2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt to concat and assign a macro to a variable
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ i = 123$pid;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh
new file mode 100644
index 0000000..cc1e6dd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh
@@ -0,0 +1,80 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Attempt to pass some arguments and try not to print it.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$.d
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+BEGIN
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+$dtrace -x errtags -s $dfilename "this is test" 1>/dev/null \
+ 2>/var/tmp/err.$$.txt
+
+if [ $? -ne 1 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+grep "D_MACRO_UNUSED" /var/tmp/err.$$.txt >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ print -u2 "Expected error D_MACRO_UNUSED not returned"
+ /bin/rm -f /var/tmp/err.$$.txt
+ exit 1
+fi
+
+/bin/rm -f $dfilename
+/bin/rm -f /var/tmp/err.$$.txt
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arg0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arg0.d
new file mode 100644
index 0000000..999dbc3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arg0.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print argument 0 I mean "$0"
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The arg0 is %s\n", $0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh
new file mode 100644
index 0000000..6ec078a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh
@@ -0,0 +1,90 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Pass 10 arguments and try to print them.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+bname=`/usr/bin/basename $0`
+
+dfilename=/var/tmp/$bname.$$
+
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+{
+ printf("%d %d %d %d %d %d %d %d %d %d", \$1, \$2, \$3, \$4, \$5, \$6,
+ \$7, \$8, \$9, \$10);
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+
+output=`$dfilename 1 2 3 4 5 6 7 8 9 10 2>/dev/null`
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+set -A outarray $output
+
+if [[ ${outarray[0]} != 1 || ${outarray[1]} != 2 || ${outarray[2]} != 3 || \
+ ${outarray[3]} != 4 || ${outarray[4]} != 5 || ${outarray[5]} != 6 || \
+ ${outarray[6]} != 7 || ${outarray[7]} != 8 || ${outarray[8]} != 9 || \
+ ${outarray[9]} != 10 ]]; then
+ print -u2 "Error in output by $dfilename"
+ exit 1
+fi
+
+/bin/rm -f $dfilename
+exit 0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.assign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.assign.d
new file mode 100644
index 0000000..5dd1740
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.assign.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Assign macros to variables
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ processid = $pid;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.basic.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.basic.d
new file mode 100644
index 0000000..a407f83
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.basic.d
@@ -0,0 +1,42 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Basic script which uses exit(0) to exit.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.d
new file mode 100644
index 0000000..3899d2a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints effective group id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The egid is %d\n", $egid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh
new file mode 100644
index 0000000..afee24f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh
@@ -0,0 +1,97 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+#
+# To verify egid of current process
+#
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/usr/bin/basename $0`
+dfilename=/var/tmp/$bname.$$.d
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$egid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$egid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#chmod 555 the .d file
+
+chmod 555 $dfilename >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ print -u2 "chmod $dfilename failed"
+ exit 1
+fi
+
+#Get the groupid of the calling process using ps
+
+groupid=`ps -o pid,pgid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+#Pass groupid as argument to .d file
+$dfilename $groupid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#Cleanup leftovers
+
+/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.d
new file mode 100644
index 0000000..e4cdaa6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.d
@@ -0,0 +1,44 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Script which prints effective user id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The euid is %d\n", $euid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh
new file mode 100644
index 0000000..1b6b9b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify euid of current process
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$euid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$euid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+userid=`ps -o pid,uid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $userid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.d
new file mode 100644
index 0000000..c3329ce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints group id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The gid is %d\n", $gid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh
new file mode 100644
index 0000000..332b8e70
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify gid of the child process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$gid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$gid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+groupid=`ps -o pid,gid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $groupid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pgid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pgid.d
new file mode 100644
index 0000000..e01b996
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pgid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints effective process group id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The pgid is %d\n", $pgid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pid.d
new file mode 100644
index 0000000..1364366
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.pid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints pid.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The pid is %d\n", $pid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.d
new file mode 100644
index 0000000..8712cd9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints parent processid
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The ppid is %d\n", $ppid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh
new file mode 100644
index 0000000..bbd9a53
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify ppid of child process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$.d
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$ppid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$ppid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#chmod the .d file to 555
+
+chmod 555 $dfilename >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ print -u2 "chmod 555 $dfilename failed"
+ exit 1
+fi
+
+#Pass current pid (I mean parent pid for .d script).
+
+$dfilename $$ >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.d
new file mode 100644
index 0000000..a81ab8e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints current project id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The projid is %d\n", $projid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh
new file mode 100644
index 0000000..62bc817
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify projid of child process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$projid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$projid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+projectid=`ps -o pid,projid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $projectid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.quite.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.quite.d
new file mode 100644
index 0000000..c61debe
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.quite.d
@@ -0,0 +1,42 @@
+#!/usr/sbin/dtrace -qs
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which uses -qs in scripting line
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.d
new file mode 100644
index 0000000..87bab53
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints session id.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The sid is %d\n", $sid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh
new file mode 100644
index 0000000..477ebc0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify sid of current process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$sid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$sid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+sessionid=`ps -o pid,sid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get sid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $sessionid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh
new file mode 100644
index 0000000..724bd5f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# Pass a bunch of strings as a sentence and print them
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$.d
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+BEGIN
+{
+ printf("%s", \$\$1);
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+output=`$dfilename 'this is test' 2>/dev/null`
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+if [ "$output" != "this is test" ]; then
+ print -u2 "Expected output not returned"
+ exit 1
+fi
+
+/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.d
new file mode 100644
index 0000000..617827c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Script which prints taskid.
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The taskid is %d\n", $taskid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh
new file mode 100644
index 0000000..88b450d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify taskid of current process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$taskid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$taskid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+taskidval=`ps -o pid,taskid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $taskidval >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.trace.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.trace.d
new file mode 100644
index 0000000..34ba243
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.trace.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * To use trace in a script
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ trace("hello");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.d
new file mode 100644
index 0000000..f3ebca6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.d
@@ -0,0 +1,43 @@
+#!/usr/sbin/dtrace -s
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * print uid in a script
+ *
+ * SECTION: Scripting
+ *
+ */
+
+BEGIN
+{
+ printf("The uid is %d\n", $uid);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh
new file mode 100644
index 0000000..fabf0ed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+############################################################################
+# ASSERTION:
+# To verify uid of current process.
+#
+# SECTION: Scripting
+#
+############################################################################
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+bname=`/bin/basename $0`
+dfilename=/var/tmp/$bname.$$
+
+## Create .d file
+##########################################################################
+cat > $dfilename <<-EOF
+#!$dtrace -qs
+
+
+BEGIN
+/\$uid != \$1/
+{
+ exit(1);
+}
+
+BEGIN
+/\$uid == \$1/
+{
+ exit(0);
+}
+EOF
+##########################################################################
+
+
+#Call dtrace -C -s <.d>
+
+chmod 555 $dfilename
+
+userid=`ps -o pid,uid | grep "$$ " | awk '{print $2}' 2>/dev/null`
+if [ $? -ne 0 ]; then
+ print -u2 "unable to get uid of the current process with pid = $$"
+ exit 1
+fi
+
+$dfilename $userid >/dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ print -u2 "Error in executing $dfilename"
+ exit 1
+fi
+
+#/bin/rm -f $dfilename
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
new file mode 100644
index 0000000..e2e9505
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#ifndef __FreeBSD__
+#include <sys/uadmin.h>
+#endif
+
+int
+main(int argc, char **argv)
+{
+#ifdef __FreeBSD__
+ return (1);
+#else
+ while (1) {
+ if (uadmin(A_SDTTEST, 0, 0) < 0) {
+ perror("uadmin");
+ return (1);
+ }
+
+ sleep(1);
+ }
+
+ return (0);
+#endif
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
new file mode 100644
index 0000000..0523de0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that argN (1..7) variables are properly remapped.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+ ignore = $1;
+}
+
+ERROR
+{
+ printf("sdt:::test failed.\n");
+ exit(1);
+}
+
+sdt:::test
+/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6 ||
+ arg6 != 7/
+{
+ printf("sdt arg mismatch\n\n");
+ printf("args are : %d, %d, %d, %d, %d, %d, %d\n", arg0, arg1, arg2,
+ arg3, arg4, arg5, arg6);
+ printf("should be : 1, 2, 3, 4, 5, 6, 7\n");
+ exit(1);
+}
+
+sdt:::test
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_BADREF.SizeofAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_BADREF.SizeofAssoc.d
new file mode 100644
index 0000000..9ace419
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_BADREF.SizeofAssoc.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. For an associative array, the D compiler should throw an error since
+ * an associative array does not have a fixed size.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ assoc_array[0] = 010;
+ assoc_array[1] = 100;
+ assoc_array[2] = 210;
+
+ printf("sizeof (assoc_array): %d\n", sizeof (assoc_array));
+ printf("sizeof (assoc_array[0]): %d\n", sizeof (assoc_array[0]));
+ printf("sizeof (assoc_array[1]): %d\n", sizeof (assoc_array[1]));
+ printf("sizeof (assoc_array[2]): %d\n", sizeof (assoc_array[2]));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_UNDEF.UnknownSymbol.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_UNDEF.UnknownSymbol.d
new file mode 100644
index 0000000..f2dcdfa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_IDENT_UNDEF.UnknownSymbol.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: The D compiler throws a D_IDENT_UNDEF error when sizeof is passed
+ * an unknown symbol.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sizeof (`): %d\n", sizeof (`));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.badstruct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.badstruct.d
new file mode 100644
index 0000000..c921db8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.badstruct.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ trace(sizeof (struct suckitlarry));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.d
new file mode 100644
index 0000000..43c493a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SIZEOF_TYPE.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * sizeof() should handle invalid types
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+
+BEGIN
+{
+ trace(sizeof (void));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SYNTAX.SizeofBadType.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SYNTAX.SizeofBadType.d
new file mode 100644
index 0000000..85519e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/err.D_SYNTAX.SizeofBadType.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. When an operator or non-symbol is passed as an argument to sizeof
+ * operator, the D_SYNTAX error is thrown by the compiler.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sizeof (*): %d\n", sizeof (*));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofArray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofArray.d
new file mode 100644
index 0000000..8843728
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofArray.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. For a simpler array, the sizeof on the array variable itself gives
+ * the sum total of memory allocated to the array in bytes. With individual
+ * members of the array it gives their respective sizes.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+
+int array[5];
+
+BEGIN
+{
+ array[0] = 010;
+ array[1] = 100;
+ array[2] = 210;
+
+ printf("sizeof (array): %d\n", sizeof (array));
+ printf("sizeof (array[0]): %d\n", sizeof (array[0]));
+ printf("sizeof (array[1]): %d\n", sizeof (array[1]));
+ printf("sizeof (array[2]): %d\n", sizeof (array[2]));
+
+ exit(0);
+}
+
+END
+/(20 != sizeof (array)) || (4 != sizeof (array[0])) || (4 != sizeof (array[1]))
+ || (4 != sizeof (array[2]))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofDataTypes.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofDataTypes.d
new file mode 100644
index 0000000..fe558e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofDataTypes.d
@@ -0,0 +1,122 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ */
+#pragma D option quiet
+
+char new_char;
+short new_short;
+int new_int;
+long new_long;
+long long new_long_long;
+int8_t new_int8;
+int16_t new_int16;
+int32_t new_int32;
+int64_t new_int64;
+intptr_t new_intptr;
+uint8_t new_uint8;
+uint16_t new_uint16;
+uint32_t new_uint32;
+uint64_t new_uint64;
+uintptr_t new_uintptr;
+
+/*
+float new_float;
+double new_double;
+long double new_long_double;
+
+string new_string;
+*/
+
+struct record {
+ char ch;
+ int in;
+} new_struct;
+
+struct {
+ char ch;
+ int in;
+} anon_struct;
+
+union record {
+ char ch;
+ int in;
+} new_union;
+
+union {
+ char ch;
+ int in;
+} anon_union;
+
+enum colors {
+ RED,
+ GREEN,
+ BLUE
+} new_enum;
+
+
+int *pointer;
+
+BEGIN
+{
+ printf("sizeof (new_char): %d\n", sizeof (new_char));
+ printf("sizeof (new_short): %d\n", sizeof (new_short));
+ printf("sizeof (new_int): %d\n", sizeof (new_int));
+ printf("sizeof (new_long): %d\n", sizeof (new_long));
+ printf("sizeof (new_long_long): %d\n", sizeof (new_long_long));
+ printf("sizeof (new_int8): %d\n", sizeof (new_int8));
+ printf("sizeof (new_int16): %d\n", sizeof (new_int16));
+ printf("sizeof (new_int32): %d\n", sizeof (new_int32));
+ printf("sizeof (new_int64): %d\n", sizeof (new_int64));
+ printf("sizeof (pointer): %d\n", sizeof (pointer));
+ printf("sizeof (intptr_t): %d\n", sizeof (intptr_t));
+ printf("sizeof (new_struct): %d\n", sizeof (new_struct));
+ printf("sizeof (anon_struct): %d\n", sizeof (anon_struct));
+ printf("sizeof (new_union): %d\n", sizeof (new_union));
+ printf("sizeof (anon_union): %d\n", sizeof (anon_union));
+ printf("sizeof (new_enum): %d\n", sizeof (new_enum));
+ exit(0);
+}
+
+END
+/(1 != sizeof (new_char)) || (2 != sizeof (new_short)) ||
+ (4 != sizeof (new_int)) ||
+ ((4 != sizeof (new_long)) && (8 != sizeof (new_long))) ||
+ (8 != sizeof (new_long_long)) ||
+ (1 != sizeof (new_int8)) || (2 != sizeof (new_int16)) ||
+ (4 != sizeof (new_int32)) || (8 != sizeof (new_int64)) ||
+ (sizeof (pointer) != sizeof (new_intptr)) || (8 != sizeof (new_struct)) ||
+ (4 != sizeof (new_union)) || (4 != sizeof (new_enum))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofExpression.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofExpression.d
new file mode 100644
index 0000000..0bb7f68
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofExpression.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the use of sizeof with expressions.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sizeof ('c') : %d\n", sizeof ('c'));
+ printf("sizeof (10 * 'c') : %d\n", sizeof (10 * 'c'));
+ printf("sizeof (100 + 12345) : %d\n", sizeof (100 + 12345));
+ printf("sizeof (1234567890) : %d\n", sizeof (1234567890));
+
+ printf("sizeof (1234512345 * 1234512345 * 12345678 * 1ULL) : %d\n",
+ sizeof (1234512345 * 1234512345 * 12345678 * 1ULL));
+ printf("sizeof (-129) : %d\n", sizeof (-129));
+ printf("sizeof (0x67890/0x77000) : %d\n", sizeof (0x67890/0x77000));
+
+ printf("sizeof (3 > 2 ? 3 : 2) : %d\n", sizeof (3 > 2 ? 3 : 2));
+
+ exit(0);
+}
+
+END
+/(4 != sizeof ('c')) || (4 != sizeof (10 * 'c')) ||
+ (4 != sizeof (100 + 12345)) || (4 != sizeof (1234567890)) ||
+ (8 != sizeof (1234512345 * 1234512345 * 12345678 * 1ULL)) ||
+ (4 != sizeof (-129)) || (4 != sizeof (0x67890/0x77000)) ||
+ (4 != sizeof (3 > 2 ? 3 : 2))/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofNULL.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofNULL.d
new file mode 100644
index 0000000..4bd8a48
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofNULL.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: The size of the inbuilt variable NULL is the same as that of an
+ * integer.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sizeof (NULL): %d\n", sizeof (NULL));
+ exit(0);
+}
+
+END
+/4 != sizeof (NULL)/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d
new file mode 100644
index 0000000..51f7250
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. When a raw string is passed to the sizeof operator, the compiler
+ * throws a D_SYNTAX error.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ printf("sizeof \"hi\": %d\n", sizeof ("hi"));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d.out
new file mode 100644
index 0000000..3fe02aa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofStrConst.d.out
@@ -0,0 +1,2 @@
+sizeof "hi": 3
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d
new file mode 100644
index 0000000..0be9e45
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. For sizeof strings the D compiler throws D_SIZEOF_TYPE.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+#pragma D option strsize=256
+
+BEGIN
+{
+ assoc_array["hello"] = "hello";
+ assoc_array["hi"] = "hi";
+ assoc_array["hello"] = "hello, world";
+
+ printf("sizeof (assoc_array[\"hello\"]): %d\n",
+ sizeof (assoc_array["hello"]));
+ printf("sizeof (assoc_array[\"hi\"]): %d\n",
+ sizeof (assoc_array["hi"]));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d.out
new file mode 100644
index 0000000..9c43b1e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString1.d.out
@@ -0,0 +1,3 @@
+sizeof (assoc_array["hello"]): 256
+sizeof (assoc_array["hi"]): 256
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d
new file mode 100644
index 0000000..f12a600
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: sizeof returns the size in bytes of any D expression or data
+ * type. For a string variable, the D compiler throws a D_SIZEOF_TYPE.
+ *
+ * SECTION: Structs and Unions/Member Sizes and Offsets
+ *
+ */
+#pragma D option quiet
+#pragma D option strsize=256
+
+BEGIN
+{
+ var = "hello";
+ printf("sizeof (var): %d\n", sizeof (var));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d.out
new file mode 100644
index 0000000..fdeca69
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sizeof/tst.SizeofString2.d.out
@@ -0,0 +1,2 @@
+sizeof (var): 256
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/bug.1001148.SpecSizeVariations.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/bug.1001148.SpecSizeVariations.d
new file mode 100644
index 0000000..318a2d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/bug.1001148.SpecSizeVariations.d
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ * BUG: 1001148
+ *
+ * NOTES: This code has four different behaviors.
+ * 1. 0 < specsize < 8
+ * 2. 8 <= specsize <= 39 || 0 == specsize
+ * 3. 40 <= specsize
+ * 4. 0 > specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=10
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d
new file mode 100644
index 0000000..e97506e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations1.d
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in bufsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/bufsize
+ *
+ * NOTES: This test behaves differently depending on the values
+ * assigned to bufsize.
+ * 1. 0 > bufsize.
+ * 2. 0 == bufsize.
+ * 3. 0 < bufsize <= 7
+ * 4. 8 <= bufsize <= 31
+ * 5. 32 <= bufsize <= 47
+ * 6. 48 <= bufsize <= 71
+ * 7. 72 <= bufsize
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=41
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d
new file mode 100644
index 0000000..f660e9a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.BufSizeVariations2.d
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in bufsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/bufsize
+ *
+ * NOTES: This test behaves differently depending on the values
+ * assigned to bufsize.
+ * 1. 0 > bufsize.
+ * 2. 0 == bufsize.
+ * 3. 0 < bufsize <= 7
+ * 4. 8 <= bufsize <= 31
+ * 5. 32 <= bufsize <= 47
+ * 6. 48 <= bufsize <= 71
+ * 7. 72 <= bufsize
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=4
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d
new file mode 100644
index 0000000..958ce68
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+syscall:::
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ breakpoint();
+ i++;
+}
+
+syscall:::
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d
new file mode 100644
index 0000000..ebb3b01
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace (1M) Utility/ -w option
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ chill(10);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == 1/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d
new file mode 100644
index 0000000..9c14bb5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ *
+ */
+#pragma D option quiet
+
+char a[2];
+void *buf;
+uintptr_t addr;
+size_t nbytes;
+BEGIN
+{
+ self->i = 0;
+ addr = (uintptr_t) &a[0];
+ nbytes = 10;
+ var = speculation();
+}
+
+BEGIN
+{
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ self->i++;
+ copyout(buf, addr, nbytes);
+}
+
+BEGIN
+{
+ printf("This test should not have compiled\n");
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d
new file mode 100644
index 0000000..695eb8c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ */
+#pragma D option quiet
+
+string str;
+char a[2];
+uintptr_t addr;
+size_t maxlen;
+BEGIN
+{
+ self->i = 0;
+ addr = (uintptr_t) &a[0];
+ maxlen = 10;
+ var = speculation();
+}
+
+BEGIN
+{
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ self->i++;
+ copyoutstr(str, addr, maxlen);
+}
+
+BEGIN
+{
+ printf("This test should not have compiled\n");
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d
new file mode 100644
index 0000000..dcba080
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d
@@ -0,0 +1,69 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ panic();
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d
new file mode 100644
index 0000000..e4fe06b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ raise(9);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d
new file mode 100644
index 0000000..468e8f2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -ws
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Destructive actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ * SECTION: dtrace(1M) Utility/ -w option
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ stop();
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_COMM.AggAftCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_COMM.AggAftCommit.d
new file mode 100644
index 0000000..89a15c0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_COMM.AggAftCommit.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A clause cannot contain a commit() followed by an aggregating action.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ */
+
+BEGIN
+{
+ commit(1);
+ @a["foo"] = count();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithAvg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithAvg.d
new file mode 100644
index 0000000..a763543
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithAvg.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @avrg["speculate"] = avg(i);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithCount.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithCount.d
new file mode 100644
index 0000000..57d0d03
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithCount.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @counts["speculate"] = count();
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithLquant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithLquant.d
new file mode 100644
index 0000000..90a899d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithLquant.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+syscall:::entry
+{
+ self->ts = timestamp;
+}
+
+syscall:::return
+/self->ts/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @Lqauntus[execname] = lquantize(timestamp - self->ts, 0, 100, 1);
+ i++;
+}
+
+syscall:::
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMax.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMax.d
new file mode 100644
index 0000000..a10fff1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMax.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @Maximus["speculate"] = max(i);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMin.d
new file mode 100644
index 0000000..4ad8dee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithMin.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @Minimus["speculate"] = min(i);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithQuant.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithQuant.d
new file mode 100644
index 0000000..38e816e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithQuant.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+syscall:::entry
+{
+ self->ts = timestamp;
+}
+
+syscall:::return
+/self->ts/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @Qauntus[execname] = quantize(timestamp - self->ts);
+ i++;
+}
+
+syscall:::
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d
new file mode 100644
index 0000000..22953c2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Aggregating actions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @sdev["speculate"] = stddev(i);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithSum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithSum.d
new file mode 100644
index 0000000..620a076
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithSum.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Aggregating functions may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+profile:::tick-1sec
+/i < 1/
+{
+ var = speculation();
+ speculate(var);
+ printf("Speculation ID: %d", var);
+ @sums["speculate"] = sum(i);
+ i++;
+}
+
+profile:::tick-1sec
+/1 == i/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.CommitAftCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.CommitAftCommit.d
new file mode 100644
index 0000000..ebc316a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.CommitAftCommit.d
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A clause cannot contain multiple commit() calls to same buffer.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Options and Tunables/cleanrate
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ var1 = 0;
+}
+
+profile:::tick-1sec
+/!var1/
+{
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+profile:::tick-1sec
+/var1/
+{
+ speculate(var1);
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+profile:::tick-1sec
+/(!self->i)/
+{
+}
+
+profile:::tick-1sec
+/(self->i)/
+{
+ commit(var1);
+ commit(var1);
+ exit(0);
+}
+
+END
+{
+ printf("Succesfully commited both buffers");
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.DisjointCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.DisjointCommit.d
new file mode 100644
index 0000000..e482d07
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_COMM.DisjointCommit.d
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A clause cannot contain multiple commit() calls to disjoint buffers.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Options and Tunables/cleanrate
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ self->j = 0;
+ self->commit = 0;
+ var1 = 0;
+ var2 = 0;
+}
+
+BEGIN
+{
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+BEGIN
+{
+ var2 = speculation();
+ printf("Speculation ID: %d\n", var2);
+}
+
+BEGIN
+/var1/
+{
+ speculate(var1);
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+BEGIN
+/var2/
+{
+ speculate(var2);
+ printf("Speculating on id: %d", var2);
+ self->j++;
+
+}
+
+BEGIN
+/(self->i) && (self->j)/
+{
+ commit(var1);
+ commit(var2);
+ self->commit++;
+}
+
+BEGIN
+/self->commit/
+{
+ printf("Succesfully commited both buffers");
+ exit(0);
+}
+
+BEGIN
+/!self->commit/
+{
+ printf("Couldnt commit both buffers");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_DREC.CommitAftDataRec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_DREC.CommitAftDataRec.d
new file mode 100644
index 0000000..268b68f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_COMM_DREC.CommitAftDataRec.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Commit may not follow data recording actions.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+ exit(0);
+}
+
+END
+{
+ printf("This test shouldnt have compiled\n");
+ commit(self->spec);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.DataRecAftCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.DataRecAftCommit.d
new file mode 100644
index 0000000..75560d8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.DataRecAftCommit.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Data recording actions may not follow commit.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=2000hz
+
+BEGIN
+{
+ self->speculateFlag = 0;
+}
+
+syscall:::entry
+{
+ self->spec = speculation();
+}
+
+syscall:::
+/self->spec/
+{
+ speculate(self->spec);
+ printf("Called speculate with id: %d\n", self->spec);
+ self->speculateFlag++;
+}
+
+syscall:::
+/(self->spec) && (self->speculateFlag)/
+{
+ commit(self->spec);
+ printf("Data recording after commit\n");
+}
+
+END
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.ExitAfterCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.ExitAfterCommit.d
new file mode 100644
index 0000000..c190740
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_DREC_COMM.ExitAfterCommit.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Exit after commit should throw a D_DREC_COMM.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ self->i = 0;
+ self->spec = speculation();
+}
+
+BEGIN
+/self->spec/
+{
+ speculate(self->spec);
+ self->i++;
+ printf("self->i: %d\n", self->i);
+}
+
+BEGIN
+/self->i/
+{
+ commit(self->spec);
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_EXIT_SPEC.ExitAftSpec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_EXIT_SPEC.ExitAftSpec.d
new file mode 100644
index 0000000..70964f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_EXIT_SPEC.ExitAftSpec.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Exit action may never be speculative.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+BEGIN
+{
+ i = 0;
+}
+
+syscall:::entry
+{
+ self->spec = speculation();
+}
+
+syscall:::
+/self->spec/
+{
+ speculate(self->spec);
+ i++;
+ printf("i: %d\n", i);
+ exit(0);
+}
+
+syscall:::
+/1 == i/
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_MALFORM.NspecExpr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_MALFORM.NspecExpr.d
new file mode 100644
index 0000000..91168e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_MALFORM.NspecExpr.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using an expression in the pragma for nspec throws a D_PRAGMA_MALFORM
+ * error.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/nspec
+ *
+ */
+
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+#pragma D option nspec=24 * 44
+
+BEGIN
+{
+ var1 = 0;
+ var2 = 0;
+ var3 = 0;
+}
+
+BEGIN
+{
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+ var2 = speculation();
+ printf("Speculation ID: %d\n", var2);
+ var3 = speculation();
+ printf("Speculation ID: %d\n", var3);
+}
+
+BEGIN
+/var1 && var2 && (!var3)/
+{
+ printf("Succesfully got two speculative buffers");
+ exit(0);
+}
+
+BEGIN
+/(!var1) || (!var2) || var3/
+{
+ printf("Test failed");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.HugeNspecValue.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.HugeNspecValue.d
new file mode 100644
index 0000000..d13132e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.HugeNspecValue.d
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Setting the nspec option to a huge integer throws a D_PRAGMA_OPTSET error.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/nspec
+ *
+ */
+
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+#pragma D option nspec=245566729809009887663
+
+BEGIN
+{
+ var1 = 0;
+ var2 = 0;
+ var3 = 0;
+}
+
+BEGIN
+{
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+ var2 = speculation();
+ printf("Speculation ID: %d\n", var2);
+ var3 = speculation();
+ printf("Speculation ID: %d\n", var3);
+}
+
+BEGIN
+/var1 && var2 && (!var3)/
+{
+ printf("Succesfully got two speculative buffers");
+ exit(0);
+}
+
+BEGIN
+/(!var1) || (!var2) || var3/
+{
+ printf("Test failed");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.InvalidSpecSize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.InvalidSpecSize.d
new file mode 100644
index 0000000..d957f67
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.InvalidSpecSize.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Setting the specsize option to an illegal value throws the compiler error
+ * D_PRAGMA_OPTSET.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ */
+
+#pragma D option quiet
+#pragma D option specsize=1b
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+ exit(0);
+}
+
+END
+{
+ printf("This shouldnt have compiled\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.NegSpecSize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.NegSpecSize.d
new file mode 100644
index 0000000..c5fa9f5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PRAGMA_OPTSET.NegSpecSize.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of speculations with changes in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=-40
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PROTO_LEN.SpecNoId.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PROTO_LEN.SpecNoId.d
new file mode 100644
index 0000000..65d53ba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_PROTO_LEN.SpecNoId.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * An identifier returned from speculation must be passed to the speculate()
+ * function.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ var = speculation();
+ printf("Speculation ID: %d", var);
+ self->i = 0;
+}
+
+profile:::tick-1sec
+{
+ speculate();
+ self->i++;
+}
+
+profile:::tick-1sec
+/1 <= self->i/
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_COMM.SpecAftCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_COMM.SpecAftCommit.d
new file mode 100644
index 0000000..ec4b22b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_COMM.SpecAftCommit.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A clause cannot contain a speculate after a commit.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ var1 = 0;
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+profile:::tick-1sec
+/var1/
+{
+ speculate(var1);
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+profile:::tick-1sec
+/(!self->i)/
+{
+}
+
+profile:::tick-1sec
+/(self->i)/
+{
+ commit(var1);
+ speculate(var1);
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_DREC.SpecAftDataRec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_DREC.SpecAftDataRec.d
new file mode 100644
index 0000000..80f1fdd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_DREC.SpecAftDataRec.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * speculate() may not follow data recording actions.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+BEGIN
+{
+ i = 0;
+}
+
+syscall:::entry
+{
+ self->spec = speculation();
+}
+
+syscall:::
+/self->spec/
+{
+ printf("Entering syscall clause\n");
+ speculate(self->spec);
+ i++;
+ printf("i: %d\n", i);
+}
+
+syscall:::
+/1 == i/
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_SPEC.SpecAftSpec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_SPEC.SpecAftSpec.d
new file mode 100644
index 0000000..67af53b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_SPEC_SPEC.SpecAftSpec.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A clause can contain only one speculate() call.
+ *
+ * SECTION: Speculative Tracing/Using a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ self->i = 0;
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+ var2 = speculation();
+ printf("Speculation ID: %d\n", var2);
+}
+
+profile:::tick-1sec
+{
+ speculate(var1);
+ printf("Speculating on id: %d\n", var1);
+ speculate(var2);
+ printf("Speculating on id: %d", var2);
+ self->i++;
+
+}
+
+profile:::tick-1sec
+/1 > self->i/
+{
+ exit(0);
+}
+
+END
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeBufSize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeBufSize.d
new file mode 100644
index 0000000..7d2f4b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeBufSize.d
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in bufsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/bufsize
+ *
+ * NOTES: This test behaves differently depending on the values
+ * assigned to bufsize.
+ * 1. 0 > bufsize.
+ * 2. 0 == bufsize.
+ * 3. 0 < bufsize <= 7
+ * 4. 8 <= bufsize <= 31
+ * 5. 32 <= bufsize <= 47
+ * 6. 48 <= bufsize <= 71
+ * 7. 72 <= bufsize
+ */
+
+#pragma D option quiet
+#pragma D option bufsize=-72
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeNspec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeNspec.d
new file mode 100644
index 0000000..9e1d063
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeNspec.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using a negative value for nspec throws a compiler error.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/nspec
+ */
+
+#pragma D option quiet
+#pragma D option nspec=-72
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+ printf("This test shouldnt have compiled\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeSpecSize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeSpecSize.d
new file mode 100644
index 0000000..233257a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.NegativeSpecSize.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Setting the specsize to a negative number should throw a compiler error.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ * NOTES: Why dont we have an error tag for this error?
+ */
+
+#pragma D option quiet
+#pragma D option specsize=-10
+
+BEGIN
+{
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations1.d
new file mode 100644
index 0000000..c42029c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations1.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=2
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations2.d
new file mode 100644
index 0000000..8a57280
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.SpecSizeVariations2.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of variations in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=0
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitAfterDiscard.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitAfterDiscard.d
new file mode 100644
index 0000000..a874ab5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitAfterDiscard.d
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Call to commit() on a buffer after it has been discarded is silently
+ * ignored.
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ self->commit = 0;
+ self->discard = 0;
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+BEGIN
+/var1/
+{
+ speculate(var1);
+ printf("This statement and the following are speculative!!\n");
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+BEGIN
+/(self->i)/
+{
+ discard(var1);
+ self->discard++;
+ commit(var1);
+ self->commit++;
+}
+
+BEGIN
+/self->commit/
+{
+ printf("Commited a discarded buffer\n");
+ exit(0);
+}
+
+
+BEGIN
+/!self->commit/
+{
+ printf("Couldnt commit a discarded buffer\n");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitWithZero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitWithZero.d
new file mode 100644
index 0000000..647552f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.CommitWithZero.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: An Id of zero though invalid may be passed to speculate(),
+ * commit() and discard() without any ill effects.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation;
+ * Options and Tunables/cleanrate
+ */
+#pragma D option quiet
+#pragma D option cleanrate=4000hz
+
+BEGIN
+{
+ self->commitFlag = 0;
+ self->var1 = speculation();
+ printf("Speculative buffer ID: %d\n", self->var1);
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/0 < self->commitFlag/
+{
+ printf("commit(), self->commitFlag = %d\n", self->commitFlag);
+ exit(0);
+}
+
+BEGIN
+/0 == self->commitFlag/
+{
+ printf("commit(), self->commitFlag = %d\n", self->commitFlag);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DataRecAftDiscard.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DataRecAftDiscard.d
new file mode 100644
index 0000000..03ae1b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DataRecAftDiscard.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Data recording actions may follow discard.
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation;
+ * Options and Tunables/cleanrate
+ */
+#pragma D option quiet
+#pragma D option cleanrate=2000hz
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->discardFlag = 0;
+ self->spec = speculation();
+}
+
+BEGIN
+/self->spec/
+{
+ speculate(self->spec);
+ printf("Called speculate with id: %d\n", self->spec);
+ self->speculateFlag++;
+}
+
+BEGIN
+/(self->spec) && (self->speculateFlag)/
+{
+ discard(self->spec);
+ self->discardFlag++;
+ printf("Data recording after discard\n");
+}
+
+BEGIN
+/self->discardFlag/
+{
+ exit(0);
+}
+
+BEGIN
+/!self->discardFlag/
+{
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftCommit.d
new file mode 100644
index 0000000..25fcfc5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftCommit.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Can call discard() on a buffer after it has been commited.
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ self->commit = 0;
+ self->discard = 0;
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+BEGIN
+/var1/
+{
+ speculate(var1);
+ printf("This statement and the following are speculative!!\n");
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+BEGIN
+/(self->i)/
+{
+ commit(var1);
+ self->commit++;
+ discard(var1);
+ self->discard++;
+}
+
+BEGIN
+/self->discard/
+{
+ printf("Discarded a commited buffer\n");
+ exit(0);
+}
+
+
+BEGIN
+/!self->discard/
+{
+ printf("Couldnt discard a commited buffer\n");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDataRec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDataRec.d
new file mode 100644
index 0000000..d5c573f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDataRec.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Discard may not follow data recording actions.
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ printf("Can have data recording before discarding\n");
+ discard(self->spec);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDiscard.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDiscard.d
new file mode 100644
index 0000000..8c95cee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardAftDiscard.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Can call discard on an already discarded buffer.
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+
+BEGIN
+{
+ self->i = 0;
+ self->discard1 = 0;
+ self->discard2 = 0;
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+}
+
+BEGIN
+/var1/
+{
+ speculate(var1);
+ printf("This statement and the following are speculative!!\n");
+ printf("Speculating on id: %d\n", var1);
+ self->i++;
+}
+
+BEGIN
+/(self->i)/
+{
+ discard(var1);
+ self->discard1++;
+ discard(var1);
+ self->discard2++;
+}
+
+BEGIN
+/(self->discard2) && (self->discard1)/
+{
+ printf("Discarded a discarded buffer\n");
+ exit(0);
+}
+
+
+BEGIN
+/(!self->discard2) || (!self->discard1)/
+{
+ printf("Couldnt discard a discarded buffer\n");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardWithZero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardWithZero.d
new file mode 100644
index 0000000..1a78561
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.DiscardWithZero.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: An Id of zero though invalid may be passed to speculate(),
+ * commit() and discard() without any ill effects.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation;
+ * Options and Tunables/cleanrate
+ */
+#pragma D option quiet
+#pragma D option cleanrate=4000hz
+
+BEGIN
+{
+ self->discardFlag = 0;
+ self->var1 = speculation();
+ printf("Speculative buffer ID: %d\n", self->var1);
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+/0 == self->spec/
+{
+ discard(self->spec);
+ self->discardFlag++;
+}
+
+BEGIN
+/0 < self->discardFlag/
+{
+ printf("discard(), self->discardFlag = %d\n", self->discardFlag);
+ exit(0);
+}
+
+BEGIN
+/0 == self->discardFlag/
+{
+ printf("discard(), self->discardFlag = %d\n", self->discardFlag);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.ExitAftDiscard.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.ExitAftDiscard.d
new file mode 100644
index 0000000..f5bcd66
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.ExitAftDiscard.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Using exit after discard should work fine.
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ self->i = 0;
+ self->spec = speculation();
+}
+
+BEGIN
+/self->spec/
+{
+ speculate(self->spec);
+ self->i++;
+ printf("self->i: %d\n", self->i);
+}
+
+BEGIN
+/self->i/
+{
+ discard(self->spec);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.NoSpecBuffer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.NoSpecBuffer.d
new file mode 100644
index 0000000..8fe3a19
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.NoSpecBuffer.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The number of speculative buffers defaults to one. If no speculative buffer
+ * is available when speculation is called, an ID of zero is returned.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ i = 0;
+}
+
+syscall::open:entry
+/i < 2/
+{
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+ i++;
+}
+
+syscall:::
+/(2 == i) && (0 == self->spec)/
+{
+ printf("i: %d\tself->spec: %d", i, self->spec);
+ exit(0);
+}
+
+syscall:::
+/(2 == i) && (0 != self->spec)/
+{
+ printf("i: %d\tself->spec: %d", i, self->spec);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations1.d
new file mode 100644
index 0000000..17df6b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations1.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of speculations with changes in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=8
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(1);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations2.d
new file mode 100644
index 0000000..bcd2f2e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations2.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of speculations with changes in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=10
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(1);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d
new file mode 100644
index 0000000..6b91efd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpecSizeVariations3.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * ASSERTION:
+ * Verify the behavior of speculations with changes in specsize.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/specsize
+ *
+ */
+
+#pragma D option quiet
+#pragma D option specsize=40
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->commitFlag = 0;
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ printf("Lots of data\n");
+ printf("Has to be crammed into this buffer\n");
+ printf("Until it overflows\n");
+ printf("And causes flops\n");
+ self->speculateFlag++;
+
+}
+
+BEGIN
+/1 <= self->speculateFlag/
+{
+ commit(self->spec);
+ self->commitFlag++;
+}
+
+BEGIN
+/1 <= self->commitFlag/
+{
+ printf("Statement was executed\n");
+ exit(0);
+}
+
+BEGIN
+/1 > self->commitFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculateWithRandom.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculateWithRandom.d
new file mode 100644
index 0000000..24f1ff4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculateWithRandom.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When speculate() is called with an inactive buffer number, it is
+ * ignored.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation
+ *
+ */
+#pragma D option quiet
+BEGIN
+{
+ self->i = 0;
+}
+
+BEGIN
+{
+ speculate(3456710);
+ self->i++;
+ printf("self->i: %d\n", self->i);
+
+}
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationCommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationCommit.d
new file mode 100644
index 0000000..744ba67
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationCommit.d
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test the normal behavior of speculate() and commit().
+ *
+ * SECTION: Speculative Tracing/Committing a Speculation;
+ * Actions and Subroutines/speculation();
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=2000hz
+
+BEGIN
+{
+ self->var = speculation();
+ printf("Speculation ID: %d\n", self->var);
+ self->speculate = 0;
+ self->commit = 0;
+}
+
+BEGIN
+/1 > self->speculate/
+{
+ speculate(self->var);
+ self->speculate++;
+ printf("Called speculate on id: %d\n", self->var);
+}
+
+BEGIN
+/1 <= self->speculate/
+{
+ commit(self->var);
+ self->commit++;
+}
+
+BEGIN
+/(1 == self->commit)/
+{
+ printf("Succesfully tested buffer commit\n");
+ exit(0);
+}
+
+BEGIN
+/(0 == self->commit)/
+{
+ printf("Failed to commit buffer\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationDiscard.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationDiscard.d
new file mode 100644
index 0000000..4ac0e23
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationDiscard.d
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Test the normal behavior of speculate() and discard().
+ *
+ * SECTION: Speculative Tracing/Discarding a Speculation;
+ * Options and Tunables/cleanrate
+ *
+ */
+#pragma D option quiet
+#pragma D option cleanrate=2000hz
+
+BEGIN
+{
+ self->var = speculation();
+ printf("Speculation ID: %d\n", self->var);
+ self->speculate = 0;
+ self->discard = 0;
+}
+
+BEGIN
+/1 > self->speculate/
+{
+ speculate(self->var);
+ self->speculate++;
+ printf("Called speculate on id: %d\n", self->var);
+}
+
+BEGIN
+/1 <= self->speculate/
+{
+ discard(self->var);
+ self->discard++;
+}
+
+BEGIN
+/(1 == self->discard)/
+{
+ printf("Succesfully tested buffer discard\n");
+ exit(0);
+}
+
+BEGIN
+/(0 == self->discard)/
+{
+ printf("Failed to discard buffer\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationID.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationID.d
new file mode 100644
index 0000000..b2e3678
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationID.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The speculation() function returns a speculative identifier when a
+ * speculative buffer is available.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation
+ *
+ */
+#pragma D option quiet
+
+BEGIN
+{
+ var = speculation();
+ printf("Speculation ID: %d", var);
+ exit(0);
+}
+
+END
+/0 == var/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationWithZero.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationWithZero.d
new file mode 100644
index 0000000..76600db
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.SpeculationWithZero.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Calling speculate() with zero does not have any ill effects.
+ * Statement after speculate does not execute.
+ *
+ * SECTION: Speculative Tracing/Creating a Speculation
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ self->speculateFlag = 0;
+ self->spec = speculation();
+ self->spec = speculation();
+ printf("Speculative buffer ID: %d\n", self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+ self->speculateFlag++;
+}
+
+BEGIN
+/1 == self->speculateFlag/
+{
+ printf("Statement was executed\n");
+ exit(1);
+}
+
+BEGIN
+/1 != self->speculateFlag/
+{
+ printf("Statement wasn't executed\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.TwoSpecBuffers.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.TwoSpecBuffers.d
new file mode 100644
index 0000000..8016b20
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.TwoSpecBuffers.d
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Increasing the value of nspec to two should will increase the number of
+ * speculative buffers to two.
+ *
+ * SECTION: Speculative Tracing/Options and Tuning;
+ * Options and Tunables/nspec
+ *
+ */
+
+#pragma D option quiet
+#pragma D option cleanrate=3000hz
+#pragma D option nspec=2
+
+BEGIN
+{
+ var1 = 0;
+ var2 = 0;
+ var3 = 0;
+}
+
+BEGIN
+{
+ var1 = speculation();
+ printf("Speculation ID: %d\n", var1);
+ var2 = speculation();
+ printf("Speculation ID: %d\n", var2);
+ var3 = speculation();
+ printf("Speculation ID: %d\n", var3);
+}
+
+BEGIN
+/var1 && var2 && (!var3)/
+{
+ printf("Succesfully got two speculative buffers");
+ exit(0);
+}
+
+BEGIN
+/(!var1) || (!var2) || var3/
+{
+ printf("Test failed");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negcommit.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negcommit.d
new file mode 100644
index 0000000..cf17c71
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negcommit.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ commit(-1);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negspec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negspec.d
new file mode 100644
index 0000000..72965c7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.negspec.d
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+BEGIN
+{
+ speculate(-1);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.zerosize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.zerosize.d
new file mode 100644
index 0000000..a4b4001
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/tst.zerosize.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option destructive
+
+BEGIN
+{
+ self->spec = speculation();
+ speculate(self->spec);
+}
+
+BEGIN
+{
+ this->one = 1;
+ this->two = 2;
+ chill(1);
+ speculate(self->spec);
+}
+
+BEGIN
+{
+ speculate(self->spec);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stability/err.D_ATTR_MIN.MinAttributes.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stability/err.D_ATTR_MIN.MinAttributes.d
new file mode 100644
index 0000000..99fcede
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stability/err.D_ATTR_MIN.MinAttributes.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: If a program has a set of attributes less than the predefined
+ * minimum a D_ATTR_MIN is thrown
+ *
+ * SECTION: Stability/Stability Enforcement
+ * SECTION: Errtags/D_ATTR_MIN
+ *
+ */
+
+#pragma D option quiet
+#pragma D option amin=Evolving/Evolving/Common
+
+BEGIN
+{
+ trace(curthread->t_procp);
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_PROTO.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_PROTO.bad.d
new file mode 100644
index 0000000..0af06e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_PROTO.bad.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * stack() accepts one argument
+ *
+ * SECTION: Actions and Subroutines/stack()
+ *
+ */
+
+
+BEGIN
+{
+ stack(1, 2);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_SIZE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_SIZE.d
new file mode 100644
index 0000000..8344e5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_STACK_SIZE.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test stack() with an invalid argument.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ stack("i'm not an integer constant");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_FRAMES.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_FRAMES.bad.d
new file mode 100644
index 0000000..bfd7376
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_FRAMES.bad.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * ustack() first argument must be a non-zero positive integer constant
+ *
+ * SECTION: User Process Tracing/ustack();
+ * Actions and Subroutines/ustack()
+ *
+ */
+
+
+BEGIN
+{
+ ustack(0, 200);
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_PROTO.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_PROTO.bad.d
new file mode 100644
index 0000000..5360d98
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_PROTO.bad.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * ustack() accepts two arguments
+ *
+ * SECTION: User Process Tracing/ustack();
+ * Actions and Subroutines/ustack()
+ *
+ */
+
+
+BEGIN
+{
+ ustack(1, 10, "badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_STRSIZE.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_STRSIZE.bad.d
new file mode 100644
index 0000000..4c89ed5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/err.D_USTACK_STRSIZE.bad.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * ustack() second argument must be a positive integer constant.
+ *
+ * SECTION: User Process Tracing/ustack();
+ * Actions and Subroutines/ustack()
+ *
+ */
+
+
+BEGIN
+{
+ ustack(1, "badarg");
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/tst.default.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/tst.default.d
new file mode 100644
index 0000000..f7a4f06
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stack/tst.default.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the stack action with the default stack depth.
+ *
+ * SECTION: Output Formatting/printf()
+ *
+ */
+
+BEGIN
+{
+ stack();
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stackdepth/tst.default.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stackdepth/tst.default.d
new file mode 100644
index 0000000..c37380d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stackdepth/tst.default.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the stackdepth variable.
+ *
+ * SECTION: Variables/Built-in Variables
+ *
+ */
+
+BEGIN
+{
+ trace(stackdepth);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.c
new file mode 100644
index 0000000..28ce1b8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.c
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ getpid();
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.d
new file mode 100644
index 0000000..dd5a4b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop1.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for stop
+ *
+ * SECTION: Actions and Subroutines/stop()
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the process to call getpid().
+ */
+ timeout = timestamp + 1000000000;
+ stopped = 0;
+}
+
+syscall::getpid:entry
+/pid == $1 && stopped == 1/
+{
+ trace("looks like it's still going");
+ exit(1);
+}
+
+syscall::getpid:entry
+/pid == $1 && stopped == 0/
+{
+ stop();
+ trace("stopped");
+ stopped = 1;
+ /*
+ * Wait for a quarter second before declaring victory.
+ */
+ timeout = timestamp + 1000000000 / 4;
+}
+
+profile:::tick-8
+/timestamp > timeout && stopped == 1/
+{
+ trace("looks like it really stopped");
+ exit(0);
+}
+
+profile:::tick-8
+/timestamp > timeout/
+{
+ trace("timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.c
new file mode 100644
index 0000000..28ce1b8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.c
@@ -0,0 +1,37 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ getpid();
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.d
new file mode 100644
index 0000000..4c79cd8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/stop/tst.stop2.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive test for stop
+ *
+ * SECTION: Actions and Subroutines/stop()
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ /*
+ * Wait no more than a second for the process to call getpid().
+ */
+ timeout = timestamp + 1000000000;
+ stopped = 0;
+}
+
+syscall::getpid:entry
+/pid == $1 && stopped == 1/
+{
+ trace("looks like it's still going");
+ exit(1);
+}
+
+syscall::getpid:return
+/pid == $1 && stopped == 0/
+{
+ stop();
+ trace("stopped");
+ stopped = 1;
+ /*
+ * Wait for a quarter second before declaring victory.
+ */
+ timeout = timestamp + 1000000000 / 4;
+}
+
+profile:::tick-8
+/timestamp > timeout && stopped == 1/
+{
+ trace("looks like it really stopped");
+ exit(0);
+}
+
+profile:::tick-8
+/timestamp > timeout/
+{
+ trace("timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strlen/tst.strlen1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strlen/tst.strlen1.d
new file mode 100644
index 0000000..7775395
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strlen/tst.strlen1.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the strlen() subroutine.
+ *
+ * SECTION: Actions and Subroutines/strlen()
+ *
+ */
+
+BEGIN
+/strlen("I like DTrace") == 13/
+{
+ correct = 1;
+}
+
+BEGIN
+{
+ exit(correct ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_ADDROF_VAR.StructPointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_ADDROF_VAR.StructPointer.d
new file mode 100644
index 0000000..85e49fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_ADDROF_VAR.StructPointer.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Trying to access the members of a user defined struct by means of
+ * a pointer to it should throw a D_ADDROF_VAR compiler error.
+ *
+ * SECTION: Structs and Unions/Pointers to Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct record {
+ int position;
+ int content;
+
+};
+
+struct record var;
+struct record *ptr;
+BEGIN
+{
+
+ var.position = 1;
+ var.content = 'a';
+
+ ptr = &var;
+
+ printf("ptr->position: %d\tptr->content: %c\n",
+ ptr->position, ptr->content);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon.d
new file mode 100644
index 0000000..004e901
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon.d
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Combining multiple struct definitions in a single line should throw a
+ * compiler error.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma D option quiet
+
+struct superStruct {
+ int position;
+ char content;
+}
+
+struct record {
+ int position;
+ char content;
+}
+
+
+struct pirate {
+ int position;
+ char content;
+};
+
+struct superStruct super;
+struct record rec;
+struct pirate pir;
+
+BEGIN
+{
+ rec.content = 'a';
+ rec.position = 1;
+
+ pir.content = 'b';
+ pir.position = 2;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon1.d
new file mode 100644
index 0000000..1c403b6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_COMBO.StructWithoutColon1.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Combining multiple struct definitions in a single line should throw a
+ * compiler error.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct record {
+ int position;
+ char content;
+};
+
+
+struct pirate {
+ int position;
+ char content;
+}
+
+struct record rec;
+struct pirate pir;
+
+BEGIN
+{
+ rec.content = 'a';
+ rec.position = 1;
+
+ pir.content = 'b';
+ pir.position = 2;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.circular.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.circular.d
new file mode 100644
index 0000000..dcbc8ee
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.circular.d
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * A circular definition of structs (two structs defining each other as
+ * members) should throw an error at compile time.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma D option quiet
+
+
+struct record {
+ struct pirate p;
+ int position;
+ char content;
+};
+
+
+struct pirate {
+ struct record r;
+ int position;
+ char content;
+};
+
+struct record rec;
+struct pirate pir;
+
+BEGIN
+{
+ rec.position = 0;
+ rec.content = 'a';
+ printf("rec.position: %d\nrec.content: %c\n",
+ rec.position, rec.content);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order.d
new file mode 100644
index 0000000..932f4dc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order.d
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When two struct are defined such that one of them contains the other, the
+ * inner struct has to be defined first.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+
+struct record {
+ struct pirate p;
+ int position;
+ char content;
+};
+
+struct pirate {
+ int position;
+ char content;
+};
+
+struct record rec;
+struct pirate pir;
+
+BEGIN
+{
+ rec.content = 'y';
+ rec.position = 2;
+
+ pir.content = 'z';
+ pir.position = 26;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order2.d
new file mode 100644
index 0000000..807b618
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.order2.d
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When struct definitions are nested inside one another, the inner struct
+ * should be defined before the outer one can declare it as a variable.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct InnerMore {
+ struct InnerMost IMost;
+ int dummy_More;
+};
+
+struct InnerMost {
+ int position;
+ char content;
+};
+
+struct Inner {
+ struct InnerMore IMore;
+ int dummy_More;
+};
+
+struct Outer {
+ struct Inner I;
+ int dummy_More;
+};
+
+struct OuterMore {
+ struct Outer O;
+ int dummy_More;
+};
+
+struct OuterMost {
+ struct OuterMore OMore;
+ int dummy_More;
+} OMost;
+
+
+BEGIN
+{
+
+ OMost.dummy_More = 0;
+ OMost.OMore.dummy_More = 1;
+ OMost.OMore.O.dummy_More = 2;
+ OMost.OMore.O.I.dummy_More = 3;
+ OMost.OMore.O.I.IMore.dummy_More = 4;
+ OMost.OMore.O.I.IMore.IMost.position = 5;
+ OMost.OMore.O.I.IMore.IMost.content = 'e';
+
+ printf("OMost.dummy_More: %d\nOMost.OMore.dummy_More: %d\n",
+ OMost.dummy_More, OMost.OMore.dummy_More);
+
+ printf("OMost.OMore.O.dummy_More: %d\nOMost.OMore.O.I.dummy_More: %d\n",
+ OMost.OMore.O.dummy_More, OMost.OMore.O.I.dummy_More);
+
+ printf("OMost.OMore.O.I.IMore.dummy_More:%d\n",
+ OMost.OMore.O.I.IMore.dummy_More);
+
+ printf("OMost.OMore.O.I.IMore.IMost.position: %d\n",
+ OMost.OMore.O.I.IMore.IMost.position);
+
+ printf("OMost.OMore.O.I.IMore.IMost.content: %c\n",
+ OMost.OMore.O.I.IMore.IMost.content);
+
+ exit(0);
+}
+
+END
+/(0 != OMost.dummy_More) || (1 != OMost.OMore.dummy_More)
+ (2 != OMost.OMore.O.dummy_More) || (3 != OMost.OMore.O.I.dummy_More)
+ (4 != OMost.OMore.O.I.IMore.dummy_More)
+ (5 != OMost.OMore.O.I.IMore.IMost.position)
+ ('e' != OMost.OMore.O.I.IMore.IMost.content)/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.recursive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.recursive.d
new file mode 100644
index 0000000..011fbdd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.recursive.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION: Recursive naming of structures should produce compiler error.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma D option quiet
+
+struct record {
+ struct record rec;
+ int position;
+ char content;
+};
+
+struct record r1;
+struct record r2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 2;
+ r2.content = 'b';
+
+ printf("r1.position: %d\nr1.content: %c\n", r1.position, r1.content);
+ printf("r2.position: %d\nr2.content: %c\n", r2.position, r2.content);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.simple.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.simple.d
new file mode 100644
index 0000000..7fc54ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_INCOMPLETE.simple.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Declaring an inner struct within another struct and not defining it should
+ * throw a compiler error.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma D option quiet
+
+
+struct record {
+ struct pirate p;
+ int position;
+ char content;
+};
+
+
+struct record rec;
+
+BEGIN
+{
+ rec.position = 0;
+ rec.content = 'a';
+ printf("rec.position: %d\nrec.content: %c\n",
+ rec.position, rec.content);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_VOIDOBJ.baddec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_VOIDOBJ.baddec.d
new file mode 100644
index 0000000..bba126f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_DECL_VOIDOBJ.baddec.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declaring void objects will result in a D_DECL_VOIDOBJ error
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct {
+ int trace();
+};
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_PROTO_ARG.DupStructAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_PROTO_ARG.DupStructAssoc.d
new file mode 100644
index 0000000..0eea2d8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/err.D_PROTO_ARG.DupStructAssoc.d
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declaring an associative array with a struct to be its key type and trying to
+ * index with another struct having the same composition throws an error.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct record {
+ int position;
+ char content;
+};
+
+struct pirate {
+ int position;
+ char content;
+};
+
+struct record r1;
+struct record r2;
+struct pirate p1;
+struct pirate p2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 2;
+ r2.content = 'b';
+
+ p1.position = 1;
+ p1.content = 'a';
+
+ p2.position = 2;
+ p2.content = 'b';
+
+ assoc_array[r1] = 1000;
+ assoc_array[r2] = 2000;
+ assoc_array[p1] = 3333;
+ assoc_array[p2] = 4444;
+
+ printf("assoc_array[r1]: %d\n", assoc_array[r1]);
+ printf("assoc_array[r2]: %d\n", assoc_array[r2]);
+ printf("assoc_array[p1]: %d\n", assoc_array[p1]);
+ printf("assoc_array[p2]: %d\n", assoc_array[p2]);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructAssoc.d
new file mode 100644
index 0000000..ead235d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructAssoc.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When a struct is used as a key for an associative array, the key is formed
+ * by using the values of the members of the struct variable and not the
+ * address of the struct variable.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct record {
+ int position;
+ char content;
+};
+
+struct record r1;
+struct record r2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 1;
+ r2.content = 'a';
+
+ assoc_array[r1] = 1000;
+ assoc_array[r2] = 2000;
+
+ printf("assoc_array[r1]: %d\n", assoc_array[r1]);
+ printf("assoc_array[r2]: %d\n", assoc_array[r2]);
+
+ exit(0);
+}
+
+END
+/assoc_array[r1] != assoc_array[r2]/
+{
+ printf("Error");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructDataTypes.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructDataTypes.d
new file mode 100644
index 0000000..5cfdc32
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructDataTypes.d
@@ -0,0 +1,133 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Declaration of the different data types within a struct and
+ * their definitions in a later clause should work fine.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ * NOTES: The floats, doubles and strings have not been implemented yet.
+ * When they do, appropriate lines in the code below should be uncommented.
+ * Similarly, the lines with the kmem_flags pointer assignment should be
+ * uncommented when the issues pertaining to it are clarified.
+ *
+ */
+#pragma D option quiet
+
+struct record {
+ char new_char;
+ short new_short;
+ int new_int;
+ long new_long;
+ long long new_long_long;
+ int8_t new_int8;
+ int16_t new_int16;
+ int32_t new_int32;
+ int64_t new_int64;
+ intptr_t new_intptr;
+ uint8_t new_uint8;
+ uint16_t new_uint16;
+ uint32_t new_uint32;
+ uint64_t new_uint64;
+ uintptr_t new_uintptr;
+
+ /*
+ float new_float;
+ double new_double;
+ long double new_long_double;
+
+ string new_string;
+ */
+
+ struct {
+ char ch;
+ int in;
+ long lg;
+ } new_struct;
+
+ union {
+ char ch;
+ int in;
+ long lg;
+ } new_union;
+
+enum colors {
+ RED,
+ GREEN,
+ BLUE
+} new_enum;
+
+
+ int *pointer;
+} var;
+
+/*
+ var.pointer = &`kmem_flags;
+*/
+BEGIN
+{
+ var.new_char = 'c';
+ var.new_short = 10;
+ var.new_int = 100;
+ var.new_long = 1234567890;
+ var.new_long_long = 1234512345;
+ var.new_int8 = 'p';
+ var.new_int16 = 20;
+ var.new_int32 = 200;
+ var.new_int64 = 2000000;
+ var.new_intptr = 0x12345;
+ var.new_uint8 = 'q';
+ var.new_uint16 = 30;
+ var.new_uint32 = 300;
+ var.new_uint64 = 3000000;
+ var.new_uintptr = 0x67890;
+
+/* var.new_float = 1.23456;
+ var.new_double = 2.34567890;
+ var.new_long_double = 3.567890123;
+
+ var.new_string = "hello";
+*/
+
+/*
+ var.pointer = &`kmem_flags;
+*/
+
+ var.new_struct.ch = 'c';
+ var.new_struct.in = 4;
+ var.new_struct.lg = 4;
+
+ var.new_union.ch = 'd';
+ var.new_union.in = 5;
+ var.new_union.lg = 5;
+
+ this->var = var;
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructInside.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructInside.d
new file mode 100644
index 0000000..159accc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.StructInside.d
@@ -0,0 +1,124 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the nested behavior of structs.
+ *
+ * SECTION: Structs and Unions/Structs
+ *
+ */
+
+#pragma D option quiet
+
+struct InnerMost {
+ int position;
+ char content;
+};
+
+struct InnerMore {
+ struct InnerMost IMost;
+ int dummy_More;
+};
+
+struct Inner {
+ struct InnerMore IMore;
+ int dummy_More;
+};
+
+struct Outer {
+ struct Inner I;
+ int dummy_More;
+};
+
+struct OuterMore {
+ struct Outer O;
+ int dummy_More;
+};
+
+struct OuterMost {
+ struct OuterMore OMore;
+ int dummy_More;
+} OMost;
+
+struct OuterMost OMostCopy;
+
+BEGIN
+{
+
+ OMost.dummy_More = 0;
+ OMost.OMore.dummy_More = 1;
+ OMost.OMore.O.dummy_More = 2;
+ OMost.OMore.O.I.dummy_More = 3;
+ OMost.OMore.O.I.IMore.dummy_More = 4;
+ OMost.OMore.O.I.IMore.IMost.position = 5;
+ OMost.OMore.O.I.IMore.IMost.content = 'e';
+
+ printf("OMost.dummy_More: %d\nOMost.OMore.dummy_More: %d\n",
+ OMost.dummy_More, OMost.OMore.dummy_More);
+
+ printf("OMost.OMore.O.dummy_More: %d\n",
+ OMost.OMore.O.dummy_More);
+
+ printf("OMost.OMore.O.I.dummy_More: %d\n",
+ OMost.OMore.O.I.dummy_More);
+
+ printf("OMost.OMore.O.I.IMore.dummy_More:%d\n",
+ OMost.OMore.O.I.IMore.dummy_More);
+
+ printf("OMost.OMore.O.I.IMore.IMost.position: %d\n",
+ OMost.OMore.O.I.IMore.IMost.position);
+
+ printf("OMost.OMore.O.I.IMore.IMost.content: %c\n",
+ OMost.OMore.O.I.IMore.IMost.content);
+
+ OMostCopy = OMost;
+
+ exit(0);
+}
+
+END
+/(0 != OMost.dummy_More) || (1 != OMost.OMore.dummy_More) ||
+ (2 != OMost.OMore.O.dummy_More) || (3 != OMost.OMore.O.I.dummy_More) ||
+ (4 != OMost.OMore.O.I.IMore.dummy_More) ||
+ (5 != OMost.OMore.O.I.IMore.IMost.position) ||
+ ('e' != OMost.OMore.O.I.IMore.IMost.content)/
+{
+ exit(1);
+}
+
+END
+/(0 != OMostCopy.dummy_More) || (1 != OMostCopy.OMore.dummy_More) ||
+ (2 != OMostCopy.OMore.O.dummy_More) ||
+ (3 != OMostCopy.OMore.O.I.dummy_More) ||
+ (4 != OMostCopy.OMore.O.I.IMore.dummy_More) ||
+ (5 != OMostCopy.OMore.O.I.IMore.IMost.position) ||
+ ('e' != OMostCopy.OMore.O.I.IMore.IMost.content)/
+{
+ exit(2);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d
new file mode 100644
index 0000000..0a7e80e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+struct foo {
+ int x;
+ char y;
+ short z;
+};
+
+this struct foo bar;
+long bignum;
+
+BEGIN
+{
+ this->bar.x = 1;
+ this->bar.y = ',';
+ this->bar.z = 1234;
+}
+
+BEGIN
+{
+ printf("Die %s%c %s.\n", this->bar.x == 1 ? "SystemTap" : "DTrace",
+ this->bar.y, this->bar.z == 1234 ? "Die" : "The");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d.out
new file mode 100644
index 0000000..c3fbf22
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/struct/tst.clauselocal.d.out
@@ -0,0 +1,2 @@
+Die SystemTap, Die.
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.c
new file mode 100644
index 0000000..209160b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.c
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <sys/syscall.h>
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ (void) syscall(SYS_mmap, NULL, 1, 2, 3, -1, 0x12345678);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.d
new file mode 100644
index 0000000..8e473b4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.args.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure we're correctly reporting arguments to syscall probes.
+ */
+
+#pragma D option quiet
+
+syscall::mmap*:entry
+/pid == $1 && arg0 == 0 && arg1 == 1 && arg2 == 2 && arg3 == 3 &&
+ (int)arg4 == -1 && arg5 == 0x12345678/
+{
+ exit(0);
+}
+
+tick-1s
+/i++ == 3/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.openret.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.openret.ksh
new file mode 100644
index 0000000..6469db7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/syscall/tst.openret.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+script() {
+ $dtrace -c 'cat shajirosan' -qs /dev/stdin <<EOF
+ syscall::open*:entry
+ /pid == \$target/
+ {
+ self->p = arg0;
+ }
+
+ syscall::open*:return
+ /self->p && copyinstr(self->p) == "shajirosan"/
+ {
+ self->err = 1;
+ self->p = 0;
+ }
+
+ syscall::open*:return
+ /self->err && (int)arg0 == -1 && (int)arg1 == -1/
+ {
+ exit(0);
+ }
+
+ syscall::open*:return
+ /self->err/
+ {
+ printf("a failed open(2) returned %d\n", (int)arg0);
+ exit(1);
+ }
+
+ syscall::open*:return
+ /self->p/
+ {
+ self->p = 0;
+ }
+EOF
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+script
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.c
new file mode 100644
index 0000000..1e7f957
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.c
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libsysevent.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ sysevent_id_t id;
+
+ for (;;) {
+ if (sysevent_post_event("class_dtest", "subclass_dtest",
+ "vendor_dtest", "publisher_dtest", NULL, &id) != 0) {
+ (void) fprintf(stderr, "failed to post sysevent\n");
+ return (1);
+ }
+
+ sleep(1);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.d
new file mode 100644
index 0000000..e547a26
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post.d
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ $1 + 0; /* make sure pid is referenced */
+
+ /*
+ * Wait no more than a five seconds for the sysevent to be posted
+ */
+ timeout = timestamp + 5000000000;
+}
+
+sysevent:::post
+/args[0]->ec_name != NULL/
+{
+ printf("channel name is non-NULL (%s)\n",
+ args[0]->ec_name);
+ exit(1);
+}
+
+sysevent:::post
+/strstr(args[1]->se_publisher, "vendor_dtest") == NULL/
+{
+ printf("missing vendor name from publisher (%s)\n",
+ args[1]->se_publisher);
+ exit(1);
+}
+
+sysevent:::post
+/strstr(args[1]->se_publisher, "publisher_dtest") == NULL/
+{
+ printf("missing publisher name from publisher (%s)\n",
+ args[1]->se_publisher);
+ exit(1);
+}
+
+sysevent:::post
+/args[1]->se_class != "class_dtest"/
+{
+ printf("unexpected class name (%s)\n", args[1]->se_class);
+ exit(1);
+}
+
+sysevent:::post
+/args[1]->se_subclass != "subclass_dtest"/
+{
+ printf("unexpected subclass name (%s)\n", args[1]->se_subclass);
+ exit(1);
+}
+
+sysevent:::post
+{
+ exit(0);
+}
+
+profile:::tick-8
+/timestamp > timeout/
+{
+ printf("timed out\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c
new file mode 100644
index 0000000..4a452a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <libsysevent.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ evchan_t *ch;
+
+ if (sysevent_evc_bind("channel_dtest", &ch,
+ EVCH_CREAT | EVCH_HOLD_PEND) != 0) {
+ (void) fprintf(stderr, "failed to bind to sysevent channel\n");
+ return (1);
+ }
+
+ for (;;) {
+ if (sysevent_evc_publish(ch, "class_dtest", "subclass_dtest",
+ "vendor_dtest", "publisher_dtest", NULL, EVCH_SLEEP) != 0) {
+ (void) sysevent_evc_unbind(ch);
+ (void) fprintf(stderr, "failed to publisth sysevent\n");
+ return (1);
+ }
+ sleep(1);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.d
new file mode 100644
index 0000000..9d12e1e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.d
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ $1 + 0; /* make sure pid is referenced */
+
+ /*
+ * Wait no more than five seconds for the sysevent to be posted
+ */
+ timeout = timestamp + 5000000000;
+}
+
+sysevent:::post
+/args[0]->ec_name != "channel_dtest"/
+{
+ printf("unexpected channel name (%s)\n", args[0]->ec_name);
+ exit(1);
+}
+
+sysevent:::post
+/strstr(args[1]->se_publisher, "vendor_dtest") == NULL/
+{
+ printf("missing vendor name from publisher (%s)\n",
+ args[1]->se_publisher);
+ exit(1);
+}
+
+sysevent:::post
+/strstr(args[1]->se_publisher, "publisher_dtest") == NULL/
+{
+ printf("missing publisher name from publisher (%s)\n",
+ args[1]->se_publisher);
+ exit(1);
+}
+
+sysevent:::post
+/args[1]->se_class != "class_dtest"/
+{
+ printf("unexpected class name (%s)\n", args[1]->se_class);
+ exit(1);
+}
+
+sysevent:::post
+/args[1]->se_subclass != "subclass_dtest"/
+{
+ printf("unexpected subclass name (%s)\n", args[1]->se_subclass);
+ exit(1);
+}
+
+sysevent:::post
+{
+ exit(0);
+}
+
+profile:::tick-8
+/timestamp > timeout/
+{
+ printf("timed out\n");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZERO.tick.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZERO.tick.d
new file mode 100644
index 0000000..015ae2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZERO.tick.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Negative test; calls tick without valid value.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-n
+{
+ printf("This test is a simple tick-n negative test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonens.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonens.d
new file mode 100644
index 0000000..3ed28b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonens.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-'ns' less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1ns
+{
+ printf("Calls 'ns' less than 200 micro seconds\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonensec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonensec.d
new file mode 100644
index 0000000..7b4df19
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROonensec.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-1nsec; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1nsec
+{
+ printf("Call profile-1nsec; less than 200 micro seconds\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneus.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneus.d
new file mode 100644
index 0000000..6a64a3a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneus.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Call profile-us; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1us
+{
+ printf(" Calling profile-us less than 200 micro seconds should fail\n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneusec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneusec.d
new file mode 100644
index 0000000..b6b80be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/err.D_PDESC_ZEROoneusec.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * profile-usec; less than 200 micro seconds.
+ *
+ * SECTION: profile Provider/profile-n probes
+ *
+ */
+
+#pragma D option quiet
+
+profile-1usec
+{
+ printf("profile-usec; less than 200 micro seconds \n");
+ exit (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickarg0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickarg0.d
new file mode 100644
index 0000000..4dda358
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickarg0.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * Simple tick-n 'arg0' test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1
+{
+ printf("The arg0 is %d\n", (int)arg0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d
new file mode 100644
index 0000000..602f3a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-ms simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1ms
+{
+ printf("This test is a simple tick-ms provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d.out
new file mode 100644
index 0000000..1e26759
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickms.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-ms provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d
new file mode 100644
index 0000000..1cf3b74
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-msec simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1msec
+{
+ printf("This test is a simple tick-msec provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d.out
new file mode 100644
index 0000000..286bb14
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickmsec.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-msec provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d
new file mode 100644
index 0000000..917139c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-ns simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-20000000ns
+{
+ printf("This test is a simple tick-ns provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d.out
new file mode 100644
index 0000000..26addde
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickns.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-ns provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d
new file mode 100644
index 0000000..3eedead
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-nsec simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-20000000nsec
+{
+ printf("This test is a simple tick-nsec provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d.out
new file mode 100644
index 0000000..4ad77b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticknsec.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-nsec provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d
new file mode 100644
index 0000000..05f2657
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-1s simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1s
+{
+ printf("This test is a simple tick-s provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d.out
new file mode 100644
index 0000000..b063121
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticks.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-s provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d
new file mode 100644
index 0000000..703af4d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-1sec simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-1sec
+{
+ printf("This test is a simple tick-sec provider test\n");
+}
+tick-1sec
+{
+ printf("This test is a simple tick-sec provider test");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d.out
new file mode 100644
index 0000000..d9d4f45
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.ticksec.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-sec provider test
+This test is a simple tick-sec provider test
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d
new file mode 100644
index 0000000..aa10cbb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-2000us simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-2000us
+{
+ printf("This test is a simple tick-us provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d.out
new file mode 100644
index 0000000..00baa3d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickus.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-us provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d
new file mode 100644
index 0000000..9deb8f4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * tick-2000usec simple test.
+ *
+ * SECTION: profile Provider/tick-n probes
+ *
+ */
+
+
+#pragma D option quiet
+
+tick-2000usec
+{
+ printf("This test is a simple tick-usec provider test\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d.out
new file mode 100644
index 0000000..40987e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tick-n/tst.tickusec.d.out
@@ -0,0 +1,2 @@
+This test is a simple tick-usec provider test
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d
new file mode 100644
index 0000000..a1ec95c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_PROTO_LEN.bad.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test trace() with no arguments.
+ *
+ * SECTION: Actions and Subroutines/trace()
+ */
+
+BEGIN
+{
+
+ trace();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d
new file mode 100644
index 0000000..eb9f194
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/err.D_TRACE_VOID.bad.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test an invalid specification of trace() with a void argument.
+ *
+ * SECTION: Actions and Subroutines/trace()
+ */
+
+BEGIN
+{
+ trace((void)`kmem_flags);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.misc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.misc.d
new file mode 100644
index 0000000..70ad5fc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.misc.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a variety of trace() action invocations.
+ *
+ * SECTION: Actions and Subroutines/trace();
+ * Output Formatting/trace()
+ *
+ * NOTES:
+ * We test things that exercise different kinds of DIFO return types
+ * to ensure each one can be traced.
+ */
+
+BEGIN
+{
+ i = 1;
+}
+
+
+tick-1
+/i != 5/
+{
+ trace("test trace"); /* DT_TYPE_STRING */
+ trace(12345); /* DT_TYPE_INT (constant) */
+ trace(x++); /* DT_TYPE_INT (derived) */
+ trace(timestamp); /* DT_TYPE_INT (variable) */
+ trace(`kmem_flags); /* CTF type (by value) */
+ trace(*`rootvp); /* CTF type (by ref) */
+ i++;
+}
+
+tick-1
+/i == 5/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d
new file mode 100644
index 0000000..a81d147b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+/*
+ * ASSERTION:
+ * Positive trace tests - trace with strings, using quiet option
+ *
+ * SECTION: Actions and Subroutines/trace()
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ trace("this");
+ trace(" %should work.\n");
+ trace("%don't w%orry -- this won't cause a %segfault.\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d.out
new file mode 100644
index 0000000..908ffb2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.qstring.d.out
@@ -0,0 +1,3 @@
+this %should work.
+%don't w%orry -- this won't cause a %segfault.
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.string.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.string.d
new file mode 100644
index 0000000..c5e7c2c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/trace/tst.string.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive trace tests - trace with strings
+ *
+ * SECTION: Actions and Subroutines/trace()
+ */
+
+BEGIN
+{
+ trace("this");
+ trace(" %should work.\n");
+ trace("%don't w%orry -- this won't cause a %segfault.\n");
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_ARG.badsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_ARG.badsize.d
new file mode 100644
index 0000000..4e137ce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_ARG.badsize.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() with an invalid size argument.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+BEGIN
+{
+ tracemem(123, "i'm a string");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toofew.d
new file mode 100644
index 0000000..91c4f77
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_PROTO_LEN.toofew.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() with too few arguments.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+
+BEGIN
+{
+ tracemem(123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ADDR.badaddr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ADDR.badaddr.d
new file mode 100644
index 0000000..6814577
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ADDR.badaddr.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() with an invalid address argument.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+BEGIN
+{
+ tracemem(`v, 123);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d
new file mode 100644
index 0000000..1eb96be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_ARGS.d
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ tracemem(`dtrace_zero, 256, 0, "fishpong");
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d
new file mode 100644
index 0000000..554bb7d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_DYNSIZE.d
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+BEGIN
+{
+ tracemem(`dtrace_zero, 256, "fishpong");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.negsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.negsize.d
new file mode 100644
index 0000000..b3dd438
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.negsize.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() with a negative size argument.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+BEGIN
+{
+ tracemem(123, -456);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.zerosize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.zerosize.d
new file mode 100644
index 0000000..595bfcc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/err.D_TRACEMEM_SIZE.zerosize.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() with a zero size argument.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+BEGIN
+{
+ tracemem(123, 0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d
new file mode 100644
index 0000000..de530e8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ i = -10;
+}
+
+tick-10ms
+/i++ < 150/
+{
+ printf("%d:", i);
+ tracemem(`dtrace_zero, 128, i);
+ printf("\n");
+}
+
+tick-10ms
+/i >= 150/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out
new file mode 100644
index 0000000..6415893
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.dynsize.d.out
@@ -0,0 +1,1313 @@
+-9:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-8:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-7:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-6:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-5:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-4:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-3:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-2:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+-1:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+0:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+1:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 .
+
+2:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 ..
+
+3:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 ...
+
+4:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 ....
+
+5:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 .....
+
+6:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 ......
+
+7:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 .......
+
+8:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 ........
+
+9:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 .........
+
+10:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 ..........
+
+11:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+12:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+13:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+14:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+15:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+16:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+17:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 .
+
+18:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 ..
+
+19:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 ...
+
+20:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 ....
+
+21:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 .....
+
+22:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 ......
+
+23:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 .......
+
+24:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 ........
+
+25:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 .........
+
+26:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 ..........
+
+27:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+28:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+29:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+30:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+31:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+32:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+33:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 .
+
+34:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 ..
+
+35:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 ...
+
+36:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 ....
+
+37:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 .....
+
+38:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 ......
+
+39:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 .......
+
+40:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 ........
+
+41:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 .........
+
+42:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 ..........
+
+43:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+44:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+45:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+46:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+47:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+48:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+49:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 .
+
+50:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 ..
+
+51:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 ...
+
+52:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 ....
+
+53:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 .....
+
+54:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 ......
+
+55:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 .......
+
+56:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 ........
+
+57:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 .........
+
+58:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 ..........
+
+59:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+60:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+61:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+62:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+63:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+64:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+65:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 .
+
+66:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 ..
+
+67:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 ...
+
+68:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 ....
+
+69:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 .....
+
+70:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 ......
+
+71:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 .......
+
+72:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 ........
+
+73:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 .........
+
+74:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 ..........
+
+75:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+76:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+77:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+78:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+79:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+80:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+81:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 .
+
+82:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 ..
+
+83:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 ...
+
+84:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 ....
+
+85:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 .....
+
+86:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 ......
+
+87:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 .......
+
+88:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 ........
+
+89:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 .........
+
+90:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 ..........
+
+91:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+92:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+93:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+94:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+95:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+96:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+97:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 .
+
+98:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 ..
+
+99:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 ...
+
+100:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 ....
+
+101:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 .....
+
+102:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 ......
+
+103:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 .......
+
+104:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 ........
+
+105:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 .........
+
+106:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 ..........
+
+107:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+108:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+109:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+110:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+111:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+112:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+113:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 .
+
+114:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 ..
+
+115:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 ...
+
+116:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 ....
+
+117:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 .....
+
+118:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 ......
+
+119:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 .......
+
+120:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 ........
+
+121:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 .........
+
+122:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 ..........
+
+123:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 ...........
+
+124:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 ............
+
+125:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
+
+126:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
+
+127:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
+
+128:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+129:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+130:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+131:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+132:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+133:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+134:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+135:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+136:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+137:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+138:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+139:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+140:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+141:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+142:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+143:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+144:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+145:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+146:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+147:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+148:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+149:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+150:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.rootvp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.rootvp.d
new file mode 100644
index 0000000..537b722
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/tracemem/tst.rootvp.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test tracemem() by tracing out the contents of the root vnode
+ * as a raw stream of bytes.
+ *
+ * SECTION: Actions and Subroutines/tracemem()
+ */
+
+
+BEGIN
+{
+ i = 1;
+}
+
+tick-1
+/i != 5/
+{
+ tracemem(`rootvp, 20);
+ i++;
+}
+
+tick-1
+/i == 5/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_DECL_TYPERED.BadTransDecl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_DECL_TYPERED.BadTransDecl.d
new file mode 100644
index 0000000..2a44778
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_DECL_TYPERED.BadTransDecl.d
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with the input type enclosed in
+ * between braces rather than angle brackets.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct
+{
+ struct input_struct *uvar
+}
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+}
+
+BEGIN
+{
+ printf("Using braces instead of angle brackets for translator input");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_OP_INCOMPLETE.NonExistentInput1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_OP_INCOMPLETE.NonExistentInput1.d
new file mode 100644
index 0000000..0c8c84d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_OP_INCOMPLETE.NonExistentInput1.d
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with a non-existent input type.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ */
+
+#pragma D option quiet
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct *ivar >
+{
+ myi = ((struct input_struct *) ivar)->nonexistentI;
+ myc = ((struct input_struct *) ivar)->nonexistentC;
+};
+
+BEGIN
+{
+ printf("Test the translation of a non existing input type");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl1.d
new file mode 100644
index 0000000..52e5c9a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl1.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with the input type enclosed in
+ * between parantheses rather than angle brackets.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct ( struct input_struct *uvar )
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+}
+
+BEGIN
+{
+ printf("Test translator with input type in parantheses");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl3.d
new file mode 100644
index 0000000..6be8128
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl3.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator without enclosing braces { }.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct *uvar >
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+;
+
+BEGIN
+{
+ printf("Test the translator definition without enclosing braces");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl4.d
new file mode 100644
index 0000000..926f74c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_SYNTAX.BadTransDecl4.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator without terminating semi-colon (;).
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct *uvar >
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+}
+
+translator struct output_struct < struct new_struct *newvar >
+{
+};
+
+
+BEGIN
+{
+ printf("Test translator declaration without terminating semi-colon");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_TYPE_MEMBER.NonExistentInput2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_TYPE_MEMBER.NonExistentInput2.d
new file mode 100644
index 0000000..16deff8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_TYPE_MEMBER.NonExistentInput2.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with a non-existent member
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *ivar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct *ivar >
+{
+ myi = ((struct input_struct *) ivar)->i;
+ myc = ((struct input_struct *) ivar)->nonexistent;
+};
+
+BEGIN
+{
+ printf("Testing the assignment of a non-existent input member");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_INCOMPAT.BadInputType1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_INCOMPAT.BadInputType1.d
new file mode 100644
index 0000000..26cab45
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_INCOMPAT.BadInputType1.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with a mismatch in types.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char *myc;
+};
+
+translator struct output_struct < struct input_struct *uvar >
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+};
+
+BEGIN
+{
+ printf("Translating against the rules of assignment operator");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_MEMB.NonExistentOutput2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_MEMB.NonExistentOutput2.d
new file mode 100644
index 0000000..6d6eba1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_MEMB.NonExistentOutput2.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with a non-existent output member.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *ivar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct *ivar >
+{
+ myi = ((struct input_struct *) ivar)->i;
+ yourc = ((struct input_struct *) ivar)->nonexistent;
+};
+
+BEGIN
+{
+ printf("Testing translation with non existent output member");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_NONE.BadTransDecl6.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_NONE.BadTransDecl6.d
new file mode 100644
index 0000000..4cfabce
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_NONE.BadTransDecl6.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When xlate is used on a variable for which no translation exists a
+ * D_XLATE_NONE is thrown
+ *
+ * SECTION: Translators/Translate Operator
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myoutput_struct {
+ int myi;
+ char myc;
+};
+
+translator struct myoutput_struct < struct myinput_struct *ivar >
+{
+ myi = ((struct myinput_struct *) ivar)->i;
+ myc = ((struct myinput_struct *) ivar)->c;
+
+};
+
+struct myinput_struct f;
+BEGIN
+{
+ f.i = 10;
+ f.c = 'c';
+
+ xlate < struct myoutput_struct >(f)->myi;
+ printf("Translate operator used without correct translator decl\n");
+ exit(0);
+}
+
+ERROR
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_REDECL.RepeatTransDecl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_REDECL.RepeatTransDecl.d
new file mode 100644
index 0000000..62f8482
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_REDECL.RepeatTransDecl.d
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Redeclaring the same translation twice throws a D_XLATE_REDECL error.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii1;
+ char ic1;
+} *ivar1;
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct *ivar1 >
+{
+ oi = ((struct input_struct *) ivar1)->ii1;
+ oc = ((struct input_struct *) ivar1)->ic1;
+};
+
+translator struct output_struct < struct input_struct *ivar1 >
+{
+ oi = ((struct input_struct *) ivar1)->ii1;
+ oc = ((struct input_struct *) ivar1)->ic1;
+};
+
+
+BEGIN
+{
+ printf("Redeclaration of the same translation");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransDecl8.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransDecl8.d
new file mode 100644
index 0000000..63786c7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransDecl8.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When the output type of the translator declaration is not a struct or
+ * union a D_XLATE_SOU is thrown.
+ *
+ * SECTION: Translators/Translator Declarations
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+enum colors
+{
+ RED,
+ BLUE
+};
+
+translator enum colors < struct input_struct *ivar >
+{
+};
+
+BEGIN
+{
+ printf("Output type of translation is an enum");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransInt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransInt.d
new file mode 100644
index 0000000..6545569
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.BadTransInt.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When the output type of the translator declaration is not a struct or
+ * union a D_XLATE_SOU is thrown.
+ *
+ * SECTION: Translators/Translator Declarations
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+translator int < struct input_struct *ivar >
+{
+};
+
+BEGIN
+{
+ printf("Output type of translation is an int");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.NonExistentOutput1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.NonExistentOutput1.d
new file mode 100644
index 0000000..1ebb94c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/err.D_XLATE_SOU.NonExistentOutput1.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator with a non-existent output type.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *ivar;
+
+translator struct output_struct < struct input_struct *ivar >
+{
+ myi = ((struct input_struct *) ivar)->i;
+ myc = ((struct input_struct *) ivar)->nonexistent;
+};
+
+BEGIN
+{
+ printf("Translation with non existent output type struct");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d
new file mode 100644
index 0000000..c664188
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/man.TestTransStability.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The D inline translation mechanism can be used to facilitate stable
+ * translations.
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ * SECTION: Translators/Stable Translations
+ *
+ * NOTES: Uncomment the pragma that explicitly resets the attributes of
+ * myinfo identifier to Stable/Stable/Common from Private/Private/Unknown.
+ * Run the program with and without the comments as:
+ * /usr/sbin/dtrace -vs man.TestTransStability.d
+ */
+
+#pragma D option quiet
+
+inline lwpsinfo_t *myinfo = xlate < lwpsinfo_t *> (curthread);
+
+/*
+#pragma D attributes Stable/Stable/Common myinfo
+*/
+
+BEGIN
+{
+ trace(myinfo->pr_flag);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.CircularTransDecl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.CircularTransDecl.d
new file mode 100644
index 0000000..58466f7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.CircularTransDecl.d
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test circular declaration of translations
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+};
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct ivar >
+{
+ myi = ((struct input_struct ) ivar).i;
+ myc = ((struct input_struct ) ivar).c;
+};
+
+translator struct input_struct < struct output_struct uvar >
+{
+ i = ((struct output_struct ) uvar).myi;
+ c = ((struct output_struct ) uvar).myc;
+};
+
+struct input_struct f1;
+struct output_struct f2;
+
+BEGIN
+{
+ f1.i = 10;
+ f1.c = 'c';
+
+ f2.myi = 100;
+ f2.myc = 'd';
+
+ printf("Testing circular translations\n");
+ forwardi = xlate < struct output_struct > (f1).myi;
+ forwardc = xlate < struct output_struct > (f1).myc;
+ backwardi = xlate < struct input_struct > (f2).i;
+ backwardc = xlate < struct input_struct > (f2).c;
+
+ printf("forwardi: %d\tforwardc: %c\n", forwardi, forwardc);
+ printf("backwardi: %d\tbackwardc: %c", backwardi, backwardc);
+ exit(0);
+}
+
+BEGIN
+/(10 == forwardi) && ('c' == forwardc) && (100 == backwardi) &&
+ ('d' == backwardc)/
+{
+ exit(0);
+}
+
+BEGIN
+/(10 != forwardi) || ('c' != forwardc) || (100 != backwardi) ||
+ ('d' != backwardc)/
+{
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.EmptyTransDecl.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.EmptyTransDecl.d
new file mode 100644
index 0000000..5a29207
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.EmptyTransDecl.d
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the empty declaration of a translator
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct input_struct uvar >
+{
+};
+
+struct input_struct in;
+struct output_struct ou;
+
+BEGIN
+{
+ in.i = 10;
+ in.c = 'c';
+
+ ou = xlate < struct output_struct > (in);
+
+ printf("ou.myi: %d\tou.myc: %c\n", ou.myi, ou.myc);
+}
+
+BEGIN
+/(0 != ou.myi) || (0 != ou.myc)/
+{
+ printf("Failed\n");
+ exit(1);
+}
+
+BEGIN
+/(0 == ou.myi) || (0 == ou.myc)/
+{
+ printf("Passed\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ForwardTag.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ForwardTag.d
new file mode 100644
index 0000000..246a8d2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ForwardTag.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a forward tag using a translator definition.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct callmewhatever *idontcare >
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myc = ((struct input_struct *) uvar)->c;
+};
+
+BEGIN
+{
+ printf("This test defines a forward tag");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputAliasTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputAliasTrans.d
new file mode 100644
index 0000000..a562b39
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputAliasTrans.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The input type of the tranlator declaration is an alias.
+ *
+ * SECTION: Translators/ Translator Declarations.
+ *
+ */
+
+#pragma D option quiet
+
+typedef struct input_struct {
+ int ii;
+ char ic;
+} input_t;
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < input_t *ivar >
+{
+ oi = ((input_t *) ivar)->ii;
+ oc = ((input_t *) ivar)->ic;
+};
+
+BEGIN
+{
+ printf("Input type is an alias");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputIntTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputIntTrans.d
new file mode 100644
index 0000000..e5159ed
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.InputIntTrans.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of a translator the input type in the translator
+ * declaration being different from the values being assigned inside.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int i;
+ char c;
+} *uvar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < int idontcare >
+{
+ myi = ((struct input_struct *) uvar)->i;
+ myi = ((struct input_struct *) uvar)->c;
+};
+
+BEGIN
+{
+ printf("Input type to the translator decl is different from members");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d
new file mode 100644
index 0000000..cd47153
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The output type is an alias.
+ *
+ * SECTION: Translators/ Translator Declarations.
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+typedef struct output_struct output_t;
+
+
+translator output_t < struct input_struct *ivar >
+{
+ oi = ((struct input_struct *) ivar)->ii;
+ oc = ((struct input_struct *) ivar)->ic;
+};
+
+BEGIN
+{
+ printf("Output type is an alias");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialDereferencing.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialDereferencing.d
new file mode 100644
index 0000000..ae532cc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialDereferencing.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * If you dereference a single member of the translation input, then the
+ * compiler will generate the code corresponding to that member
+ *
+ * SECTION: Translators/ Translate Operator
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct ivar >
+{
+ oi = ((struct input_struct) ivar).ii;
+ oc = ((struct input_struct) ivar).ic;
+};
+
+struct output_struct out;
+struct input_struct in;
+
+BEGIN
+{
+ in.ii = 100;
+ in.ic = 'z';
+
+ printf("Translating only a part of the input struct\n");
+ out.oi = xlate < struct output_struct > (in).oi;
+
+ printf("out.oi: %d\t out.oc: %d\n", out.oi, out.oc);
+}
+
+BEGIN
+/(100 != out.oi) || (0 != out.oc)/
+{
+ exit(1);
+}
+
+BEGIN
+/(100 == out.oi) && (0 == out.oc)/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialOutputTransDefn.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialOutputTransDefn.d
new file mode 100644
index 0000000..9be52a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.PartialOutputTransDefn.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A translator declaration may omit expressions for one or more members
+ * of the output type
+ *
+ * SECTION: Translators/Translator Declarations;
+ * Translators/Translate Operator
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct *ivar >
+{
+ oi = ((struct input_struct *) ivar)->ii;
+};
+
+BEGIN
+{
+ printf("Translating only a part of the input struct");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ProcModelTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ProcModelTrans.d
new file mode 100644
index 0000000..ff313ec
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.ProcModelTrans.d
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Use the translators in /usr/lib/dtrace/procfs.d
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ * SECTION: Translators/Process Model Translators
+ *
+ */
+
+#pragma D option quiet
+
+proc_t *T;
+
+BEGIN
+{
+ mypr_addr = xlate < psinfo_t > (T).pr_addr;
+ printf("pr_addr: %d", mypr_addr);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.RepeatDeclaration.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.RepeatDeclaration.d
new file mode 100644
index 0000000..a928c3e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.RepeatDeclaration.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Reassign the members of the output struct using another translator
+ * input struct.
+ *
+ * SECTION: Translators/Translator Declarations
+ */
+
+#pragma D option quiet
+
+struct input_struct1 {
+ int ii1;
+ char ic1;
+} *ivar1;
+
+struct input_struct2 {
+ long ii2;
+ long ic2;
+} *ivar2;
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct1 *ivar1 >
+{
+ oi = ((struct input_struct1 *) ivar1)->ii1;
+ oc = ((struct input_struct1 *) ivar1)->ic1;
+};
+
+translator struct output_struct < struct input_struct2 *ivar2 >
+{
+ oi = ((struct input_struct2 *) ivar2)->ii2;
+ oc = ((struct input_struct2 *) ivar2)->ic2;
+};
+
+BEGIN
+{
+ printf("Reassignment of a struct's members with different input");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.SimultaneousTranslators.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.SimultaneousTranslators.d
new file mode 100644
index 0000000..63cd72c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.SimultaneousTranslators.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Assign the different members of the output of the translator using
+ * different translator declarations.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct1 {
+ int ii1;
+ char ic1;
+} *ivar1;
+
+struct input_struct2 {
+ int ii2;
+ char ic2;
+} *ivar2;
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct1 *ivar1 >
+{
+ oi = ((struct input_struct1 *) ivar1)->ii1;
+};
+
+translator struct output_struct < struct input_struct2 *ivar2 >
+{
+ oc = ((struct input_struct2 *) ivar2)->ic2;
+};
+
+BEGIN
+{
+ printf("Translate members of output with different input structs");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.StructureAssignment.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.StructureAssignment.d
new file mode 100644
index 0000000..277d95f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.StructureAssignment.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * If the entire output is copied by means of a structure assignment, any
+ * members for which no translation expressions are defined will be filled
+ * with zeroes.
+ *
+ * SECTION: Translators/ Translate Operator
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+};
+
+struct output_struct {
+ int oi;
+ char oc;
+};
+
+
+translator struct output_struct < struct input_struct ivar >
+{
+ oi = ((struct input_struct) ivar).ii;
+};
+
+struct output_struct out;
+struct input_struct in;
+
+BEGIN
+{
+ in.ii = 100;
+ in.ic = 'z';
+
+ printf("Translating via struct assignment\n");
+ out = xlate < struct output_struct > (in);
+
+ printf("out.oi: %d\t out.oc: %d\n", out.oi, out.oc);
+}
+
+BEGIN
+/(100 != out.oi) || (0 != out.oc)/
+{
+ exit(1);
+}
+
+BEGIN
+/(100 == out.oi) && (0 == out.oc)/
+{
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransNonPointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransNonPointer.d
new file mode 100644
index 0000000..3ec8143
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransNonPointer.d
@@ -0,0 +1,84 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Translate the input expression to output struct type
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myoutput_struct {
+ int myi;
+ char myc;
+};
+
+translator struct myoutput_struct < struct myinput_struct ivar >
+{
+ myi = ((struct myinput_struct ) ivar).i;
+ myc = ((struct myinput_struct ) ivar).c;
+
+};
+
+struct myinput_struct f;
+BEGIN
+{
+ f.i = 10;
+ f.c = 'c';
+
+ realmyi = xlate < struct myoutput_struct > (f).myi;
+ realmyc = xlate < struct myoutput_struct > (f).myc;
+}
+
+BEGIN
+/(10 != f.i) || ('c' != f.c)/
+{
+ exit(1);
+}
+
+BEGIN
+/(10 == f.i) && ('c' == f.c)/
+{
+ printf("realmyi: %d\n", realmyi);
+ printf("realmyc: %c\n", realmyc);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransOutputPointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransOutputPointer.d
new file mode 100644
index 0000000..9069bf5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransOutputPointer.d
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Translate an input expression to a pointer to a struct
+ *
+ * SECTION: Translators/ Translator Declarations
+ * SECTION: Translators/ Translate Operator
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myoutput_struct {
+ int myi;
+ char myc;
+};
+
+translator struct myoutput_struct < struct myinput_struct ivar >
+{
+ myi = ((struct myinput_struct ) ivar).i;
+ myc = ((struct myinput_struct ) ivar).c;
+
+};
+
+struct myinput_struct f;
+
+BEGIN
+{
+ f.i = 1203;
+ f.c = 'v';
+
+ realmyi = xlate < struct myoutput_struct *> (f)->myi;
+ realmyc = xlate < struct myoutput_struct *> (f)->myc;
+}
+
+BEGIN
+/(1203 != realmyi) || ('v' != realmyc)/
+{
+ printf("Failure");
+ exit(1);
+}
+
+BEGIN
+/(1203 == realmyi) && ('v' == realmyc)/
+{
+ printf("Success");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransPointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransPointer.d
new file mode 100644
index 0000000..34d31d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TransPointer.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the normal declaration of translators.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct myinput_struct {
+ int i;
+ char c;
+};
+
+struct myoutput_struct {
+ int myi;
+ char myc;
+};
+
+translator struct myoutput_struct < struct myinput_struct *ivar >
+{
+ myi = ((struct myinput_struct *) ivar)->i;
+ myc = ((struct myinput_struct *) ivar)->c;
+
+};
+
+struct myinput_struct *f;
+
+BEGIN
+{
+ printf("Good translator defn");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TranslateSelf.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TranslateSelf.d
new file mode 100644
index 0000000..9059093
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.TranslateSelf.d
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the translation of a struct to itself.
+ *
+ * SECTION: Translators/ Translator Declarations.
+ * SECTION: Translators/ Translate operator.
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < struct output_struct uvar >
+{
+ myi = ((struct output_struct ) uvar).myi;
+ myc = ((struct output_struct ) uvar).myc;
+};
+
+struct output_struct out;
+struct output_struct outer;
+
+BEGIN
+{
+ out.myi = 1234;
+ out.myc = 'a';
+
+ printf("Test translation of a struct to itself\n");
+ outer = xlate < struct output_struct > (out);
+
+ printf("outer.myi: %d\t outer.myc: %c\n", outer.myi, outer.myc);
+}
+
+BEGIN
+/(1234 != outer.myi) || ('a' != outer.myc)/
+{
+ exit(1);
+}
+
+BEGIN
+/(1234 == outer.myi) && ('a' == outer.myc)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionInputTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionInputTrans.d
new file mode 100644
index 0000000..fb2dcf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionInputTrans.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test the declaration of translators with a union to be the input type.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+union input_union {
+ int i;
+ char c;
+} *ivar;
+
+struct output_struct {
+ int myi;
+ char myc;
+};
+
+translator struct output_struct < union input_union *ivar >
+{
+ myi = ((union input_union *) ivar)->i;
+ myc = ((union input_union *) ivar)->c;
+
+};
+
+BEGIN
+{
+ printf("Translator definition good\n");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionOutputTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionOutputTrans.d
new file mode 100644
index 0000000..3b2c588
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.UnionOutputTrans.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * The output type in a translator definition can be a union.
+ *
+ * SECTION: Translators/Translator Declarations
+ *
+ *
+ */
+
+#pragma D option quiet
+
+struct input_struct {
+ int ii;
+ char ic;
+} *ivar;
+
+union output_union {
+ int oi;
+ char oc;
+};
+
+translator union output_union < struct input_struct *ivar >
+{
+ oi = ((struct input_struct *) ivar)->ii;
+ oc = ((struct input_struct *) ivar)->ic;
+
+};
+
+BEGIN
+{
+ printf("Test translator definition with union output");
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_DECL_IDRED.DupTypeDef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_DECL_IDRED.DupTypeDef.d
new file mode 100644
index 0000000..47a9fdf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_DECL_IDRED.DupTypeDef.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * ASSERTION: Cannot redeclare identifier using typedef.
+ *
+ * SECTION: Type and Constant Definitions/Typedef
+ *
+ * NOTES:
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+typedef int new_int;
+
+BEGIN
+{
+ exit(0);
+}
+
+typedef char new_int;
+
+END
+{
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.BadExistingTypedef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.BadExistingTypedef.d
new file mode 100644
index 0000000..38521a0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.BadExistingTypedef.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * ASSERTION:
+ * The typedef keyword throws an D_SYNTAX error when a bad existing type is
+ * used.
+ *
+ * SECTION: Type and Constant Definitions/Typedef
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+typedef pint new_int;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.TypedefInClause.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.TypedefInClause.d
new file mode 100644
index 0000000..0cb8cf7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/err.D_SYNTAX.TypedefInClause.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * ASSERTION:
+ * The typedef keyword can be used outside of the probe clauses only.
+ *
+ * SECTION: Type and Constant Definitions/Typedef
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ typedef int new_int;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.ChainTypedef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.ChainTypedef.d
new file mode 100644
index 0000000..00810a5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.ChainTypedef.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION: An identifier used to alias a primitive data type can be further
+ * used to typedef other aliases. typedef is transitive.
+ *
+ * SECTION: Type and Constant Definitions/Typedef
+ *
+ * NOTES:
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+typedef int new_int;
+typedef new_int latest_int;
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.TypedefDataAssign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.TypedefDataAssign.d
new file mode 100644
index 0000000..4565be5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/typedef/tst.TypedefDataAssign.d
@@ -0,0 +1,118 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Test the typedef keyword with the different D data types. Declare different
+ * data types and test some of them with values.
+ *
+ * SECTION: Type and Constant Definitions/Typedef
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+typedef char new_char;
+typedef short new_short;
+typedef int new_int;
+typedef long new_long;
+typedef long long new_long_long;
+typedef int8_t new_int8;
+typedef int16_t new_int16;
+typedef int32_t new_int32;
+typedef int64_t new_int64;
+typedef intptr_t new_intptr;
+typedef uint8_t new_uint8;
+typedef uint16_t new_uint16;
+typedef uint32_t new_uint32;
+typedef uint64_t new_uint64;
+typedef uintptr_t new_uintptr;
+typedef float new_float;
+typedef double new_double;
+typedef long double new_long_double;
+
+typedef int * pointer;
+
+typedef struct {
+ char ch;
+ int in;
+ long lg;
+} new_struct;
+
+typedef union {
+ char ch;
+ int in;
+ long lg;
+} new_union;
+
+typedef enum {
+ RED,
+ GREEN,
+ BLUE
+} new_enum;
+
+new_char c;
+new_short s;
+new_int i;
+new_long l;
+new_long_long ll;
+new_int8 i8;
+new_int16 i16;
+new_int32 i32;
+new_int64 i64;
+new_intptr iptr;
+new_uint8 ui8;
+new_uint16 ui16;
+new_uint32 ui32;
+new_uint64 ui64;
+new_uintptr uiptr;
+new_float f;
+new_double d;
+new_long_double ld;
+new_struct ns;
+new_union nu;
+new_enum ne;
+
+pointer p;
+
+BEGIN
+{
+ ns.ch = 'c';
+ ns.in = 4;
+ ns.lg = 4;
+
+ nu.ch = 'd';
+ nu.in = 5;
+ nu.lg = 5;
+
+ i = 10;
+
+ printf("Struct: %c, %d, %d\n", ns.ch, ns.in, ns.lg);
+ printf("Union: %c, %d, %d\n", nu.ch, nu.in, nu.lg);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CAST_INVAL.badcast.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CAST_INVAL.badcast.d
new file mode 100644
index 0000000..13d58ea
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CAST_INVAL.badcast.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Test an illegal cast - make sure dtrace catches it.
+ *
+ * SECTION: Aggregations/Clearing aggregations
+ *
+ *
+ */
+
+
+BEGIN
+{
+ (char)trace(`kmem_flags);
+ exit();
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CG_DYN.ResultDynType.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CG_DYN.ResultDynType.d
new file mode 100644
index 0000000..74f2d70
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CG_DYN.ResultDynType.d
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * An expression cannot evaluate to result of dynamic type.
+ *
+ * SECTION: Errtag/D_CG_DYN
+ */
+
+#pragma D option quiet
+
+translator lwpsinfo_t < int i >
+{
+ pr_flag = i;
+};
+
+BEGIN
+{
+ xlate < lwpsinfo_t * > (0);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CHR_OFLOW.charconst.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CHR_OFLOW.charconst.d
new file mode 100644
index 0000000..b158c3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_CHR_OFLOW.charconst.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * verify the use of multi-char constants in single quotes
+ *
+ * SECTION: Types, Operators, and Expressions/Constants
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ char_bad = 'abc\fefghi';
+
+ printf("decimal value = %d", char_bad);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_BADCLASS.bad.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_BADCLASS.bad.d
new file mode 100644
index 0000000..5064a59
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_BADCLASS.bad.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid class names should be handled as an error.
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+register x;
+
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_CHARATTR.badtype3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_CHARATTR.badtype3.d
new file mode 100644
index 0000000..e1407bc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_CHARATTR.badtype3.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid type name
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ i = (char long)0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype4.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype4.d
new file mode 100644
index 0000000..e925a86
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype4.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid type name
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ i = (char int)0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype5.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype5.d
new file mode 100644
index 0000000..b7a3b05
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_COMBO.badtype5.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid type name
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ i = (double double)0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENCONST.badeval.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENCONST.badeval.d
new file mode 100644
index 0000000..5e1c19d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENCONST.badeval.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt a bogus enum declaration by assigning a non-constant expression
+ * to an enumerator.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+enum e {
+ TAG = "i am not an integer constant!"
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enoflow.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enoflow.d
new file mode 100644
index 0000000..25e14a6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enoflow.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Define an enumerations with a overflow value.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+enum e {
+ toobig = 2147483648
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enuflow.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enuflow.d
new file mode 100644
index 0000000..3709cb2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_ENOFLOW.enuflow.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Define an enumerations with a overflow value using negative value.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+
+enum e {
+ toosmall = -2147483649
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_SCOPE.scopeop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_SCOPE.scopeop.d
new file mode 100644
index 0000000..ddac451
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_SCOPE.scopeop.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Using the scope operator in a declaration will result in a
+ * D_DECL_SCOPE error.
+ *
+ * SECTION: Variables/External Variables
+ *
+ */
+
+#pragma D option quiet
+
+int `xyz;
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_USELESS.baddec.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_USELESS.baddec.d
new file mode 100644
index 0000000..7e3606e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_DECL_USELESS.baddec.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Bad external declarations will result in a D_DECL_USELESS
+ * error.
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+extern int;
+
+BEGIN
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ACT.badcond.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ACT.badcond.d
new file mode 100644
index 0000000..b139f9e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ACT.badcond.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Tracing functions may not be second and third expressions
+ * of a conditional expr.
+ *
+ * SECTION: Types, Operators, and Expressions/Conditional Expressions
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ i = 1;
+ x = i == 0 ? trace(0): trace(1);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ARITH.badoperand.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ARITH.badoperand.d
new file mode 100644
index 0000000..9fefb17
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_ARITH.badoperand.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Arithmetic operations with a +/- must be followed by an arithmetic
+ * type.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ *
+ */
+
+
+
+BEGIN
+{
+ p = 123 + -trace(0);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INCOMPAT.badassign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INCOMPAT.badassign.d
new file mode 100644
index 0000000..04815a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INCOMPAT.badassign.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Assignment operators do not supported on all types
+ *
+ * SECTION: Types, Operators, and Expressions/Assignment Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = 3;
+ a += "foobar";
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badbitop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badbitop.d
new file mode 100644
index 0000000..a210ea1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badbitop.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Bitwise operators not supported on all types
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+/"char" & "foo"/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badshift.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badshift.d
new file mode 100644
index 0000000..978df1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_INT.badshift.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Shift operators not supported on all types
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ x = "char" << 2;
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badcond.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badcond.d
new file mode 100644
index 0000000..2972ac2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badcond.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Conditional expressions not supported on all types
+ *
+ * SECTION: Types, Operators, and Expressions/Conditional Expressions
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = "boo";
+ c = "boo" ? "should": "fail";
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badincop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badincop.d
new file mode 100644
index 0000000..dfd5a31
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badincop.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Increment operators not supported on all types
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = "boo";
+ c = a++;
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badlogop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badlogop.d
new file mode 100644
index 0000000..4f084c7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_OP_SCALAR.badlogop.d
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Logical operators not supported on all types
+ *
+ * SECTION: Types, Operators, and Expressions/Logical Operators
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+/"char" && "foo"/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_PROTO_LEN.badcond1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_PROTO_LEN.badcond1.d
new file mode 100644
index 0000000..8e32750
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_PROTO_LEN.badcond1.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Conditional expressions do not accept tracing functions in
+ * the second or third expression
+ *
+ * SECTION: Types, Operators, and Expressions/Conditional Expressions
+ *
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ a = "boo";
+ c = a == "boo" ? printf("error\n") : trace();
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badenum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badenum.d
new file mode 100644
index 0000000..3b53775
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badenum.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a bogus enum declaration using an invalid identifer.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+
+enum foo`bar
+{
+
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badid.d
new file mode 100644
index 0000000..a28182c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badid.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Identifiers cannot begin with a digit
+ *
+ * SECTION: Types, Operators, and Expressions/Identifier Names and Keywords
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+int 0abc;
+
+BEGIN
+{
+ 0abc = 5;
+ printf("0abc is %d", 0abc);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badstruct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badstruct.d
new file mode 100644
index 0000000..6c57d21
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_SYNTAX.badstruct.d
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt a bogus struct declaration using an invalid identifer.
+ *
+ * SECTION: Structs and Unions/Structs
+ */
+
+struct foo`bar {
+
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype1.d
new file mode 100644
index 0000000..4f6d1e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype1.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid type name
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ i = (long short)0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype2.d
new file mode 100644
index 0000000..f40e95f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.badtype2.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Invalid type name
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ *
+ */
+
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ i = (short long)0;
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupenum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupenum.d
new file mode 100644
index 0000000..2282f2d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupenum.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt a bogus enum declaration that contains duplicated enumerator names.
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+enum foo {
+ x = 3,
+ x = 4
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupstruct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupstruct.d
new file mode 100644
index 0000000..4102cd9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_UNKNOWN.dupstruct.d
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Attempt a bogus struct declaration that contains duplicated member names.
+ *
+ * SECTION: Structs and Unions/Structs
+ */
+
+struct foo {
+ int x;
+ char x;
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_XLATE_REDECL.ResultDynType.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_XLATE_REDECL.ResultDynType.d
new file mode 100644
index 0000000..f4e7dfd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/err.D_XLATE_REDECL.ResultDynType.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * An expression cannot evaluate to result of dynamic type.
+ *
+ * SECTION: Errtag/D_CG_DYN
+ */
+
+#pragma D option quiet
+
+translator lwpsinfo_t < kthread_t *T >
+{
+ pr_flag = T->t_flag;
+ pr_lwpid = T->t_tid;
+};
+
+BEGIN
+{
+ xlate < lwpsinfo_t * > (curthread);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.assignops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.assignops.d
new file mode 100644
index 0000000..6bc27b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.assignops.d
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify assignment operators
+ *
+ * SECTION: Types, Operators, and Expressions/Assignment Operators
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0x100;
+ int_2 = 0xf0f0;
+ int_3 = 0x0f0f;
+
+ intn = 0x1;
+
+ intn += int_1;
+ printf("%x\n", intn);
+ intn -= int_1;
+ printf("%x\n", intn);
+ intn *= int_1;
+ printf("%x\n", intn);
+ intn /= int_1;
+ printf("%x\n", intn);
+ intn %= int_1;
+ printf("%x\n", intn);
+ printf("\n");
+
+ intb = 0x0000;
+
+ intb |= (int_2 | intb);
+ printf("%x\n", intb);
+ intb &= (int_2 | int_3);
+ printf("%x\n", intb);
+ intb ^= (int_2 | int_3);
+ printf("%x\n", intb);
+ intb |= ~(intb);
+ printf("%x\n", intb);
+ printf("\n");
+
+ intb = int_2;
+
+ printf("%x\n", intb);
+ intb <<= 3;
+ printf("%x\n", intb);
+ intb >>= 3;
+ printf("%x\n", intb);
+
+ exit(0);
+
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.badshiftops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.badshiftops.d
new file mode 100644
index 0000000..ac3c014
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.badshiftops.d
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Negative values and values greater than the LH operand are
+ * accepted.
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0xffff;
+
+ nint = int_1 << -6;
+ printf("%x %x\n", int_1, nint);
+ nint = int_1 << 100;
+ printf("%x %x\n", int_1, nint);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d
new file mode 100644
index 0000000..8e762d5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test declaration processing of all the fundamental kinds of type
+ * declarations. Check their sizes.
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ */
+
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("\nsizeof (char) = %u\n", sizeof (char));
+ printf("sizeof (signed char) = %u\n", sizeof (signed char));
+ printf("sizeof (unsigned char) = %u\n", sizeof (unsigned char));
+ printf("sizeof (short) = %u\n", sizeof (short));
+ printf("sizeof (signed short) = %u\n", sizeof (signed short));
+ printf("sizeof (unsigned short) = %u\n", sizeof (unsigned short));
+ printf("sizeof (int) = %u\n", sizeof (int));
+ printf("sizeof (signed int) = %u\n", sizeof (signed int));
+ printf("sizeof (unsigned int) = %u\n", sizeof (unsigned int));
+ printf("sizeof (long long) = %u\n", sizeof (long long));
+ printf("sizeof (signed long long) = %u\n", sizeof (signed long long));
+ printf("sizeof (unsigned long long) = %u\n",
+ sizeof (unsigned long long));
+ printf("sizeof (float) = %u\n", sizeof (float));
+ printf("sizeof (double) = %u\n", sizeof (double));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d.out
new file mode 100644
index 0000000..fd05217
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.basics.d.out
@@ -0,0 +1,16 @@
+
+sizeof (char) = 1
+sizeof (signed char) = 1
+sizeof (unsigned char) = 1
+sizeof (short) = 2
+sizeof (signed short) = 2
+sizeof (unsigned short) = 2
+sizeof (int) = 4
+sizeof (signed int) = 4
+sizeof (unsigned int) = 4
+sizeof (long long) = 8
+sizeof (signed long long) = 8
+sizeof (unsigned long long) = 8
+sizeof (float) = 4
+sizeof (double) = 8
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.bitops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.bitops.d
new file mode 100644
index 0000000..fc643ba
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.bitops.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify relational operators with pointers
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0xffff;
+ int_2 = 0;
+ int_3 = 0x0f0f;
+
+
+ printf("%x %x %x\n", int_1 & int_2, int_1 & int_3, int_2 & int_3);
+ printf("%x %x %x\n", int_1 | int_2, int_1 | int_3, int_2 | int_3);
+ printf("%x %x %x\n", int_1 ^ int_2, int_1 ^ int_3, int_2 ^ int_3);
+
+ printf("%x\n", int_1 & int_2 & int_3);
+ printf("%x\n", int_1 & int_2 ^ int_3);
+ printf("%x\n", int_1 & int_2 | int_3);
+ printf("%x\n", int_1 | int_2 & int_3);
+ printf("%x\n", int_1 | int_2 ^ int_3);
+ printf("%x\n", int_1 | int_2 | int_3);
+ printf("%x\n", int_1 ^ int_2 & int_3);
+ printf("%x\n", int_1 ^ int_2 ^ int_3);
+ printf("%x\n", int_1 ^ int_2 | int_3);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.charconstants.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.charconstants.d
new file mode 100644
index 0000000..84aa61b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.charconstants.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * verify the use of char constants
+ *
+ * SECTION: Types, Operators, and Expressions/Constants
+ *
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ char_1 = 'a';
+ char_2 = '\"';
+ char_3 = '\"\ba';
+ char_4 = '\?';
+ char_5 = '\'';
+ char_6 = '\\';
+ char_7 = '\0103';
+ char_8 = '\x4E';
+ char_9 = '\c'; /* Note - this is not an escape sequence */
+ char_10 = 'ab\"d';
+ char_11 = 'a\bcdefgh';
+
+ printf("decimal value = %d; character value = %c\n", char_1, char_1);
+ printf("decimal value = %d; character value = %c\n", char_2, char_2);
+ printf("decimal value = %d; character value = %c\n", char_3, char_3);
+ printf("decimal value = %d; character value = %c\n", char_4, char_4);
+ printf("decimal value = %d; character value = %c\n", char_5, char_5);
+ printf("decimal value = %d; character value = %c\n", char_6, char_6);
+ printf("decimal value = %d; character value = %c\n", char_7, char_7);
+ printf("decimal value = %d; character value = %c\n", char_8, char_8);
+ printf("decimal value = %d; character value = %c\n", char_9, char_9);
+ printf("decimal value = %d; character value = %c\n", char_10, char_10);
+ printf("decimal value = %d\n", char_11);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.complex.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.complex.d
new file mode 100644
index 0000000..a912670
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.complex.d
@@ -0,0 +1,74 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Test a complex structure and verify that tracemem can be used to
+ * look at it.
+ *
+ * SECTION: Structs and Unions/Structs;
+ * Actions and Subroutines/tracemem()
+ */
+
+
+
+#pragma D option quiet
+
+struct s {
+ int i;
+ char c;
+ double d;
+ float f;
+ long l;
+ long long ll;
+ union sigval u;
+ enum uio_rw e;
+ struct vnode s;
+ struct s1 {
+ int i;
+ char c;
+ double d;
+ float f;
+ long l;
+ long long ll;
+ union sigval u;
+ enum uio_rw e;
+ struct vnode s;
+ } sx;
+ int a[2];
+ int *p;
+ int *ap[4];
+ int (*fp)();
+ int (*afp[2])();
+};
+
+BEGIN
+{
+ tracemem(curthread, sizeof (struct s));
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.condexpr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.condexpr.d
new file mode 100644
index 0000000..fe23a73
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.condexpr.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * positive check conditional expressions
+ *
+ * SECTION: Types, Operators, and Expressions/Conditional Expressions
+ *
+ * NOTES: these tests are from the User's Guide
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ i = 0;
+ x = i == 0 ? "zero" : "non-zero";
+
+ c = 'd';
+ hexval = (c >= '0' && c <= '9') ? c - '0':
+ (c >= 'a' && c <= 'z') ? c + 10 - 'a' : c + 10 - 'A';
+}
+
+tick-1
+/x == "zero" && hexval == 13/
+{
+ exit(0);
+}
+
+tick-1
+/x != "zero" || hexval != 13/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.constants.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.constants.d
new file mode 100644
index 0000000..101bb8b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.constants.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * verify that integer constants can be written in decimal
+ * octal or hexadecimal
+ *
+ * SECTION: Types, Operators, and Expressions/Constants
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ decimal = 12345;
+ octal = 012345;
+ hexadecimal_1 = 0x12345;
+ hexadecimal_2 = 0X12345;
+
+ printf("%d %d %d %d", decimal, octal, hexadecimal_1, hexadecimal_2);
+ printf("%d %o %x %x", decimal, octal, hexadecimal_1, hexadecimal_2);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.conv.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.conv.d
new file mode 100644
index 0000000..9020424
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.conv.d
@@ -0,0 +1,109 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * positive type conversion checks
+ *
+ * SECTION: Types, Operators, and Expressions/Type Conversions
+ *
+ * NOTES: not all type conversions are checked. A lot of this section
+ * is tested within other tests.
+ */
+
+#pragma D option quiet
+
+unsigned int i;
+char c;
+short s;
+long l;
+long long ll;
+
+BEGIN
+{
+/* char -> int */
+ c = 'A';
+ i = c;
+ printf("c is %c i is %d\n", c, i);
+
+/* int -> char */
+
+ i = 1601;
+ c = i;
+ printf("i is %d c is %c\n", i, c);
+
+/* char -> short */
+ c = 'A';
+ s = c;
+ printf("c is %c s is %d\n", c, s);
+
+/* short -> char */
+
+ s = 1601;
+ c = s;
+ printf("s is %d c is %c\n", s, c);
+
+/* int -> short */
+
+ i = 1601;
+ s = i;
+ printf("i is %d s is %d\n", i, s);
+
+/* short -> int */
+
+ s = 1601;
+ i = s;
+ printf("s is %d i is %d\n", s, i);
+
+/* int -> long long */
+
+ i = 4294967295;
+ ll = i;
+ printf("i is %d ll is %x\n", i, ll);
+
+/* long long -> int */
+
+ ll = 8589934591;
+ i = ll;
+ printf("ll is %d i is %x\n", ll, i);
+
+/* char -> long long */
+
+ c = 'A';
+ ll = c;
+ printf("c is %c ll is %x\n", c, ll);
+
+/* long long -> char */
+
+ ll = 8589934401;
+ c = ll;
+ printf("ll is %x c is %c\n", ll, c);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.enum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.enum.d
new file mode 100644
index 0000000..49a97bf
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.enum.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Positive enumeration test
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ */
+
+#pragma D option quiet
+
+enum my_enum {
+ zero,
+ one = 1,
+ two,
+ three,
+ four = 4,
+ minimum = -2147483648,
+ maximum = 2147483647
+};
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intincop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intincop.d
new file mode 100644
index 0000000..77eb702
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intincop.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify increment operator using integers
+ *
+ * SECTION: Type and Constant Definitions/Enumerations
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_orig = 100;
+ int_pos = 100+1;
+ int_neg = 100-1;
+
+ int_pos_before = ++int_orig;
+ int_orig = 100;
+ int_neg_before = --int_orig;
+ int_orig = 100;
+ int_pos_after = int_orig++;
+ int_orig = 100;
+ int_neg_after = int_orig--;
+ int_orig = 100;
+
+}
+
+tick-1
+/int_pos_before == int_pos && int_neg_before == int_neg &&
+ int_pos_after == int_orig && int_pos_after == int_orig/
+{
+ exit(0);
+}
+
+
+tick-1
+/int_pos_before != int_pos || int_neg_before != int_neg ||
+ int_pos_after != int_orig || int_pos_after != int_orig/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intops.d
new file mode 100644
index 0000000..a374480
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.intops.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify relational operators with integers
+ *
+ * SECTION: Types, Operators, and Expressions/Relational Operators;
+ * Types, Operators, and Expressions/Precedence
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0x100;
+ int_2 = 0x101;
+ int_3 = 0x99;
+}
+
+tick-1
+/int_1 >= int_2 || int_2 <= int_1 || int_1 == int_2/
+{
+ printf("Shouldn't end up here (1)\n");
+ printf("int_1 = %x int_2 = %x int_3 = %x\n",
+ (int) int_1, (int) int_2, (int) int_3);
+ exit(1);
+}
+
+tick-1
+/int_3 > int_1 || int_1 < int_3 || int_3 == int_1/
+{
+ printf("Shouldn't end up here (2)\n");
+ printf("int_1 = %x int_2 = %x int_3 = %x\n",
+ (int) int_1, (int) int_2, (int) int_3);
+ exit(1);
+}
+
+tick-1
+/int_2 > int_3 && int_1 < int_2 ^^ int_3 == int_2 && !(int_1 != int_2)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.inttypes.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.inttypes.d
new file mode 100644
index 0000000..80bfa1f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.inttypes.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * Verify integer type aliases
+ *
+ * SECTION: Types, Operators, and Expressions/Data Types and Sizes
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+BEGIN
+{
+ printf("sizeof (int8_t) = %u\n", sizeof (int8_t));
+ printf("sizeof (int16_t) = %u\n", sizeof (int16_t));
+ printf("sizeof (int32_t) = %u\n", sizeof (int32_t));
+ printf("sizeof (int64_t) = %u\n", sizeof (int64_t));
+ printf("sizeof (intptr_t) = %u\n", sizeof (intptr_t));
+ printf("sizeof (uint8_t) = %u\n", sizeof (uint8_t));
+ printf("sizeof (uint16_t) = %u\n", sizeof (uint16_t));
+ printf("sizeof (uint32_t) = %u\n", sizeof (uint32_t));
+ printf("sizeof (uint64_t) = %u\n", sizeof (uint64_t));
+ printf("sizeof (uintptr_t) = %u\n", sizeof (uintptr_t));
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrincop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrincop.d
new file mode 100644
index 0000000..0fdd561
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrincop.d
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify increment/decrement operator using pointers
+ *
+ * SECTION: Types, Operators, and Expressions/Increment and Decrement Operators
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr_orig = &`kmem_flags;
+ ptr_pos = &`kmem_flags+1;
+ ptr_neg = &`kmem_flags-1;
+
+ ptr_pos_before = ++ptr_orig;
+ ptr_orig = &`kmem_flags;
+ ptr_neg_before = --ptr_orig;
+
+ ptr_orig = &`kmem_flags;
+ ptr_pos_after = ptr_orig++;
+ ptr_orig = &`kmem_flags;
+ ptr_neg_after = ptr_orig--;
+ ptr_orig = &`kmem_flags;
+
+}
+
+tick-1
+/ptr_pos_before == ptr_pos && ptr_neg_before == ptr_neg &&
+ ptr_pos_after == ptr_orig && ptr_pos_after == ptr_orig/
+{
+ exit(0);
+}
+
+
+tick-1
+/ptr_pos_before != ptr_pos || ptr_neg_before != ptr_neg ||
+ ptr_pos_after != ptr_orig || ptr_pos_after != ptr_orig/
+{
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrops.d
new file mode 100644
index 0000000..d4144b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.ptrops.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify relational operators with pointers
+ *
+ * SECTION: Types, Operators, and Expressions/Relational Operators;
+ * Types, Operators, and Expressions/Logical Operators;
+ * Types, Operators, and Expressions/Precedence
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ ptr_1 = &`kmem_flags;
+ ptr_2 = (&`kmem_flags) + 1;
+ ptr_3 = (&`kmem_flags) - 1 ;
+}
+
+tick-1
+/ptr_1 >= ptr_2 || ptr_2 <= ptr_1 || ptr_1 == ptr_2/
+{
+ printf("Shouldn't end up here (1)\n");
+ printf("ptr_1 = %x ptr_2 = %x ptr_3 = %x\n",
+ (int) ptr_1, (int) ptr_2, (int) ptr_3);
+ exit(1);
+}
+
+tick-1
+/ptr_3 > ptr_1 || ptr_1 < ptr_3 || ptr_3 == ptr_1/
+{
+ printf("Shouldn't end up here (2)\n");
+ printf("ptr_1 = %x ptr_2 = %x ptr_3 = %x\n",
+ (int) ptr_1, (int) ptr_2, (int) ptr_3);
+ exit(1);
+}
+
+tick-1
+/ptr_3 > ptr_2 || ptr_1 < ptr_2 ^^ ptr_3 == ptr_2 && !(ptr_1 != ptr_2)/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relenum.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relenum.d
new file mode 100644
index 0000000..8fa6d58
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relenum.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify relational operators with enumerations
+ *
+ * SECTION: Types, Operators, and Expressions/Relational Operators
+ *
+ */
+
+#pragma D option quiet
+
+enum numbers_1 {
+ zero,
+ one,
+ two
+};
+
+enum numbers_2 {
+ null,
+ first,
+ second
+};
+
+tick-1
+/zero >= one || second <= first || zero == second/
+{
+ printf("Shouldn't end up here (1)\n");
+ printf("zero = %d; one = %d; two = %d", zero, one, two);
+ printf("null = %d; first = %d; second = %d", null, first, second);
+ exit(1);
+}
+
+tick-1
+/second < one || two > second || null == first/
+{
+ printf("Shouldn't end up here (2)\n");
+ printf("zero = %d; one = %d; two = %d", zero, one, two);
+ printf("null = %d; first = %d; second = %d", null, first, second);
+ exit(1);
+}
+
+tick-1
+/first < two && second > one && one != two && zero != first/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relstring.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relstring.d
new file mode 100644
index 0000000..9e9ef29
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.relstring.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify relational operators with strings
+ *
+ * SECTION: Types, Operators, and Expressions/Relational Operators
+ *
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ string_1 = "abcde";
+ string_2 = "aabcde";
+ string_3 = "abcdef";
+}
+
+tick-1
+/string_1 <= string_2 || string_2 >= string_1 || string_1 == string_2/
+{
+ printf("Shouldn't end up here (1)\n");
+ printf("string_1 = %s string_2 = %s string_3 = %s\n",
+ string_1, string_2, string_3);
+ exit(1);
+}
+
+tick-1
+/string_3 < string_1 || string_1 > string_3 || string_3 == string_1/
+{
+ printf("Shouldn't end up here (2)\n");
+ printf("string_1 = %s string_2 = %s string_3 = %s n",
+ string_1, string_2, string_3);
+ exit(1);
+}
+
+tick-1
+/string_3 > string_1 && string_1 > string_2 &&
+ string_1 != string_2 && string_2 != string_3/
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.shiftops.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.shiftops.d
new file mode 100644
index 0000000..a260238
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.shiftops.d
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify shift operators
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators;
+ * Types, Operators, and Expressions/Precedence
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0xffff;
+
+ nint = (((((((((((int_1 << 2 >> 2) << 3 >> 3) << 4 >> 4) << 5 >> 5)
+ << 6 >> 6) << 7 >> 7) << 8 >>8) << 9 >> 9) << 10 >> 10)
+ << 11 >> 11) << 12 >> 12);
+
+}
+
+tick-1
+/nint != int_1/
+{
+ printf("Unexpected error nint = %x, expected %x\n", nint, int_1);
+ exit(1);
+}
+
+tick-1
+/nint == int_1/
+{
+ exit(0);
+
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.stringconstants.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.stringconstants.d
new file mode 100644
index 0000000..9fa0805
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.stringconstants.d
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * verify the use of char type
+ *
+ * SECTION: Types, Operators, and Expressions/Constants
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+string string_1;
+
+BEGIN
+{
+ string_1 = "abcd\n\n\nefg";
+ string_2 = "abc\"\t\044\?\x4D";
+ string_3 = "\?\\\'\"\0";
+
+ printf("string_1 = %s\n", string_1);
+ printf("string_2 = %s\n", string_2);
+ printf("string_3 = %s\n", string_3);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.struct.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.struct.d
new file mode 100644
index 0000000..86610f6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.struct.d
@@ -0,0 +1,84 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declare a dynamic type and then use it to copyin the first 3 environment
+ * variable pointers from the current process.
+ *
+ * SECTION: Structs and Unions/Structs;
+ * Actions and Subroutines/copyin();
+ * Actions and Subroutines/copyinstr();
+ * Variables/External Variables
+ *
+ * NOTES:
+ * This test program declares a dynamic type and then uses it to copyin the
+ * first three environment variable pointers from the current process. We
+ * then use the dynamic type to access the result of our copyin(). The
+ * special "D" module type scope is also tested.
+ */
+
+#pragma D option quiet
+
+struct env_vars_32 {
+ uint32_t e1;
+ uint32_t e2;
+ uint32_t e3;
+};
+
+struct env_vars_64 {
+ uint64_t e1;
+ uint64_t e2;
+ uint64_t e3;
+};
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_ILP32/
+{
+ e32 = (struct D`env_vars_32 *)
+ copyin(curpsinfo->pr_envp, sizeof (struct D`env_vars_32));
+
+ printf("e1 = \"%s\"\n", stringof(copyinstr(e32->e1)));
+ printf("e2 = \"%s\"\n", stringof(copyinstr(e32->e2)));
+ printf("e3 = \"%s\"\n", stringof(copyinstr(e32->e3)));
+
+ exit(0);
+}
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_LP64/
+{
+ e64 = (struct D`env_vars_64 *)
+ copyin(curpsinfo->pr_envp, sizeof (struct D`env_vars_64));
+
+ printf("e1 = \"%s\"\n", stringof(copyinstr(e64->e1)));
+ printf("e2 = \"%s\"\n", stringof(copyinstr(e64->e2)));
+ printf("e3 = \"%s\"\n", stringof(copyinstr(e64->e3)));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.typedef.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.typedef.d
new file mode 100644
index 0000000..aabfc9b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.typedef.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declares a dynamic type and then uses it to copyin the first three
+ * environment variable pointers from the current process.
+ *
+ * SECTION: Structs and Unions/Structs;
+ * Actions and Subroutines/copyin();
+ * Actions and Subroutines/copyinstr();
+ * Variables/External Variables
+ *
+ * NOTES:
+ * This test program declares a dynamic type and then uses it to copyin the
+ * first three environment variable pointers from the current process. We
+ * then use the dynamic type to access the result of our copyin(). The
+ * special "D" module type scope is also tested. This is similar to our
+ * struct declaration test but here we use a typedef.
+ */
+
+#pragma D option quiet
+
+typedef struct env_vars_32 {
+ uint32_t e1;
+ uint32_t e2;
+ uint32_t e3;
+} env_vars_32_t;
+
+typedef struct env_vars_64 {
+ uint64_t e1;
+ uint64_t e2;
+ uint64_t e3;
+} env_vars_64_t;
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_ILP32/
+{
+ e32 = (D`env_vars_32_t *)
+ copyin(curpsinfo->pr_envp, sizeof (D`env_vars_32_t));
+
+ printf("e1 = \"%s\"\n", stringof(copyinstr(e32->e1)));
+ printf("e2 = \"%s\"\n", stringof(copyinstr(e32->e2)));
+ printf("e3 = \"%s\"\n", stringof(copyinstr(e32->e3)));
+
+ exit(0);
+}
+
+BEGIN
+/curpsinfo->pr_dmodel == PR_MODEL_LP64/
+{
+ e64 = (D`env_vars_64_t *)
+ copyin(curpsinfo->pr_envp, sizeof (D`env_vars_64_t));
+
+ printf("e1 = \"%s\"\n", stringof(copyinstr(e64->e1)));
+ printf("e2 = \"%s\"\n", stringof(copyinstr(e64->e2)));
+ printf("e3 = \"%s\"\n", stringof(copyinstr(e64->e3)));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.unaryop.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.unaryop.d
new file mode 100644
index 0000000..b9938e4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/types/tst.unaryop.d
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify unary operator
+ *
+ * SECTION: Types, Operators, and Expressions/Bitwise Operators
+ */
+
+#pragma D option quiet
+
+
+BEGIN
+{
+ int_1 = 0xffff;
+ int_2 = 0;
+ int_3 = 0x0f0f;
+
+ printf("%x %x %x\n", int_1, int_2, int_3);
+ printf("%x %x %x\n", ~int_1, ~int_2, ~int_3);
+ printf("%x %x %x\n", ~~int_1, ~~int_2, ~~int_3);
+ printf("%x %x %x\n", ~~~int_1, ~~~int_2, ~~~int_3);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_ADDROF_VAR.UnionPointer.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_ADDROF_VAR.UnionPointer.d
new file mode 100644
index 0000000..0a292cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_ADDROF_VAR.UnionPointer.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Trying to access the members of a user defined union by means of
+ * a pointer to it should throw a D_ADDROF_VAR compiler error.
+ *
+ * SECTION: Structs and Unions/Pointers to Structs
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int position;
+ int content;
+
+};
+
+union record var;
+union record *ptr;
+
+BEGIN
+{
+
+ var.position = 1;
+ var.content = 'a';
+
+ ptr = &var;
+
+ printf("ptr->position: %d\tptr->content: %c\n",
+ ptr->position, ptr->content);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon.d
new file mode 100644
index 0000000..4adb36e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon.d
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Combining multiple union definitions in a single line should throw a
+ * compiler error.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int position;
+ char content;
+}
+
+
+union pirate {
+ int position;
+ char content;
+};
+
+union superStruct super;
+union record rec;
+union pirate pir;
+
+BEGIN
+{
+ rec.content = 'a';
+ rec.position = 1;
+
+ pir.content = 'b';
+ pir.position = 2;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon1.d
new file mode 100644
index 0000000..5506a97
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon1.d
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Combining multiple union definitions in a single line should throw a
+ * compiler error.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int position;
+ char content;
+};
+
+
+union pirate {
+ int position;
+ char content;
+}
+
+union record rec;
+union pirate pir;
+
+BEGIN
+{
+ rec.content = 'a';
+ rec.position = 1;
+
+ pir.content = 'b';
+ pir.position = 2;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.circular.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.circular.d
new file mode 100644
index 0000000..ae6e647
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.circular.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * A circular definition of unions (two unions defining each other as
+ * members) should throw an error at compile time.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ union pirate p;
+ int position;
+ char content;
+};
+
+
+union pirate {
+ union record r;
+ int position;
+ char content;
+};
+
+union record rec;
+union pirate pir;
+
+BEGIN
+{
+ rec.position = 0;
+ rec.content = 'a';
+ printf(
+ "rec.position: %d\nrec.content: %c\n", rec.position, rec.content);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.order.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.order.d
new file mode 100644
index 0000000..9e2ec69
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.order.d
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When two unions are defined such that one of them contains the other, the
+ * inner union has to be defined first.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+
+union record {
+ union pirate p;
+ int position;
+ char content;
+};
+
+union pirate {
+ int position;
+ char content;
+};
+
+union record rec;
+union pirate pir;
+
+BEGIN
+{
+ rec.content = 'y';
+ rec.position = 2;
+
+ pir.content = 'z';
+ pir.position = 26;
+
+ printf(
+ "rec.content: %c\nrec.position: %d\npir.content: %c\npir.position: %d",
+ rec.content, rec.position, pir.content, pir.position);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.recursive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.recursive.d
new file mode 100644
index 0000000..2a86b9c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.recursive.d
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Recursive naming of unions should produce compiler error.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ union record rec;
+ int position;
+ char content;
+};
+
+union record r1;
+union record r2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 2;
+ r2.content = 'b';
+
+ printf("r1.position: %d\nr1.content: %c\n", r1.position, r1.content);
+ printf("r2.position: %d\nr2.content: %c\n", r2.position, r2.content);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.simple.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.simple.d
new file mode 100644
index 0000000..781d726
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_DECL_INCOMPLETE.simple.d
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declaring an inner union without defining it else where should throw
+ * a compiler error.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+#pragma D option quiet
+
+
+union record {
+ union pirate p;
+ int position;
+ char content;
+};
+
+
+union record rec;
+
+BEGIN
+{
+ rec.position = 0;
+ rec.content = 'a';
+ printf("rec.position: %d\nrec.content: %c\n",
+ rec.position, rec.content);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_PROTO_ARG.DupUnionAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_PROTO_ARG.DupUnionAssoc.d
new file mode 100644
index 0000000..f918741
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/err.D_PROTO_ARG.DupUnionAssoc.d
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Declaring an associative array with a union to be its key type and trying to
+ * index with another union having the same composition throws an error.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int position;
+ char content;
+};
+
+union pirate {
+ int position;
+ char content;
+};
+
+union record r1;
+union record r2;
+union pirate p1;
+union pirate p2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 2;
+ r2.content = 'b';
+
+ p1.position = 1;
+ p1.content = 'a';
+
+ p2.position = 2;
+ p2.content = 'b';
+
+ assoc_array[r1] = 1000;
+ assoc_array[r2] = 2000;
+ assoc_array[p1] = 3333;
+ assoc_array[p2] = 4444;
+
+ printf("assoc_array[r1]: %d\n", assoc_array[r1]);
+ printf("assoc_array[r2]: %d\n", assoc_array[r2]);
+ printf("assoc_array[p1]: %d\n", assoc_array[p1]);
+ printf("assoc_array[p2]: %d\n", assoc_array[p2]);
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionAssoc.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionAssoc.d
new file mode 100644
index 0000000..882b6ae
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionAssoc.d
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * When a union is used as a key for an associative array, the key is formed
+ * by using the values of the members of the union variable and not the
+ * address of the union variable.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ int position;
+ char content;
+};
+
+union record r1;
+union record r2;
+
+BEGIN
+{
+ r1.position = 1;
+ r1.content = 'a';
+
+ r2.position = 1;
+ r2.content = 'a';
+
+ assoc_array[r1] = 1000;
+ assoc_array[r2] = 2000;
+
+ printf("assoc_array[r1]: %d\n", assoc_array[r1]);
+ printf("assoc_array[r2]: %d\n", assoc_array[r2]);
+
+ exit(0);
+}
+
+END
+/assoc_array[r1] != assoc_array[r2]/
+{
+ printf("Error");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionDataTypes.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionDataTypes.d
new file mode 100644
index 0000000..d5d292d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionDataTypes.d
@@ -0,0 +1,132 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Declaration of the different data types within a union and
+ * their definitions in a later clause should work fine.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ * NOTES: The floats, doubles and strings have not been implemented yet.
+ * When they do, appropriate lines in the code below should be uncommented.
+ * Similarly, the lines with the kmem_flags pointer assignment should be
+ * uncommented when the issues pertaining to it are clarified.
+ *
+ */
+
+#pragma D option quiet
+
+union record {
+ char new_char;
+ short new_short;
+ int new_int;
+ long new_long;
+ long long new_long_long;
+ int8_t new_int8;
+ int16_t new_int16;
+ int32_t new_int32;
+ int64_t new_int64;
+ intptr_t new_intptr;
+ uint8_t new_uint8;
+ uint16_t new_uint16;
+ uint32_t new_uint32;
+ uint64_t new_uint64;
+ uintptr_t new_uintptr;
+
+ /*float new_float;
+ double new_double;
+ long double new_long_double;
+
+ string new_string;
+ */
+
+ struct {
+ char ch;
+ int in;
+ long lg;
+ } new_struct;
+
+ union {
+ char ch;
+ int in;
+ long lg;
+ } new_union;
+
+enum {
+ RED,
+ GREEN,
+ BLUE
+} new_enum;
+
+
+ int *pointer;
+} var;
+
+/*
+ var.pointer = &`kmem_flags;
+*/
+BEGIN
+{
+ var.new_char = 'c';
+ var.new_short = 10;
+ var.new_int = 100;
+ var.new_long = 1234567890;
+ var.new_long_long = 1234512345;
+ var.new_int8 = 'p';
+ var.new_int16 = 20;
+ var.new_int32 = 200;
+ var.new_int64 = 2000000;
+ var.new_intptr = 0x12345;
+ var.new_uint8 = 'q';
+ var.new_uint16 = 30;
+ var.new_uint32 = 300;
+ var.new_uint64 = 3000000;
+ var.new_uintptr = 0x67890;
+
+ /* var.new_float = 1.23456;
+ var.new_double = 2.34567890;
+ var.new_long_double = 3.567890123;
+
+ var.new_string = "hello";
+ */
+
+ /*
+ var.pointer = &`kmem_flags;
+ */
+
+ var.new_struct.ch = 'c';
+ var.new_struct.in = 4;
+ var.new_struct.lg = 4;
+
+ var.new_union.ch = 'd';
+ var.new_union.in = 5;
+ var.new_union.lg = 5;
+
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionInside.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionInside.d
new file mode 100644
index 0000000..9569002
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/union/tst.UnionInside.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * Verify the nested behavior of unions.
+ *
+ * SECTION: Structs and Unions/Unions
+ *
+ */
+#pragma D option quiet
+
+union InnerMost {
+ int position;
+ char content;
+};
+
+union InnerMore {
+ union InnerMost IMost;
+ int dummy_More;
+};
+
+union Inner {
+ union InnerMore IMore;
+ int dummy_More;
+};
+
+union Outer {
+ union Inner I;
+ int dummy_More;
+};
+
+union OuterMore {
+ union Outer O;
+ int dummy_More;
+};
+
+union OuterMost {
+ union OuterMore OMore;
+ int dummy_More;
+} OMost;
+
+
+BEGIN
+{
+
+ OMost.OMore.O.I.IMore.IMost.position = 5;
+ OMost.OMore.O.I.IMore.IMost.content = 'e';
+
+ printf("OMost.OMore.O.I.IMore.IMost.content: %c\n",
+ OMost.OMore.O.I.IMore.IMost.content);
+
+ exit(0);
+}
+
+END
+/'e' != OMost.OMore.O.I.IMore.IMost.content/
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile
new file mode 100644
index 0000000..77fe870
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile
@@ -0,0 +1,13 @@
+all: main
+
+main: main.o prov.o
+ $(CC) -o main main.o prov.o
+
+main.o: main.c prov.h
+ $(CC) -c main.c
+
+prov.h: prov.d
+ /usr/sbin/dtrace -h -s prov.d
+
+prov.o: prov.d main.o
+ /usr/sbin/dtrace -G -32 -s prov.d main.o
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/argmap.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/argmap.d
new file mode 100644
index 0000000..0a1c360
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/argmap.d
@@ -0,0 +1,31 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+provider test_prov {
+ probe place(int i, int j) : (int j, int i, int i, int j);
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/args.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/args.d
new file mode 100644
index 0000000..a11984c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/args.d
@@ -0,0 +1,31 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+provider test_prov {
+ probe place(int i, int j);
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/forker.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/forker.d
new file mode 100644
index 0000000..f63b965
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/forker.d
@@ -0,0 +1,31 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+provider forker {
+ probe fire();
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c
new file mode 100644
index 0000000..9dc0a0e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <sys/sdt.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv, char **envp)
+{
+ envp[0] = (char*)0xff;
+ TESTER_ENTRY();
+ return 0;
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d
new file mode 100644
index 0000000..53e5ef3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d
@@ -0,0 +1,3 @@
+provider tester {
+ probe entry();
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h
new file mode 100644
index 0000000..e29654e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h
@@ -0,0 +1,46 @@
+/*
+ * Generated by dtrace(1M).
+ */
+
+#ifndef _PROV_H
+#define _PROV_H
+
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if _DTRACE_VERSION
+
+#define TESTER_ENTRY() \
+ __dtrace_tester___entry()
+#ifndef __sparc
+#define TESTER_ENTRY_ENABLED() \
+ __dtraceenabled_tester___entry()
+#else
+#define TESTER_ENTRY_ENABLED() \
+ __dtraceenabled_tester___entry(0)
+#endif
+
+
+extern void __dtrace_tester___entry(void);
+#ifndef __sparc
+extern int __dtraceenabled_tester___entry(void);
+#else
+extern int __dtraceenabled_tester___entry(long);
+#endif
+
+#else
+
+#define TESTER_ENTRY()
+#define TESTER_ENTRY_ENABLED() (0)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROV_H */
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.andpid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.andpid.ksh
new file mode 100644
index 0000000..2096422
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.andpid.ksh
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -c date -s /dev/stdin <<EOF
+plockstat\$target::mutex_lock_impl:,
+pid\$target::mutex_lock_impl:
+{}
+EOF
+
+if [ $? -ne 0 ]; then
+ print -u2 "dtrace failed"
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.c
new file mode 100644
index 0000000..5697ef5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.c
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ DTRACE_PROBE2(test_prov, place, 10, 4);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.d
new file mode 100644
index 0000000..fd9f9f4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.argmap.d
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that argN and args[N] variables are properly remapped.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place
+/arg0 != 4 || arg1 != 10 || arg2 != 10 || arg3 != 4/
+{
+ printf("args are %d, %d, %d, %d; should be 4, 10, 10, 4",
+ arg0, arg1, arg2, arg3);
+ exit(1);
+}
+
+test_prov$1:::place
+/args[0] != 4 || args[1] != 10 || args[2] != 10 || args[3] != 4/
+{
+ printf("args are %d, %d, %d, %d; should be 4, 10, 10, 4",
+ args[0], args[1], args[2], args[3]);
+ exit(1);
+}
+
+test_prov$1:::place
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.c
new file mode 100644
index 0000000..5697ef5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.c
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ DTRACE_PROBE2(test_prov, place, 10, 4);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.d
new file mode 100644
index 0000000..bb74e80
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.args.d
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+}
+
+test_prov$1:::place
+/arg0 == 10 && arg1 == 4/
+{
+ exit(0);
+}
+
+test_prov$1:::place
+{
+ printf("args are %d, %d; should be 10, 4", arg0, arg1);
+ exit(1);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh
new file mode 100644
index 0000000..91b6cf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+}
+EOF
+
+cc -xarch=generic64 -c -o test64.o test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c 64-bit"
+ exit 1
+fi
+cc -xarch=generic -c -o test32.o test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c 32-bit"
+ exit 1
+fi
+
+$dtrace -G -s prov.d test32.o test64.o
+if [ $? -eq 0 ]; then
+ print -u2 "DOF generation failed to generate a warning"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh
new file mode 100644
index 0000000..68dbb03
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh
@@ -0,0 +1,107 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This test verifies that a program that corrupts its own environment
+# without inducing a crash does not crash solely due to drti.o's use of
+# getenv(3C).
+#
+
+PATH=/usr/bin:/usr/sbin:$PATH
+
+if (( $# != 1 )); then
+ print -u2 'expected one argument: <dtrace-path>'
+ exit 2
+fi
+
+#
+# jdtrace does not implement the -h option that is required to generate
+# C header files.
+#
+if [[ "$1" == */jdtrace ]]; then
+ exit 0
+fi
+
+dtrace="$1"
+startdir="$PWD"
+dir=$(mktemp -td drtiXXXXXX)
+if (( $? != 0 )); then
+ print -u2 'Could not create safe temporary directory'
+ exit 2
+fi
+
+cd "$dir"
+
+cat > Makefile <<EOF
+all: main
+
+main: main.o prov.o
+ \$(CC) -o main main.o prov.o
+
+main.o: main.c prov.h
+ \$(CC) -c main.c
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+prov.o: prov.d main.o
+ $dtrace -G -32 -s prov.d main.o
+EOF
+
+cat > prov.d <<EOF
+provider tester {
+ probe entry();
+};
+EOF
+
+cat > main.c <<EOF
+#include <stdlib.h>
+#include <sys/sdt.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv, char **envp)
+{
+ envp[0] = (char*)0xff;
+ TESTER_ENTRY();
+ return 0;
+}
+EOF
+
+make > /dev/null
+status=$?
+if (( $status != 0 )) ; then
+ print -u2 "failed to build"
+else
+ ./main
+ status=$?
+fi
+
+cd "$startdir"
+rm -rf "$dir"
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh
new file mode 100644
index 0000000..1c155fe
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh
@@ -0,0 +1,159 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that USDT providers are removed when its associated
+# load object is closed via dlclose(3dl).
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main livelib.so deadlib.so
+
+main: main.o prov.o
+ cc -o main main.o
+
+main.o: main.c
+ cc -c main.c
+
+
+livelib.so: livelib.o prov.o
+ cc -z defs -G -o livelib.so livelib.o prov.o -lc
+
+livelib.o: livelib.c prov.h
+ cc -c livelib.c
+
+prov.o: livelib.o prov.d
+ $dtrace -G -s prov.d livelib.o
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+
+deadlib.so: deadlib.o
+ cc -z defs -G -o deadlib.so deadlib.o -lc
+
+deadlib.o: deadlib.c
+ cc -c deadlib.c
+
+clean:
+ rm -f main.o livelib.o prov.o prov.h deadlib.o
+
+clobber: clean
+ rm -f main livelib.so deadlib.so
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+cat > livelib.c <<EOF
+#include "prov.h"
+
+void
+go(void)
+{
+ TEST_PROV_GO();
+}
+EOF
+
+cat > deadlib.c <<EOF
+void
+go(void)
+{
+}
+EOF
+
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ void *live;
+
+ if ((live = dlopen("./livelib.so", RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ printf("dlopen of livelib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ (void) dlclose(live);
+
+ pause();
+
+ return (0);
+}
+EOF
+
+/usr/bin/make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+script() {
+ $dtrace -w -x bufsize=1k -c ./main -qs /dev/stdin <<EOF
+ syscall::pause:entry
+ /pid == \$target/
+ {
+ system("$dtrace -l -P test_prov*");
+ system("kill %d", \$target);
+ exit(0);
+ }
+
+ tick-1s
+ /i++ == 5/
+ {
+ printf("failed\n");
+ exit(1);
+ }
+EOF
+}
+
+script 2>&1
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh.out
new file mode 100644
index 0000000..2f5bb15
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh.out
@@ -0,0 +1,3 @@
+dtrace: failed to match test_prov*:::: No probe matches description
+ ID PROVIDER MODULE FUNCTION NAME
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh
new file mode 100644
index 0000000..107707e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh
@@ -0,0 +1,160 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main livelib.so deadlib.so
+
+main: main.o prov.o
+ cc -o main main.o
+
+main.o: main.c
+ cc -c main.c
+
+
+livelib.so: livelib.o prov.o
+ cc -z defs -G -o livelib.so livelib.o prov.o -lc
+
+livelib.o: livelib.c prov.h
+ cc -c livelib.c
+
+prov.o: livelib.o prov.d
+ $dtrace -G -s prov.d livelib.o
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+
+deadlib.so: deadlib.o
+ cc -z defs -G -o deadlib.so deadlib.o -lc
+
+deadlib.o: deadlib.c
+ cc -c deadlib.c
+
+clean:
+ rm -f main.o livelib.o prov.o prov.h deadlib.o
+
+clobber: clean
+ rm -f main livelib.so deadlib.so
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+cat > livelib.c <<EOF
+#include "prov.h"
+
+void
+go(void)
+{
+ TEST_PROV_GO();
+}
+EOF
+
+cat > deadlib.c <<EOF
+void
+go(void)
+{
+}
+EOF
+
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ void *live, *dead;
+ void *go;
+
+ if ((live = dlopen("./livelib.so", RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ printf("dlopen of livelib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ (void) dlclose(live);
+
+ if ((dead = dlopen("./deadlib.so", RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ printf("dlopen of deadlib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ if ((live = dlopen("./livelib.so", RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ printf("dlopen of livelib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ if ((go = dlsym(live, "go")) == NULL) {
+ printf("failed to lookup 'go' in livelib.so\n");
+ return (1);
+ }
+
+ ((void (*)(void))go)();
+
+ return (0);
+}
+EOF
+
+/usr/bin/make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+script() {
+ $dtrace -w -c ./main -Zqs /dev/stdin <<EOF
+ test_prov*:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh.out
new file mode 100644
index 0000000..2164eab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh.out
@@ -0,0 +1,2 @@
+livelib.so:go:go
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh
new file mode 100644
index 0000000..a750b59
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh
@@ -0,0 +1,170 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test verifies that performing a dlclose(3dl) on a library doesn't
+# cause existing pid provider probes to become invalid.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > Makefile <<EOF
+all: main livelib.so deadlib.so
+
+main: main.o prov.o
+ cc -o main main.o
+
+main.o: main.c
+ cc -c main.c
+
+
+livelib.so: livelib.o prov.o
+ cc -z defs -G -o livelib.so livelib.o prov.o -lc
+
+livelib.o: livelib.c prov.h
+ cc -c livelib.c
+
+prov.o: livelib.o prov.d
+ $dtrace -G -s prov.d livelib.o
+
+prov.h: prov.d
+ $dtrace -h -s prov.d
+
+
+deadlib.so: deadlib.o
+ cc -z defs -G -o deadlib.so deadlib.o -lc
+
+deadlib.o: deadlib.c
+ cc -c deadlib.c
+
+clean:
+ rm -f main.o livelib.o prov.o prov.h deadlib.o
+
+clobber: clean
+ rm -f main livelib.so deadlib.so
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+cat > livelib.c <<EOF
+#include "prov.h"
+
+void
+go(void)
+{
+ TEST_PROV_GO();
+}
+EOF
+
+cat > deadlib.c <<EOF
+void
+go(void)
+{
+}
+EOF
+
+
+cat > main.c <<EOF
+#include <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+
+static void
+foo(void)
+{
+ (void) close(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ void *live;
+
+ if ((live = dlopen("./livelib.so", RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ printf("dlopen of livelib.so failed: %s\n", dlerror());
+ return (1);
+ }
+
+ (void) dlclose(live);
+
+ foo();
+
+ return (0);
+}
+EOF
+
+/usr/bin/make > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "failed to build"
+ exit 1
+fi
+
+script() {
+ $dtrace -c ./main -s /dev/stdin <<EOF
+ pid\$target:a.out:foo:entry
+ {
+ gotit = 1;
+ exit(0);
+ }
+
+ tick-1s
+ /i++ == 5/
+ {
+ printf("test timed out");
+ exit(1);
+ }
+
+ END
+ /!gotit/
+ {
+ printf("program ended without hitting probe");
+ exit(1);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh
new file mode 100644
index 0000000..96b05d5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh
@@ -0,0 +1,106 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Make sure temporary symbols generated due to DTrace probes in static
+# functions are removed in the final link step.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+static void
+foo(void)
+{
+ TEST_PROV_GO();
+}
+
+int
+main(int argc, char **argv)
+{
+ foo();
+
+ return (0);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+nm test.o | grep \$dtrace > /dev/null
+if [ $? -ne 0 ]; then
+ print -u2 "no temporary symbols in the object file"
+ exit 1
+fi
+
+nm test | grep \$dtrace > /dev/null
+if [ $? -eq 0 ]; then
+ print -u2 "failed to eliminate temporary symbols"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh
new file mode 100644
index 0000000..d0ac186
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh
@@ -0,0 +1,96 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh.out
new file mode 100644
index 0000000..b856cc5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh.out
@@ -0,0 +1,2 @@
+test:main:go
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh
new file mode 100644
index 0000000..d40036d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh
@@ -0,0 +1,113 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test is primarily intended to verify a fix for SPARC, but there's no
+# harm in running it on other platforms. Here, we verify that is-enabled
+# probes don't interfere with return values from previously invoked functions.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <stdio.h>
+#include "prov.h"
+
+int
+foo(void)
+{
+ return (24);
+}
+
+int
+main(int argc, char **argv)
+{
+ int a = foo();
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+ (void) printf("%d %d %d\n", a, a, a);
+
+ return (0);
+}
+EOF
+
+cc -c -xO2 test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ ./test
+
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out
new file mode 100644
index 0000000..563d68f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out
@@ -0,0 +1,3 @@
+24 24 24
+24 24 24
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh
new file mode 100644
index 0000000..51afe96
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh
@@ -0,0 +1,118 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, entry);
+ DTRACE_PROBE(test_prov, __entry);
+ DTRACE_PROBE(test_prov, foo__entry);
+ DTRACE_PROBE(test_prov, carpentry);
+ DTRACE_PROBE(test_prov, miniatureturn);
+ DTRACE_PROBE(test_prov, foo__return);
+ DTRACE_PROBE(test_prov, __return);
+ /*
+ * Unfortunately, a "return" probe is not currently possible due to
+ * the conflict with a reserved word.
+ */
+ DTRACE_PROBE(test_prov, done);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe entry();
+ probe __entry();
+ probe foo__entry();
+ probe carpentry();
+ probe miniatureturn();
+ probe foo__return();
+ probe __return();
+ probe done();
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -wqZFs /dev/stdin <<EOF
+ BEGIN
+ {
+ system("$DIR/test");
+ printf("\n");
+ }
+
+ test_prov*:::done
+ /progenyof(\$pid)/
+ {
+ exit(0);
+ }
+
+ test_prov*:::
+ /progenyof(\$pid)/
+ {
+ printf("\n");
+ }
+EOF
+}
+
+script | cut -c5-
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh.out
new file mode 100644
index 0000000..3bf2890
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh.out
@@ -0,0 +1,10 @@
+FUNCTION
+| :BEGIN
+ -> main
+ -> main
+ -> main
+ | main:carpentry
+ | main:miniatureturn
+ <- main
+ <- main
+ | main:done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh
new file mode 100644
index 0000000..3ee9e9f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh
@@ -0,0 +1,105 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_GO();
+ if (fork() == 0) {
+ TEST_PROV_GO();
+ return (0);
+ }
+
+ (void) wait(NULL);
+ TEST_PROV_GO();
+
+ return (0);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script() {
+ $dtrace -c ./test -Zqs /dev/stdin <<EOF
+ test_prov*:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh.out
new file mode 100644
index 0000000..c656c33
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh.out
@@ -0,0 +1,4 @@
+test:main:go
+test:main:go
+test:main:go
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.c
new file mode 100644
index 0000000..ade7f83
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.c
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+#include "forker.h"
+
+int
+main(int argc, char **argv)
+{
+ int i;
+
+ for (i = 0; i < 10000; i++) {
+ FORKER_FIRE();
+ if (fork() == 0)
+ exit(0);
+
+ (void) wait(NULL);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.ksh
new file mode 100644
index 0000000..d35fc4d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.forker.ksh
@@ -0,0 +1,55 @@
+#!/usr/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+#
+# Test that we don't deadlock between forking and enabling/disabling USDT
+# probes. This test has succeeded if it completes at all.
+#
+
+./tst.forker.exe &
+id=$!
+
+while kill -0 $id >/dev/null 2>&1; do
+ $dtrace -p $id -s /dev/stdin <<-EOF
+ forker*:::fire
+ /i++ == 4/
+ {
+ exit(0);
+ }
+ EOF
+done
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh
new file mode 100644
index 0000000..8affb35
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh
@@ -0,0 +1,96 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+}
+EOF
+
+cc -xarch=generic -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -xarch=generic -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh
new file mode 100644
index 0000000..0c28018
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh
@@ -0,0 +1,100 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+}
+EOF
+
+cc -xarch=generic64 -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -xarch=generic64 -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+if [ `isainfo -b` -ne '64']; then
+ script
+ status=$?
+else
+ status=0
+fi
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh
new file mode 100644
index 0000000..37ad97c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh
@@ -0,0 +1,85 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe zero();
+ probe one(uintptr_t);
+ probe u_nder(char *);
+ probe d__ash(int **);
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_ZERO();
+ TEST_PROV_ONE(1);
+ TEST_PROV_U_NDER("hi there");
+ TEST_PROV_D_ASH(argv);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh
new file mode 100644
index 0000000..6f809fd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+# Make sure <unistd.h> defines _DTRACE_VERSION
+
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+#ifdef _DTRACE_VERSION
+ return (0);
+#else
+ return (1);
+#endif
+}
+EOF
+
+cc -xarch=generic -o test test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+
+./test
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh
new file mode 100644
index 0000000..a1ef9d8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh
@@ -0,0 +1,82 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, zero);
+ DTRACE_PROBE1(test_prov, one, 1);
+ DTRACE_PROBE2(test_prov, two, 2, 3);
+ DTRACE_PROBE3(test_prov, three, 4, 5, 7);
+ DTRACE_PROBE4(test_prov, four, 7, 8, 9, 10);
+ DTRACE_PROBE5(test_prov, five, 11, 12, 13, 14, 15);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe zero();
+ probe one(uintptr_t);
+ probe two(uintptr_t, uintptr_t);
+ probe three(uintptr_t, uintptr_t, uintptr_t);
+ probe four(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe five(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh
new file mode 100644
index 0000000..ffc5107
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+ppriv -s A=basic $$
+
+cat > test.c <<EOF
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, zero);
+ DTRACE_PROBE1(test_prov, one, 1);
+ DTRACE_PROBE2(test_prov, two, 2, 3);
+ DTRACE_PROBE3(test_prov, three, 4, 5, 7);
+ DTRACE_PROBE4(test_prov, four, 7, 8, 9, 10);
+ DTRACE_PROBE5(test_prov, five, 11, 12, 13, 14, 15);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe zero();
+ probe one(uintptr_t);
+ probe two(uintptr_t, uintptr_t);
+ probe three(uintptr_t, uintptr_t, uintptr_t);
+ probe four(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe five(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh
new file mode 100644
index 0000000..3f545a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh
@@ -0,0 +1,99 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_GO();
+ TEST_PROV_GO();
+ TEST_PROV_GO();
+ TEST_PROV_GO();
+
+ return (0);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script() {
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh.out
new file mode 100644
index 0000000..5e82619
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh.out
@@ -0,0 +1,5 @@
+test:main:go
+test:main:go
+test:main:go
+test:main:go
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh
new file mode 100644
index 0000000..f766f6d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh
@@ -0,0 +1,90 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+# Fake up a scenario where _DTRACE_VERSION is not defined by having our own
+# <unistd.h>. This tests that dtrace -h will produce a header file which can
+# be used on a system where DTrace is not present.
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+touch unistd.h
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_GO();
+
+ if (TEST_PROV_GO_ENABLED()) {
+ TEST_PROV_GO();
+ }
+
+ return (0);
+}
+EOF
+
+cc -I. -xarch=generic -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+cc -xarch=generic -o test test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+./test
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh
new file mode 100644
index 0000000..9def3c0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh
@@ -0,0 +1,82 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ if (TEST_PROV_GO_ENABLED())
+ return (2);
+
+ return (0);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+cd /
+/bin/rm -rf $DIR
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh
new file mode 100644
index 0000000..4ea33f7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh
@@ -0,0 +1,98 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, zero);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe zero();
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -wZs /dev/stdin <<EOF
+ BEGIN
+ {
+ system("$DIR/test");
+ }
+
+ test_prov*:::
+ {
+ seen = 1;
+ }
+
+ proc:::exit
+ /progenyof(\$pid) && execname == "test"/
+ {
+ exit(seen ? 0 : 2);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh
new file mode 100644
index 0000000..0cddf0d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh
@@ -0,0 +1,98 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+static void
+foo(void)
+{
+ DTRACE_PROBE(test_prov, probe1);
+ DTRACE_PROBE(test_prov, probe2);
+}
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, probe1);
+ DTRACE_PROBE(test_prov, probe2);
+ foo();
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe probe1();
+ probe probe2();
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh.out
new file mode 100644
index 0000000..a559d97
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh.out
@@ -0,0 +1,5 @@
+test:main:probe1
+test:main:probe2
+test:foo:probe1
+test:foo:probe2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh
new file mode 100644
index 0000000..8385b27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh
@@ -0,0 +1,108 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+# Rebuilding an object file containing DOF changes slightly when the object
+# files containing the probes have already been modified. This tests that
+# case by generating the DOF object, removing it, and building it again.
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+static void
+foo(void)
+{
+ DTRACE_PROBE(test_prov, probe1);
+ DTRACE_PROBE(test_prov, probe2);
+}
+
+int
+main(int argc, char **argv)
+{
+ DTRACE_PROBE(test_prov, probe1);
+ DTRACE_PROBE(test_prov, probe2);
+ foo();
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe probe1();
+ probe probe2();
+};
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create initial DOF"
+ exit 1
+fi
+rm -f prov.o
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create final DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script()
+{
+ $dtrace -c ./test -qs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh.out
new file mode 100644
index 0000000..a559d97
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh.out
@@ -0,0 +1,5 @@
+test:main:probe1
+test:main:probe2
+test:foo:probe1
+test:foo:probe2
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh
new file mode 100644
index 0000000..89ceb4a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh
@@ -0,0 +1,96 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > prov.d <<EOF
+provider test_prov {
+ probe go();
+};
+EOF
+
+$dtrace -h -s prov.d
+if [ $? -ne 0 ]; then
+ print -u2 "failed to generate header file"
+ exit 1
+fi
+
+cat > test.c <<EOF
+#include <sys/types.h>
+#include "prov.h"
+
+int
+main(int argc, char **argv)
+{
+ TEST_PROV_GO();
+
+ return (0);
+}
+EOF
+
+cc -c test.c
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.c"
+ exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+script() {
+ $dtrace -c 'ppriv -e -s A=basic ./test' -Zqs /dev/stdin <<EOF
+ test_prov\$target:::
+ {
+ printf("%s:%s:%s\n", probemod, probefunc, probename);
+ }
+EOF
+}
+
+script
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh.out
new file mode 100644
index 0000000..b856cc5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh.out
@@ -0,0 +1,2 @@
+test:main:go
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.c
new file mode 100644
index 0000000..edd3dd1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.c
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void grow1(int);
+
+void
+grow(int frame)
+{
+ /*
+ * Create a ridiculously large stack - enough to push us over
+ * the default setting of 'dtrace_ustackdepth_max' (2048).
+ */
+ if (frame >= 2048)
+ for (;;)
+ getpid();
+
+ grow1(++frame);
+}
+
+void
+grow1(int frame)
+{
+ grow(++frame);
+}
+
+int
+main(int argc, char *argv[])
+{
+ grow(1);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.d
new file mode 100644
index 0000000..66fda5b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.bigstack.d
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+syscall::getpid:entry
+/pid == $1/
+{
+ @[ustackdepth] = count();
+}
+
+ERROR
+/arg4 == DTRACEFLT_BADSTACK/
+{
+ exit(0);
+}
+
+profile:::tick-1s
+/++n == 10/
+{
+ exit(1)
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.depth.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.depth.ksh
new file mode 100644
index 0000000..26cff42
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.depth.ksh
@@ -0,0 +1,110 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+file=out.$$
+dtrace=$1
+
+rm -f $file
+
+$dtrace -o $file -c date -s /dev/stdin <<EOF
+
+ #pragma D option quiet
+ #pragma D option bufsize=1M
+ #pragma D option bufpolicy=fill
+
+ pid\$target:::entry,
+ pid\$target:::return,
+ pid\$target:a.out::,
+ syscall:::return,
+ profile:::profile-997
+ /pid == \$target/
+ {
+ printf("START %s:%s:%s:%s\n",
+ probeprov, probemod, probefunc, probename);
+ trace(ustackdepth);
+ ustack(100);
+ trace("END\n");
+ }
+
+ tick-1sec
+ /n++ == 10/
+ {
+ trace("test timed out...");
+ exit(1);
+ }
+EOF
+
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+perl /dev/stdin $file <<EOF
+ while (<>) {
+ chomp;
+
+ last if /^\$/;
+
+ die "expected START at \$.\n" unless /^START/;
+
+ \$_ = <>;
+ chomp;
+ die "expected depth (\$_) at \$.\n" unless /^(\d+)\$/;
+ \$depth = \$1;
+
+ for (\$i = 0; \$i < \$depth; \$i++) {
+ \$_ = <>;
+ chomp;
+ die "unexpected END at \$.\n" if /^END/;
+ }
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /^END\$/;
+ }
+EOF
+
+status=$?
+
+count=`wc -l $file | cut -f1 -do`
+if [ "$count" -lt 1000 ]; then
+ echo $tst: output was too short
+ status=1
+fi
+
+
+if [ "$status" -eq 0 ]; then
+ rm -f $file
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.c
new file mode 100644
index 0000000..bdeb16d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.c
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+
+volatile long long count = 0;
+
+int
+baz(int a)
+{
+ (void) getpid();
+ while (count != -1) {
+ count++;
+ a++;
+ }
+
+ return (a + 1);
+}
+
+int
+bar(int a)
+{
+ return (baz(a + 1) - 1);
+}
+
+int
+foo(int a, int b)
+{
+ return (bar(a) - b);
+}
+
+int
+main(int argc, char **argv)
+{
+ return (foo(argc, (int)argv) == 0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.ksh
new file mode 100644
index 0000000..1a7e0e1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ustack/tst.spin.ksh
@@ -0,0 +1,139 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+file=out.$$
+dtrace=$1
+
+rm -f $file
+
+dir=`dirname $tst`
+
+$dtrace -o $file -c $dir/tst.spin.exe -s /dev/stdin <<EOF
+
+ #pragma D option quiet
+ #pragma D option destructive
+ #pragma D option evaltime=main
+
+ /*
+ * Toss out the first 100 samples to wait for the program to enter
+ * its steady state.
+ */
+
+ profile-1999
+ /pid == \$target && n++ > 100/
+ {
+ @total = count();
+ @stacks[ustack(4)] = count();
+ }
+
+ tick-1s
+ {
+ secs++;
+ }
+
+ tick-1s
+ /secs > 5/
+ {
+ done = 1;
+ }
+
+ tick-1s
+ /secs > 10/
+ {
+ trace("test timed out");
+ exit(1);
+ }
+
+ profile-1999
+ /pid == \$target && done/
+ {
+ raise(SIGINT);
+ exit(0);
+ }
+
+ END
+ {
+ printa("TOTAL %@u\n", @total);
+ printa("START%kEND\n", @stacks);
+ }
+EOF
+
+status=$?
+if [ "$status" -ne 0 ]; then
+ echo $tst: dtrace failed
+ exit $status
+fi
+
+perl /dev/stdin $file <<EOF
+ \$_ = <>;
+ chomp;
+ die "output problem\n" unless /^TOTAL (\d+)/;
+ \$count = \$1;
+ die "too few samples (\$count)\n" unless \$count >= 1000;
+
+ while (<>) {
+ chomp;
+
+ last if /^$/;
+
+ die "expected START at \$.\n" unless /^START/;
+
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /\`baz\+/;
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /\`bar\+/;
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /\`foo\+/;
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /\`main\+/;
+
+ \$_ = <>;
+ chomp;
+ die "expected END at \$.\n" unless /^END\$/;
+ }
+
+EOF
+
+status=$?
+if [ "$status" -eq 0 ]; then
+ rm -f $file
+fi
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.gid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.gid.d
new file mode 100644
index 0000000..23fcf38
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.gid.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+/curpsinfo->pr_gid == gid/
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("%d != %d\n", curpsinfo->pr_gid, gid);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.nullassign.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.nullassign.d
new file mode 100644
index 0000000..accc763
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.nullassign.d
@@ -0,0 +1,94 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+{
+ die = "Die";
+ tap = ", SystemTap, ";
+ the = "The";
+}
+
+BEGIN
+{
+ phrase = strjoin(die, tap);
+ phrase = strjoin(phrase, die);
+ expected = "Die, SystemTap, Die";
+}
+
+BEGIN
+/phrase != expected/
+{
+ printf("global: expected '%s', found '%s'\n", expected, phrase);
+ exit(1);
+}
+
+BEGIN
+{
+ this->phrase = strjoin(the, tap);
+}
+
+BEGIN
+{
+ this->phrase = strjoin(this->phrase, the);
+ expected = "The, SystemTap, The";
+}
+
+BEGIN
+/this->phrase != expected/
+{
+ printf("clause-local: expected '%s', found '%s'\n",
+ expected, this->phrase);
+ exit(2);
+}
+
+BEGIN
+{
+ phrase = NULL;
+ this->phrase = NULL;
+}
+
+BEGIN
+/phrase != NULL/
+{
+ printf("expected global to be NULL\n");
+ exit(3);
+}
+
+BEGIN
+/this->phrase != NULL/
+{
+ printf("expected clause-local to be NULL\n");
+ exit(4);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ppid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ppid.d
new file mode 100644
index 0000000..5f0da5f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ppid.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+/curpsinfo->pr_ppid == ppid/
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("%d != %d\n", curpsinfo->pr_ppid, ppid);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh
new file mode 100644
index 0000000..c09825e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh
@@ -0,0 +1,65 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This test is a bit naughty; it's assuming that ld.so.1 has an implementation
+# of calloc(3C), and that it's implemented in terms of the ld.so.1
+# implementation of malloc(3C). If you're reading this comment because
+# those assumptions have become false, please accept my apologies...
+#
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -qs /dev/stdin -c "/bin/echo" <<EOF
+pid\$target:ld.so.1:calloc:entry
+{
+ self->calloc = 1;
+}
+
+pid\$target:ld.so.1:malloc:entry
+/self->calloc/
+{
+ @[umod(ucaller), ufunc(ucaller)] = count();
+}
+
+pid\$target:ld.so.1:calloc:return
+/self->calloc/
+{
+ self->calloc = 0;
+}
+
+END
+{
+ printa("%A %A\n", @);
+}
+EOF
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh.out
new file mode 100644
index 0000000..86c72a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh.out
@@ -0,0 +1,3 @@
+
+ld.so.1 ld.so.1`calloc
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.uid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.uid.d
new file mode 100644
index 0000000..bf1c9dc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.uid.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+BEGIN
+/curpsinfo->pr_uid == uid/
+{
+ exit(0);
+}
+
+BEGIN
+{
+ printf("%d != %d\n", curpsinfo->pr_uid, uid);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.walltimestamp.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.walltimestamp.d
new file mode 100644
index 0000000..e17bb94
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.walltimestamp.d
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+uint64_t now;
+
+BEGIN
+{
+ now = 18252813184; /* Jan 1, 2004 00:00:00 */
+}
+
+BEGIN
+/walltimestamp < timestamp/
+{
+ printf("%d < %d", walltimestamp, timestamp);
+ exit(1);
+}
+
+BEGIN
+/walltimestamp < now/
+{
+ printf("%d (%Y) is before %Y", walltimestamp, walltimestamp, now);
+ exit(2);
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/version/tst.1.0.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/version/tst.1.0.d
new file mode 100644
index 0000000..0ab2af7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/version/tst.1.0.d
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option version=1.0
+
+/*
+ * The following identifiers were added as D built-ins as of version 1.1.
+ * Using these identifiers as user-specified variables should be illegal in
+ * that and any later versions, but legal in earlier versions.
+ */
+int strstr;
+int strchr;
+int strrchr;
+int strtok;
+int substr;
+int index;
+int freopen;
+
+BEGIN
+{
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/arrays/tst.uregsarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/arrays/tst.uregsarray.d
new file mode 100644
index 0000000..5543c0a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/arrays/tst.uregsarray.d
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive test to make sure that we can invoke x86
+ * ureg[] aliases.
+ *
+ * SECTION: User Process Tracing/uregs Array
+ *
+ * NOTES: This test does no verification - the value of the output
+ * is not deterministic.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("R_GS = 0x%x\n", uregs[R_GS]);
+ printf("R_ES = 0x%x\n", uregs[R_ES]);
+ printf("R_DS = 0x%x\n", uregs[R_DS]);
+ printf("R_EDI = 0x%x\n", uregs[R_EDI]);
+ printf("R_ESI = 0x%x\n", uregs[R_ESI]);
+ printf("R_EBP = 0x%x\n", uregs[R_EBP]);
+ printf("R_EBX = 0x%x\n", uregs[R_EBX]);
+ printf("R_EDX = 0x%x\n", uregs[R_EDX]);
+ printf("R_ECX = 0x%x\n", uregs[R_ECX]);
+ printf("R_EAX = 0x%x\n", uregs[R_EAX]);
+ printf("R_TRAPNO = 0x%x\n", uregs[R_TRAPNO]);
+ printf("R_ERR = 0x%x\n", uregs[R_ERR]);
+ printf("R_EIP = 0x%x\n", uregs[R_EIP]);
+ printf("R_CS = 0x%x\n", uregs[R_CS]);
+ printf("R_EFL = 0x%x\n", uregs[R_EFL]);
+ printf("R_UESP = 0x%x\n", uregs[R_UESP]);
+ printf("R_SS = 0x%x\n", uregs[R_SS]);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d
new file mode 100644
index 0000000..f14c8af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * ASSERTION:
+ * On IA/32, there is a single 32-bit address space that is partitioned
+ * between user-level and kernel-level. copyin()/copyinstr() and
+ * copyout()/copyoutstr() must check that addresses specified as
+ * user-level addresses are actually at user-level. This test attempts
+ * to perform an illegal copyin() from a kernel address. It asserts that
+ * the fault type is DTRACEFLT_BADADDR and that the bad address is set to
+ * the kernel address from which the copyin() was attempted.
+ *
+ * SECTION: Actions and Subroutines/copyin();
+ * Actions and Subroutines/copyin();
+ * User Process Tracing/copyin() and copyinstr()
+ */
+
+BEGIN
+{
+ dtrace_zero = copyin((uintptr_t)&`dtrace_zero, sizeof (int));
+ exit(1);
+}
+
+ERROR
+{
+ exit(arg4 == DTRACEFLT_BADADDR &&
+ arg5 == (uint64_t)&`dtrace_zero ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyinstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyinstr.d
new file mode 100644
index 0000000..ac04993
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyinstr.d
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * On IA/32, there is a single 32-bit address space that is partitioned
+ * between user-level and kernel-level. copyin()/copyinstr() and
+ * copyout()/copyoutstr() must check that addresses specified as
+ * user-level addresses are actually at user-level. This test attempts
+ * to perform an illegal copyinstr() from a kernel address. It asserts
+ * that the fault type is DTRACEFLT_BADADDR and that the bad address is
+ * set to the kernel address from which the copyinstr() was attempted.
+ *
+ * SECTION: Actions and Subroutines/copyinstr();
+ * User Process Tracing/copyin() and copyinstr()
+ */
+
+BEGIN
+{
+ os = copyinstr((uintptr_t)&`utsname);
+ exit(1);
+}
+
+ERROR
+{
+ exit(arg4 == DTRACEFLT_BADADDR && arg5 == (uint64_t)&`utsname ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyout.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyout.d
new file mode 100644
index 0000000..8909cd3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyout.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * On IA/32, there is a single 32-bit address space that is partitioned
+ * between user-level and kernel-level. copyin()/copyinstr() and
+ * copyout()/copyoutstr() must check that addresses specified as
+ * user-level addresses are actually at user-level. This test attempts
+ * to perform an illegal copyout() to a kernel address. It asserts that
+ * the fault type is DTRACEFLT_BADADDR and that the bad address is set to
+ * the kernel address to which the copyout() was attempted.
+ *
+ * SECTION: Actions and Subroutines/copyout()
+ *
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ this->a = (uint32_t *)alloca(4);
+ *this->a = -1;
+ copyout(this->a, (uintptr_t)&`clock, 4);
+ exit(1);
+}
+
+ERROR
+{
+ exit(arg4 == DTRACEFLT_BADADDR && arg5 == (uint64_t)&`clock ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyoutstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyoutstr.d
new file mode 100644
index 0000000..d7166cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyoutstr.d
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ * On IA/32, there is a single 32-bit address space that is partitioned
+ * between user-level and kernel-level. copyin()/copyinstr() and
+ * copyout()/copyoutstr() must check that addresses specified as
+ * user-level addresses are actually at user-level. This test attempts
+ * to perform an illegal copyoutstr() to a kernel address. It asserts
+ * that the fault type is DTRACEFLT_BADADDR and that the bad address is
+ * set to the kernel address to which the copyoutstr() was attempted.
+ *
+ * SECTION: Actions and Subroutines/copyoutstr()
+ *
+ */
+
+#pragma D option destructive
+
+BEGIN
+{
+ this->str = alloca(10);
+ bcopy("kablammo!", this->str, 10);
+ copyoutstr(this->str, (uintptr_t)&`clock, 10);
+ exit(1);
+}
+
+ERROR
+{
+ exit(arg4 == DTRACEFLT_BADADDR && arg5 == (uint64_t)&`clock ? 0 : 1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.d
new file mode 100644
index 0000000..50753b8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Make sure that DTrace doesn't explode on an invalid instruction.
+ */
+
+pid$1:a.out:badfunc:entry
+{
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.s
new file mode 100644
index 0000000..27f7f99
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.badinstr.s
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(badfunc)
+ .byte 0xff
+ .byte 0xff
+ SET_SIZE(badfunc)
+
+ ENTRY(main)
+1: jmp 1b
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.d
new file mode 100644
index 0000000..cfcf0a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:main:,
+pid$1:a.out:other:
+{
+}
+
+pid$1:a.out:bad:entry
+{
+ exit(1);
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.s
new file mode 100644
index 0000000..82a5892
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.branch.s
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(waiting)
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ movl (%eax), %eax
+ popl %ebp
+ ret
+ SET_SIZE(waiting)
+
+ ENTRY(main)
+ pushl %ebp
+ movl %esp, %ebp
+ subl $0x4, %esp
+ movl $0x0, -4(%ebp)
+
+1:
+ leal -4(%ebp), %eax
+ pushl %eax
+ call waiting
+ addl $0x4, %esp
+
+ testl %eax, %eax
+ jz 1b
+
+ addl $0x4, %esp
+
+ xorl %eax, %eax
+ testl %eax, %eax
+ jz other
+
+ ALTENTRY(bad)
+ movl 0x0, %eax
+ SET_SIZE(bad)
+ SET_SIZE(main)
+
+ ENTRY(other)
+ xorl %eax, %eax
+ popl %ebp
+ ret
+ SET_SIZE(other)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.d
new file mode 100644
index 0000000..c484c3f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:main:,
+pid$1:a.out:inner:
+{
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.s
new file mode 100644
index 0000000..134a5af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.embedded.s
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(waiting)
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ movl (%eax), %eax
+ popl %ebp
+ ret
+ SET_SIZE(waiting)
+
+ ENTRY(main)
+ pushl %ebp
+ movl %esp, %ebp
+ subl $0x4, %esp
+ movl $0x0, -4(%ebp)
+1:
+ leal -4(%ebp), %eax
+ pushl %eax
+ call waiting
+ addl $0x4, %esp
+
+ testl %eax, %eax
+ jz 1b
+
+ addl $0x4, %esp
+
+ ALTENTRY(inner)
+ nop
+ nop
+ nop
+ SET_SIZE(inner)
+
+ xorl %eax, %eax
+ popl %ebp
+ ret
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.d
new file mode 100644
index 0000000..358466fe
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.d
@@ -0,0 +1,76 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Validated the emulation of various flavors of the return
+ * instruction.
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:ret*:
+{
+ printf("%%sp = %x", uregs[R_SP]);
+}
+
+pid$1:a.out:ret*:return
+{
+}
+
+pid$1:a.out:done:entry
+{
+ exit(0);
+}
+
+pid$1:a.out:main:return
+{
+ printf("%%eax = %x", uregs[R_EAX]);
+}
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.s
new file mode 100644
index 0000000..bccdb1a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.ret.s
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(ret1)
+ ret
+ SET_SIZE(ret1)
+
+ ENTRY(ret2)
+ repz
+ ret
+ SET_SIZE(ret2)
+
+ ENTRY(ret3)
+ ret $0
+ SET_SIZE(ret3)
+
+ ENTRY(ret4)
+ repz
+ ret $0
+ SET_SIZE(ret4)
+
+ ENTRY(ret5)
+ pushl (%esp)
+ ret $4
+ SET_SIZE(ret5)
+
+ ENTRY(ret6)
+ pushl (%esp)
+ repz
+ ret $4
+ SET_SIZE(ret6)
+
+ ENTRY(waiting)
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ movl (%eax), %eax
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ SET_SIZE(waiting)
+
+ ENTRY(main)
+ pushl %ebp
+ movl %esp, %ebp
+ subl $0x4, %esp
+ movl $0x0, -4(%ebp)
+
+1:
+ leal -4(%ebp), %eax
+ pushl %eax
+ call waiting
+ addl $0x4, %esp
+
+ testl %eax, %eax
+ jz 1b
+
+ movl %esp, %esi
+
+ call ret1
+ call ret2
+ call ret3
+ call ret4
+ call ret5
+ call ret6
+
+ cmpl %esp, %esi
+ jne 1f
+
+ ALTENTRY(done)
+ nop
+ SET_SIZE(done)
+
+ movl $0, %eax
+ movl %ebp, %esp
+ popl %ebp
+ ret
+
+1:
+ movl $1, %eax
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.ksh
new file mode 100644
index 0000000..5477f5c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.ksh
@@ -0,0 +1,50 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+# Make sure we can match against 2-byte rets
+
+./tst.retlist.exe&
+PID=$!
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+match=`$dtrace -l -n pid$PID:a.out:simple: -n pid$PID:a.out:complex: | wc -l`
+
+kill $PID
+
+if [ "$match" -ne 12 ]; then
+ echo wrong number of matched probes: $match
+ exit 1
+fi
+
+exit 0
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.s
new file mode 100644
index 0000000..e85e9f5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/pid/tst.retlist.s
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(simple)
+ repz
+ ret
+ SET_SIZE(simple)
+
+ ENTRY(complex)
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ movl (%eax), %eax
+ popl %ebp
+ repz
+ ret
+ SET_SIZE(complex)
+
+ ENTRY(main)
+1: jmp 1b
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/annotated_helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/annotated_helper.d
new file mode 100644
index 0000000..3b97709
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/annotated_helper.d
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+dtrace:helper:ustack:
+{
+ "@it's annotated"
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/helper_helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/helper_helper.d
new file mode 100644
index 0000000..8abc47d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/helper_helper.d
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+dtrace:helper:ustack:
+{
+ "<it's working>"
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.c
new file mode 100644
index 0000000..8cdf8ab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.c
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+int
+baz(void)
+{
+ return (8);
+}
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ baz();
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d
new file mode 100644
index 0000000..dd795be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+pid$1:a.out:baz:entry
+{
+ ustack(1, 1024);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d.out
new file mode 100644
index 0000000..806d6a2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.annotated.d.out
@@ -0,0 +1,4 @@
+
+ tst.annotated.exe`baz
+ [ it's annotated ]
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.d
new file mode 100644
index 0000000..78218bd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+syscall::getpid:entry
+/pid == $1/
+{
+ @[ustackdepth] = count();
+}
+
+ERROR
+/arg4 == DTRACEFLT_BADSTACK/
+{
+ exit(0);
+}
+
+profile:::tick-1s
+/++n == 10/
+{
+ exit(1)
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.s
new file mode 100644
index 0000000..3bf7c0b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.circstack.s
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .long 0
+
+ ENTRY(main)
+ pushl %ebp
+ movl %esp, %ebp
+ movl %esp, (%ebp)
+loop:
+ call getpid
+ jmp loop
+ leave
+ ret
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.c
new file mode 100644
index 0000000..69ab6a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.c
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <strings.h>
+
+int
+baz(void)
+{
+ return (8);
+}
+
+static int
+foo(void)
+{
+ /*
+ * In order to assure that our helper is properly employed to identify
+ * the frame, we're going to trampoline through data.
+ */
+ uint8_t instr[] = {
+ 0x55, /* pushl %ebp */
+ 0x8b, 0xec, /* movl %esp, %ebp */
+ 0xe8, 0x0, 0x0, 0x0, 0x0, /* call baz */
+ 0x8b, 0xe5, /* movl %ebp, %esp */
+ 0x5d, /* popl %ebp */
+ 0xc3 /* ret */
+ };
+ uint8_t *fp = malloc(sizeof (instr));
+
+ /*
+ * Do our little relocation dance.
+ */
+ *((int *)&instr[4]) = (uintptr_t)baz - (uintptr_t)&fp[8];
+
+ /*
+ * Copy the code to the heap (it's a pain to build in ON with an
+ * executable stack).
+ */
+ bcopy(instr, fp, sizeof (instr));
+
+ (*(int (*)(void))fp)();
+
+ free(fp);
+
+ return (0);
+}
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ foo();
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d
new file mode 100644
index 0000000..ce2b9b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+pid$1:a.out:baz:entry
+{
+ ustack(2, 1024);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d.out
new file mode 100644
index 0000000..2964628
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/ustack/tst.helper.d.out
@@ -0,0 +1,4 @@
+
+ tst.helper.exe`baz
+ <it's working>
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh
new file mode 100755
index 0000000..3a5ce6f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh
@@ -0,0 +1,77 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# ASSERTION: Make sure that we can map in and read the Xen trace buffers.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+#
+# Do not fail the test in a domU
+#
+if [ ! -c /dev/xen/privcmd ]; then
+ exit 0
+fi
+
+dtrace=$1
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ xdt:sched::on-cpu
+ /arg0 == 0/
+ {
+ self->on++;
+ }
+
+ xdt:sched::off-cpu
+ /arg0 == 0 && self->on/
+ {
+ self->off++;
+ }
+
+ xdt:sched::off-cpu
+ /self->on > 50 && self->off > 50/
+ {
+ exit(0);
+ }
+
+ profile:::tick-1sec
+ /n++ > 10/
+ {
+ exit(1);
+ }
+EOF
+}
+
+script
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh
new file mode 100755
index 0000000..3719c20
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# ASSERTION: HVM probes should enable successfully.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+#
+# Do not fail the test in a domU
+#
+if [ ! -c /dev/xen/privcmd ]; then
+ exit 0
+fi
+
+dtrace=$1
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ dtrace:::BEGIN
+ {
+ exit(0);
+ }
+
+ xdt:hvm::vmentry,
+ xdt:hvm::vmexit
+ {}
+EOF
+}
+
+script
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh
new file mode 100755
index 0000000..25d39cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh
@@ -0,0 +1,65 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# ASSERTION: Mem probes should enable successfully.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+#
+# Do not fail the test in a domU
+#
+if [ ! -c /dev/xen/privcmd ]; then
+ exit 0
+fi
+
+dtrace=$1
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ dtrace:::BEGIN
+ {
+ exit(0);
+ }
+
+ xdt:mem::page-grant-map,
+ xdt:mem::page-grant-unmap,
+ xdt:mem::page-grant-transfer
+ {}
+EOF
+}
+
+script
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh
new file mode 100755
index 0000000..5b14fc9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh
@@ -0,0 +1,121 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# ASSERTION: Sched probe arguments should be valid.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+#
+# do not fail test in a domU
+#
+if [ ! -c /dev/xen/privcmd ]; then
+ exit 0
+fi
+
+dtrace=$1
+outf=/tmp/sched.args.$$
+
+script()
+{
+ $dtrace -c '/usr/bin/sleep 10' -o $outf -qs /dev/stdin <<EOF
+ xdt:sched::off-cpu,
+ xdt:sched::on-cpu,
+ xdt:sched::block,
+ xdt:sched::sleep,
+ xdt:sched::wake,
+ xdt:sched::yield
+ {
+ /* print domid vcpu pcpu probename */
+ printf("%d %d %d %s\n", arg0, arg1, \`xdt_curpcpu, probename);
+ }
+EOF
+}
+
+validate()
+{
+ /usr/bin/nawk '
+ BEGIN {
+ while (("/usr/sbin/xm vcpu-list" | getline)) {
+ if ($1 != "Name") {
+ domid = $2
+ vcpu = $3
+
+ vcpumap[domid, vcpu] = 1
+
+ split($7, affinity, ",")
+ for (i in affinity) {
+ if (split(affinity[i], p, "-") > 1) {
+ for (pcpu = p[1]; pcpu <= p[2];\
+ pcpu++) {
+ cpumap[domid, vcpu,
+ pcpu] = 1
+ }
+ } else {
+ cpumap[domid, vcpu,
+ affinity[i]] = 1
+ }
+ }
+ }
+ }
+ }
+
+ /^$/ { next }
+
+ /wake/ {
+ if (vcpumap[$1, $2]) {
+ next
+ } else {
+ print "error: " $0
+ exit 1
+ }
+ }
+
+ {
+ if (cpumap[$1, $2, "any"] || cpumap[$1, $2, $3]) {
+ next
+ } else {
+ print "error: " $0
+ exit 1
+ }
+ }
+ ' $outf
+}
+
+script
+status=$?
+
+if [ $status == 0 ]; then
+ validate
+ status=$?
+fi
+
+rm $outf
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh
new file mode 100755
index 0000000..54c3352
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# ASSERTION: Sched probes should enable successfully.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+#
+# do not fail test in a domU
+#
+if [ ! -c /dev/xen/privcmd ]; then
+ exit 0
+fi
+
+dtrace=$1
+
+script()
+{
+ $dtrace -qs /dev/stdin <<EOF
+ dtrace:::BEGIN
+ {
+ exit(0);
+ }
+
+ xdt:sched::off-cpu,
+ xdt:sched::on-cpu,
+ xdt:sched::idle-off-cpu,
+ xdt:sched::idle-on-cpu,
+ xdt:sched::block,
+ xdt:sched::sleep,
+ xdt:sched::wake,
+ xdt:sched::yield,
+ xdt:sched::shutdown-poweroff,
+ xdt:sched::shutdown-reboot,
+ xdt:sched::shutdown-suspend,
+ xdt:sched::shutdown-crash
+ {}
+EOF
+}
+
+script
+status=$?
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/arrays/tst.uregsarray.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/arrays/tst.uregsarray.d
new file mode 100644
index 0000000..3ef3898
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/arrays/tst.uregsarray.d
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * ASSERTION:
+ * Positive test to make sure that we can invoke sparc
+ * ureg[] aliases.
+ *
+ * SECTION: User Process Tracing/uregs Array
+ *
+ * NOTES: This test does no verification - the value of the output
+ * is not deterministic.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("R_G0 = 0x%x\n", uregs[R_G0]);
+ printf("R_G1 = 0x%x\n", uregs[R_G1]);
+ printf("R_G2 = 0x%x\n", uregs[R_G2]);
+ printf("R_G3 = 0x%x\n", uregs[R_G3]);
+ printf("R_G4 = 0x%x\n", uregs[R_G4]);
+ printf("R_G5 = 0x%x\n", uregs[R_G5]);
+ printf("R_G6 = 0x%x\n", uregs[R_G6]);
+ printf("R_G7 = 0x%x\n", uregs[R_G7]);
+ printf("R_O0 = 0x%x\n", uregs[R_O0]);
+ printf("R_O1 = 0x%x\n", uregs[R_O1]);
+ printf("R_O2 = 0x%x\n", uregs[R_O2]);
+ printf("R_O3 = 0x%x\n", uregs[R_O3]);
+ printf("R_O4 = 0x%x\n", uregs[R_O4]);
+ printf("R_O5 = 0x%x\n", uregs[R_O5]);
+ printf("R_O6 = 0x%x\n", uregs[R_O6]);
+ printf("R_O7 = 0x%x\n", uregs[R_O7]);
+ printf("R_L0 = 0x%x\n", uregs[R_L0]);
+ printf("R_L1 = 0x%x\n", uregs[R_L1]);
+ printf("R_L2 = 0x%x\n", uregs[R_L2]);
+ printf("R_L3 = 0x%x\n", uregs[R_L3]);
+ printf("R_L4 = 0x%x\n", uregs[R_L4]);
+ printf("R_L5 = 0x%x\n", uregs[R_L5]);
+ printf("R_L6 = 0x%x\n", uregs[R_L6]);
+ printf("R_L7 = 0x%x\n", uregs[R_L7]);
+ printf("R_I0 = 0x%x\n", uregs[R_I0]);
+ printf("R_I1 = 0x%x\n", uregs[R_I1]);
+ printf("R_I2 = 0x%x\n", uregs[R_I2]);
+ printf("R_I3 = 0x%x\n", uregs[R_I3]);
+ printf("R_I4 = 0x%x\n", uregs[R_I4]);
+ printf("R_I5 = 0x%x\n", uregs[R_I5]);
+ printf("R_I6 = 0x%x\n", uregs[R_I6]);
+ printf("R_I7 = 0x%x\n", uregs[R_I7]);
+ printf("R_CCR = 0x%x\n", uregs[R_CCR]);
+ printf("R_PC = 0x%x\n", uregs[R_PC]);
+ printf("R_NPC = 0x%x\n", uregs[R_NPC]);
+ printf("R_Y = 0x%x\n", uregs[R_Y]);
+ printf("R_ASI = 0x%x\n", uregs[R_ASI]);
+ printf("R_FPRS = 0x%x\n", uregs[R_FPRS]);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.d
new file mode 100644
index 0000000..3e46627
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.d
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: On SPARC, you can't trace misaligned offsets
+ *
+ * SECTION: User Process Tracing/pid Provider
+ *
+ * NOTES:
+ *
+ */
+
+pid$1:a.out:main:7
+{
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe
new file mode 100644
index 0000000..595db1d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe
@@ -0,0 +1,29 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+sleep 1000000
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d
new file mode 100644
index 0000000..cf1dc02
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Trace all instructions in the function 'test' to verify that
+ * the branches are emulated correctly.
+ */
+
+#pragma D option destructive
+#pragma D option quiet
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:test:
+{
+ printf("%s:%s\n", probefunc, probename);
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d.out
new file mode 100644
index 0000000..8559271
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.d.out
@@ -0,0 +1,23 @@
+test:entry
+test:0
+test:4
+test:8
+test:c
+test:10
+test:14
+test:18
+test:1c
+test:20
+test:24
+test:28
+test:2c
+test:30
+test:34
+test:38
+test:3c
+test:40
+test:44
+test:48
+test:4c
+test:return
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.s
new file mode 100644
index 0000000..dfa7d27
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.br.s
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .word 0
+
+ ENTRY(waiting)
+ retl
+ ldub [%o0], %o0
+ SET_SIZE(waiting)
+
+ ENTRY(test)
+ mov 1, %g1
+
+ brz %g1, 1f
+ nop
+ brlez %g1, 1f
+ nop
+ brlz %g0, 1f
+ nop
+ brlz %g1, 1f
+ nop
+ brnz %g0, 1f
+ sub %g0, 2, %g1
+ brgz %g1, 1f
+ nop
+ brgz %g0, 1f
+ nop
+ brgez %g1, 1f
+ nop
+
+ mov %g1, %o0
+
+1:
+ retl
+ nop
+ SET_SIZE(test)
+
+ ENTRY(main)
+ save %sp, -SA(MINFRAME + 4), %sp
+ stb %g0, [%fp - 4]
+1:
+ call waiting
+ sub %fp, 4, %o0
+ tst %o0
+ bz 1b
+ nop
+
+ call test
+ nop
+
+ ret
+ restore %g0, %g0, %o0
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.d
new file mode 100644
index 0000000..cfcf0a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.d
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:main:,
+pid$1:a.out:other:
+{
+}
+
+pid$1:a.out:bad:entry
+{
+ exit(1);
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.s
new file mode 100644
index 0000000..3e6531f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.branch.s
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .word 0
+
+ ENTRY(waiting)
+ retl
+ ldub [%o0], %o0
+ SET_SIZE(waiting)
+
+ ENTRY(main)
+ save %sp, -SA(MINFRAME + 4), %sp
+ stb %g0, [%fp - 4]
+1:
+ call waiting
+ sub %fp, 4, %o0
+ tst %o0
+ bz 1b
+ nop
+
+ restore
+
+ tst %g0
+ be other
+ nop
+
+ ALTENTRY(bad)
+ illtrap
+ SET_SIZE(bad)
+ SET_SIZE(main)
+
+ ENTRY(other)
+ retl
+ clr %o0
+ SET_SIZE(other)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.d
new file mode 100644
index 0000000..c484c3f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.d
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option destructive
+
+pid$1:a.out:waiting:entry
+{
+ this->a = (char *)alloca(1);
+ *this->a = 1;
+ copyout(this->a, arg0, 1);
+}
+
+pid$1:a.out:main:,
+pid$1:a.out:inner:
+{
+}
+
+syscall::rexit:entry
+/pid == $1/
+{
+ exit(0);
+}
+
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.s
new file mode 100644
index 0000000..612f0b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/tst.embedded.s
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .word 0
+
+ ENTRY(waiting)
+ retl
+ ldub [%o0], %o0
+ SET_SIZE(waiting)
+
+ ENTRY(main)
+ save %sp, -SA(MINFRAME + 4), %sp
+ stb %g0, [%fp - 4]
+1:
+ call waiting
+ sub %fp, 4, %o0
+ tst %o0
+ bz 1b
+ nop
+
+ restore
+
+ ALTENTRY(inner)
+ nop
+ nop
+ nop
+ SET_SIZE(inner)
+
+ retl
+ clr %o0
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh
new file mode 100644
index 0000000..c3651ec
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh
@@ -0,0 +1,132 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# ASSERTION: Make sure USDT probes work as tail-calls on SPARC.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.s <<EOF
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .word 0
+
+ ENTRY(test)
+ save %sp, -SA(MINFRAME + 4), %sp
+ mov 9, %i0
+ mov 19, %i1
+ mov 2006, %i2
+ call __dtrace_test___fire
+ restore
+ SET_SIZE(test)
+
+ ENTRY(main)
+ save %sp, -SA(MINFRAME + 4), %sp
+
+1:
+ call test
+ nop
+
+ ba 1b
+ nop
+
+ ret
+ restore %g0, %g0, %o0
+ SET_SIZE(main)
+EOF
+
+cat > prov.d <<EOF
+provider test {
+ probe fire(int, int, int);
+};
+EOF
+
+/usr/bin/as -xregsym=no -P -D_ASM -o test.o test.s
+if [ $? -ne 0 ]; then
+ print -u2 "failed to compile test.s"
+ exit 1
+fi
+
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to create DOF"
+ exit 1
+fi
+
+cc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+ print -u2 "failed to link final executable"
+ exit 1
+fi
+
+$dtrace -c ./test -s /dev/stdin <<EOF
+test\$target:::fire
+/arg0 == 9 && arg1 == 19 && arg2 == 2006/
+{
+ printf("%d/%d/%d", arg0, arg1, arg2);
+ exit(0);
+}
+
+test\$target:::fire
+{
+ printf("%d/%d/%d", arg0, arg1, arg2);
+ exit(1);
+}
+
+BEGIN
+{
+ /*
+ * Let's just do this for 5 seconds.
+ */
+ timeout = timestamp + 5000000000;
+}
+
+profile:::tick-4
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
+EOF
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/annotated_helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/annotated_helper.d
new file mode 100644
index 0000000..3577f86
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/annotated_helper.d
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ident "%Z%%M% %I% %E% SMI"
+
+dtrace:helper:ustack:
+{
+ "@it's annotated"
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/helper_helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/helper_helper.d
new file mode 100644
index 0000000..8abc47d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/helper_helper.d
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+dtrace:helper:ustack:
+{
+ "<it's working>"
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.c
new file mode 100644
index 0000000..8cdf8ab
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.c
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+int
+baz(void)
+{
+ return (8);
+}
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ baz();
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d
new file mode 100644
index 0000000..dd795be
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma D option quiet
+
+pid$1:a.out:baz:entry
+{
+ ustack(1, 1024);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d.out
new file mode 100644
index 0000000..806d6a2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.annotated.d.out
@@ -0,0 +1,4 @@
+
+ tst.annotated.exe`baz
+ [ it's annotated ]
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.d
new file mode 100644
index 0000000..78218bd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.d
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+syscall::getpid:entry
+/pid == $1/
+{
+ @[ustackdepth] = count();
+}
+
+ERROR
+/arg4 == DTRACEFLT_BADSTACK/
+{
+ exit(0);
+}
+
+profile:::tick-1s
+/++n == 10/
+{
+ exit(1)
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.s b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.s
new file mode 100644
index 0000000..a5076c9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.circstack.s
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/asm_linkage.h>
+
+ DGDEF(__fsr_init_value)
+ .word 0
+
+ ENTRY(main)
+ save %sp, -SA(MINFRAME), %sp
+ mov %sp, %fp
+loop:
+ call getpid
+ nop
+ ba loop
+ nop
+ ret
+ restore
+ SET_SIZE(main)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.c
new file mode 100644
index 0000000..fa4802a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.c
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <strings.h>
+
+int
+baz(void)
+{
+ return (8);
+}
+
+static int
+foo(void)
+{
+ /*
+ * In order to assure that our helper is properly employed to identify
+ * the frame, we're going to trampoline through data.
+ */
+ uint32_t instr[] = {
+ 0x9de3bfa0, /* save %sp, -0x60, %sp */
+ 0x40000000, /* call baz */
+ 0x01000000, /* nop */
+ 0x81c7e008, /* ret */
+ 0x81e80000 /* restore */
+ };
+ uint32_t *fp = malloc(sizeof (instr));
+
+ /*
+ * Do our little relocation dance.
+ */
+ instr[1] |= ((uintptr_t)baz - (uintptr_t)&fp[1]) >> 2;
+
+ /*
+ * Copy the code to the heap (it's a pain to build in ON with an
+ * executable stack).
+ */
+ bcopy(instr, fp, sizeof (instr));
+
+ (*(int (*)(void))fp)();
+
+ free(fp);
+
+ return (0);
+}
+
+int
+main(int argc, char **argv)
+{
+ for (;;) {
+ foo();
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d
new file mode 100644
index 0000000..ce2b9b3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION:
+ *
+ * SECTION:
+ *
+ * NOTES:
+ *
+ */
+
+#pragma D option quiet
+
+pid$1:a.out:baz:entry
+{
+ ustack(2, 1024);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d.out
new file mode 100644
index 0000000..2964628
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.helper.d.out
@@ -0,0 +1,4 @@
+
+ tst.helper.exe`baz
+ <it's working>
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.trapstat.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.trapstat.ksh
new file mode 100644
index 0000000..84af800
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/ustack/tst.trapstat.ksh
@@ -0,0 +1,87 @@
+#/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# This script verifies that user-land stacks can be walked safely
+# when the trapstat(1M) utility is running. An arbitrary program, w(1),
+# is started once a second to ensure stacks can be walked at all stages
+# of the process lifecycle.
+#
+
+script()
+{
+ $dtrace -o $dtraceout -s /dev/stdin <<EOF
+ fbt:::
+ {
+ @[ustackdepth] = count();
+ }
+EOF
+}
+
+run_commands()
+{
+ cnt=0
+
+ while [ $cnt -lt 10 ]; do
+ w > /dev/null
+ sleep 1
+ cnt=$(($cnt+1))
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+dtraceout=/tmp/dtrace.out.$$
+script 2>/dev/null &
+timeout=15
+
+#
+# Sleep while the above script fires into life. To guard against dtrace dying
+# and us sleeping forever we allow 15 secs for this to happen. This should be
+# enough for even the slowest systems.
+#
+while [ ! -f $dtraceout ]; do
+ sleep 1
+ timeout=$(($timeout-1))
+ if [ $timeout -eq 0 ]; then
+ echo "dtrace failed to start. Exiting."
+ exit 1
+ fi
+done
+
+run_commands &
+trapstat -t 1 10
+status=$?
+
+rm $dtraceout
+
+exit $status
diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1 b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1
new file mode 100644
index 0000000..f3fc8e6
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.1
@@ -0,0 +1,875 @@
+'\" te
+.\" CDDL HEADER START
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" CDDL HEADER END
+.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.TH lockstat 1M "28 Feb 2008" "SunOS 5.11" "System Administration Commands"
+.SH NAME
+lockstat \- report kernel lock and profiling statistics
+.SH SYNOPSIS
+.LP
+.nf
+\fBlockstat\fR [\fB-ACEHI\fR] [\fB-e\fR \fIevent_list\fR] [\fB-i\fR \fIrate\fR]
+ [\fB-b\fR | \fB-t\fR | \fB-h\fR | \fB-s\fR \fIdepth\fR] [\fB-n\fR \fInrecords\fR]
+ [\fB-l\fR \fIlock\fR [, \fIsize\fR]] [\fB-d\fR \fIduration\fR]
+ [\fB-f\fR \fIfunction\fR [, \fIsize\fR]] [\fB-T\fR] [\fB-ckgwWRpP\fR] [\fB-D\fR \fIcount\fR]
+ [\fB-o\fR \fIfilename\fR] [\fB-x\fR \fIopt\fR [=val]] \fIcommand\fR [\fIargs\fR]
+.fi
+
+.SH DESCRIPTION
+.sp
+.LP
+The \fBlockstat\fR utility gathers and displays kernel locking and profiling statistics. \fBlockstat\fR allows you to specify which events to watch (for example, spin on adaptive mutex, block on read access to rwlock due to waiting writers, and so forth) how much
+data to gather for each event, and how to display the data. By default, \fBlockstat\fR monitors all lock contention events, gathers frequency and timing data about those events, and displays the data in decreasing frequency order, so that the most common events appear first.
+.sp
+.LP
+\fBlockstat\fR gathers data until the specified command completes. For example, to gather statistics for a fixed-time interval, use \fBsleep\fR(1) as
+the command, as follows:
+.sp
+.LP
+\fBexample#\fR \fBlockstat\fR \fBsleep\fR \fB5\fR
+.sp
+.LP
+When the \fB-I\fR option is specified, \fBlockstat\fR establishes a per-processor high-level periodic interrupt source to gather profiling data. The interrupt handler simply generates a \fBlockstat\fR event whose caller is the interrupted PC (program counter).
+The profiling event is just like any other \fBlockstat\fR event, so all of the normal \fBlockstat\fR options are applicable.
+.sp
+.LP
+\fBlockstat\fR relies on DTrace to modify the running kernel's text to intercept events of interest. This imposes a small but measurable overhead on all system activity, so access to \fBlockstat\fR is restricted to super-user by default. The system administrator
+can permit other users to use \fBlockstat\fR by granting them additional DTrace privileges. Refer to the \fISolaris Dynamic Tracing Guide\fR for more information about DTrace security features.
+.SH OPTIONS
+.sp
+.LP
+The following options are supported:
+.SS "Event Selection"
+.sp
+.LP
+If no event selection options are specified, the default is \fB-C\fR.
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-A\fR\fR
+.ad
+.sp .6
+.RS 4n
+Watch all lock events. \fB-A\fR is equivalent to \fB-CH\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-C\fR\fR
+.ad
+.sp .6
+.RS 4n
+Watch contention events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-E\fR\fR
+.ad
+.sp .6
+.RS 4n
+Watch error events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-e\fR \fIevent_list\fR\fR
+.ad
+.sp .6
+.RS 4n
+Only watch the specified events. \fIevent\fR \fIlist\fR is a comma-separated list of events or ranges of events such as 1,4-7,35. Run \fBlockstat\fR with no arguments to get a brief description of all events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-H\fR\fR
+.ad
+.sp .6
+.RS 4n
+Watch hold events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-I\fR\fR
+.ad
+.sp .6
+.RS 4n
+Watch profiling interrupt events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-i\fR \fIrate\fR\fR
+.ad
+.sp .6
+.RS 4n
+Interrupt rate (per second) for \fB-I\fR. The default is 97 Hz, so that profiling doesn't run in lockstep with the clock interrupt (which runs at 100 Hz).
+.RE
+
+.SS "Data Gathering"
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-x\fR \fIarg\fR[=\fIval\fR]\fR
+.ad
+.sp .6
+.RS 4n
+Enable or modify a DTrace runtime option or D compiler option. The list of options is found in the \fI\fR. Boolean options are enabled by specifying their name. Options with values are set by separating the option name and
+value with an equals sign (=).
+.RE
+
+.SS "Data Gathering (Mutually Exclusive)"
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-b\fR\fR
+.ad
+.sp .6
+.RS 4n
+Basic statistics: lock, caller, number of events.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-h\fR\fR
+.ad
+.sp .6
+.RS 4n
+Histogram: Timing plus time-distribution histograms.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-s\fR \fIdepth\fR\fR
+.ad
+.sp .6
+.RS 4n
+Stack trace: Histogram plus stack traces up to \fIdepth\fR frames deep.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-t\fR\fR
+.ad
+.sp .6
+.RS 4n
+Timing: Basic plus timing for all events [default].
+.RE
+
+.SS "Data Filtering"
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-d\fR \fIduration\fR\fR
+.ad
+.sp .6
+.RS 4n
+Only watch events longer than \fIduration\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-f\fR \fIfunc[,size]\fR\fR
+.ad
+.sp .6
+.RS 4n
+Only watch events generated by \fIfunc\fR, which can be specified as a symbolic name or hex address. \fIsize\fR defaults to the \fBELF\fR symbol size if available, or \fB1\fR if not.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-l\fR \fIlock[,size]\fR\fR
+.ad
+.sp .6
+.RS 4n
+Only watch \fIlock\fR, which can be specified as a symbolic name or hex address. \fBsize\fR defaults to the \fBELF\fR symbol size or \fB1\fR if the symbol size is not available.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-n\fR \fInrecords\fR\fR
+.ad
+.sp .6
+.RS 4n
+Maximum number of data records.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-T\fR\fR
+.ad
+.sp .6
+.RS 4n
+Trace (rather than sample) events [off by default].
+.RE
+
+.SS "Data Reporting"
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-c\fR\fR
+.ad
+.sp .6
+.RS 4n
+Coalesce lock data for lock arrays (for example, \fBpse_mutex[]\fR).
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-D\fR \fIcount\fR\fR
+.ad
+.sp .6
+.RS 4n
+Only display the top \fIcount\fR events of each type.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-g\fR\fR
+.ad
+.sp .6
+.RS 4n
+Show total events generated by function. For example, if \fBfoo()\fR calls \fBbar()\fR in a loop, the work done by \fBbar()\fR counts as work generated by \fBfoo()\fR (along with any work done by \fBfoo()\fR itself).
+The \fB-g\fR option works by counting the total number of stack frames in which each function appears. This implies two things: (1) the data reported by \fB-g\fR can be misleading if the stack traces are not deep enough, and (2) functions that are called recursively might show
+greater than 100% activity. In light of issue (1), the default data gathering mode when using \fB-g\fR is \fB-s\fR \fB50\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-k\fR\fR
+.ad
+.sp .6
+.RS 4n
+Coalesce PCs within functions.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB\fR\fB-o\fR \fIfilename\fR\fR
+.ad
+.sp .6
+.RS 4n
+Direct output to \fIfilename\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-P\fR\fR
+.ad
+.sp .6
+.RS 4n
+Sort data by (\fIcount * time\fR) product.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-p\fR\fR
+.ad
+.sp .6
+.RS 4n
+Parsable output format.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-R\fR\fR
+.ad
+.sp .6
+.RS 4n
+Display rates (events per second) rather than counts.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-W\fR\fR
+.ad
+.sp .6
+.RS 4n
+Whichever: distinguish events only by caller, not by lock.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-w\fR\fR
+.ad
+.sp .6
+.RS 4n
+Wherever: distinguish events only by lock, not by caller.
+.RE
+
+.SH DISPLAY FORMATS
+.sp
+.LP
+The following headers appear over various columns of data.
+.sp
+.ne 2
+.mk
+.na
+\fB\fBCount\fR or \fBops/s\fR\fR
+.ad
+.sp .6
+.RS 4n
+Number of times this event occurred, or the rate (times per second) if \fB-R\fR was specified.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBindv\fR\fR
+.ad
+.sp .6
+.RS 4n
+Percentage of all events represented by this individual event.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBgenr\fR\fR
+.ad
+.sp .6
+.RS 4n
+Percentage of all events generated by this function.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBcuml\fR\fR
+.ad
+.sp .6
+.RS 4n
+Cumulative percentage; a running total of the individuals.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBrcnt\fR\fR
+.ad
+.sp .6
+.RS 4n
+Average reference count. This will always be \fB1\fR for exclusive locks (mutexes, spin locks, rwlocks held as writer) but can be greater than \fB1\fR for shared locks (rwlocks held as reader).
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBnsec\fR\fR
+.ad
+.sp .6
+.RS 4n
+Average duration of the events in nanoseconds, as appropriate for the event. For the profiling event, duration means interrupt latency.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBLock\fR\fR
+.ad
+.sp .6
+.RS 4n
+Address of the lock; displayed symbolically if possible.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBCPU+PIL\fR\fR
+.ad
+.sp .6
+.RS 4n
+\fBCPU\fR plus processor interrupt level (\fBPIL\fR). For example, if \fBCPU\fR 4 is interrupted while at \fBPIL\fR 6, this will be reported as \fBcpu[4]+6\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBCaller\fR\fR
+.ad
+.sp .6
+.RS 4n
+Address of the caller; displayed symbolically if possible.
+.RE
+
+.SH EXAMPLES
+.LP
+\fBExample 1 \fRMeasuring Kernel Lock Contention
+.sp
+.in +2
+.nf
+example# \fBlockstat sleep 5\fR
+Adaptive mutex spin: 2210 events in 5.055 seconds (437 events/sec)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+Count indv cuml rcnt nsec Lock Caller
+------------------------------------------------------------------------
+ 269 12% 12% 1.00 2160 service_queue background+0xdc
+ 249 11% 23% 1.00 86 service_queue qenable_locked+0x64
+ 228 10% 34% 1.00 131 service_queue background+0x15c
+ 68 3% 37% 1.00 79 0x30000024070 untimeout+0x1c
+ 59 3% 40% 1.00 384 0x300066fa8e0 background+0xb0
+ 43 2% 41% 1.00 30 rqcred_lock svc_getreq+0x3c
+ 42 2% 43% 1.00 341 0x30006834eb8 background+0xb0
+ 41 2% 45% 1.00 135 0x30000021058 untimeout+0x1c
+ 40 2% 47% 1.00 39 rqcred_lock svc_getreq+0x260
+ 37 2% 49% 1.00 2372 0x300068e83d0 hmestart+0x1c4
+ 36 2% 50% 1.00 77 0x30000021058 timeout_common+0x4
+ 36 2% 52% 1.00 354 0x300066fa120 background+0xb0
+ 32 1% 53% 1.00 97 0x30000024070 timeout_common+0x4
+ 31 1% 55% 1.00 2923 0x300069883d0 hmestart+0x1c4
+ 29 1% 56% 1.00 366 0x300066fb290 background+0xb0
+ 28 1% 57% 1.00 117 0x3000001e040 untimeout+0x1c
+ 25 1% 59% 1.00 93 0x3000001e040 timeout_common+0x4
+ 22 1% 60% 1.00 25 0x30005161110 sync_stream_buf+0xdc
+ 21 1% 60% 1.00 291 0x30006834eb8 putq+0xa4
+ 19 1% 61% 1.00 43 0x3000515dcb0 mdf_alloc+0xc
+ 18 1% 62% 1.00 456 0x30006834eb8 qenable+0x8
+ 18 1% 63% 1.00 61 service_queue queuerun+0x168
+ 17 1% 64% 1.00 268 0x30005418ee8 vmem_free+0x3c
+[...]
+
+R/W reader blocked by writer: 76 events in 5.055 seconds (15 events/sec)
+
+Count indv cuml rcnt nsec Lock Caller
+------------------------------------------------------------------------
+ 23 30% 30% 1.00 22590137 0x300098ba358 ufs_dirlook+0xd0
+ 17 22% 53% 1.00 5820995 0x3000ad815e8 find_bp+0x10
+ 13 17% 70% 1.00 2639918 0x300098ba360 ufs_iget+0x198
+ 4 5% 75% 1.00 3193015 0x300098ba360 ufs_getattr+0x54
+ 3 4% 79% 1.00 7953418 0x3000ad817c0 find_bp+0x10
+ 3 4% 83% 1.00 935211 0x3000ad815e8 find_read_lof+0x14
+ 2 3% 86% 1.00 16357310 0x300073a4720 find_bp+0x10
+ 2 3% 88% 1.00 2072433 0x300073a4720 find_read_lof+0x14
+ 2 3% 91% 1.00 1606153 0x300073a4370 find_bp+0x10
+ 1 1% 92% 1.00 2656909 0x300107e7400 ufs_iget+0x198
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 2 \fRMeasuring Hold Times
+.sp
+.in +2
+.nf
+example# \fBlockstat -H -D 10 sleep 1\fR
+Adaptive mutex spin: 513 events
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+Count indv cuml rcnt nsec Lock Caller
+-------------------------------------------------------------------------
+ 480 5% 5% 1.00 1136 0x300007718e8 putnext+0x40
+ 286 3% 9% 1.00 666 0x3000077b430 getf+0xd8
+ 271 3% 12% 1.00 537 0x3000077b430 msgio32+0x2fc
+ 270 3% 15% 1.00 3670 0x300007718e8 strgetmsg+0x3d4
+ 270 3% 18% 1.00 1016 0x300007c38b0 getq_noenab+0x200
+ 264 3% 20% 1.00 1649 0x300007718e8 strgetmsg+0xa70
+ 216 2% 23% 1.00 6251 tcp_mi_lock tcp_snmp_get+0xfc
+ 206 2% 25% 1.00 602 thread_free_lock clock+0x250
+ 138 2% 27% 1.00 485 0x300007c3998 putnext+0xb8
+ 138 2% 28% 1.00 3706 0x300007718e8 strrput+0x5b8
+-------------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 3 \fRMeasuring Hold Times for Stack Traces Containing a Specific Function
+.sp
+.in +2
+.nf
+example# \fBlockstat -H -f tcp_rput_data -s 50 -D 10 sleep 1\fR
+Adaptive mutex spin: 11 events in 1.023 seconds (11
+events/sec)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+-------------------------------------------------------------------------
+Count indv cuml rcnt nsec Lock Caller
+ 9 82% 82% 1.00 2540 0x30000031380 tcp_rput_data+0x2b90
+
+ nsec ------ Time Distribution ------ count Stack
+ 256 |@@@@@@@@@@@@@@@@ 5 tcp_rput_data+0x2b90
+ 512 |@@@@@@ 2 putnext+0x78
+ 1024 |@@@ 1 ip_rput+0xec4
+ 2048 | 0 _c_putnext+0x148
+ 4096 | 0 hmeread+0x31c
+ 8192 | 0 hmeintr+0x36c
+ 16384 |@@@ 1
+sbus_intr_wrapper+0x30
+[...]
+
+Count indv cuml rcnt nsec Lock Caller
+ 1 9% 91% 1.00 1036 0x30000055380 freemsg+0x44
+
+ nsec ------ Time Distribution ------ count Stack
+ 1024 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 freemsg+0x44
+ tcp_rput_data+0x2fd0
+ putnext+0x78
+ ip_rput+0xec4
+ _c_putnext+0x148
+ hmeread+0x31c
+ hmeintr+0x36c
+
+sbus_intr_wrapper+0x30
+-------------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 4 \fRBasic Kernel Profiling
+.sp
+.LP
+For basic profiling, we don't care whether the profiling interrupt sampled \fBfoo()\fR\fB+0x4c\fR or \fBfoo()\fR\fB+0x78\fR; we care only that it sampled somewhere in \fBfoo()\fR, so we use \fB-k\fR. The \fBCPU\fR and \fBPIL\fR aren't relevant to basic profiling because we are measuring the system as a whole, not a particular \fBCPU\fR or interrupt level, so we use \fB-W\fR.
+
+.sp
+.in +2
+.nf
+example# \fBlockstat -kIW -D 20 ./polltest\fR
+Profiling interrupt: 82 events in 0.424 seconds (194
+events/sec)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+Count indv cuml rcnt nsec Hottest CPU+PIL Caller
+-----------------------------------------------------------------------
+ 8 10% 10% 1.00 698 cpu[1] utl0
+ 6 7% 17% 1.00 299 cpu[0] read
+ 5 6% 23% 1.00 124 cpu[1] getf
+ 4 5% 28% 1.00 327 cpu[0] fifo_read
+ 4 5% 33% 1.00 112 cpu[1] poll
+ 4 5% 38% 1.00 212 cpu[1] uiomove
+ 4 5% 43% 1.00 361 cpu[1] mutex_tryenter
+ 3 4% 46% 1.00 682 cpu[0] write
+ 3 4% 50% 1.00 89 cpu[0] pcache_poll
+ 3 4% 54% 1.00 118 cpu[1] set_active_fd
+ 3 4% 57% 1.00 105 cpu[0] syscall_trap32
+ 3 4% 61% 1.00 640 cpu[1] (usermode)
+ 2 2% 63% 1.00 127 cpu[1] fifo_poll
+ 2 2% 66% 1.00 300 cpu[1] fifo_write
+ 2 2% 68% 1.00 669 cpu[0] releasef
+ 2 2% 71% 1.00 112 cpu[1] bt_getlowbit
+ 2 2% 73% 1.00 247 cpu[1] splx
+ 2 2% 76% 1.00 503 cpu[0] mutex_enter
+ 2 2% 78% 1.00 467 cpu[0]+10 disp_lock_enter
+ 2 2% 80% 1.00 139 cpu[1] default_copyin
+-----------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 5 \fRGenerated-load Profiling
+.sp
+.LP
+In the example above, 5% of the samples were in \fBpoll()\fR. This tells us how much time was spent inside \fBpoll()\fR itself, but tells us nothing about how much work was \fBgenerated\fR by \fBpoll()\fR; that is, how much time we spent
+in functions called by \fBpoll()\fR. To determine that, we use the \fB-g\fR option. The example below shows that although \fBpolltest\fR spends only 5% of its time in \fBpoll()\fR itself, \fBpoll()\fR-induced work accounts for 34% of
+the load.
+
+.sp
+.LP
+Note that the functions that generate the profiling interrupt (\fBlockstat_intr()\fR, \fBcyclic_fire()\fR, and so forth) appear in every stack trace, and therefore are considered to have generated 100% of the load. This illustrates an important point: the generated
+load percentages do \fBnot\fR add up to 100% because they are not independent. If 72% of all stack traces contain both \fBfoo()\fR and \fBbar()\fR, then both \fBfoo()\fR and \fBbar()\fR are 72% load generators.
+
+.sp
+.in +2
+.nf
+example# \fBlockstat -kgIW -D 20 ./polltest\fR
+Profiling interrupt: 80 events in 0.412 seconds (194 events/sec)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+Count genr cuml rcnt nsec Hottest CPU+PIL Caller
+-------------------------------------------------------------------------
+ 80 100% ---- 1.00 310 cpu[1] lockstat_intr
+ 80 100% ---- 1.00 310 cpu[1] cyclic_fire
+ 80 100% ---- 1.00 310 cpu[1] cbe_level14
+ 80 100% ---- 1.00 310 cpu[1] current_thread
+ 27 34% ---- 1.00 176 cpu[1] poll
+ 20 25% ---- 1.00 221 cpu[0] write
+ 19 24% ---- 1.00 249 cpu[1] read
+ 17 21% ---- 1.00 232 cpu[0] write32
+ 17 21% ---- 1.00 207 cpu[1] pcache_poll
+ 14 18% ---- 1.00 319 cpu[0] fifo_write
+ 13 16% ---- 1.00 214 cpu[1] read32
+ 10 12% ---- 1.00 208 cpu[1] fifo_read
+ 10 12% ---- 1.00 787 cpu[1] utl0
+ 9 11% ---- 1.00 178 cpu[0] pcacheset_resolve
+ 9 11% ---- 1.00 262 cpu[0] uiomove
+ 7 9% ---- 1.00 506 cpu[1] (usermode)
+ 5 6% ---- 1.00 195 cpu[1] fifo_poll
+ 5 6% ---- 1.00 136 cpu[1] syscall_trap32
+ 4 5% ---- 1.00 139 cpu[0] releasef
+ 3 4% ---- 1.00 277 cpu[1] polllock
+-------------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 6 \fRGathering Lock Contention and Profiling Data for a Specific Module
+.sp
+.LP
+In this example we use the \fB-f\fR option not to specify a single function, but rather to specify the entire text space of the \fBsbus\fR module. We gather both lock contention and profiling statistics so that contention can be correlated with overall load on the
+module.
+
+.sp
+.in +2
+.nf
+example# \fBmodinfo | grep sbus\fR
+24 102a8b6f b8b4 59 1 sbus (SBus (sysio) nexus driver)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+example# \fBlockstat -kICE -f 0x102a8b6f,0xb8b4 sleep 10\fR
+Adaptive mutex spin: 39 events in 10.042 seconds (4 events/sec)
+.fi
+.in -2
+.sp
+
+.sp
+.in +2
+.nf
+Count indv cuml rcnt nsec Lock Caller
+-------------------------------------------------------------------------
+ 15 38% 38% 1.00 206 0x30005160528 sync_stream_buf
+ 7 18% 56% 1.00 14 0x30005160d18 sync_stream_buf
+ 6 15% 72% 1.00 27 0x300060c3118 sync_stream_buf
+ 5 13% 85% 1.00 24 0x300060c3510 sync_stream_buf
+ 2 5% 90% 1.00 29 0x300060c2d20 sync_stream_buf
+ 2 5% 95% 1.00 24 0x30005161cf8 sync_stream_buf
+ 1 3% 97% 1.00 21 0x30005161110 sync_stream_buf
+ 1 3% 100% 1.00 23 0x30005160130 sync_stream_buf
+[...]
+
+Adaptive mutex block: 9 events in 10.042 seconds (1 events/sec)
+
+Count indv cuml rcnt nsec Lock Caller
+-------------------------------------------------------------------------
+ 4 44% 44% 1.00 156539 0x30005160528 sync_stream_buf
+ 2 22% 67% 1.00 763516 0x30005160d18 sync_stream_buf
+ 1 11% 78% 1.00 462130 0x300060c3510 sync_stream_buf
+ 1 11% 89% 1.00 288749 0x30005161110 sync_stream_buf
+ 1 11% 100% 1.00 1015374 0x30005160130 sync_stream_buf
+[...]
+
+Profiling interrupt: 229 events in 10.042 seconds (23 events/sec)
+
+Count indv cuml rcnt nsec Hottest CPU+PIL Caller
+
+-------------------------------------------------------------------------
+ 89 39% 39% 1.00 426 cpu[0]+6 sync_stream_buf
+ 64 28% 67% 1.00 398 cpu[0]+6 sbus_intr_wrapper
+ 23 10% 77% 1.00 324 cpu[0]+6 iommu_dvma_kaddr_load
+ 21 9% 86% 1.00 512 cpu[0]+6 iommu_tlb_flush
+ 14 6% 92% 1.00 342 cpu[0]+6 iommu_dvma_unload
+ 13 6% 98% 1.00 306 cpu[1] iommu_dvma_sync
+ 5 2% 100% 1.00 389 cpu[1] iommu_dma_bindhdl
+-------------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 7 \fRDetermining the Average PIL (processor interrupt level) for a CPU
+.sp
+.in +2
+.nf
+example# \fBlockstat -Iw -l cpu[3] ./testprog\fR
+
+Profiling interrupt: 14791 events in 152.463 seconds (97 events/sec)
+
+Count indv cuml rcnt nsec CPU+PIL Hottest Caller
+
+-----------------------------------------------------------------------
+13641 92% 92% 1.00 253 cpu[3] (usermode)
+ 579 4% 96% 1.00 325 cpu[3]+6 ip_ocsum+0xe8
+ 375 3% 99% 1.00 411 cpu[3]+10 splx
+ 154 1% 100% 1.00 527 cpu[3]+4 fas_intr_svc+0x80
+ 41 0% 100% 1.00 293 cpu[3]+13 send_mondo+0x18
+ 1 0% 100% 1.00 266 cpu[3]+12 zsa_rxint+0x400
+-----------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.LP
+\fBExample 8 \fRDetermining which Subsystem is Causing the System to be Busy
+.sp
+.in +2
+.nf
+example# \fBlockstat -s 10 -I sleep 20\fR
+
+Profiling interrupt: 4863 events in 47.375 seconds (103 events/sec)
+
+Count indv cuml rcnt nsec CPU+PIL Caller
+
+-----------------------------------------------------------------------
+1929 40% 40% 0.00 3215 cpu[0] usec_delay+0x78
+ nsec ------ Time Distribution ------ count Stack
+ 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1872 ata_wait+0x90
+ 8192 | 27 acersb_get_intr_status+0x34
+16384 | 29 ata_set_feature+0x124
+32768 | 1 ata_disk_start+0x15c
+ ata_hba_start+0xbc
+ ghd_waitq_process_and \e
+ _mutex_hold+0x70
+ ghd_waitq_process_and \e
+ _mutex_exit+0x4
+ ghd_transport+0x12c
+ ata_disk_tran_start+0x108
+-----------------------------------------------------------------------
+[...]
+.fi
+.in -2
+.sp
+
+.SH ATTRIBUTES
+.sp
+.LP
+See \fBattributes\fR(5) for descriptions of the following attributes:
+.sp
+
+.sp
+.TS
+tab() box;
+cw(2.75i) |cw(2.75i)
+lw(2.75i) |lw(2.75i)
+.
+ATTRIBUTE TYPEATTRIBUTE VALUE
+_
+AvailabilitySUNWdtrc
+.TE
+
+.SH SEE ALSO
+.sp
+.LP
+\fBdtrace\fR(1M), \fBplockstat\fR(1M), \fBattributes\fR(5), \fBlockstat\fR(7D), \fBmutex\fR(9F), \fBrwlock\fR(9F)
+.sp
+.LP
+\fISolaris Dynamic Tracing Guide\fR
+.SH NOTES
+.sp
+.LP
+The profiling support provided by \fBlockstat\fR \fB-I\fR replaces the old (and undocumented) \fB/usr/bin/kgmon\fR and \fB/dev/profile\fR.
+.sp
+.LP
+Tail-call elimination can affect call sites. For example, if \fBfoo()\fR\fB+0x50\fR calls \fBbar()\fR and the last thing \fBbar()\fR does is call \fBmutex_exit()\fR, the compiler can arrange for \fBbar()\fR to
+branch to \fBmutex_exit()\fRwith a return address of \fBfoo()\fR\fB+0x58\fR. Thus, the \fBmutex_exit()\fR in \fBbar()\fR will appear as though it occurred at \fBfoo()\fR\fB+0x58\fR.
+.sp
+.LP
+The \fBPC\fR in the stack frame in which an interrupt occurs can be bogus because, between function calls, the compiler is free to use the return address register for local storage.
+.sp
+.LP
+When using the \fB-I\fR and \fB-s\fR options together, the interrupted PC will usually not appear anywhere in the stack since the interrupt handler is entered asynchronously, not by a function call from that \fBPC\fR.
+.sp
+.LP
+The \fBlockstat\fR technology is provided on an as-is basis. The format and content of \fBlockstat\fR output reflect the current Solaris kernel implementation and are therefore subject to change in future releases.
diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
new file mode 100644
index 0000000..0a609d7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
@@ -0,0 +1,1921 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/modctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <dtrace.h>
+#include <sys/lockstat.h>
+#include <alloca.h>
+#include <signal.h>
+#include <assert.h>
+
+#if defined(sun)
+#define GETOPT_EOF EOF
+#else
+/* FreeBSD */
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#define mergesort(a, b, c, d) lsmergesort(a, b, c, d)
+#define GETOPT_EOF (-1)
+
+typedef uintptr_t pc_t;
+#endif /* defined(sun) */
+
+#define LOCKSTAT_OPTSTR "x:bths:n:d:i:l:f:e:ckwWgCHEATID:RpPo:V"
+
+#define LS_MAX_STACK_DEPTH 50
+#define LS_MAX_EVENTS 64
+
+typedef struct lsrec {
+ struct lsrec *ls_next; /* next in hash chain */
+ uintptr_t ls_lock; /* lock address */
+ uintptr_t ls_caller; /* caller address */
+ uint32_t ls_count; /* cumulative event count */
+ uint32_t ls_event; /* type of event */
+ uintptr_t ls_refcnt; /* cumulative reference count */
+ uint64_t ls_time; /* cumulative event duration */
+ uint32_t ls_hist[64]; /* log2(duration) histogram */
+ uintptr_t ls_stack[LS_MAX_STACK_DEPTH];
+} lsrec_t;
+
+typedef struct lsdata {
+ struct lsrec *lsd_next; /* next available */
+ int lsd_count; /* number of records */
+} lsdata_t;
+
+/*
+ * Definitions for the types of experiments which can be run. They are
+ * listed in increasing order of memory cost and processing time cost.
+ * The numerical value of each type is the number of bytes needed per record.
+ */
+#define LS_BASIC offsetof(lsrec_t, ls_time)
+#define LS_TIME offsetof(lsrec_t, ls_hist[0])
+#define LS_HIST offsetof(lsrec_t, ls_stack[0])
+#define LS_STACK(depth) offsetof(lsrec_t, ls_stack[depth])
+
+static void report_stats(FILE *, lsrec_t **, size_t, uint64_t, uint64_t);
+static void report_trace(FILE *, lsrec_t **);
+
+extern int symtab_init(void);
+extern char *addr_to_sym(uintptr_t, uintptr_t *, size_t *);
+extern uintptr_t sym_to_addr(char *name);
+extern size_t sym_size(char *name);
+extern char *strtok_r(char *, const char *, char **);
+
+#define DEFAULT_NRECS 10000
+#define DEFAULT_HZ 97
+#define MAX_HZ 1000
+#define MIN_AGGSIZE (16 * 1024)
+#define MAX_AGGSIZE (32 * 1024 * 1024)
+
+static int g_stkdepth;
+static int g_topn = INT_MAX;
+static hrtime_t g_elapsed;
+static int g_rates = 0;
+static int g_pflag = 0;
+static int g_Pflag = 0;
+static int g_wflag = 0;
+static int g_Wflag = 0;
+static int g_cflag = 0;
+static int g_kflag = 0;
+static int g_gflag = 0;
+static int g_Vflag = 0;
+static int g_tracing = 0;
+static size_t g_recsize;
+static size_t g_nrecs;
+static int g_nrecs_used;
+static uchar_t g_enabled[LS_MAX_EVENTS];
+static hrtime_t g_min_duration[LS_MAX_EVENTS];
+static dtrace_hdl_t *g_dtp;
+static char *g_predicate;
+static char *g_ipredicate;
+static char *g_prog;
+static int g_proglen;
+static int g_dropped;
+
+typedef struct ls_event_info {
+ char ev_type;
+ char ev_lhdr[20];
+ char ev_desc[80];
+ char ev_units[10];
+ char ev_name[DTRACE_NAMELEN];
+ char *ev_predicate;
+ char *ev_acquire;
+} ls_event_info_t;
+
+static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
+ { 'C', "Lock", "Adaptive mutex spin", "nsec",
+ "lockstat:::adaptive-spin" },
+ { 'C', "Lock", "Adaptive mutex block", "nsec",
+ "lockstat:::adaptive-block" },
+ { 'C', "Lock", "Spin lock spin", "nsec",
+ "lockstat:::spin-spin" },
+ { 'C', "Lock", "Thread lock spin", "nsec",
+ "lockstat:::thread-spin" },
+ { 'C', "Lock", "R/W writer blocked by writer", "nsec",
+ "lockstat:::rw-block", "arg2 == 0 && arg3 == 1" },
+ { 'C', "Lock", "R/W writer blocked by readers", "nsec",
+ "lockstat:::rw-block", "arg2 == 0 && arg3 == 0 && arg4" },
+ { 'C', "Lock", "R/W reader blocked by writer", "nsec",
+ "lockstat:::rw-block", "arg2 != 0 && arg3 == 1" },
+ { 'C', "Lock", "R/W reader blocked by write wanted", "nsec",
+ "lockstat:::rw-block", "arg2 != 0 && arg3 == 0 && arg4" },
+ { 'C', "Lock", "Unknown event (type 8)", "units" },
+ { 'C', "Lock", "Unknown event (type 9)", "units" },
+ { 'C', "Lock", "Unknown event (type 10)", "units" },
+ { 'C', "Lock", "Unknown event (type 11)", "units" },
+ { 'C', "Lock", "Unknown event (type 12)", "units" },
+ { 'C', "Lock", "Unknown event (type 13)", "units" },
+ { 'C', "Lock", "Unknown event (type 14)", "units" },
+ { 'C', "Lock", "Unknown event (type 15)", "units" },
+ { 'C', "Lock", "Unknown event (type 16)", "units" },
+ { 'C', "Lock", "Unknown event (type 17)", "units" },
+ { 'C', "Lock", "Unknown event (type 18)", "units" },
+ { 'C', "Lock", "Unknown event (type 19)", "units" },
+ { 'C', "Lock", "Unknown event (type 20)", "units" },
+ { 'C', "Lock", "Unknown event (type 21)", "units" },
+ { 'C', "Lock", "Unknown event (type 22)", "units" },
+ { 'C', "Lock", "Unknown event (type 23)", "units" },
+ { 'C', "Lock", "Unknown event (type 24)", "units" },
+ { 'C', "Lock", "Unknown event (type 25)", "units" },
+ { 'C', "Lock", "Unknown event (type 26)", "units" },
+ { 'C', "Lock", "Unknown event (type 27)", "units" },
+ { 'C', "Lock", "Unknown event (type 28)", "units" },
+ { 'C', "Lock", "Unknown event (type 29)", "units" },
+ { 'C', "Lock", "Unknown event (type 30)", "units" },
+ { 'C', "Lock", "Unknown event (type 31)", "units" },
+ { 'H', "Lock", "Adaptive mutex hold", "nsec",
+ "lockstat:::adaptive-release", NULL,
+ "lockstat:::adaptive-acquire" },
+ { 'H', "Lock", "Spin lock hold", "nsec",
+ "lockstat:::spin-release", NULL,
+ "lockstat:::spin-acquire" },
+ { 'H', "Lock", "R/W writer hold", "nsec",
+ "lockstat:::rw-release", "arg1 == 0",
+ "lockstat:::rw-acquire" },
+ { 'H', "Lock", "R/W reader hold", "nsec",
+ "lockstat:::rw-release", "arg1 != 0",
+ "lockstat:::rw-acquire" },
+ { 'H', "Lock", "Unknown event (type 36)", "units" },
+ { 'H', "Lock", "Unknown event (type 37)", "units" },
+ { 'H', "Lock", "Unknown event (type 38)", "units" },
+ { 'H', "Lock", "Unknown event (type 39)", "units" },
+ { 'H', "Lock", "Unknown event (type 40)", "units" },
+ { 'H', "Lock", "Unknown event (type 41)", "units" },
+ { 'H', "Lock", "Unknown event (type 42)", "units" },
+ { 'H', "Lock", "Unknown event (type 43)", "units" },
+ { 'H', "Lock", "Unknown event (type 44)", "units" },
+ { 'H', "Lock", "Unknown event (type 45)", "units" },
+ { 'H', "Lock", "Unknown event (type 46)", "units" },
+ { 'H', "Lock", "Unknown event (type 47)", "units" },
+ { 'H', "Lock", "Unknown event (type 48)", "units" },
+ { 'H', "Lock", "Unknown event (type 49)", "units" },
+ { 'H', "Lock", "Unknown event (type 50)", "units" },
+ { 'H', "Lock", "Unknown event (type 51)", "units" },
+ { 'H', "Lock", "Unknown event (type 52)", "units" },
+ { 'H', "Lock", "Unknown event (type 53)", "units" },
+ { 'H', "Lock", "Unknown event (type 54)", "units" },
+ { 'H', "Lock", "Unknown event (type 55)", "units" },
+#if defined(sun)
+ { 'I', "CPU+PIL", "Profiling interrupt", "nsec",
+#else
+ /* FreeBSD */
+ { 'I', "CPU+Pri_Class", "Profiling interrupt", "nsec",
+#endif
+ "profile:::profile-97", NULL },
+ { 'I', "Lock", "Unknown event (type 57)", "units" },
+ { 'I', "Lock", "Unknown event (type 58)", "units" },
+ { 'I', "Lock", "Unknown event (type 59)", "units" },
+ { 'E', "Lock", "Recursive lock entry detected", "(N/A)",
+ "lockstat:::rw-release", NULL, "lockstat:::rw-acquire" },
+ { 'E', "Lock", "Lockstat enter failure", "(N/A)" },
+ { 'E', "Lock", "Lockstat exit failure", "nsec" },
+ { 'E', "Lock", "Lockstat record failure", "(N/A)" },
+};
+
+#if !defined(sun)
+static char *g_pri_class[] = {
+ "",
+ "Intr",
+ "RealT",
+ "TShar",
+ "Idle"
+};
+#endif
+
+static void
+fail(int do_perror, const char *message, ...)
+{
+ va_list args;
+ int save_errno = errno;
+
+ va_start(args, message);
+ (void) fprintf(stderr, "lockstat: ");
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ if (do_perror)
+ (void) fprintf(stderr, ": %s", strerror(save_errno));
+ (void) fprintf(stderr, "\n");
+ exit(2);
+}
+
+static void
+dfail(const char *message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+ (void) fprintf(stderr, "lockstat: ");
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ (void) fprintf(stderr, ": %s\n",
+ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
+
+ exit(2);
+}
+
+static void
+show_events(char event_type, char *desc)
+{
+ int i, first = -1, last;
+
+ for (i = 0; i < LS_MAX_EVENTS; i++) {
+ ls_event_info_t *evp = &g_event_info[i];
+ if (evp->ev_type != event_type ||
+ strncmp(evp->ev_desc, "Unknown event", 13) == 0)
+ continue;
+ if (first == -1)
+ first = i;
+ last = i;
+ }
+
+ (void) fprintf(stderr,
+ "\n%s events (lockstat -%c or lockstat -e %d-%d):\n\n",
+ desc, event_type, first, last);
+
+ for (i = first; i <= last; i++)
+ (void) fprintf(stderr,
+ "%4d = %s\n", i, g_event_info[i].ev_desc);
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "Usage: lockstat [options] command [args]\n"
+ "\nEvent selection options:\n\n"
+ " -C watch contention events [on by default]\n"
+ " -E watch error events [off by default]\n"
+ " -H watch hold events [off by default]\n"
+ " -I watch interrupt events [off by default]\n"
+ " -A watch all lock events [equivalent to -CH]\n"
+ " -e event_list only watch the specified events (shown below);\n"
+ " <event_list> is a comma-separated list of\n"
+ " events or ranges of events, e.g. 1,4-7,35\n"
+ " -i rate interrupt rate for -I [default: %d Hz]\n"
+ "\nData gathering options:\n\n"
+ " -b basic statistics (lock, caller, event count)\n"
+ " -t timing for all events [default]\n"
+ " -h histograms for event times\n"
+ " -s depth stack traces <depth> deep\n"
+ " -x opt[=val] enable or modify DTrace options\n"
+ "\nData filtering options:\n\n"
+ " -n nrecords maximum number of data records [default: %d]\n"
+ " -l lock[,size] only watch <lock>, which can be specified as a\n"
+ " symbolic name or hex address; <size> defaults\n"
+ " to the ELF symbol size if available, 1 if not\n"
+ " -f func[,size] only watch events generated by <func>\n"
+ " -d duration only watch events longer than <duration>\n"
+ " -T trace (rather than sample) events\n"
+ "\nData reporting options:\n\n"
+ " -c coalesce lock data for arrays like pse_mutex[]\n"
+ " -k coalesce PCs within functions\n"
+ " -g show total events generated by function\n"
+ " -w wherever: don't distinguish events by caller\n"
+ " -W whichever: don't distinguish events by lock\n"
+ " -R display rates rather than counts\n"
+ " -p parsable output format (awk(1)-friendly)\n"
+ " -P sort lock data by (count * avg_time) product\n"
+ " -D n only display top <n> events of each type\n"
+ " -o filename send output to <filename>\n",
+ DEFAULT_HZ, DEFAULT_NRECS);
+
+ show_events('C', "Contention");
+ show_events('H', "Hold-time");
+ show_events('I', "Interrupt");
+ show_events('E', "Error");
+ (void) fprintf(stderr, "\n");
+
+ exit(1);
+}
+
+static int
+lockcmp(lsrec_t *a, lsrec_t *b)
+{
+ int i;
+
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ for (i = g_stkdepth - 1; i >= 0; i--) {
+ if (a->ls_stack[i] < b->ls_stack[i])
+ return (-1);
+ if (a->ls_stack[i] > b->ls_stack[i])
+ return (1);
+ }
+
+ if (a->ls_caller < b->ls_caller)
+ return (-1);
+ if (a->ls_caller > b->ls_caller)
+ return (1);
+
+ if (a->ls_lock < b->ls_lock)
+ return (-1);
+ if (a->ls_lock > b->ls_lock)
+ return (1);
+
+ return (0);
+}
+
+static int
+countcmp(lsrec_t *a, lsrec_t *b)
+{
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ return (b->ls_count - a->ls_count);
+}
+
+static int
+timecmp(lsrec_t *a, lsrec_t *b)
+{
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ if (a->ls_time < b->ls_time)
+ return (1);
+ if (a->ls_time > b->ls_time)
+ return (-1);
+
+ return (0);
+}
+
+static int
+lockcmp_anywhere(lsrec_t *a, lsrec_t *b)
+{
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ if (a->ls_lock < b->ls_lock)
+ return (-1);
+ if (a->ls_lock > b->ls_lock)
+ return (1);
+
+ return (0);
+}
+
+static int
+lock_and_count_cmp_anywhere(lsrec_t *a, lsrec_t *b)
+{
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ if (a->ls_lock < b->ls_lock)
+ return (-1);
+ if (a->ls_lock > b->ls_lock)
+ return (1);
+
+ return (b->ls_count - a->ls_count);
+}
+
+static int
+sitecmp_anylock(lsrec_t *a, lsrec_t *b)
+{
+ int i;
+
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ for (i = g_stkdepth - 1; i >= 0; i--) {
+ if (a->ls_stack[i] < b->ls_stack[i])
+ return (-1);
+ if (a->ls_stack[i] > b->ls_stack[i])
+ return (1);
+ }
+
+ if (a->ls_caller < b->ls_caller)
+ return (-1);
+ if (a->ls_caller > b->ls_caller)
+ return (1);
+
+ return (0);
+}
+
+static int
+site_and_count_cmp_anylock(lsrec_t *a, lsrec_t *b)
+{
+ int i;
+
+ if (a->ls_event < b->ls_event)
+ return (-1);
+ if (a->ls_event > b->ls_event)
+ return (1);
+
+ for (i = g_stkdepth - 1; i >= 0; i--) {
+ if (a->ls_stack[i] < b->ls_stack[i])
+ return (-1);
+ if (a->ls_stack[i] > b->ls_stack[i])
+ return (1);
+ }
+
+ if (a->ls_caller < b->ls_caller)
+ return (-1);
+ if (a->ls_caller > b->ls_caller)
+ return (1);
+
+ return (b->ls_count - a->ls_count);
+}
+
+static void
+lsmergesort(int (*cmp)(lsrec_t *, lsrec_t *), lsrec_t **a, lsrec_t **b, int n)
+{
+ int m = n / 2;
+ int i, j;
+
+ if (m > 1)
+ lsmergesort(cmp, a, b, m);
+ if (n - m > 1)
+ lsmergesort(cmp, a + m, b + m, n - m);
+ for (i = m; i > 0; i--)
+ b[i - 1] = a[i - 1];
+ for (j = m - 1; j < n - 1; j++)
+ b[n + m - j - 2] = a[j + 1];
+ while (i < j)
+ *a++ = cmp(b[i], b[j]) < 0 ? b[i++] : b[j--];
+ *a = b[i];
+}
+
+static void
+coalesce(int (*cmp)(lsrec_t *, lsrec_t *), lsrec_t **lock, int n)
+{
+ int i, j;
+ lsrec_t *target, *current;
+
+ target = lock[0];
+
+ for (i = 1; i < n; i++) {
+ current = lock[i];
+ if (cmp(current, target) != 0) {
+ target = current;
+ continue;
+ }
+ current->ls_event = LS_MAX_EVENTS;
+ target->ls_count += current->ls_count;
+ target->ls_refcnt += current->ls_refcnt;
+ if (g_recsize < LS_TIME)
+ continue;
+ target->ls_time += current->ls_time;
+ if (g_recsize < LS_HIST)
+ continue;
+ for (j = 0; j < 64; j++)
+ target->ls_hist[j] += current->ls_hist[j];
+ }
+}
+
+static void
+coalesce_symbol(uintptr_t *addrp)
+{
+ uintptr_t symoff;
+ size_t symsize;
+
+ if (addr_to_sym(*addrp, &symoff, &symsize) != NULL && symoff < symsize)
+ *addrp -= symoff;
+}
+
+static void
+predicate_add(char **pred, char *what, char *cmp, uintptr_t value)
+{
+ char *new;
+ int len, newlen;
+
+ if (what == NULL)
+ return;
+
+ if (*pred == NULL) {
+ *pred = malloc(1);
+ *pred[0] = '\0';
+ }
+
+ len = strlen(*pred);
+ newlen = len + strlen(what) + 32 + strlen("( && )");
+ new = malloc(newlen);
+
+ if (*pred[0] != '\0') {
+ if (cmp != NULL) {
+ (void) sprintf(new, "(%s) && (%s %s 0x%p)",
+ *pred, what, cmp, (void *)value);
+ } else {
+ (void) sprintf(new, "(%s) && (%s)", *pred, what);
+ }
+ } else {
+ if (cmp != NULL) {
+ (void) sprintf(new, "%s %s 0x%p",
+ what, cmp, (void *)value);
+ } else {
+ (void) sprintf(new, "%s", what);
+ }
+ }
+
+ free(*pred);
+ *pred = new;
+}
+
+static void
+predicate_destroy(char **pred)
+{
+ free(*pred);
+ *pred = NULL;
+}
+
+static void
+filter_add(char **filt, char *what, uintptr_t base, uintptr_t size)
+{
+ char buf[256], *c = buf, *new;
+ int len, newlen;
+
+ if (*filt == NULL) {
+ *filt = malloc(1);
+ *filt[0] = '\0';
+ }
+
+#if defined(sun)
+ (void) sprintf(c, "%s(%s >= 0x%p && %s < 0x%p)", *filt[0] != '\0' ?
+ " || " : "", what, (void *)base, what, (void *)(base + size));
+#else
+ (void) sprintf(c, "%s(%s >= %p && %s < %p)", *filt[0] != '\0' ?
+ " || " : "", what, (void *)base, what, (void *)(base + size));
+#endif
+
+ newlen = (len = strlen(*filt) + 1) + strlen(c);
+ new = malloc(newlen);
+ bcopy(*filt, new, len);
+ (void) strcat(new, c);
+ free(*filt);
+ *filt = new;
+}
+
+static void
+filter_destroy(char **filt)
+{
+ free(*filt);
+ *filt = NULL;
+}
+
+static void
+dprog_add(const char *fmt, ...)
+{
+ va_list args;
+ int size, offs;
+ char c;
+
+ va_start(args, fmt);
+ size = vsnprintf(&c, 1, fmt, args) + 1;
+ va_end(args);
+
+ if (g_proglen == 0) {
+ offs = 0;
+ } else {
+ offs = g_proglen - 1;
+ }
+
+ g_proglen = offs + size;
+
+ if ((g_prog = realloc(g_prog, g_proglen)) == NULL)
+ fail(1, "failed to reallocate program text");
+
+ va_start(args, fmt);
+ (void) vsnprintf(&g_prog[offs], size, fmt, args);
+ va_end(args);
+}
+
+/*
+ * This function may read like an open sewer, but keep in mind that programs
+ * that generate other programs are rarely pretty. If one has the unenviable
+ * task of maintaining or -- worse -- extending this code, use the -V option
+ * to examine the D program as generated by this function.
+ */
+static void
+dprog_addevent(int event)
+{
+ ls_event_info_t *info = &g_event_info[event];
+ char *pred = NULL;
+ char stack[20];
+ const char *arg0, *caller;
+ char *arg1 = "arg1";
+ char buf[80];
+ hrtime_t dur;
+ int depth;
+
+ if (info->ev_name[0] == '\0')
+ return;
+
+ if (info->ev_type == 'I') {
+ /*
+ * For interrupt events, arg0 (normally the lock pointer) is
+ * the CPU address plus the current pil, and arg1 (normally
+ * the number of nanoseconds) is the number of nanoseconds
+ * late -- and it's stored in arg2.
+ */
+#if defined(sun)
+ arg0 = "(uintptr_t)curthread->t_cpu + \n"
+ "\t curthread->t_cpu->cpu_profile_pil";
+#else
+ arg0 = "(uintptr_t)(curthread->td_oncpu << 16) + \n"
+ "\t 0x01000000 + curthread->td_pri_class";
+#endif
+ caller = "(uintptr_t)arg0";
+ arg1 = "arg2";
+ } else {
+ arg0 = "(uintptr_t)arg0";
+ caller = "caller";
+ }
+
+ if (g_recsize > LS_HIST) {
+ for (depth = 0; g_recsize > LS_STACK(depth); depth++)
+ continue;
+
+ if (g_tracing) {
+ (void) sprintf(stack, "\tstack(%d);\n", depth);
+ } else {
+ (void) sprintf(stack, ", stack(%d)", depth);
+ }
+ } else {
+ (void) sprintf(stack, "");
+ }
+
+ if (info->ev_acquire != NULL) {
+ /*
+ * If this is a hold event, we need to generate an additional
+ * clause for the acquire; the clause for the release will be
+ * generated with the aggregating statement, below.
+ */
+ dprog_add("%s\n", info->ev_acquire);
+ predicate_add(&pred, info->ev_predicate, NULL, 0);
+ predicate_add(&pred, g_predicate, NULL, 0);
+ if (pred != NULL)
+ dprog_add("/%s/\n", pred);
+
+ dprog_add("{\n");
+ (void) sprintf(buf, "self->ev%d[(uintptr_t)arg0]", event);
+
+ if (info->ev_type == 'H') {
+ dprog_add("\t%s = timestamp;\n", buf);
+ } else {
+ /*
+ * If this isn't a hold event, it's the recursive
+ * error event. For this, we simply bump the
+ * thread-local, per-lock count.
+ */
+ dprog_add("\t%s++;\n", buf);
+ }
+
+ dprog_add("}\n\n");
+ predicate_destroy(&pred);
+ pred = NULL;
+
+ if (info->ev_type == 'E') {
+ /*
+ * If this is the recursive lock error event, we need
+ * to generate an additional clause to decrement the
+ * thread-local, per-lock count. This assures that we
+ * only execute the aggregating clause if we have
+ * recursive entry.
+ */
+ dprog_add("%s\n", info->ev_name);
+ dprog_add("/%s/\n{\n\t%s--;\n}\n\n", buf, buf);
+ }
+
+ predicate_add(&pred, buf, NULL, 0);
+
+ if (info->ev_type == 'H') {
+ (void) sprintf(buf, "timestamp -\n\t "
+ "self->ev%d[(uintptr_t)arg0]", event);
+ }
+
+ arg1 = buf;
+ } else {
+ predicate_add(&pred, info->ev_predicate, NULL, 0);
+ if (info->ev_type != 'I')
+ predicate_add(&pred, g_predicate, NULL, 0);
+ else
+ predicate_add(&pred, g_ipredicate, NULL, 0);
+ }
+
+ if ((dur = g_min_duration[event]) != 0)
+ predicate_add(&pred, arg1, ">=", dur);
+
+ dprog_add("%s\n", info->ev_name);
+
+ if (pred != NULL)
+ dprog_add("/%s/\n", pred);
+ predicate_destroy(&pred);
+
+ dprog_add("{\n");
+
+ if (g_tracing) {
+ dprog_add("\ttrace(%dULL);\n", event);
+ dprog_add("\ttrace(%s);\n", arg0);
+ dprog_add("\ttrace(%s);\n", caller);
+ dprog_add(stack);
+ } else {
+ /*
+ * The ordering here is important: when we process the
+ * aggregate, we count on the fact that @avg appears before
+ * @hist in program order to assure that @avg is assigned the
+ * first aggregation variable ID and @hist assigned the
+ * second; see the comment in process_aggregate() for details.
+ */
+ dprog_add("\t@avg[%dULL, %s, %s%s] = avg(%s);\n",
+ event, arg0, caller, stack, arg1);
+
+ if (g_recsize >= LS_HIST) {
+ dprog_add("\t@hist[%dULL, %s, %s%s] = quantize"
+ "(%s);\n", event, arg0, caller, stack, arg1);
+ }
+ }
+
+ if (info->ev_acquire != NULL)
+ dprog_add("\tself->ev%d[arg0] = 0;\n", event);
+
+ dprog_add("}\n\n");
+}
+
+static void
+dprog_compile()
+{
+ dtrace_prog_t *prog;
+ dtrace_proginfo_t info;
+
+ if (g_Vflag) {
+ (void) fprintf(stderr, "lockstat: vvvv D program vvvv\n");
+ (void) fputs(g_prog, stderr);
+ (void) fprintf(stderr, "lockstat: ^^^^ D program ^^^^\n");
+ }
+
+ if ((prog = dtrace_program_strcompile(g_dtp, g_prog,
+ DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL)
+ dfail("failed to compile program");
+
+ if (dtrace_program_exec(g_dtp, prog, &info) == -1)
+ dfail("failed to enable probes");
+
+ if (dtrace_go(g_dtp) != 0)
+ dfail("couldn't start tracing");
+}
+
+static void
+#if defined(sun)
+status_fire(void)
+#else
+status_fire(int i)
+#endif
+{}
+
+static void
+status_init(void)
+{
+ dtrace_optval_t val, status, agg;
+ struct sigaction act;
+ struct itimerspec ts;
+ struct sigevent ev;
+ timer_t tid;
+
+ if (dtrace_getopt(g_dtp, "statusrate", &status) == -1)
+ dfail("failed to get 'statusrate'");
+
+ if (dtrace_getopt(g_dtp, "aggrate", &agg) == -1)
+ dfail("failed to get 'statusrate'");
+
+ /*
+ * We would want to awaken at a rate that is the GCD of the statusrate
+ * and the aggrate -- but that seems a bit absurd. Instead, we'll
+ * simply awaken at a rate that is the more frequent of the two, which
+ * assures that we're never later than the interval implied by the
+ * more frequent rate.
+ */
+ val = status < agg ? status : agg;
+
+ (void) sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = status_fire;
+ (void) sigaction(SIGUSR1, &act, NULL);
+
+ ev.sigev_notify = SIGEV_SIGNAL;
+ ev.sigev_signo = SIGUSR1;
+
+ if (timer_create(CLOCK_REALTIME, &ev, &tid) == -1)
+ dfail("cannot create CLOCK_REALTIME timer");
+
+ ts.it_value.tv_sec = val / NANOSEC;
+ ts.it_value.tv_nsec = val % NANOSEC;
+ ts.it_interval = ts.it_value;
+
+ if (timer_settime(tid, TIMER_RELTIME, &ts, NULL) == -1)
+ dfail("cannot set time on CLOCK_REALTIME timer");
+}
+
+static void
+status_check(void)
+{
+ if (!g_tracing && dtrace_aggregate_snap(g_dtp) != 0)
+ dfail("failed to snap aggregate");
+
+ if (dtrace_status(g_dtp) == -1)
+ dfail("dtrace_status()");
+}
+
+static void
+lsrec_fill(lsrec_t *lsrec, const dtrace_recdesc_t *rec, int nrecs, caddr_t data)
+{
+ bzero(lsrec, g_recsize);
+ lsrec->ls_count = 1;
+
+ if ((g_recsize > LS_HIST && nrecs < 4) || (nrecs < 3))
+ fail(0, "truncated DTrace record");
+
+ if (rec->dtrd_size != sizeof (uint64_t))
+ fail(0, "bad event size in first record");
+
+ /* LINTED - alignment */
+ lsrec->ls_event = (uint32_t)*((uint64_t *)(data + rec->dtrd_offset));
+ rec++;
+
+ if (rec->dtrd_size != sizeof (uintptr_t))
+ fail(0, "bad lock address size in second record");
+
+ /* LINTED - alignment */
+ lsrec->ls_lock = *((uintptr_t *)(data + rec->dtrd_offset));
+ rec++;
+
+ if (rec->dtrd_size != sizeof (uintptr_t))
+ fail(0, "bad caller size in third record");
+
+ /* LINTED - alignment */
+ lsrec->ls_caller = *((uintptr_t *)(data + rec->dtrd_offset));
+ rec++;
+
+ if (g_recsize > LS_HIST) {
+ int frames, i;
+ pc_t *stack;
+
+ frames = rec->dtrd_size / sizeof (pc_t);
+ /* LINTED - alignment */
+ stack = (pc_t *)(data + rec->dtrd_offset);
+
+ for (i = 1; i < frames; i++)
+ lsrec->ls_stack[i - 1] = stack[i];
+ }
+}
+
+/*ARGSUSED*/
+static int
+count_aggregate(const dtrace_aggdata_t *agg, void *arg)
+{
+ *((size_t *)arg) += 1;
+
+ return (DTRACE_AGGWALK_NEXT);
+}
+
+static int
+process_aggregate(const dtrace_aggdata_t *agg, void *arg)
+{
+ const dtrace_aggdesc_t *aggdesc = agg->dtada_desc;
+ caddr_t data = agg->dtada_data;
+ lsdata_t *lsdata = arg;
+ lsrec_t *lsrec = lsdata->lsd_next;
+ const dtrace_recdesc_t *rec;
+ uint64_t *avg, *quantized;
+ int i, j;
+
+ assert(lsdata->lsd_count < g_nrecs);
+
+ /*
+ * Aggregation variable IDs are guaranteed to be generated in program
+ * order, and they are guaranteed to start from DTRACE_AGGVARIDNONE
+ * plus one. As "avg" appears before "hist" in program order, we know
+ * that "avg" will be allocated the first aggregation variable ID, and
+ * "hist" will be allocated the second aggregation variable ID -- and
+ * we therefore use the aggregation variable ID to differentiate the
+ * cases.
+ */
+ if (aggdesc->dtagd_varid > DTRACE_AGGVARIDNONE + 1) {
+ /*
+ * If this is the histogram entry. We'll copy the quantized
+ * data into lc_hist, and jump over the rest.
+ */
+ rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1];
+
+ if (aggdesc->dtagd_varid != DTRACE_AGGVARIDNONE + 2)
+ fail(0, "bad variable ID in aggregation record");
+
+ if (rec->dtrd_size !=
+ DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t))
+ fail(0, "bad quantize size in aggregation record");
+
+ /* LINTED - alignment */
+ quantized = (uint64_t *)(data + rec->dtrd_offset);
+
+ for (i = DTRACE_QUANTIZE_ZEROBUCKET, j = 0;
+ i < DTRACE_QUANTIZE_NBUCKETS; i++, j++)
+ lsrec->ls_hist[j] = quantized[i];
+
+ goto out;
+ }
+
+ lsrec_fill(lsrec, &aggdesc->dtagd_rec[1],
+ aggdesc->dtagd_nrecs - 1, data);
+
+ rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1];
+
+ if (rec->dtrd_size != 2 * sizeof (uint64_t))
+ fail(0, "bad avg size in aggregation record");
+
+ /* LINTED - alignment */
+ avg = (uint64_t *)(data + rec->dtrd_offset);
+ lsrec->ls_count = (uint32_t)avg[0];
+ lsrec->ls_time = (uintptr_t)avg[1];
+
+ if (g_recsize >= LS_HIST)
+ return (DTRACE_AGGWALK_NEXT);
+
+out:
+ lsdata->lsd_next = (lsrec_t *)((uintptr_t)lsrec + g_recsize);
+ lsdata->lsd_count++;
+
+ return (DTRACE_AGGWALK_NEXT);
+}
+
+static int
+process_trace(const dtrace_probedata_t *pdata, void *arg)
+{
+ lsdata_t *lsdata = arg;
+ lsrec_t *lsrec = lsdata->lsd_next;
+ dtrace_eprobedesc_t *edesc = pdata->dtpda_edesc;
+ caddr_t data = pdata->dtpda_data;
+
+ if (lsdata->lsd_count >= g_nrecs)
+ return (DTRACE_CONSUME_NEXT);
+
+ lsrec_fill(lsrec, edesc->dtepd_rec, edesc->dtepd_nrecs, data);
+
+ lsdata->lsd_next = (lsrec_t *)((uintptr_t)lsrec + g_recsize);
+ lsdata->lsd_count++;
+
+ return (DTRACE_CONSUME_NEXT);
+}
+
+static int
+process_data(FILE *out, char *data)
+{
+ lsdata_t lsdata;
+
+ /* LINTED - alignment */
+ lsdata.lsd_next = (lsrec_t *)data;
+ lsdata.lsd_count = 0;
+
+ if (g_tracing) {
+ if (dtrace_consume(g_dtp, out,
+ process_trace, NULL, &lsdata) != 0)
+ dfail("failed to consume buffer");
+
+ return (lsdata.lsd_count);
+ }
+
+ if (dtrace_aggregate_walk_keyvarsorted(g_dtp,
+ process_aggregate, &lsdata) != 0)
+ dfail("failed to walk aggregate");
+
+ return (lsdata.lsd_count);
+}
+
+/*ARGSUSED*/
+static int
+drophandler(const dtrace_dropdata_t *data, void *arg)
+{
+ g_dropped++;
+ (void) fprintf(stderr, "lockstat: warning: %s", data->dtdda_msg);
+ return (DTRACE_HANDLE_OK);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *data_buf;
+ lsrec_t *lsp, **current, **first, **sort_buf, **merge_buf;
+ FILE *out = stdout;
+ int c;
+ pid_t child;
+ int status;
+ int i, j;
+ hrtime_t duration;
+ char *addrp, *offp, *sizep, *evp, *lastp, *p;
+ uintptr_t addr;
+ size_t size, off;
+ int events_specified = 0;
+ int exec_errno = 0;
+ uint32_t event;
+ char *filt = NULL, *ifilt = NULL;
+ static uint64_t ev_count[LS_MAX_EVENTS + 1];
+ static uint64_t ev_time[LS_MAX_EVENTS + 1];
+ dtrace_optval_t aggsize;
+ char aggstr[10];
+ long ncpus;
+ int dynvar = 0;
+ int err;
+
+ if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
+ fail(0, "cannot open dtrace library: %s",
+ dtrace_errmsg(NULL, err));
+ }
+
+ if (dtrace_handle_drop(g_dtp, &drophandler, NULL) == -1)
+ dfail("couldn't establish drop handler");
+
+ if (symtab_init() == -1)
+ fail(1, "can't load kernel symbols");
+
+ g_nrecs = DEFAULT_NRECS;
+
+ while ((c = getopt(argc, argv, LOCKSTAT_OPTSTR)) != GETOPT_EOF) {
+ switch (c) {
+ case 'b':
+ g_recsize = LS_BASIC;
+ break;
+
+ case 't':
+ g_recsize = LS_TIME;
+ break;
+
+ case 'h':
+ g_recsize = LS_HIST;
+ break;
+
+ case 's':
+ if (!isdigit(optarg[0]))
+ usage();
+ g_stkdepth = atoi(optarg);
+ if (g_stkdepth > LS_MAX_STACK_DEPTH)
+ fail(0, "max stack depth is %d",
+ LS_MAX_STACK_DEPTH);
+ g_recsize = LS_STACK(g_stkdepth);
+ break;
+
+ case 'n':
+ if (!isdigit(optarg[0]))
+ usage();
+ g_nrecs = atoi(optarg);
+ break;
+
+ case 'd':
+ if (!isdigit(optarg[0]))
+ usage();
+ duration = atoll(optarg);
+
+ /*
+ * XXX -- durations really should be per event
+ * since the units are different, but it's hard
+ * to express this nicely in the interface.
+ * Not clear yet what the cleanest solution is.
+ */
+ for (i = 0; i < LS_MAX_EVENTS; i++)
+ if (g_event_info[i].ev_type != 'E')
+ g_min_duration[i] = duration;
+
+ break;
+
+ case 'i':
+ if (!isdigit(optarg[0]))
+ usage();
+ i = atoi(optarg);
+ if (i <= 0)
+ usage();
+ if (i > MAX_HZ)
+ fail(0, "max interrupt rate is %d Hz", MAX_HZ);
+
+ for (j = 0; j < LS_MAX_EVENTS; j++)
+ if (strcmp(g_event_info[j].ev_desc,
+ "Profiling interrupt") == 0)
+ break;
+
+ (void) sprintf(g_event_info[j].ev_name,
+ "profile:::profile-%d", i);
+ break;
+
+ case 'l':
+ case 'f':
+ addrp = strtok(optarg, ",");
+ sizep = strtok(NULL, ",");
+ addrp = strtok(optarg, ",+");
+ offp = strtok(NULL, ",");
+
+ size = sizep ? strtoul(sizep, NULL, 0) : 1;
+ off = offp ? strtoul(offp, NULL, 0) : 0;
+
+ if (addrp[0] == '0') {
+ addr = strtoul(addrp, NULL, 16) + off;
+ } else {
+ addr = sym_to_addr(addrp) + off;
+ if (sizep == NULL)
+ size = sym_size(addrp) - off;
+ if (addr - off == 0)
+ fail(0, "symbol '%s' not found", addrp);
+ if (size == 0)
+ size = 1;
+ }
+
+
+ if (c == 'l') {
+ filter_add(&filt, "arg0", addr, size);
+ } else {
+ filter_add(&filt, "caller", addr, size);
+ filter_add(&ifilt, "arg0", addr, size);
+ }
+ break;
+
+ case 'e':
+ evp = strtok_r(optarg, ",", &lastp);
+ while (evp) {
+ int ev1, ev2;
+ char *evp2;
+
+ (void) strtok(evp, "-");
+ evp2 = strtok(NULL, "-");
+ ev1 = atoi(evp);
+ ev2 = evp2 ? atoi(evp2) : ev1;
+ if ((uint_t)ev1 >= LS_MAX_EVENTS ||
+ (uint_t)ev2 >= LS_MAX_EVENTS || ev1 > ev2)
+ fail(0, "-e events out of range");
+ for (i = ev1; i <= ev2; i++)
+ g_enabled[i] = 1;
+ evp = strtok_r(NULL, ",", &lastp);
+ }
+ events_specified = 1;
+ break;
+
+ case 'c':
+ g_cflag = 1;
+ break;
+
+ case 'k':
+ g_kflag = 1;
+ break;
+
+ case 'w':
+ g_wflag = 1;
+ break;
+
+ case 'W':
+ g_Wflag = 1;
+ break;
+
+ case 'g':
+ g_gflag = 1;
+ break;
+
+ case 'C':
+ case 'E':
+ case 'H':
+ case 'I':
+ for (i = 0; i < LS_MAX_EVENTS; i++)
+ if (g_event_info[i].ev_type == c)
+ g_enabled[i] = 1;
+ events_specified = 1;
+ break;
+
+ case 'A':
+ for (i = 0; i < LS_MAX_EVENTS; i++)
+ if (strchr("CH", g_event_info[i].ev_type))
+ g_enabled[i] = 1;
+ events_specified = 1;
+ break;
+
+ case 'T':
+ g_tracing = 1;
+ break;
+
+ case 'D':
+ if (!isdigit(optarg[0]))
+ usage();
+ g_topn = atoi(optarg);
+ break;
+
+ case 'R':
+ g_rates = 1;
+ break;
+
+ case 'p':
+ g_pflag = 1;
+ break;
+
+ case 'P':
+ g_Pflag = 1;
+ break;
+
+ case 'o':
+ if ((out = fopen(optarg, "w")) == NULL)
+ fail(1, "error opening file");
+ break;
+
+ case 'V':
+ g_Vflag = 1;
+ break;
+
+ default:
+ if (strchr(LOCKSTAT_OPTSTR, c) == NULL)
+ usage();
+ }
+ }
+
+ if (filt != NULL) {
+ predicate_add(&g_predicate, filt, NULL, 0);
+ filter_destroy(&filt);
+ }
+
+ if (ifilt != NULL) {
+ predicate_add(&g_ipredicate, ifilt, NULL, 0);
+ filter_destroy(&ifilt);
+ }
+
+ if (g_recsize == 0) {
+ if (g_gflag) {
+ g_stkdepth = LS_MAX_STACK_DEPTH;
+ g_recsize = LS_STACK(g_stkdepth);
+ } else {
+ g_recsize = LS_TIME;
+ }
+ }
+
+ if (g_gflag && g_recsize <= LS_STACK(0))
+ fail(0, "'-g' requires at least '-s 1' data gathering");
+
+ /*
+ * Make sure the alignment is reasonable
+ */
+ g_recsize = -(-g_recsize & -sizeof (uint64_t));
+
+ for (i = 0; i < LS_MAX_EVENTS; i++) {
+ /*
+ * If no events were specified, enable -C.
+ */
+ if (!events_specified && g_event_info[i].ev_type == 'C')
+ g_enabled[i] = 1;
+ }
+
+ for (i = 0; i < LS_MAX_EVENTS; i++) {
+ if (!g_enabled[i])
+ continue;
+
+ if (g_event_info[i].ev_acquire != NULL) {
+ /*
+ * If we've enabled a hold event, we must explicitly
+ * allocate dynamic variable space.
+ */
+ dynvar = 1;
+ }
+
+ dprog_addevent(i);
+ }
+
+ /*
+ * Make sure there are remaining arguments to specify a child command
+ * to execute.
+ */
+ if (argc <= optind)
+ usage();
+
+ if ((ncpus = sysconf(_SC_NPROCESSORS_ONLN)) == -1)
+ dfail("couldn't determine number of online CPUs");
+
+ /*
+ * By default, we set our data buffer size to be the number of records
+ * multiplied by the size of the record, doubled to account for some
+ * DTrace slop and divided by the number of CPUs. We silently clamp
+ * the aggregation size at both a minimum and a maximum to prevent
+ * absurdly low or high values.
+ */
+ if ((aggsize = (g_nrecs * g_recsize * 2) / ncpus) < MIN_AGGSIZE)
+ aggsize = MIN_AGGSIZE;
+
+ if (aggsize > MAX_AGGSIZE)
+ aggsize = MAX_AGGSIZE;
+
+ (void) sprintf(aggstr, "%lld", (long long)aggsize);
+
+ if (!g_tracing) {
+ if (dtrace_setopt(g_dtp, "bufsize", "4k") == -1)
+ dfail("failed to set 'bufsize'");
+
+ if (dtrace_setopt(g_dtp, "aggsize", aggstr) == -1)
+ dfail("failed to set 'aggsize'");
+
+ if (dynvar) {
+ /*
+ * If we're using dynamic variables, we set our
+ * dynamic variable size to be one megabyte per CPU,
+ * with a hard-limit of 32 megabytes. This may still
+ * be too small in some cases, but it can be tuned
+ * manually via -x if need be.
+ */
+ (void) sprintf(aggstr, "%ldm", ncpus < 32 ? ncpus : 32);
+
+ if (dtrace_setopt(g_dtp, "dynvarsize", aggstr) == -1)
+ dfail("failed to set 'dynvarsize'");
+ }
+ } else {
+ if (dtrace_setopt(g_dtp, "bufsize", aggstr) == -1)
+ dfail("failed to set 'bufsize'");
+ }
+
+ if (dtrace_setopt(g_dtp, "statusrate", "10sec") == -1)
+ dfail("failed to set 'statusrate'");
+
+ optind = 1;
+ while ((c = getopt(argc, argv, LOCKSTAT_OPTSTR)) != GETOPT_EOF) {
+ switch (c) {
+ case 'x':
+ if ((p = strchr(optarg, '=')) != NULL)
+ *p++ = '\0';
+
+ if (dtrace_setopt(g_dtp, optarg, p) != 0)
+ dfail("failed to set -x %s", optarg);
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ dprog_compile();
+ status_init();
+
+ g_elapsed = -gethrtime();
+
+ /*
+ * Spawn the specified command and wait for it to complete.
+ */
+ child = fork();
+ if (child == -1)
+ fail(1, "cannot fork");
+ if (child == 0) {
+ (void) dtrace_close(g_dtp);
+ (void) execvp(argv[0], &argv[0]);
+ exec_errno = errno;
+ exit(127);
+ }
+
+#if defined(sun)
+ while (waitpid(child, &status, WEXITED) != child)
+#else
+ while (waitpid(child, &status, 0) != child)
+#endif
+ status_check();
+
+ g_elapsed += gethrtime();
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ if (exec_errno != 0) {
+ errno = exec_errno;
+ fail(1, "could not execute %s", argv[0]);
+ }
+ (void) fprintf(stderr,
+ "lockstat: warning: %s exited with code %d\n",
+ argv[0], WEXITSTATUS(status));
+ }
+ } else {
+ (void) fprintf(stderr,
+ "lockstat: warning: %s died on signal %d\n",
+ argv[0], WTERMSIG(status));
+ }
+
+ if (dtrace_stop(g_dtp) == -1)
+ dfail("failed to stop dtrace");
+
+ /*
+ * Before we read out the results, we need to allocate our buffer.
+ * If we're tracing, then we'll just use the precalculated size. If
+ * we're not, then we'll take a snapshot of the aggregate, and walk
+ * it to count the number of records.
+ */
+ if (!g_tracing) {
+ if (dtrace_aggregate_snap(g_dtp) != 0)
+ dfail("failed to snap aggregate");
+
+ g_nrecs = 0;
+
+ if (dtrace_aggregate_walk(g_dtp,
+ count_aggregate, &g_nrecs) != 0)
+ dfail("failed to walk aggregate");
+ }
+
+#if defined(sun)
+ if ((data_buf = memalign(sizeof (uint64_t),
+ (g_nrecs + 1) * g_recsize)) == NULL)
+#else
+ if (posix_memalign((void **)&data_buf, sizeof (uint64_t),
+ (g_nrecs + 1) * g_recsize) )
+#endif
+ fail(1, "Memory allocation failed");
+
+ /*
+ * Read out the DTrace data.
+ */
+ g_nrecs_used = process_data(out, data_buf);
+
+ if (g_nrecs_used > g_nrecs || g_dropped)
+ (void) fprintf(stderr, "lockstat: warning: "
+ "ran out of data records (use -n for more)\n");
+
+ /* LINTED - alignment */
+ for (i = 0, lsp = (lsrec_t *)data_buf; i < g_nrecs_used; i++,
+ /* LINTED - alignment */
+ lsp = (lsrec_t *)((char *)lsp + g_recsize)) {
+ ev_count[lsp->ls_event] += lsp->ls_count;
+ ev_time[lsp->ls_event] += lsp->ls_time;
+ }
+
+ /*
+ * If -g was specified, convert stacks into individual records.
+ */
+ if (g_gflag) {
+ lsrec_t *newlsp, *oldlsp;
+
+#if defined(sun)
+ newlsp = memalign(sizeof (uint64_t),
+ g_nrecs_used * LS_TIME * (g_stkdepth + 1));
+#else
+ posix_memalign((void **)&newlsp, sizeof (uint64_t),
+ g_nrecs_used * LS_TIME * (g_stkdepth + 1));
+#endif
+ if (newlsp == NULL)
+ fail(1, "Cannot allocate space for -g processing");
+ lsp = newlsp;
+ /* LINTED - alignment */
+ for (i = 0, oldlsp = (lsrec_t *)data_buf; i < g_nrecs_used; i++,
+ /* LINTED - alignment */
+ oldlsp = (lsrec_t *)((char *)oldlsp + g_recsize)) {
+ int fr;
+ int caller_in_stack = 0;
+
+ if (oldlsp->ls_count == 0)
+ continue;
+
+ for (fr = 0; fr < g_stkdepth; fr++) {
+ if (oldlsp->ls_stack[fr] == 0)
+ break;
+ if (oldlsp->ls_stack[fr] == oldlsp->ls_caller)
+ caller_in_stack = 1;
+ bcopy(oldlsp, lsp, LS_TIME);
+ lsp->ls_caller = oldlsp->ls_stack[fr];
+ /* LINTED - alignment */
+ lsp = (lsrec_t *)((char *)lsp + LS_TIME);
+ }
+ if (!caller_in_stack) {
+ bcopy(oldlsp, lsp, LS_TIME);
+ /* LINTED - alignment */
+ lsp = (lsrec_t *)((char *)lsp + LS_TIME);
+ }
+ }
+ g_nrecs = g_nrecs_used =
+ ((uintptr_t)lsp - (uintptr_t)newlsp) / LS_TIME;
+ g_recsize = LS_TIME;
+ g_stkdepth = 0;
+ free(data_buf);
+ data_buf = (char *)newlsp;
+ }
+
+ if ((sort_buf = calloc(2 * (g_nrecs + 1),
+ sizeof (void *))) == NULL)
+ fail(1, "Sort buffer allocation failed");
+ merge_buf = sort_buf + (g_nrecs + 1);
+
+ /*
+ * Build the sort buffer, discarding zero-count records along the way.
+ */
+ /* LINTED - alignment */
+ for (i = 0, lsp = (lsrec_t *)data_buf; i < g_nrecs_used; i++,
+ /* LINTED - alignment */
+ lsp = (lsrec_t *)((char *)lsp + g_recsize)) {
+ if (lsp->ls_count == 0)
+ lsp->ls_event = LS_MAX_EVENTS;
+ sort_buf[i] = lsp;
+ }
+
+ if (g_nrecs_used == 0)
+ exit(0);
+
+ /*
+ * Add a sentinel after the last record
+ */
+ sort_buf[i] = lsp;
+ lsp->ls_event = LS_MAX_EVENTS;
+
+ if (g_tracing) {
+ report_trace(out, sort_buf);
+ return (0);
+ }
+
+ /*
+ * Application of -g may have resulted in multiple records
+ * with the same signature; coalesce them.
+ */
+ if (g_gflag) {
+ mergesort(lockcmp, sort_buf, merge_buf, g_nrecs_used);
+ coalesce(lockcmp, sort_buf, g_nrecs_used);
+ }
+
+ /*
+ * Coalesce locks within the same symbol if -c option specified.
+ * Coalesce PCs within the same function if -k option specified.
+ */
+ if (g_cflag || g_kflag) {
+ for (i = 0; i < g_nrecs_used; i++) {
+ int fr;
+ lsp = sort_buf[i];
+ if (g_cflag)
+ coalesce_symbol(&lsp->ls_lock);
+ if (g_kflag) {
+ for (fr = 0; fr < g_stkdepth; fr++)
+ coalesce_symbol(&lsp->ls_stack[fr]);
+ coalesce_symbol(&lsp->ls_caller);
+ }
+ }
+ mergesort(lockcmp, sort_buf, merge_buf, g_nrecs_used);
+ coalesce(lockcmp, sort_buf, g_nrecs_used);
+ }
+
+ /*
+ * Coalesce callers if -w option specified
+ */
+ if (g_wflag) {
+ mergesort(lock_and_count_cmp_anywhere,
+ sort_buf, merge_buf, g_nrecs_used);
+ coalesce(lockcmp_anywhere, sort_buf, g_nrecs_used);
+ }
+
+ /*
+ * Coalesce locks if -W option specified
+ */
+ if (g_Wflag) {
+ mergesort(site_and_count_cmp_anylock,
+ sort_buf, merge_buf, g_nrecs_used);
+ coalesce(sitecmp_anylock, sort_buf, g_nrecs_used);
+ }
+
+ /*
+ * Sort data by contention count (ls_count) or total time (ls_time),
+ * depending on g_Pflag. Override g_Pflag if time wasn't measured.
+ */
+ if (g_recsize < LS_TIME)
+ g_Pflag = 0;
+
+ if (g_Pflag)
+ mergesort(timecmp, sort_buf, merge_buf, g_nrecs_used);
+ else
+ mergesort(countcmp, sort_buf, merge_buf, g_nrecs_used);
+
+ /*
+ * Display data by event type
+ */
+ first = &sort_buf[0];
+ while ((event = (*first)->ls_event) < LS_MAX_EVENTS) {
+ current = first;
+ while ((lsp = *current)->ls_event == event)
+ current++;
+ report_stats(out, first, current - first, ev_count[event],
+ ev_time[event]);
+ first = current;
+ }
+
+ return (0);
+}
+
+static char *
+format_symbol(char *buf, uintptr_t addr, int show_size)
+{
+ uintptr_t symoff;
+ char *symname;
+ size_t symsize;
+
+ symname = addr_to_sym(addr, &symoff, &symsize);
+
+ if (show_size && symoff == 0)
+ (void) sprintf(buf, "%s[%ld]", symname, (long)symsize);
+ else if (symoff == 0)
+ (void) sprintf(buf, "%s", symname);
+ else if (symoff < 16 && bcmp(symname, "cpu[", 4) == 0) /* CPU+PIL */
+#if defined(sun)
+ (void) sprintf(buf, "%s+%ld", symname, (long)symoff);
+#else
+ (void) sprintf(buf, "%s+%s", symname, g_pri_class[(int)symoff]);
+#endif
+ else if (symoff <= symsize || (symoff < 256 && addr != symoff))
+ (void) sprintf(buf, "%s+0x%llx", symname,
+ (unsigned long long)symoff);
+ else
+ (void) sprintf(buf, "0x%llx", (unsigned long long)addr);
+ return (buf);
+}
+
+static void
+report_stats(FILE *out, lsrec_t **sort_buf, size_t nrecs, uint64_t total_count,
+ uint64_t total_time)
+{
+ uint32_t event = sort_buf[0]->ls_event;
+ lsrec_t *lsp;
+ double ptotal = 0.0;
+ double percent;
+ int i, j, fr;
+ int displayed;
+ int first_bin, last_bin, max_bin_count, total_bin_count;
+ int rectype;
+ char buf[256];
+ char lhdr[80], chdr[80];
+
+ rectype = g_recsize;
+
+ if (g_topn == 0) {
+ (void) fprintf(out, "%20llu %s\n",
+ g_rates == 0 ? total_count :
+ ((unsigned long long)total_count * NANOSEC) / g_elapsed,
+ g_event_info[event].ev_desc);
+ return;
+ }
+
+ (void) sprintf(lhdr, "%s%s",
+ g_Wflag ? "Hottest " : "", g_event_info[event].ev_lhdr);
+ (void) sprintf(chdr, "%s%s",
+ g_wflag ? "Hottest " : "", "Caller");
+
+ if (!g_pflag)
+ (void) fprintf(out,
+ "\n%s: %.0f events in %.3f seconds (%.0f events/sec)\n\n",
+ g_event_info[event].ev_desc, (double)total_count,
+ (double)g_elapsed / NANOSEC,
+ (double)total_count * NANOSEC / g_elapsed);
+
+ if (!g_pflag && rectype < LS_HIST) {
+ (void) sprintf(buf, "%s", g_event_info[event].ev_units);
+ (void) fprintf(out, "%5s %4s %4s %4s %8s %-22s %-24s\n",
+ g_rates ? "ops/s" : "Count",
+ g_gflag ? "genr" : "indv",
+ "cuml", "rcnt", rectype >= LS_TIME ? buf : "", lhdr, chdr);
+ (void) fprintf(out, "---------------------------------"
+ "----------------------------------------------\n");
+ }
+
+ displayed = 0;
+ for (i = 0; i < nrecs; i++) {
+ lsp = sort_buf[i];
+
+ if (displayed++ >= g_topn)
+ break;
+
+ if (g_pflag) {
+ int j;
+
+ (void) fprintf(out, "%u %u",
+ lsp->ls_event, lsp->ls_count);
+ (void) fprintf(out, " %s",
+ format_symbol(buf, lsp->ls_lock, g_cflag));
+ (void) fprintf(out, " %s",
+ format_symbol(buf, lsp->ls_caller, 0));
+ (void) fprintf(out, " %f",
+ (double)lsp->ls_refcnt / lsp->ls_count);
+ if (rectype >= LS_TIME)
+ (void) fprintf(out, " %llu",
+ (unsigned long long)lsp->ls_time);
+ if (rectype >= LS_HIST) {
+ for (j = 0; j < 64; j++)
+ (void) fprintf(out, " %u",
+ lsp->ls_hist[j]);
+ }
+ for (j = 0; j < LS_MAX_STACK_DEPTH; j++) {
+ if (rectype <= LS_STACK(j) ||
+ lsp->ls_stack[j] == 0)
+ break;
+ (void) fprintf(out, " %s",
+ format_symbol(buf, lsp->ls_stack[j], 0));
+ }
+ (void) fprintf(out, "\n");
+ continue;
+ }
+
+ if (rectype >= LS_HIST) {
+ (void) fprintf(out, "---------------------------------"
+ "----------------------------------------------\n");
+ (void) sprintf(buf, "%s",
+ g_event_info[event].ev_units);
+ (void) fprintf(out, "%5s %4s %4s %4s %8s %-22s %-24s\n",
+ g_rates ? "ops/s" : "Count",
+ g_gflag ? "genr" : "indv",
+ "cuml", "rcnt", buf, lhdr, chdr);
+ }
+
+ if (g_Pflag && total_time != 0)
+ percent = (lsp->ls_time * 100.00) / total_time;
+ else
+ percent = (lsp->ls_count * 100.00) / total_count;
+
+ ptotal += percent;
+
+ if (rectype >= LS_TIME)
+ (void) sprintf(buf, "%llu",
+ (unsigned long long)(lsp->ls_time / lsp->ls_count));
+ else
+ buf[0] = '\0';
+
+ (void) fprintf(out, "%5llu ",
+ g_rates == 0 ? lsp->ls_count :
+ ((uint64_t)lsp->ls_count * NANOSEC) / g_elapsed);
+
+ (void) fprintf(out, "%3.0f%% ", percent);
+
+ if (g_gflag)
+ (void) fprintf(out, "---- ");
+ else
+ (void) fprintf(out, "%3.0f%% ", ptotal);
+
+ (void) fprintf(out, "%4.2f %8s ",
+ (double)lsp->ls_refcnt / lsp->ls_count, buf);
+
+ (void) fprintf(out, "%-22s ",
+ format_symbol(buf, lsp->ls_lock, g_cflag));
+
+ (void) fprintf(out, "%-24s\n",
+ format_symbol(buf, lsp->ls_caller, 0));
+
+ if (rectype < LS_HIST)
+ continue;
+
+ (void) fprintf(out, "\n");
+ (void) fprintf(out, "%10s %31s %-9s %-24s\n",
+ g_event_info[event].ev_units,
+ "------ Time Distribution ------",
+ g_rates ? "ops/s" : "count",
+ rectype > LS_STACK(0) ? "Stack" : "");
+
+ first_bin = 0;
+ while (lsp->ls_hist[first_bin] == 0)
+ first_bin++;
+
+ last_bin = 63;
+ while (lsp->ls_hist[last_bin] == 0)
+ last_bin--;
+
+ max_bin_count = 0;
+ total_bin_count = 0;
+ for (j = first_bin; j <= last_bin; j++) {
+ total_bin_count += lsp->ls_hist[j];
+ if (lsp->ls_hist[j] > max_bin_count)
+ max_bin_count = lsp->ls_hist[j];
+ }
+
+ /*
+ * If we went a few frames below the caller, ignore them
+ */
+ for (fr = 3; fr > 0; fr--)
+ if (lsp->ls_stack[fr] == lsp->ls_caller)
+ break;
+
+ for (j = first_bin; j <= last_bin; j++) {
+ uint_t depth = (lsp->ls_hist[j] * 30) / total_bin_count;
+ (void) fprintf(out, "%10llu |%s%s %-9u ",
+ 1ULL << j,
+ "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + 30 - depth,
+ " " + depth,
+ g_rates == 0 ? lsp->ls_hist[j] :
+ (uint_t)(((uint64_t)lsp->ls_hist[j] * NANOSEC) /
+ g_elapsed));
+ if (rectype <= LS_STACK(fr) || lsp->ls_stack[fr] == 0) {
+ (void) fprintf(out, "\n");
+ continue;
+ }
+ (void) fprintf(out, "%-24s\n",
+ format_symbol(buf, lsp->ls_stack[fr], 0));
+ fr++;
+ }
+ while (rectype > LS_STACK(fr) && lsp->ls_stack[fr] != 0) {
+ (void) fprintf(out, "%15s %-36s %-24s\n", "", "",
+ format_symbol(buf, lsp->ls_stack[fr], 0));
+ fr++;
+ }
+ }
+
+ if (!g_pflag)
+ (void) fprintf(out, "---------------------------------"
+ "----------------------------------------------\n");
+
+ (void) fflush(out);
+}
+
+static void
+report_trace(FILE *out, lsrec_t **sort_buf)
+{
+ lsrec_t *lsp;
+ int i, fr;
+ int rectype;
+ char buf[256], buf2[256];
+
+ rectype = g_recsize;
+
+ if (!g_pflag) {
+ (void) fprintf(out, "%5s %7s %11s %-24s %-24s\n",
+ "Event", "Time", "Owner", "Lock", "Caller");
+ (void) fprintf(out, "---------------------------------"
+ "----------------------------------------------\n");
+ }
+
+ for (i = 0; i < g_nrecs_used; i++) {
+
+ lsp = sort_buf[i];
+
+ if (lsp->ls_event >= LS_MAX_EVENTS || lsp->ls_count == 0)
+ continue;
+
+ (void) fprintf(out, "%2d %10llu %11p %-24s %-24s\n",
+ lsp->ls_event, (unsigned long long)lsp->ls_time,
+ (void *)lsp->ls_next,
+ format_symbol(buf, lsp->ls_lock, 0),
+ format_symbol(buf2, lsp->ls_caller, 0));
+
+ if (rectype <= LS_STACK(0))
+ continue;
+
+ /*
+ * If we went a few frames below the caller, ignore them
+ */
+ for (fr = 3; fr > 0; fr--)
+ if (lsp->ls_stack[fr] == lsp->ls_caller)
+ break;
+
+ while (rectype > LS_STACK(fr) && lsp->ls_stack[fr] != 0) {
+ (void) fprintf(out, "%53s %-24s\n", "",
+ format_symbol(buf, lsp->ls_stack[fr], 0));
+ fr++;
+ }
+ (void) fprintf(out, "\n");
+ }
+
+ (void) fflush(out);
+}
diff --git a/cddl/contrib/opensolaris/cmd/lockstat/sym.c b/cddl/contrib/opensolaris/cmd/lockstat/sym.c
new file mode 100644
index 0000000..78b27d2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/lockstat/sym.c
@@ -0,0 +1,311 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <libelf.h>
+#include <link.h>
+#include <elf.h>
+#if defined(sun)
+#include <sys/machelf.h>
+
+#include <kstat.h>
+#else
+/* FreeBSD */
+#include <sys/elf.h>
+#include <sys/ksyms.h>
+#endif
+#include <sys/cpuvar.h>
+
+typedef struct syment {
+ uintptr_t addr;
+ char *name;
+ size_t size;
+} syment_t;
+
+static syment_t *symbol_table;
+static int nsyms, maxsyms;
+static char maxsymname[64];
+
+#if defined(sun)
+#ifdef _ELF64
+#define elf_getshdr elf64_getshdr
+#else
+#define elf_getshdr elf32_getshdr
+#endif
+#endif
+
+static void
+add_symbol(char *name, uintptr_t addr, size_t size)
+{
+ syment_t *sep;
+
+ if (nsyms >= maxsyms) {
+ maxsyms += 10000;
+ symbol_table = realloc(symbol_table, maxsyms * sizeof (*sep));
+ if (symbol_table == NULL) {
+ (void) fprintf(stderr, "can't allocate symbol table\n");
+ exit(3);
+ }
+ }
+ sep = &symbol_table[nsyms++];
+
+ sep->name = name;
+ sep->addr = addr;
+ sep->size = size;
+}
+
+static void
+remove_symbol(uintptr_t addr)
+{
+ int i;
+ syment_t *sep = symbol_table;
+
+ for (i = 0; i < nsyms; i++, sep++)
+ if (sep->addr == addr)
+ sep->addr = 0;
+}
+
+#if defined(sun)
+static void
+fake_up_certain_popular_kernel_symbols(void)
+{
+ kstat_ctl_t *kc;
+ kstat_t *ksp;
+ char *name;
+
+ if ((kc = kstat_open()) == NULL)
+ return;
+
+ for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
+ if (strcmp(ksp->ks_module, "cpu_info") == 0) {
+ if ((name = malloc(20)) == NULL)
+ break;
+ /*
+ * For consistency, keep cpu[0] and toss cpu0
+ * or any other such symbols.
+ */
+ if (ksp->ks_instance == 0)
+ remove_symbol((uintptr_t)ksp->ks_private);
+ (void) sprintf(name, "cpu[%d]", ksp->ks_instance);
+ add_symbol(name, (uintptr_t)ksp->ks_private,
+ sizeof (struct cpu));
+ }
+ }
+ (void) kstat_close(kc);
+}
+#else
+/* FreeBSD */
+static void
+fake_up_certain_popular_kernel_symbols(void)
+{
+ char *name;
+ uintptr_t addr;
+ int i;
+
+ /* Good for up to 256 CPUs */
+ for(i=0; i < 256; i++) {
+ if ((name = malloc(20)) == NULL)
+ break;
+ (void) sprintf(name, "cpu[%d]", i);
+ addr = 0x01000000 + (i << 16);
+ add_symbol(name, addr, sizeof (uintptr_t));
+ }
+}
+#endif /* !defined(sun) */
+
+static int
+symcmp(const void *p1, const void *p2)
+{
+ uintptr_t a1 = ((syment_t *)p1)->addr;
+ uintptr_t a2 = ((syment_t *)p2)->addr;
+
+ if (a1 < a2)
+ return (-1);
+ if (a1 > a2)
+ return (1);
+ return (0);
+}
+
+int
+symtab_init(void)
+{
+ Elf *elf;
+ Elf_Scn *scn = NULL;
+ Sym *symtab, *symp, *lastsym;
+ char *strtab;
+ uint_t cnt;
+ int fd;
+ int i;
+ int strindex = -1;
+#if !defined(sun)
+ void *ksyms;
+ size_t sz;
+#endif
+
+ if ((fd = open("/dev/ksyms", O_RDONLY)) == -1)
+ return (-1);
+
+#if defined(sun)
+ (void) elf_version(EV_CURRENT);
+
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+#else
+ /* FreeBSD */
+ /*
+ * XXX - libelf needs to be fixed so it will work with
+ * non 'ordinary' files like /dev/ksyms. The following
+ * is a work around for now.
+ */
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ close(fd);
+ return (-1);
+ }
+ if (ioctl(fd, KIOCGSIZE, &sz) < 0) {
+ close(fd);
+ return (-1);
+ }
+ if (ioctl(fd, KIOCGADDR, &ksyms) < 0) {
+ close(fd);
+ return (-1);
+ }
+ if ((elf = elf_memory(ksyms, sz)) == NULL) {
+ close(fd);
+ return (-1);
+ }
+#endif
+
+ for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {
+ Shdr *shdr = elf_getshdr(scn);
+ if (shdr->sh_type == SHT_SYMTAB) {
+ symtab = (Sym *)elf_getdata(scn, NULL)->d_buf;
+ nsyms = shdr->sh_size / shdr->sh_entsize;
+ strindex = shdr->sh_link;
+ }
+ }
+
+ for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {
+ if (cnt == strindex)
+ strtab = (char *)elf_getdata(scn, NULL)->d_buf;
+ }
+
+ lastsym = symtab + nsyms;
+ nsyms = 0;
+ for (symp = symtab; symp < lastsym; symp++)
+ if ((uint_t)ELF32_ST_TYPE(symp->st_info) <= STT_FUNC &&
+ symp->st_size != 0)
+ add_symbol(symp->st_name + strtab,
+ (uintptr_t)symp->st_value, (size_t)symp->st_size);
+
+ fake_up_certain_popular_kernel_symbols();
+ (void) sprintf(maxsymname, "0x%lx", ULONG_MAX);
+ add_symbol(maxsymname, ULONG_MAX, 1);
+
+ qsort(symbol_table, nsyms, sizeof (syment_t), symcmp);
+
+ /*
+ * Destroy all duplicate symbols, then sort it again.
+ */
+ for (i = 0; i < nsyms - 1; i++)
+ if (symbol_table[i].addr == symbol_table[i + 1].addr)
+ symbol_table[i].addr = 0;
+
+ qsort(symbol_table, nsyms, sizeof (syment_t), symcmp);
+
+ while (symbol_table[1].addr == 0) {
+ symbol_table++;
+ nsyms--;
+ }
+ symbol_table[0].name = "(usermode)";
+ symbol_table[0].addr = 0;
+ symbol_table[0].size = 1;
+
+ close(fd);
+ return (0);
+}
+
+char *
+addr_to_sym(uintptr_t addr, uintptr_t *offset, size_t *sizep)
+{
+ int lo = 0;
+ int hi = nsyms - 1;
+ int mid;
+ syment_t *sep;
+
+ while (hi - lo > 1) {
+ mid = (lo + hi) / 2;
+ if (addr >= symbol_table[mid].addr) {
+ lo = mid;
+ } else {
+ hi = mid;
+ }
+ }
+ sep = &symbol_table[lo];
+ *offset = addr - sep->addr;
+ *sizep = sep->size;
+ return (sep->name);
+}
+
+uintptr_t
+sym_to_addr(char *name)
+{
+ int i;
+ syment_t *sep = symbol_table;
+
+ for (i = 0; i < nsyms; i++) {
+ if (strcmp(name, sep->name) == 0)
+ return (sep->addr);
+ sep++;
+ }
+ return (0);
+}
+
+size_t
+sym_size(char *name)
+{
+ int i;
+ syment_t *sep = symbol_table;
+
+ for (i = 0; i < nsyms; i++) {
+ if (strcmp(name, sep->name) == 0)
+ return (sep->size);
+ sep++;
+ }
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/mdb/tools/common/die.c b/cddl/contrib/opensolaris/cmd/mdb/tools/common/die.c
new file mode 100644
index 0000000..602969e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/mdb/tools/common/die.c
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <elf.h>
+
+#include <util.h>
+
+void
+die(char *format, ...)
+{
+ va_list ap;
+ int err = errno;
+#if !defined(sun)
+ const char *progname = getprogname();
+#endif
+
+ (void) fprintf(stderr, "%s: ", progname);
+
+ va_start(ap, format);
+ /* LINTED - variable format specifier */
+ (void) vfprintf(stderr, format, ap);
+ va_end(ap);
+
+ if (format[strlen(format) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", strerror(err));
+
+#if defined(__FreeBSD__)
+ exit(0);
+#else
+ exit(1);
+#endif
+}
+
+void
+elfdie(char *format, ...)
+{
+ va_list ap;
+#if !defined(sun)
+ const char *progname = getprogname();
+#endif
+
+ (void) fprintf(stderr, "%s: ", progname);
+
+ va_start(ap, format);
+ /* LINTED - variable format specifier */
+ (void) vfprintf(stderr, format, ap);
+ va_end(ap);
+
+ if (format[strlen(format) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", elf_errmsg(elf_errno()));
+
+#if defined(__FreeBSD__)
+ exit(0);
+#else
+ exit(1);
+#endif
+}
diff --git a/cddl/contrib/opensolaris/cmd/mdb/tools/common/util.h b/cddl/contrib/opensolaris/cmd/mdb/tools/common/util.h
new file mode 100644
index 0000000..a0932ad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/mdb/tools/common/util.h
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libelf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int findelfsecidx(Elf *, char *);
+
+extern void die(char *, ...);
+extern void elfdie(char *, ...);
+
+#if defined(sun)
+extern const char *progname;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UTIL_H */
diff --git a/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c
new file mode 100644
index 0000000..aa2c1f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c
@@ -0,0 +1,1021 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#if defined(sun)
+#pragma ident "%Z%%M% %I% %E% SMI"
+#endif
+
+#include <assert.h>
+#include <dtrace.h>
+#include <limits.h>
+#include <link.h>
+#include <priv.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <libgen.h>
+#include <libproc.h>
+#include <libproc_compat.h>
+
+static char *g_pname;
+static dtrace_hdl_t *g_dtp;
+struct ps_prochandle *g_pr;
+
+#define E_SUCCESS 0
+#define E_ERROR 1
+#define E_USAGE 2
+
+/*
+ * For hold times we use a global associative array since for mutexes, in
+ * user-land, it's not invalid to release a sychonization primitive that
+ * another thread acquired; rwlocks require a thread-local associative array
+ * since multiple thread can hold the same lock for reading. Note that we
+ * ignore recursive mutex acquisitions and releases as they don't truly
+ * affect lock contention.
+ */
+static const char *g_hold_init =
+"plockstat$target:::rw-acquire\n"
+"{\n"
+" self->rwhold[arg0] = timestamp;\n"
+"}\n"
+"plockstat$target:::mutex-acquire\n"
+"/arg1 == 0/\n"
+"{\n"
+" mtxhold[arg0] = timestamp;\n"
+"}\n";
+
+static const char *g_hold_histogram =
+"plockstat$target:::rw-release\n"
+"/self->rwhold[arg0] && arg1 == 1/\n"
+"{\n"
+" @rw_w_hold[arg0, ustack()] =\n"
+" quantize(timestamp - self->rwhold[arg0]);\n"
+" self->rwhold[arg0] = 0;\n"
+" rw_w_hold_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-release\n"
+"/self->rwhold[arg0]/\n"
+"{\n"
+" @rw_r_hold[arg0, ustack()] =\n"
+" quantize(timestamp - self->rwhold[arg0]);\n"
+" self->rwhold[arg0] = 0;\n"
+" rw_r_hold_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-release\n"
+"/mtxhold[arg0] && arg1 == 0/\n"
+"{\n"
+" @mtx_hold[arg0, ustack()] = quantize(timestamp - mtxhold[arg0]);\n"
+" mtxhold[arg0] = 0;\n"
+" mtx_hold_found = 1;\n"
+"}\n"
+"\n"
+"END\n"
+"/mtx_hold_found/\n"
+"{\n"
+" trace(\"Mutex hold\");\n"
+" printa(@mtx_hold);\n"
+"}\n"
+"END\n"
+"/rw_r_hold_found/\n"
+"{\n"
+" trace(\"R/W reader hold\");\n"
+" printa(@rw_r_hold);\n"
+"}\n"
+"END\n"
+"/rw_w_hold_found/\n"
+"{\n"
+" trace(\"R/W writer hold\");\n"
+" printa(@rw_w_hold);\n"
+"}\n";
+
+static const char *g_hold_times =
+"plockstat$target:::rw-release\n"
+"/self->rwhold[arg0] && arg1 == 1/\n"
+"{\n"
+" @rw_w_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n"
+" @rw_w_hold_count[arg0, ustack(5)] = count();\n"
+" self->rwhold[arg0] = 0;\n"
+" rw_w_hold_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-release\n"
+"/self->rwhold[arg0]/\n"
+"{\n"
+" @rw_r_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n"
+" @rw_r_hold_count[arg0, ustack(5)] = count();\n"
+" self->rwhold[arg0] = 0;\n"
+" rw_r_hold_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-release\n"
+"/mtxhold[arg0] && arg1 == 0/\n"
+"{\n"
+" @mtx_hold[arg0, ustack(5)] = sum(timestamp - mtxhold[arg0]);\n"
+" @mtx_hold_count[arg0, ustack(5)] = count();\n"
+" mtxhold[arg0] = 0;\n"
+" mtx_hold_found = 1;\n"
+"}\n"
+"\n"
+"END\n"
+"/mtx_hold_found/\n"
+"{\n"
+" trace(\"Mutex hold\");\n"
+" printa(@mtx_hold, @mtx_hold_count);\n"
+"}\n"
+"END\n"
+"/rw_r_hold_found/\n"
+"{\n"
+" trace(\"R/W reader hold\");\n"
+" printa(@rw_r_hold, @rw_r_hold_count);\n"
+"}\n"
+"END\n"
+"/rw_w_hold_found/\n"
+"{\n"
+" trace(\"R/W writer hold\");\n"
+" printa(@rw_w_hold, @rw_w_hold_count);\n"
+"}\n";
+
+
+/*
+ * For contention, we use thread-local associative arrays since we're tracing
+ * a single thread's activity in libc and multiple threads can be blocking or
+ * spinning on the same sychonization primitive.
+ */
+static const char *g_ctnd_init =
+"plockstat$target:::rw-block\n"
+"{\n"
+" self->rwblock[arg0] = timestamp;\n"
+"}\n"
+"plockstat$target:::mutex-block\n"
+"{\n"
+" self->mtxblock[arg0] = timestamp;\n"
+"}\n"
+"plockstat$target:::mutex-spin\n"
+"{\n"
+" self->mtxspin[arg0] = timestamp;\n"
+"}\n";
+
+static const char *g_ctnd_histogram =
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n"
+"{\n"
+" @rw_w_block[arg0, ustack()] =\n"
+" quantize(timestamp - self->rwblock[arg0]);\n"
+" self->rwblock[arg0] = 0;\n"
+" rw_w_block_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0] && arg2 != 0/\n"
+"{\n"
+" @rw_r_block[arg0, ustack()] =\n"
+" quantize(timestamp - self->rwblock[arg0]);\n"
+" self->rwblock[arg0] = 0;\n"
+" rw_r_block_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0]/\n"
+"{\n"
+" self->rwblock[arg0] = 0;\n"
+"}\n"
+"plockstat$target:::mutex-spun\n"
+"/self->mtxspin[arg0] && arg1 != 0/\n"
+"{\n"
+" @mtx_spin[arg0, ustack()] =\n"
+" quantize(timestamp - self->mtxspin[arg0]);\n"
+" self->mtxspin[arg0] = 0;\n"
+" mtx_spin_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-spun\n"
+"/self->mtxspin[arg0]/\n"
+"{\n"
+" @mtx_vain_spin[arg0, ustack()] =\n"
+" quantize(timestamp - self->mtxspin[arg0]);\n"
+" self->mtxspin[arg0] = 0;\n"
+" mtx_vain_spin_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-blocked\n"
+"/self->mtxblock[arg0] && arg1 != 0/\n"
+"{\n"
+" @mtx_block[arg0, ustack()] =\n"
+" quantize(timestamp - self->mtxblock[arg0]);\n"
+" self->mtxblock[arg0] = 0;\n"
+" mtx_block_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-blocked\n"
+"/self->mtxblock[arg0]/\n"
+"{\n"
+" self->mtxblock[arg0] = 0;\n"
+"}\n"
+"\n"
+"END\n"
+"/mtx_block_found/\n"
+"{\n"
+" trace(\"Mutex block\");\n"
+" printa(@mtx_block);\n"
+"}\n"
+"END\n"
+"/mtx_spin_found/\n"
+"{\n"
+" trace(\"Mutex spin\");\n"
+" printa(@mtx_spin);\n"
+"}\n"
+"END\n"
+"/mtx_vain_spin_found/\n"
+"{\n"
+" trace(\"Mutex unsuccessful spin\");\n"
+" printa(@mtx_vain_spin);\n"
+"}\n"
+"END\n"
+"/rw_r_block_found/\n"
+"{\n"
+" trace(\"R/W reader block\");\n"
+" printa(@rw_r_block);\n"
+"}\n"
+"END\n"
+"/rw_w_block_found/\n"
+"{\n"
+" trace(\"R/W writer block\");\n"
+" printa(@rw_w_block);\n"
+"}\n";
+
+
+static const char *g_ctnd_times =
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n"
+"{\n"
+" @rw_w_block[arg0, ustack(5)] =\n"
+" sum(timestamp - self->rwblock[arg0]);\n"
+" @rw_w_block_count[arg0, ustack(5)] = count();\n"
+" self->rwblock[arg0] = 0;\n"
+" rw_w_block_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0] && arg2 != 0/\n"
+"{\n"
+" @rw_r_block[arg0, ustack(5)] =\n"
+" sum(timestamp - self->rwblock[arg0]);\n"
+" @rw_r_block_count[arg0, ustack(5)] = count();\n"
+" self->rwblock[arg0] = 0;\n"
+" rw_r_block_found = 1;\n"
+"}\n"
+"plockstat$target:::rw-blocked\n"
+"/self->rwblock[arg0]/\n"
+"{\n"
+" self->rwblock[arg0] = 0;\n"
+"}\n"
+"plockstat$target:::mutex-spun\n"
+"/self->mtxspin[arg0] && arg1 != 0/\n"
+"{\n"
+" @mtx_spin[arg0, ustack(5)] =\n"
+" sum(timestamp - self->mtxspin[arg0]);\n"
+" @mtx_spin_count[arg0, ustack(5)] = count();\n"
+" self->mtxspin[arg0] = 0;\n"
+" mtx_spin_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-spun\n"
+"/self->mtxspin[arg0]/\n"
+"{\n"
+" @mtx_vain_spin[arg0, ustack(5)] =\n"
+" sum(timestamp - self->mtxspin[arg0]);\n"
+" @mtx_vain_spin_count[arg0, ustack(5)] = count();\n"
+" self->mtxspin[arg0] = 0;\n"
+" mtx_vain_spin_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-blocked\n"
+"/self->mtxblock[arg0] && arg1 != 0/\n"
+"{\n"
+" @mtx_block[arg0, ustack(5)] =\n"
+" sum(timestamp - self->mtxblock[arg0]);\n"
+" @mtx_block_count[arg0, ustack(5)] = count();\n"
+" self->mtxblock[arg0] = 0;\n"
+" mtx_block_found = 1;\n"
+"}\n"
+"plockstat$target:::mutex-blocked\n"
+"/self->mtxblock[arg0]/\n"
+"{\n"
+" self->mtxblock[arg0] = 0;\n"
+"}\n"
+"\n"
+"END\n"
+"/mtx_block_found/\n"
+"{\n"
+" trace(\"Mutex block\");\n"
+" printa(@mtx_block, @mtx_block_count);\n"
+"}\n"
+"END\n"
+"/mtx_spin_found/\n"
+"{\n"
+" trace(\"Mutex spin\");\n"
+" printa(@mtx_spin, @mtx_spin_count);\n"
+"}\n"
+"END\n"
+"/mtx_vain_spin_found/\n"
+"{\n"
+" trace(\"Mutex unsuccessful spin\");\n"
+" printa(@mtx_vain_spin, @mtx_vain_spin_count);\n"
+"}\n"
+"END\n"
+"/rw_r_block_found/\n"
+"{\n"
+" trace(\"R/W reader block\");\n"
+" printa(@rw_r_block, @rw_r_block_count);\n"
+"}\n"
+"END\n"
+"/rw_w_block_found/\n"
+"{\n"
+" trace(\"R/W writer block\");\n"
+" printa(@rw_w_block, @rw_w_block_count);\n"
+"}\n";
+
+static char g_prog[4096];
+static size_t g_proglen;
+static int g_opt_V, g_opt_s;
+static int g_intr;
+static int g_exited;
+static dtrace_optval_t g_nframes;
+static ulong_t g_nent = ULONG_MAX;
+
+#define PLOCKSTAT_OPTSTR "n:ps:e:vx:ACHV"
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, "Usage:\n"
+ "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n"
+ "\t command [arg...]\n"
+ "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n"
+ "\t -p pid\n", g_pname, g_pname);
+
+ exit(E_USAGE);
+}
+
+static void
+verror(const char *fmt, va_list ap)
+{
+ int error = errno;
+
+ (void) fprintf(stderr, "%s: ", g_pname);
+ (void) vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", strerror(error));
+}
+
+/*PRINTFLIKE1*/
+static void
+fatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verror(fmt, ap);
+ va_end(ap);
+
+ if (g_pr != NULL && g_dtp != NULL)
+ dtrace_proc_release(g_dtp, g_pr);
+
+ exit(E_ERROR);
+}
+
+/*PRINTFLIKE1*/
+static void
+dfatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ (void) fprintf(stderr, "%s: ", g_pname);
+ if (fmt != NULL)
+ (void) vfprintf(stderr, fmt, ap);
+
+ va_end(ap);
+
+ if (fmt != NULL && fmt[strlen(fmt) - 1] != '\n') {
+ (void) fprintf(stderr, ": %s\n",
+ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
+ } else if (fmt == NULL) {
+ (void) fprintf(stderr, "%s\n",
+ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
+ }
+
+ if (g_pr != NULL) {
+ dtrace_proc_continue(g_dtp, g_pr);
+ dtrace_proc_release(g_dtp, g_pr);
+ }
+
+ exit(E_ERROR);
+}
+
+/*PRINTFLIKE1*/
+static void
+notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verror(fmt, ap);
+ va_end(ap);
+}
+
+static void
+dprog_add(const char *prog)
+{
+ size_t len = strlen(prog);
+ bcopy(prog, g_prog + g_proglen, len + 1);
+ g_proglen += len;
+ assert(g_proglen < sizeof (g_prog));
+}
+
+static void
+dprog_compile(void)
+{
+ dtrace_prog_t *prog;
+ dtrace_proginfo_t info;
+
+ if (g_opt_V) {
+ (void) fprintf(stderr, "%s: vvvv D program vvvv\n", g_pname);
+ (void) fputs(g_prog, stderr);
+ (void) fprintf(stderr, "%s: ^^^^ D program ^^^^\n", g_pname);
+ }
+
+ if ((prog = dtrace_program_strcompile(g_dtp, g_prog,
+ DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL)
+ dfatal("failed to compile program");
+
+ if (dtrace_program_exec(g_dtp, prog, &info) == -1)
+ dfatal("failed to enable probes");
+}
+
+void
+print_legend(void)
+{
+ (void) printf("%5s %8s %-28s %s\n", "Count", "nsec", "Lock", "Caller");
+}
+
+void
+print_bar(void)
+{
+ (void) printf("---------------------------------------"
+ "----------------------------------------\n");
+}
+
+void
+print_histogram_header(void)
+{
+ (void) printf("\n%10s ---- Time Distribution --- %5s %s\n",
+ "nsec", "count", "Stack");
+}
+
+/*
+ * Convert an address to a symbolic string or a numeric string. If nolocks
+ * is set, we return an error code if this symbol appears to be a mutex- or
+ * rwlock-related symbol in libc so the caller has a chance to find a more
+ * helpful symbol.
+ */
+static int
+getsym(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size,
+ int nolocks)
+{
+ char name[256];
+ GElf_Sym sym;
+#if defined(sun)
+ prsyminfo_t info;
+#else
+ prmap_t *map;
+ int info; /* XXX unused */
+#endif
+ size_t len;
+
+ if (P == NULL || Pxlookup_by_addr(P, addr, name, sizeof (name),
+ &sym, &info) != 0) {
+ (void) snprintf(buf, size, "%#lx", addr);
+ return (0);
+ }
+#if defined(sun)
+ if (info.prs_object == NULL)
+ info.prs_object = "<unknown>";
+
+ if (info.prs_lmid != LM_ID_BASE) {
+ len = snprintf(buf, size, "LM%lu`", info.prs_lmid);
+ buf += len;
+ size -= len;
+ }
+
+ len = snprintf(buf, size, "%s`%s", info.prs_object, info.prs_name);
+#else
+ map = proc_addr2map(P, addr);
+ len = snprintf(buf, size, "%s`%s", map->pr_mapname, name);
+#endif
+ buf += len;
+ size -= len;
+
+ if (sym.st_value != addr)
+ len = snprintf(buf, size, "+%#lx", addr - sym.st_value);
+
+ if (nolocks && strcmp("libc.so.1", map->pr_mapname) == 0 &&
+ (strstr("mutex", name) == 0 ||
+ strstr("rw", name) == 0))
+ return (-1);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+process_aggregate(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
+{
+ const dtrace_recdesc_t *rec;
+ uintptr_t lock;
+ uint64_t *stack;
+ caddr_t data;
+ pid_t pid;
+ struct ps_prochandle *P;
+ char buf[256];
+ int i, j;
+ uint64_t sum, count, avg;
+
+ if ((*(uint_t *)arg)++ >= g_nent)
+ return (DTRACE_AGGWALK_NEXT);
+
+ rec = aggsdata[0]->dtada_desc->dtagd_rec;
+ data = aggsdata[0]->dtada_data;
+
+ /*LINTED - alignment*/
+ lock = (uintptr_t)*(uint64_t *)(data + rec[1].dtrd_offset);
+ /*LINTED - alignment*/
+ stack = (uint64_t *)(data + rec[2].dtrd_offset);
+
+ if (!g_opt_s) {
+ /*LINTED - alignment*/
+ sum = *(uint64_t *)(aggsdata[1]->dtada_data +
+ aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset);
+ /*LINTED - alignment*/
+ count = *(uint64_t *)(aggsdata[2]->dtada_data +
+ aggsdata[2]->dtada_desc->dtagd_rec[3].dtrd_offset);
+ } else {
+ uint64_t *a;
+
+ /*LINTED - alignment*/
+ a = (uint64_t *)(aggsdata[1]->dtada_data +
+ aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset);
+
+ print_bar();
+ print_legend();
+
+ for (count = sum = 0, i = DTRACE_QUANTIZE_ZEROBUCKET, j = 0;
+ i < DTRACE_QUANTIZE_NBUCKETS; i++, j++) {
+ count += a[i];
+ sum += a[i] << (j - 64);
+ }
+ }
+
+ avg = sum / count;
+ (void) printf("%5llu %8llu ", (u_longlong_t)count, (u_longlong_t)avg);
+
+ pid = stack[0];
+ P = dtrace_proc_grab(g_dtp, pid, PGRAB_RDONLY);
+
+ (void) getsym(P, lock, buf, sizeof (buf), 0);
+ (void) printf("%-28s ", buf);
+
+ for (i = 2; i <= 5; i++) {
+ if (getsym(P, stack[i], buf, sizeof (buf), 1) == 0)
+ break;
+ }
+ (void) printf("%s\n", buf);
+
+ if (g_opt_s) {
+ int stack_done = 0;
+ int quant_done = 0;
+ int first_bin, last_bin;
+ uint64_t bin_size, *a;
+
+ /*LINTED - alignment*/
+ a = (uint64_t *)(aggsdata[1]->dtada_data +
+ aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset);
+
+ print_histogram_header();
+
+ for (first_bin = DTRACE_QUANTIZE_ZEROBUCKET;
+ a[first_bin] == 0; first_bin++)
+ continue;
+ for (last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 63;
+ a[last_bin] == 0; last_bin--)
+ continue;
+
+ for (i = 0; !stack_done || !quant_done; i++) {
+ if (!stack_done) {
+ (void) getsym(P, stack[i + 2], buf,
+ sizeof (buf), 0);
+ } else {
+ buf[0] = '\0';
+ }
+
+ if (!quant_done) {
+ bin_size = a[first_bin];
+
+ (void) printf("%10llu |%-24.*s| %5llu %s\n",
+ 1ULL <<
+ (first_bin - DTRACE_QUANTIZE_ZEROBUCKET),
+ (int)(24.0 * bin_size / count),
+ "@@@@@@@@@@@@@@@@@@@@@@@@@@",
+ (u_longlong_t)bin_size, buf);
+ } else {
+ (void) printf("%43s %s\n", "", buf);
+ }
+
+ if (i + 1 >= g_nframes || stack[i + 3] == 0)
+ stack_done = 1;
+
+ if (first_bin++ == last_bin)
+ quant_done = 1;
+ }
+ }
+
+ dtrace_proc_release(g_dtp, P);
+
+ return (DTRACE_AGGWALK_NEXT);
+}
+
+/*ARGSUSED*/
+static void
+prochandler(struct ps_prochandle *P, const char *msg, void *arg)
+{
+#if defined(sun)
+ const psinfo_t *prp = Ppsinfo(P);
+ int pid = Pstatus(P)->pr_pid;
+#else
+ int pid = proc_getpid(P);
+ int wstat = proc_getwstat(P);
+#endif
+ char name[SIG2STR_MAX];
+
+ if (msg != NULL) {
+ notice("pid %d: %s\n", pid, msg);
+ return;
+ }
+
+ switch (Pstate(P)) {
+ case PS_UNDEAD:
+ /*
+ * Ideally we would like to always report pr_wstat here, but it
+ * isn't possible given current /proc semantics. If we grabbed
+ * the process, Ppsinfo() will either fail or return a zeroed
+ * psinfo_t depending on how far the parent is in reaping it.
+ * When /proc provides a stable pr_wstat in the status file,
+ * this code can be improved by examining this new pr_wstat.
+ */
+ if (WIFSIGNALED(wstat)) {
+ notice("pid %d terminated by %s\n", pid,
+ proc_signame(WTERMSIG(wstat),
+ name, sizeof (name)));
+ } else if (WEXITSTATUS(wstat) != 0) {
+ notice("pid %d exited with status %d\n",
+ pid, WEXITSTATUS(wstat));
+ } else {
+ notice("pid %d has exited\n", pid);
+ }
+ g_exited = 1;
+ break;
+
+ case PS_LOST:
+ notice("pid %d exec'd a set-id or unobservable program\n", pid);
+ g_exited = 1;
+ break;
+ }
+}
+
+/*ARGSUSED*/
+static int
+chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg)
+{
+ dtrace_eprobedesc_t *epd = data->dtpda_edesc;
+ dtrace_aggvarid_t aggvars[2];
+ const void *buf;
+ int i, nagv;
+
+ /*
+ * A NULL rec indicates that we've processed the last record.
+ */
+ if (rec == NULL)
+ return (DTRACE_CONSUME_NEXT);
+
+ buf = data->dtpda_data - rec->dtrd_offset;
+
+ switch (rec->dtrd_action) {
+ case DTRACEACT_DIFEXPR:
+ (void) printf("\n%s\n\n", (char *)buf + rec->dtrd_offset);
+ if (!g_opt_s) {
+ print_legend();
+ print_bar();
+ }
+ return (DTRACE_CONSUME_NEXT);
+
+ case DTRACEACT_PRINTA:
+ for (nagv = 0, i = 0; i < epd->dtepd_nrecs - 1; i++) {
+ const dtrace_recdesc_t *nrec = &rec[i];
+
+ if (nrec->dtrd_uarg != rec->dtrd_uarg)
+ break;
+
+ /*LINTED - alignment*/
+ aggvars[nagv++] = *(dtrace_aggvarid_t *)((caddr_t)buf +
+ nrec->dtrd_offset);
+ }
+
+ if (nagv == (g_opt_s ? 1 : 2)) {
+ uint_t nent = 0;
+ if (dtrace_aggregate_walk_joined(g_dtp, aggvars, nagv,
+ process_aggregate, &nent) != 0)
+ dfatal("failed to walk aggregate");
+ }
+
+ return (DTRACE_CONSUME_NEXT);
+ }
+
+ return (DTRACE_CONSUME_THIS);
+}
+
+/*ARGSUSED*/
+static void
+intr(int signo)
+{
+ g_intr = 1;
+}
+
+int
+main(int argc, char **argv)
+{
+#if defined(sun)
+ ucred_t *ucp;
+#endif
+ int err;
+ int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0;
+ char c, *p, *end;
+ struct sigaction act;
+ int done = 0;
+
+ g_pname = basename(argv[0]);
+ argv[0] = g_pname; /* rewrite argv[0] for getopt errors */
+#if defined(sun)
+ /*
+ * Make sure we have the required dtrace_proc privilege.
+ */
+ if ((ucp = ucred_get(getpid())) != NULL) {
+ const priv_set_t *psp;
+ if ((psp = ucred_getprivset(ucp, PRIV_EFFECTIVE)) != NULL &&
+ !priv_ismember(psp, PRIV_DTRACE_PROC)) {
+ fatal("dtrace_proc privilege required\n");
+ }
+
+ ucred_free(ucp);
+ }
+#endif
+
+ while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) {
+ switch (c) {
+ case 'n':
+ errno = 0;
+ g_nent = strtoul(optarg, &end, 10);
+ if (*end != '\0' || errno != 0) {
+ (void) fprintf(stderr, "%s: invalid count "
+ "'%s'\n", g_pname, optarg);
+ usage();
+ }
+ break;
+
+ case 'p':
+ opt_p = 1;
+ break;
+
+ case 'v':
+ opt_v = 1;
+ break;
+
+ case 'A':
+ opt_C = opt_H = 1;
+ break;
+
+ case 'C':
+ opt_C = 1;
+ break;
+
+ case 'H':
+ opt_H = 1;
+ break;
+
+ case 'V':
+ g_opt_V = 1;
+ break;
+
+ default:
+ if (strchr(PLOCKSTAT_OPTSTR, c) == NULL)
+ usage();
+ }
+ }
+
+ /*
+ * We need a command or at least one pid.
+ */
+ if (argc == optind)
+ usage();
+
+ if (opt_C == 0 && opt_H == 0)
+ opt_C = 1;
+
+ if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL)
+ fatal("failed to initialize dtrace: %s\n",
+ dtrace_errmsg(NULL, err));
+
+ /*
+ * The longest string we trace is 23 bytes long -- so 32 is plenty.
+ */
+ if (dtrace_setopt(g_dtp, "strsize", "32") == -1)
+ dfatal("failed to set 'strsize'");
+
+ /*
+ * 1k should be more than enough for all trace() and printa() actions.
+ */
+ if (dtrace_setopt(g_dtp, "bufsize", "1k") == -1)
+ dfatal("failed to set 'bufsize'");
+
+ /*
+ * The table we produce has the hottest locks at the top.
+ */
+ if (dtrace_setopt(g_dtp, "aggsortrev", NULL) == -1)
+ dfatal("failed to set 'aggsortrev'");
+
+ /*
+ * These are two reasonable defaults which should suffice.
+ */
+ if (dtrace_setopt(g_dtp, "aggsize", "256k") == -1)
+ dfatal("failed to set 'aggsize'");
+ if (dtrace_setopt(g_dtp, "aggrate", "1sec") == -1)
+ dfatal("failed to set 'aggrate'");
+
+ /*
+ * Take a second pass through to look for options that set options now
+ * that we have an open dtrace handle.
+ */
+ optind = 1;
+ while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) {
+ switch (c) {
+ case 's':
+ g_opt_s = 1;
+ if (dtrace_setopt(g_dtp, "ustackframes", optarg) == -1)
+ dfatal("failed to set 'ustackframes'");
+ break;
+
+ case 'x':
+ if ((p = strchr(optarg, '=')) != NULL)
+ *p++ = '\0';
+
+ if (dtrace_setopt(g_dtp, optarg, p) != 0)
+ dfatal("failed to set -x %s", optarg);
+ break;
+
+ case 'e':
+ errno = 0;
+ (void) strtoul(optarg, &end, 10);
+ if (*optarg == '-' || *end != '\0' || errno != 0) {
+ (void) fprintf(stderr, "%s: invalid timeout "
+ "'%s'\n", g_pname, optarg);
+ usage();
+ }
+
+ /*
+ * Construct a DTrace enabling that will exit after
+ * the specified number of seconds.
+ */
+ dprog_add("BEGIN\n{\n\tend = timestamp + ");
+ dprog_add(optarg);
+ dprog_add(" * 1000000000;\n}\n");
+ dprog_add("tick-10hz\n/timestamp >= end/\n");
+ dprog_add("{\n\texit(0);\n}\n");
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (opt_H) {
+ dprog_add(g_hold_init);
+ if (!g_opt_s)
+ dprog_add(g_hold_times);
+ else
+ dprog_add(g_hold_histogram);
+ }
+
+ if (opt_C) {
+ dprog_add(g_ctnd_init);
+ if (!g_opt_s)
+ dprog_add(g_ctnd_times);
+ else
+ dprog_add(g_ctnd_histogram);
+ }
+
+ if (opt_p) {
+ ulong_t pid;
+
+ if (argc > 1) {
+ (void) fprintf(stderr, "%s: only one pid is allowed\n",
+ g_pname);
+ usage();
+ }
+
+ errno = 0;
+ pid = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || errno != 0 || (pid_t)pid != pid) {
+ (void) fprintf(stderr, "%s: invalid pid '%s'\n",
+ g_pname, argv[0]);
+ usage();
+ }
+
+ if ((g_pr = dtrace_proc_grab(g_dtp, (pid_t)pid, 0)) == NULL)
+ dfatal(NULL);
+ } else {
+ if ((g_pr = dtrace_proc_create(g_dtp, argv[0], argv, NULL, NULL)) == NULL)
+ dfatal(NULL);
+ }
+
+ dprog_compile();
+
+ if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1)
+ dfatal("failed to establish proc handler");
+
+ (void) sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = intr;
+ (void) sigaction(SIGINT, &act, NULL);
+ (void) sigaction(SIGTERM, &act, NULL);
+
+ if (dtrace_go(g_dtp) != 0)
+ dfatal("dtrace_go()");
+
+ if (dtrace_getopt(g_dtp, "ustackframes", &g_nframes) != 0)
+ dfatal("failed to get 'ustackframes'");
+
+ dtrace_proc_continue(g_dtp, g_pr);
+
+ if (opt_v)
+ (void) printf("%s: tracing enabled for pid %d\n", g_pname,
+#if defined(sun)
+ (int)Pstatus(g_pr)->pr_pid);
+#else
+ (int)proc_getpid(g_pr));
+#endif
+
+ do {
+ if (!g_intr && !done)
+ dtrace_sleep(g_dtp);
+
+ if (done || g_intr || g_exited) {
+ done = 1;
+ if (dtrace_stop(g_dtp) == -1)
+ dfatal("couldn't stop tracing");
+ }
+
+ switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) {
+ case DTRACE_WORKSTATUS_DONE:
+ done = 1;
+ break;
+ case DTRACE_WORKSTATUS_OKAY:
+ break;
+ default:
+ dfatal("processing aborted");
+ }
+
+ } while (!done);
+
+ dtrace_close(g_dtp);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/pyzfs/pyzfs.py b/cddl/contrib/opensolaris/cmd/pyzfs/pyzfs.py
new file mode 100644
index 0000000..3867d91
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/pyzfs/pyzfs.py
@@ -0,0 +1,79 @@
+#! /usr/bin/python2.4 -S
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# Note, we want SIGINT (control-c) to exit the process quietly, to mimic
+# the standard behavior of C programs. The best we can do with pure
+# Python is to run with -S (to disable "import site"), and start our
+# program with a "try" statement. Hopefully nobody hits ^C before our
+# try statement is executed.
+
+try:
+ import site
+ import gettext
+ import zfs.util
+ import zfs.ioctl
+ import sys
+ import errno
+
+ """This is the main script for doing zfs subcommands. It doesn't know
+ what subcommands there are, it just looks for a module zfs.<subcommand>
+ that implements that subcommand."""
+
+ _ = gettext.translation("SUNW_OST_OSCMD", "/usr/lib/locale",
+ fallback=True).gettext
+
+ if len(sys.argv) < 2:
+ sys.exit(_("missing subcommand argument"))
+
+ zfs.ioctl.set_cmdstr(" ".join(["zfs"] + sys.argv[1:]))
+
+ try:
+ # import zfs.<subcommand>
+ # subfunc = zfs.<subcommand>.do_<subcommand>
+
+ subcmd = sys.argv[1]
+ __import__("zfs." + subcmd)
+ submod = getattr(zfs, subcmd)
+ subfunc = getattr(submod, "do_" + subcmd)
+ except (ImportError, AttributeError):
+ sys.exit(_("invalid subcommand"))
+
+ try:
+ subfunc()
+ except zfs.util.ZFSError, e:
+ print(e)
+ sys.exit(1)
+
+except IOError, e:
+ import errno
+ import sys
+
+ if e.errno == errno.EPIPE:
+ sys.exit(1)
+ raise
+except KeyboardInterrupt:
+ import sys
+
+ sys.exit(1)
diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h b/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h
new file mode 100644
index 0000000..2d2963f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/include/_string_table.h
@@ -0,0 +1,126 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef __STRING_TABLE_DOT_H
+#define __STRING_TABLE_DOT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/avl.h>
+#include <string_table.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A string is represented in a string table using two values: length, and
+ * value. Grouping all the strings of a given length together allows for
+ * efficient matching of tail strings, as each input string value is hashed.
+ * Each string table uses a 2-level AVL tree of AVL trees to represent this
+ * organization.
+ *
+ * The outer (main) AVL tree contains LenNode structures. The search key for
+ * nodes on this main tree is the string length. Each such node represents
+ * all strings of a given length, and all strings of that length are found
+ * within.
+ *
+ * The strings within each LenNode are maintained using a secondary AVL tree
+ * of StrNode structures. The search key for this inner tree is the string
+ * itself. The strings are maintained in lexical order.
+ */
+typedef struct {
+ avl_node_t sn_avlnode; /* AVL book-keeping */
+ const char *sn_str; /* string */
+ size_t sn_refcnt; /* reference count */
+} StrNode;
+
+typedef struct {
+ avl_node_t ln_avlnode; /* AVL book-keeping */
+ avl_tree_t *ln_strtree; /* AVL tree of associated strings */
+ size_t ln_strlen; /* length of associated strings */
+} LenNode;
+
+/*
+ * Define a master string data item. Other strings may be suffixes of this
+ * string. The final string table will consist of the master string values,
+ * laid end to end, with the other strings referencing their tails.
+ */
+typedef struct str_master Str_master;
+
+struct str_master {
+ const char *sm_str; /* pointer to master string */
+ Str_master *sm_next; /* used for tracking master strings */
+ size_t sm_strlen; /* length of master string */
+ uint_t sm_hashval; /* hashval of master string */
+ size_t sm_stroff; /* offset into destination strtab */
+};
+
+/*
+ * Define a hash data item. This item represents an individual string that has
+ * been input into the String hash table. The string may either be a suffix of
+ * another string, or a master string.
+ */
+typedef struct str_hash Str_hash;
+
+struct str_hash {
+ size_t hi_strlen; /* string length */
+ size_t hi_refcnt; /* number of references to str */
+ uint_t hi_hashval; /* hash for string */
+ Str_master *hi_mstr; /* pointer to master string */
+ Str_hash *hi_next; /* next entry in hash bucket */
+};
+
+/*
+ * Controlling data structure for a String Table.
+ */
+struct str_tbl {
+ avl_tree_t *st_lentree; /* AVL tree of string lengths */
+ char *st_strbuf; /* string buffer */
+ Str_hash **st_hashbcks; /* hash buckets */
+ Str_master *st_mstrlist; /* list of all master strings */
+ size_t st_fullstrsize; /* uncompressed table size */
+ size_t st_nextoff; /* next available string */
+ size_t st_strsize; /* compressed size */
+ size_t st_strcnt; /* number of strings */
+ uint_t st_hbckcnt; /* number of buckets in */
+ /* hashlist */
+ uint_t st_flags;
+};
+
+#define FLG_STTAB_COMPRESS 0x01 /* compressed string table */
+#define FLG_STTAB_COOKED 0x02 /* offset has been assigned */
+
+/*
+ * Starting value for use with string hashing functions inside of string_table.c
+ */
+#define HASHSEED 5381
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STRING_TABLE_DOT_H */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/alist.h b/cddl/contrib/opensolaris/cmd/sgs/include/alist.h
new file mode 100644
index 0000000..c27160b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/include/alist.h
@@ -0,0 +1,280 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Define an Alist, a list maintained as a reallocable array, and a for() loop
+ * macro to generalize its traversal. Note that the array can be reallocated
+ * as it is being traversed, thus the offset of each element is recomputed from
+ * the start of the structure.
+ */
+
+#ifndef _ALIST_H
+#define _ALIST_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/machelf.h>
+#else
+#include <sys/elf.h>
+#endif
+
+/*
+ * An Alist implements array lists. The functionality is similar to
+ * that of a linked list. However, an Alist is represented by a single
+ * contigious allocation of memory. The head of the memory is a header
+ * that contains control information for the list. Following the header
+ * is an array used to hold the user data. In the type definitions that
+ * follow, we define these as an array with a single element, but when
+ * we allocate the memory, we actually allocate the amount of memory needed.
+ *
+ * There are two "flavors" of array list:
+ *
+ * Alist - Contain arbitrary data, usually structs.
+ * APlist - Contain pointers to data allocated elsewhere.
+ *
+ * This differentiation is useful, because pointer lists are heavily
+ * used, and support a slightly different set of operations that are
+ * unique to their purpose.
+ *
+ * Array lists are initially represented by a NULL pointer. The memory
+ * for the list is only allocated if an item is inserted. This is very
+ * efficient for data structures that may or may not be needed for a
+ * given linker operation --- you only pay for what you use. In addition:
+ *
+ * - Array lists grow as needed (memory is reallocated as necessary)
+ * - Data is kept contiguously (no unused holes in between elements)
+ * at the beginning of the data area. This locality has
+ * good cache behavior, as access to adjacent items are
+ * highly likely to be in the same page of memory.
+ * - Insert/Delete operations at the end of the list are very
+ * efficient. However, insert/delete operations elsewhere
+ * will cause a relatively expensive overlapped memory
+ * copy of the data following the insert/delete location.
+ * - As with any generic memory alloctor (i.e. malloc()/free()),
+ * array lists are not type safe for the data they contain.
+ * Data is managed as (void *) pointers to data of a given
+ * length, so the Alist module cannot prevent the caller from
+ * inserting/extracting the wrong type of data. The caller
+ * must guard against this.
+ * - To free an array list, simply call the standard free() function
+ * on the list pointer.
+ */
+
+
+
+/*
+ * Aliste is used to represent list indexes, offsets, and sizes.
+ */
+typedef size_t Aliste;
+
+
+
+/*
+ * Alist is used to hold non-pointer items --- usually structs:
+ * - There must be an even number of Aliste fields before the
+ * al_data field. This ensures that al_data will have
+ * an alignment of 8, no matter whether sizeof(Aliste)
+ * is 4 or 8. That means that al_data will have sufficient
+ * alignment for any use, just like memory allocated via
+ * malloc().
+ * - al_nitems and al_next are redundant, in that they are
+ * directly related:
+ * al_next = al_nitems * al_size
+ * We do this to make ALIST_TRAVERSE_BYOFFSET maximally
+ * efficient. This doesn't waste space, because of the
+ * requirement to have an even # of Alist fields (above).
+ *
+ * Note that Alists allow the data to be referenced by 0 based array
+ * index, or by their byte offset from the start of the Alist memory
+ * allocation. The index form is preferred for most use, as it is simpler.
+ * However, by-offset access is used by rtld link maps, and this ability
+ * is convenient in that case.
+ */
+typedef struct {
+ Aliste al_arritems; /* # of items in al_data allocation */
+ Aliste al_nitems; /* # items (index of next avail item) */
+ Aliste al_next; /* offset of next available al_data[] */
+ Aliste al_size; /* size of each al_data[] item */
+ void *al_data[1]; /* data (can grow) */
+} Alist;
+
+/*
+ * APlist is a variant of Alist that contains pointers. There are several
+ * benefits to this special type:
+ * - API is simpler
+ * - Pointers are used directly, instead of requiring a
+ * pointer-to-pointer double indirection.
+ * - The implementation is slightly more efficient.
+ * - Operations that make particular sense for pointers
+ * can be supported without confusing the API for the
+ * regular Alists.
+ */
+typedef struct {
+ Aliste apl_arritems; /* # of items in apl_data allocation */
+ Aliste apl_nitems; /* # items (index of next avail item) */
+ void *apl_data[1]; /* data area: (arrcnt * size) bytes */
+} APlist;
+
+
+/*
+ * The ALIST_OFF_DATA and APLIST_OFF_DATA macros give the byte offset
+ * from the start of an array list to the first byte of the data area
+ * used to hold user data. The same trick used by the standard offsetof()
+ * macro is used.
+ */
+#define ALIST_OFF_DATA ((size_t)(((Alist *)0)->al_data))
+#define APLIST_OFF_DATA ((size_t)(((APlist *)0)->apl_data))
+
+
+/*
+ * The TRAVERSE macros are intended to be used within a for(), and
+ * cause the resulting loop to iterate over each item in the loop,
+ * in order.
+ * ALIST_TRAVERSE: Traverse over the items in an Alist,
+ * using the zero based item array index to refer to
+ * each item.
+ * ALIST_TRAVERSE_BY_OFFSET: Traverse over the items in an
+ * Alist using the byte offset from the head of the
+ * Alist pointer to refer to each item. It should be noted
+ * that the first such offset is given by ALIST_OFF_DATA,
+ * and as such, there will never be a 0 offset. Some code
+ * uses this fact to treat 0 as a reserved value with
+ * special meaning.
+ *
+ * By-offset access is convenient for some parts of
+ * rtld, where a value of 0 is used to indicate an
+ * uninitialized link map control.
+ *
+ * APLIST_TRAVERSE: Traverse over the pointers in an APlist, using
+ * the zero based item array index to refer to each pointer.
+ */
+
+/*
+ * Within the loop:
+ *
+ * LIST - Pointer to Alist structure for list
+ * IDX - The current item index
+ * OFF - The current item offset
+ * DATA - Pointer to item
+ */
+#define ALIST_TRAVERSE(LIST, IDX, DATA) \
+ (IDX) = 0, \
+ ((LIST) != NULL) && ((DATA) = (void *)(LIST)->al_data); \
+ \
+ ((LIST) != NULL) && ((IDX) < (LIST)->al_nitems); \
+ \
+ (IDX)++, \
+ (DATA) = (void *) (((LIST)->al_size * (IDX)) + (char *)(LIST)->al_data)
+
+#define ALIST_TRAVERSE_BY_OFFSET(LIST, OFF, DATA) \
+ (((LIST) != NULL) && ((OFF) = ALIST_OFF_DATA) && \
+ (((DATA) = (void *)((char *)(LIST) + (OFF))))); \
+ \
+ (((LIST) != NULL) && ((OFF) < (LIST)->al_next)); \
+ \
+ (((OFF) += ((LIST)->al_size)), \
+ ((DATA) = (void *)((char *)(LIST) + (OFF))))
+
+/*
+ * Within the loop:
+ *
+ * LIST - Pointer to APlist structure for list
+ * IDX - The current item index
+ * PTR - item value
+ *
+ * Note that this macro is designed to ensure that PTR retains the
+ * value of the final pointer in the list after exiting the for loop,
+ * and to avoid dereferencing an out of range address. This is done by
+ * doing the dereference in the middle expression, using the comma
+ * operator to ensure that a NULL pointer won't stop the loop.
+ */
+#define APLIST_TRAVERSE(LIST, IDX, PTR) \
+ (IDX) = 0; \
+ \
+ ((LIST) != NULL) && ((IDX) < (LIST)->apl_nitems) && \
+ (((PTR) = ((LIST)->apl_data)[IDX]), 1); \
+ \
+ (IDX)++
+
+
+/*
+ * Possible values returned by aplist_test()
+ */
+typedef enum {
+ ALE_ALLOCFAIL = 0, /* Memory allocation error */
+ ALE_EXISTS = 1, /* alist entry already exists */
+ ALE_NOTFND = 2, /* item not found and insert not required */
+ ALE_CREATE = 3 /* alist entry created */
+} aplist_test_t;
+
+
+/*
+ * Access to an Alist item by index or offset. This is needed because the
+ * size of an item in an Alist is not known by the C compiler, and we
+ * have to do the indexing arithmetic explicitly.
+ *
+ * For an APlist, index the apl_data field directly --- No macro is needed.
+ */
+#define alist_item(_lp, _idx) \
+ ((void *)(ALIST_OFF_DATA + ((_idx) * (_lp)->al_size) + (char *)(_lp)))
+#define alist_item_by_offset(_lp, _off) \
+ ((void *)((_off) + (char *)(_lp)))
+
+/*
+ * # of items currently found in a list. These macros handle the case
+ * where the list has not been allocated yet.
+ */
+#define alist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->al_nitems)
+#define aplist_nitems(_lp) (((_lp) == NULL) ? 0 : (_lp)->apl_nitems)
+
+
+extern void *alist_append(Alist **, const void *, size_t, Aliste);
+extern void alist_delete(Alist *, Aliste *);
+extern void alist_delete_by_offset(Alist *, Aliste *);
+extern void *alist_insert(Alist **, const void *, size_t,
+ Aliste, Aliste);
+extern void *alist_insert_by_offset(Alist **, const void *, size_t,
+ Aliste, Aliste);
+extern void alist_reset(Alist *);
+
+
+extern void *aplist_append(APlist **, const void *, Aliste);
+extern void aplist_delete(APlist *, Aliste *);
+extern int aplist_delete_value(APlist *, const void *);
+extern void *aplist_insert(APlist **, const void *,
+ Aliste, Aliste idx);
+extern void aplist_reset(APlist *);
+extern aplist_test_t aplist_test(APlist **, const void *, Aliste);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ALIST_H */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/debug.h b/cddl/contrib/opensolaris/cmd/sgs/include/debug.h
new file mode 100644
index 0000000..0a42f8d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/include/debug.h
@@ -0,0 +1,1017 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Global include file for lddbg debugging.
+ *
+ * ld(1) and ld.so.1(1) carry out all diagnostic debugging calls via lazy
+ * loading the library liblddbg.so. Thus debugging is always enabled. The
+ * utility elfdump(1) is explicitly dependent upon this library. There are two
+ * categories of routines defined in this library:
+ *
+ * o Debugging routines that have specific linker knowledge, and test the
+ * class of debugging allowable before proceeding, start with the `Dbg_'
+ * prefix.
+ *
+ * o Lower level routines that provide generic ELF structure interpretation
+ * start with the `Elf_' prefix. These latter routines are the only
+ * routines used by the elfdump(1) utility.
+ */
+#include <sgs.h>
+#include <libld.h>
+#include <rtld.h>
+#include <gelf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Define Dbg_*() interface flags. These flags direct the debugging routine to
+ * generate different diagnostics, thus the strings themselves are maintained
+ * in the debugging library.
+ */
+#define DBG_SUP_ENVIRON 1
+#define DBG_SUP_CMDLINE 2
+#define DBG_SUP_DEFAULT 3
+
+#define DBG_CONF_IGNORE 1 /* configuration processing errors */
+#define DBG_CONF_VERSION 2
+#define DBG_CONF_PRCFAIL 3
+#define DBG_CONF_CORRUPT 4
+#define DBG_CONF_ABIMISMATCH 5
+
+#define DBG_ORDER_INFO_RANGE 1 /* sh_link out of range */
+#define DBG_ORDER_INFO_ORDER 2 /* sh_info also ordered */
+#define DBG_ORDER_LINK_OUTRANGE 3 /* sh_link out of range */
+#define DBG_ORDER_FLAGS 4 /* sh_flags do not match */
+#define DBG_ORDER_CYCLIC 5 /* sh_link cyclic */
+#define DBG_ORDER_LINK_ERROR 6 /* sh_link (one) has an error */
+
+#define DBG_INIT_SORT 1 /* calling init from sorted order */
+#define DBG_INIT_PEND 2 /* calling pending init */
+#define DBG_INIT_DYN 3 /* dynamically triggered init */
+#define DBG_INIT_DONE 4 /* init completed */
+
+#define DBG_DLSYM_DEF 0
+#define DBG_DLSYM_NEXT 1
+#define DBG_DLSYM_DEFAULT 2
+#define DBG_DLSYM_SELF 3
+#define DBG_DLSYM_PROBE 4
+#define DBG_DLSYM_SINGLETON 5
+
+#define DBG_DLCLOSE_NULL 0
+#define DBG_DLCLOSE_IGNORE 1
+#define DBG_DLCLOSE_RESCAN 2
+
+#define DBG_WAIT_INIT 1
+#define DBG_WAIT_FINI 2
+#define DBG_WAIT_SYMBOL 3
+
+#define DBG_SYM_REDUCE_GLOBAL 1 /* reporting global symbols to local */
+#define DBG_SYM_REDUCE_RETAIN 2 /* reporting non reduced local syms */
+
+/*
+ * Group handle operations - passed to Dbg_file_hdl_title(). Indicate why
+ * handle dependencies are being manipulated.
+ */
+#define DBG_HDL_CREATE 0 /* handle creation */
+#define DBG_HDL_ADD 1 /* addition to existing handle */
+#define DBG_HDL_DELETE 2 /* deletion from a handle */
+#define DBG_HDL_ORPHAN 3 /* handle being moved to orphan list */
+#define DBG_HDL_REINST 4 /* handle reinstated from orphan list */
+
+/*
+ * Group handle dependency operations - passed to Dbg_file_hdl_action().
+ * Identify the dependencies that are associated with a handle.
+ */
+#define DBG_DEP_ADD 0 /* dependency added */
+#define DBG_DEP_UPDATE 1 /* dependency updated */
+#define DBG_DEP_DELETE 2 /* dependency deleted */
+#define DBG_DEP_REMOVE 3 /* dependency removed from handle */
+#define DBG_DEP_REMAIN 4 /* dependency must remain on handle */
+#define DBG_DEP_ORPHAN 5 /* dependency must remain an orphan */
+#define DBG_DEP_REINST 6 /* dependency reinstated from orphan */
+
+/*
+ * Binding information, indicating the result of a symbol binding. Can also
+ * indicate the reference as being EXTERN or PARENT. Binding information is
+ * used to augment diagnostic binding information (which in turn can be used by
+ * lari(1)), and to enable ldd(1) -p processing.
+ */
+#define DBG_BINFO_FOUND 0x0001 /* information regarding binding */
+#define DBG_BINFO_DIRECT 0x0002 /* bound directly */
+#define DBG_BINFO_COPYREF 0x0004 /* bound to copy relocated reference */
+#define DBG_BINFO_FILTEE 0x0008 /* bound to filtee */
+#define DBG_BINFO_INTERPOSE 0x0010 /* bound to an identified interposer */
+#define DBG_BINFO_PLTADDR 0x0020 /* bound to executables undefined plt */
+#define DBG_BINFO_MSK 0x0fff
+
+#define DBG_BINFO_REF_EXTERN 0x1000 /* reference to EXTERN */
+#define DBG_BINFO_REF_PARENT 0x2000 /* reference to PARENT */
+#define DBG_BINFO_REF_MSK 0xf000
+
+
+#define DBG_CAP_INITIAL 0
+#define DBG_CAP_IGNORE 1
+#define DBG_CAP_OLD 2
+#define DBG_CAP_NEW 3
+#define DBG_CAP_RESOLVED 4
+
+#define DBG_REL_START 1
+#define DBG_REL_FINISH 2
+#define DBG_REL_NONE 3
+
+#define DBG_NL_STD 0 /* newline controllers - standard and */
+#define DBG_NL_FRC 2 /* forced. */
+
+#define DBG_BNDREJ_NODIR 0 /* bind rejected, direct to nodirect */
+#define DBG_BNDREJ_SINGLE 1 /* bind rejected, singleton without */
+ /* default search model */
+#define DBG_BNDREJ_NUM DBG_BNDREJ_SINGLE
+
+/*
+ * Define a debug descriptor, and a user macro that inspects the descriptor as
+ * a means of triggering a class of diagnostic output.
+ */
+typedef struct {
+ uint_t d_class; /* debugging classes */
+ uint_t d_extra; /* extra information for classes */
+ APlist *d_list; /* associated strings */
+} Dbg_desc;
+
+extern Dbg_desc *dbg_desc;
+
+#define DBG_ENABLED (dbg_desc->d_class)
+#define DBG_CALL(func) if (DBG_ENABLED) func
+
+/*
+ * Most debugging tokens are interpreted within liblddbg, and thus any flags
+ * within d_class are only meaningful to this library. The following flags
+ * extend the d_class diagnostic, and are maintained in d_extra. These flags
+ * may be interpreted by the debugging library itself or from the callers
+ * dbg_print() routine.
+ */
+#define DBG_E_DETAIL 0x0001 /* add detail to a class */
+#define DBG_E_LONG 0x0002 /* use long names (ie. no truncation) */
+
+#define DBG_E_STDNL 0x0010 /* standard newline indicator */
+
+#define DBG_E_SNAME 0x0100 /* prepend simple name (ld only) */
+#define DBG_E_FNAME 0x0200 /* prepend full name (ld only) */
+#define DBG_E_CLASS 0x0400 /* prepend ELF class (ld only) */
+#define DBG_E_LMID 0x0800 /* prepend link-map id (ld.so.1 only) */
+#define DBG_E_DEMANGLE 0x1000 /* demangle symbol names */
+
+#define DBG_NOTDETAIL() !(dbg_desc->d_extra & DBG_E_DETAIL)
+#define DBG_NOTLONG() !(dbg_desc->d_extra & DBG_E_LONG)
+
+#define DBG_ISSNAME() (dbg_desc->d_extra & DBG_E_SNAME)
+#define DBG_ISFNAME() (dbg_desc->d_extra & DBG_E_FNAME)
+#define DBG_ISCLASS() (dbg_desc->d_extra & DBG_E_CLASS)
+#define DBG_ISLMID() (dbg_desc->d_extra & DBG_E_LMID)
+#define DBG_ISDEMANGLE() \
+ (dbg_desc->d_extra & DBG_E_DEMANGLE)
+
+/*
+ * Print routine, this must be supplied by the application. The initial
+ * argument may provide a link-map list to associate with the format statement
+ * that follows.
+ */
+/* PRINTFLIKE2 */
+extern void dbg_print(Lm_list *, const char *, ...);
+
+extern uintptr_t Dbg_setup(const char *, Dbg_desc *);
+
+/*
+ * Establish ELF32 and ELF64 class Dbg_*() interfaces.
+ */
+#if defined(_ELF64)
+
+#define Dbg_demangle_name Dbg64_demangle_name
+
+#define Dbg_bind_global Dbg64_bind_global
+#define Dbg_bind_plt_summary Dbg64_bind_plt_summary
+#define Dbg_bind_pltpad_from Dbg64_bind_pltpad_from
+#define Dbg_bind_pltpad_to Dbg64_bind_pltpad_to
+#define Dbg_bind_reject Dbg64_bind_reject
+#define Dbg_bind_weak Dbg64_bind_weak
+
+#define Dbg_cap_val_hw1 Dbg64_cap_val_hw1
+#define Dbg_cap_hw_candidate Dbg64_cap_hw_candidate
+#define Dbg_cap_hw_filter Dbg64_cap_hw_filter
+#define Dbg_cap_mapfile Dbg64_cap_mapfile
+#define Dbg_cap_sec_entry Dbg64_cap_sec_entry
+#define Dbg_cap_sec_title Dbg64_cap_sec_title
+
+#define Dbg_ent_entry Dbg64_ent_entry
+#define Dbg_ent_print Dbg64_ent_print
+
+#define Dbg_file_analyze Dbg64_file_analyze
+#define Dbg_file_aout Dbg64_file_aout
+#define Dbg_file_ar Dbg64_file_ar
+#define Dbg_file_ar_rescan Dbg64_file_ar_rescan
+#define Dbg_file_bind_entry Dbg64_file_bind_entry
+#define Dbg_file_bindings Dbg64_file_bindings
+#define Dbg_file_cleanup Dbg64_file_cleanup
+#define Dbg_file_cntl Dbg64_file_cntl
+#define Dbg_file_config_dis Dbg64_file_config_dis
+#define Dbg_file_config_obj Dbg64_file_config_obj
+#define Dbg_file_del_rescan Dbg64_file_del_rescan
+#define Dbg_file_delete Dbg64_file_delete
+#define Dbg_file_dlclose Dbg64_file_dlclose
+#define Dbg_file_dldump Dbg64_file_dldump
+#define Dbg_file_dlopen Dbg64_file_dlopen
+#define Dbg_file_elf Dbg64_file_elf
+#define Dbg_file_filtee Dbg64_file_filtee
+#define Dbg_file_filter Dbg64_file_filter
+#define Dbg_file_fixname Dbg64_file_fixname
+#define Dbg_file_generic Dbg64_file_generic
+#define Dbg_file_hdl_action Dbg64_file_hdl_action
+#define Dbg_file_hdl_collect Dbg64_file_hdl_collect
+#define Dbg_file_hdl_title Dbg64_file_hdl_title
+#define Dbg_file_lazyload Dbg64_file_lazyload
+#define Dbg_file_ldso Dbg64_file_ldso
+#define Dbg_file_mode_promote Dbg64_file_mode_promote
+#define Dbg_file_modified Dbg64_file_modified
+#define Dbg_file_needed Dbg64_file_needed
+#define Dbg_file_output Dbg64_file_output
+#define Dbg_file_preload Dbg64_file_preload
+#define Dbg_file_prot Dbg64_file_prot
+#define Dbg_file_rejected Dbg64_file_rejected
+#define Dbg_file_reuse Dbg64_file_reuse
+#define Dbg_file_skip Dbg64_file_skip
+
+#define Dbg_got_display Dbg64_got_display
+
+#define Dbg_libs_audit Dbg64_libs_audit
+#define Dbg_libs_find Dbg64_libs_find
+#define Dbg_libs_found Dbg64_libs_found
+#define Dbg_libs_ignore Dbg64_libs_ignore
+#define Dbg_libs_init Dbg64_libs_init
+#define Dbg_libs_l Dbg64_libs_l
+#define Dbg_libs_path Dbg64_libs_path
+#define Dbg_libs_req Dbg64_libs_req
+#define Dbg_libs_update Dbg64_libs_update
+#define Dbg_libs_yp Dbg64_libs_yp
+#define Dbg_libs_ylu Dbg64_libs_ylu
+
+#define Dbg_map_dash Dbg64_map_dash
+#define Dbg_map_ent Dbg64_map_ent
+#define Dbg_map_parse Dbg64_map_parse
+#define Dbg_map_pipe Dbg64_map_pipe
+#define Dbg_map_seg Dbg64_map_seg
+#define Dbg_map_set_atsign Dbg64_map_set_atsign
+#define Dbg_map_set_equal Dbg64_map_set_equal
+#define Dbg_map_size_new Dbg64_map_size_new
+#define Dbg_map_size_old Dbg64_map_size_old
+#define Dbg_map_sort_fini Dbg64_map_sort_fini
+#define Dbg_map_sort_orig Dbg64_map_sort_orig
+#define Dbg_map_symbol Dbg64_map_symbol
+#define Dbg_map_version Dbg64_map_version
+
+#define Dbg_move_adjexpandreloc Dbg64_move_adjexpandreloc
+#define Dbg_move_adjmovereloc Dbg64_move_adjmovereloc
+#define Dbg_move_data Dbg64_move_data
+#define Dbg_move_entry1 Dbg64_move_entry1
+#define Dbg_move_entry2 Dbg64_move_entry2
+#define Dbg_move_expand Dbg64_move_expand
+#define Dbg_move_input Dbg64_move_input
+#define Dbg_move_outmove Dbg64_move_outmove
+#define Dbg_move_outsctadj Dbg64_move_outsctadj
+#define Dbg_move_parexpn Dbg64_move_parexpn
+
+#define Dbg_reloc_apply_reg Dbg64_reloc_apply_reg
+#define Dbg_reloc_apply_val Dbg64_reloc_apply_val
+#define Dbg_reloc_ars_entry Dbg64_reloc_ars_entry
+#define Dbg_reloc_copy Dbg64_reloc_copy
+#define Dbg_reloc_discard Dbg64_reloc_discard
+#define Dbg_reloc_doact Dbg64_reloc_doact
+#define Dbg_reloc_doact_title Dbg64_reloc_doact_title
+#define Dbg_reloc_dooutrel Dbg64_reloc_dooutrel
+#define Dbg_reloc_entry Dbg64_reloc_entry
+#define Dbg_reloc_error Dbg64_reloc_error
+#define Dbg_reloc_generate Dbg64_reloc_generate
+#define Dbg_reloc_in Dbg64_reloc_in
+#define Dbg_reloc_ors_entry Dbg64_reloc_ors_entry
+#define Dbg_reloc_out Dbg64_reloc_out
+#define Dbg_reloc_proc Dbg64_reloc_proc
+#define Dbg_reloc_run Dbg64_reloc_run
+#define Dbg_reloc_transition Dbg64_reloc_transition
+#define Dbg_reloc_sloppycomdat Dbg64_reloc_sloppycomdat
+
+#define Dbg_sec_added Dbg64_sec_added
+#define Dbg_sec_created Dbg64_sec_created
+#define Dbg_sec_discarded Dbg64_sec_discarded
+#define Dbg_sec_genstr_compress Dbg64_sec_genstr_compress
+#define Dbg_sec_group Dbg64_sec_group
+#define Dbg_sec_in Dbg64_sec_in
+#define Dbg_sec_order_error Dbg64_sec_order_error
+#define Dbg_sec_order_list Dbg64_sec_order_list
+#define Dbg_sec_strtab Dbg64_sec_strtab
+#define Dbg_sec_unsup_strmerge Dbg64_sec_unsup_strmerge
+
+#define Dbg_seg_desc_entry Dbg64_seg_desc_entry
+#define Dbg_seg_entry Dbg64_seg_entry
+#define Dbg_seg_list Dbg64_seg_list
+#define Dbg_seg_os Dbg64_seg_os
+#define Dbg_seg_title Dbg64_seg_title
+
+#define Dbg_shdr_modified Dbg64_shdr_modified
+
+#define Dbg_statistics_ar Dbg64_statistics_ar
+#define Dbg_statistics_ld Dbg64_statistics_ld
+
+#define Dbg_support_action Dbg64_support_action
+#define Dbg_support_load Dbg64_support_load
+#define Dbg_support_req Dbg64_support_req
+
+#define Dbg_syminfo_entry Dbg64_syminfo_entry
+#define Dbg_syminfo_title Dbg64_syminfo_title
+
+#define Dbg_syms_ar_checking Dbg64_syms_ar_checking
+#define Dbg_syms_ar_entry Dbg64_syms_ar_entry
+#define Dbg_syms_ar_resolve Dbg64_syms_ar_resolve
+#define Dbg_syms_ar_title Dbg64_syms_ar_title
+#define Dbg_syms_created Dbg64_syms_created
+#define Dbg_syms_discarded Dbg64_syms_discarded
+#define Dbg_syms_dlsym Dbg64_syms_dlsym
+#define Dbg_syms_dup_sort_addr Dbg64_syms_dup_sort_addr
+#define Dbg_syms_entered Dbg64_syms_entered
+#define Dbg_syms_entry Dbg64_syms_entry
+#define Dbg_syms_global Dbg64_syms_global
+#define Dbg_syms_ignore Dbg64_syms_ignore
+#define Dbg_syms_ignore_gnuver Dbg64_syms_ignore_gnuver
+#define Dbg_syms_lazy_rescan Dbg64_syms_lazy_rescan
+#define Dbg_syms_lookup Dbg64_syms_lookup
+#define Dbg_syms_new Dbg64_syms_new
+#define Dbg_syms_old Dbg64_syms_old
+#define Dbg_syms_process Dbg64_syms_process
+#define Dbg_syms_reduce Dbg64_syms_reduce
+#define Dbg_syms_reloc Dbg64_syms_reloc
+#define Dbg_syms_resolved Dbg64_syms_resolved
+#define Dbg_syms_resolving Dbg64_syms_resolving
+#define Dbg_syms_sec_entry Dbg64_syms_sec_entry
+#define Dbg_syms_sec_title Dbg64_syms_sec_title
+#define Dbg_syms_spec_title Dbg64_syms_spec_title
+#define Dbg_syms_updated Dbg64_syms_updated
+#define Dbg_syms_up_title Dbg64_syms_up_title
+
+#define Dbg_util_broadcast Dbg64_util_broadcast
+#define Dbg_util_call_array Dbg64_util_call_array
+#define Dbg_util_call_fini Dbg64_util_call_fini
+#define Dbg_util_call_init Dbg64_util_call_init
+#define Dbg_util_call_main Dbg64_util_call_main
+#define Dbg_util_collect Dbg64_util_collect
+#define Dbg_util_dbnotify Dbg64_util_dbnotify
+#define Dbg_util_edge_in Dbg64_util_edge_in
+#define Dbg_util_edge_out Dbg64_util_edge_out
+#define Dbg_util_intoolate Dbg64_util_intoolate
+#define Dbg_util_lcinterface Dbg64_util_lcinterface
+#define Dbg_util_nl Dbg64_util_nl
+#define Dbg_util_no_init Dbg64_util_no_init
+#define Dbg_util_scc_entry Dbg64_util_scc_entry
+#define Dbg_util_scc_title Dbg64_util_scc_title
+#define Dbg_util_str Dbg64_util_str
+#define Dbg_util_wait Dbg64_util_wait
+
+#define Dbg_unused_file Dbg64_unused_file
+#define Dbg_unused_lcinterface Dbg64_unused_lcinterface
+#define Dbg_unused_path Dbg64_unused_path
+#define Dbg_unused_sec Dbg64_unused_sec
+#define Dbg_unused_unref Dbg64_unused_unref
+
+#define Dbg_ver_avail_entry Dbg64_ver_avail_entry
+#define Dbg_ver_avail_title Dbg64_ver_avail_title
+#define Dbg_ver_def_title Dbg64_ver_def_title
+#define Dbg_ver_desc_entry Dbg64_ver_desc_entry
+#define Dbg_ver_need_entry Dbg64_ver_need_entry
+#define Dbg_ver_need_title Dbg64_ver_need_title
+#define Dbg_ver_nointerface Dbg64_ver_nointerface
+#define Dbg_ver_symbol Dbg64_ver_symbol
+
+#else
+
+#define Dbg_demangle_name Dbg32_demangle_name
+
+#define Dbg_bind_global Dbg32_bind_global
+#define Dbg_bind_plt_summary Dbg32_bind_plt_summary
+#define Dbg_bind_reject Dbg32_bind_reject
+#define Dbg_bind_weak Dbg32_bind_weak
+
+#define Dbg_cap_val_hw1 Dbg32_cap_val_hw1
+#define Dbg_cap_hw_candidate Dbg32_cap_hw_candidate
+#define Dbg_cap_hw_filter Dbg32_cap_hw_filter
+#define Dbg_cap_mapfile Dbg32_cap_mapfile
+#define Dbg_cap_sec_entry Dbg32_cap_sec_entry
+#define Dbg_cap_sec_title Dbg32_cap_sec_title
+
+#define Dbg_ent_entry Dbg32_ent_entry
+#define Dbg_ent_print Dbg32_ent_print
+
+#define Dbg_file_analyze Dbg32_file_analyze
+#define Dbg_file_aout Dbg32_file_aout
+#define Dbg_file_ar Dbg32_file_ar
+#define Dbg_file_ar_rescan Dbg32_file_ar_rescan
+#define Dbg_file_bind_entry Dbg32_file_bind_entry
+#define Dbg_file_bindings Dbg32_file_bindings
+#define Dbg_file_cleanup Dbg32_file_cleanup
+#define Dbg_file_cntl Dbg32_file_cntl
+#define Dbg_file_config_dis Dbg32_file_config_dis
+#define Dbg_file_config_obj Dbg32_file_config_obj
+#define Dbg_file_del_rescan Dbg32_file_del_rescan
+#define Dbg_file_delete Dbg32_file_delete
+#define Dbg_file_dlclose Dbg32_file_dlclose
+#define Dbg_file_dldump Dbg32_file_dldump
+#define Dbg_file_dlopen Dbg32_file_dlopen
+#define Dbg_file_elf Dbg32_file_elf
+#define Dbg_file_filtee Dbg32_file_filtee
+#define Dbg_file_filter Dbg32_file_filter
+#define Dbg_file_fixname Dbg32_file_fixname
+#define Dbg_file_generic Dbg32_file_generic
+#define Dbg_file_hdl_action Dbg32_file_hdl_action
+#define Dbg_file_hdl_collect Dbg32_file_hdl_collect
+#define Dbg_file_hdl_title Dbg32_file_hdl_title
+#define Dbg_file_lazyload Dbg32_file_lazyload
+#define Dbg_file_ldso Dbg32_file_ldso
+#define Dbg_file_mode_promote Dbg32_file_mode_promote
+#define Dbg_file_modified Dbg32_file_modified
+#define Dbg_file_needed Dbg32_file_needed
+#define Dbg_file_output Dbg32_file_output
+#define Dbg_file_preload Dbg32_file_preload
+#define Dbg_file_prot Dbg32_file_prot
+#define Dbg_file_rejected Dbg32_file_rejected
+#define Dbg_file_reuse Dbg32_file_reuse
+#define Dbg_file_skip Dbg32_file_skip
+
+#define Dbg_got_display Dbg32_got_display
+
+#define Dbg_libs_audit Dbg32_libs_audit
+#define Dbg_libs_find Dbg32_libs_find
+#define Dbg_libs_found Dbg32_libs_found
+#define Dbg_libs_ignore Dbg32_libs_ignore
+#define Dbg_libs_init Dbg32_libs_init
+#define Dbg_libs_l Dbg32_libs_l
+#define Dbg_libs_path Dbg32_libs_path
+#define Dbg_libs_req Dbg32_libs_req
+#define Dbg_libs_update Dbg32_libs_update
+#define Dbg_libs_yp Dbg32_libs_yp
+#define Dbg_libs_ylu Dbg32_libs_ylu
+
+#define Dbg_map_dash Dbg32_map_dash
+#define Dbg_map_ent Dbg32_map_ent
+#define Dbg_map_parse Dbg32_map_parse
+#define Dbg_map_pipe Dbg32_map_pipe
+#define Dbg_map_seg Dbg32_map_seg
+#define Dbg_map_set_atsign Dbg32_map_set_atsign
+#define Dbg_map_set_equal Dbg32_map_set_equal
+#define Dbg_map_size_new Dbg32_map_size_new
+#define Dbg_map_size_old Dbg32_map_size_old
+#define Dbg_map_sort_fini Dbg32_map_sort_fini
+#define Dbg_map_sort_orig Dbg32_map_sort_orig
+#define Dbg_map_symbol Dbg32_map_symbol
+#define Dbg_map_version Dbg32_map_version
+
+#define Dbg_move_adjexpandreloc Dbg32_move_adjexpandreloc
+#define Dbg_move_adjmovereloc Dbg32_move_adjmovereloc
+#define Dbg_move_data Dbg32_move_data
+#define Dbg_move_entry1 Dbg32_move_entry1
+#define Dbg_move_entry2 Dbg32_move_entry2
+#define Dbg_move_expand Dbg32_move_expand
+#define Dbg_move_input Dbg32_move_input
+#define Dbg_move_outmove Dbg32_move_outmove
+#define Dbg_move_outsctadj Dbg32_move_outsctadj
+#define Dbg_move_parexpn Dbg32_move_parexpn
+
+#define Dbg_reloc_apply_reg Dbg32_reloc_apply_reg
+#define Dbg_reloc_apply_val Dbg32_reloc_apply_val
+#define Dbg_reloc_ars_entry Dbg32_reloc_ars_entry
+#define Dbg_reloc_copy Dbg32_reloc_copy
+#define Dbg_reloc_discard Dbg32_reloc_discard
+#define Dbg_reloc_doact Dbg32_reloc_doact
+#define Dbg_reloc_doact_title Dbg32_reloc_doact_title
+#define Dbg_reloc_dooutrel Dbg32_reloc_dooutrel
+#define Dbg_reloc_entry Dbg32_reloc_entry
+#define Dbg_reloc_error Dbg32_reloc_error
+#define Dbg_reloc_generate Dbg32_reloc_generate
+#define Dbg_reloc_in Dbg32_reloc_in
+#define Dbg_reloc_ors_entry Dbg32_reloc_ors_entry
+#define Dbg_reloc_out Dbg32_reloc_out
+#define Dbg_reloc_proc Dbg32_reloc_proc
+#define Dbg_reloc_run Dbg32_reloc_run
+#define Dbg_reloc_transition Dbg32_reloc_transition
+#define Dbg_reloc_sloppycomdat Dbg32_reloc_sloppycomdat
+
+#define Dbg_sec_added Dbg32_sec_added
+#define Dbg_sec_created Dbg32_sec_created
+#define Dbg_sec_discarded Dbg32_sec_discarded
+#define Dbg_sec_genstr_compress Dbg32_sec_genstr_compress
+#define Dbg_sec_group Dbg32_sec_group
+#define Dbg_sec_in Dbg32_sec_in
+#define Dbg_sec_order_error Dbg32_sec_order_error
+#define Dbg_sec_order_list Dbg32_sec_order_list
+#define Dbg_sec_strtab Dbg32_sec_strtab
+#define Dbg_sec_unsup_strmerge Dbg32_sec_unsup_strmerge
+
+#define Dbg_seg_desc_entry Dbg32_seg_desc_entry
+#define Dbg_seg_entry Dbg32_seg_entry
+#define Dbg_seg_list Dbg32_seg_list
+#define Dbg_seg_os Dbg32_seg_os
+#define Dbg_seg_title Dbg32_seg_title
+
+#define Dbg_shdr_modified Dbg32_shdr_modified
+
+#define Dbg_statistics_ar Dbg32_statistics_ar
+#define Dbg_statistics_ld Dbg32_statistics_ld
+
+#define Dbg_support_action Dbg32_support_action
+#define Dbg_support_load Dbg32_support_load
+#define Dbg_support_req Dbg32_support_req
+
+#define Dbg_syminfo_entry Dbg32_syminfo_entry
+#define Dbg_syminfo_title Dbg32_syminfo_title
+
+#define Dbg_syms_ar_checking Dbg32_syms_ar_checking
+#define Dbg_syms_ar_entry Dbg32_syms_ar_entry
+#define Dbg_syms_ar_resolve Dbg32_syms_ar_resolve
+#define Dbg_syms_ar_title Dbg32_syms_ar_title
+#define Dbg_syms_created Dbg32_syms_created
+#define Dbg_syms_discarded Dbg32_syms_discarded
+#define Dbg_syms_dlsym Dbg32_syms_dlsym
+#define Dbg_syms_dup_sort_addr Dbg32_syms_dup_sort_addr
+#define Dbg_syms_entered Dbg32_syms_entered
+#define Dbg_syms_entry Dbg32_syms_entry
+#define Dbg_syms_global Dbg32_syms_global
+#define Dbg_syms_ignore Dbg32_syms_ignore
+#define Dbg_syms_ignore_gnuver Dbg32_syms_ignore_gnuver
+#define Dbg_syms_lazy_rescan Dbg32_syms_lazy_rescan
+#define Dbg_syms_lookup Dbg32_syms_lookup
+#define Dbg_syms_lookup_aout Dbg32_syms_lookup_aout
+#define Dbg_syms_new Dbg32_syms_new
+#define Dbg_syms_old Dbg32_syms_old
+#define Dbg_syms_process Dbg32_syms_process
+#define Dbg_syms_reduce Dbg32_syms_reduce
+#define Dbg_syms_reloc Dbg32_syms_reloc
+#define Dbg_syms_resolved Dbg32_syms_resolved
+#define Dbg_syms_resolving Dbg32_syms_resolving
+#define Dbg_syms_sec_entry Dbg32_syms_sec_entry
+#define Dbg_syms_sec_title Dbg32_syms_sec_title
+#define Dbg_syms_spec_title Dbg32_syms_spec_title
+#define Dbg_syms_updated Dbg32_syms_updated
+#define Dbg_syms_up_title Dbg32_syms_up_title
+
+#define Dbg_util_broadcast Dbg32_util_broadcast
+#define Dbg_util_call_array Dbg32_util_call_array
+#define Dbg_util_call_fini Dbg32_util_call_fini
+#define Dbg_util_call_init Dbg32_util_call_init
+#define Dbg_util_call_main Dbg32_util_call_main
+#define Dbg_util_collect Dbg32_util_collect
+#define Dbg_util_dbnotify Dbg32_util_dbnotify
+#define Dbg_util_edge_in Dbg32_util_edge_in
+#define Dbg_util_edge_out Dbg32_util_edge_out
+#define Dbg_util_intoolate Dbg32_util_intoolate
+#define Dbg_util_lcinterface Dbg32_util_lcinterface
+#define Dbg_util_nl Dbg32_util_nl
+#define Dbg_util_no_init Dbg32_util_no_init
+#define Dbg_util_scc_entry Dbg32_util_scc_entry
+#define Dbg_util_scc_title Dbg32_util_scc_title
+#define Dbg_util_str Dbg32_util_str
+#define Dbg_util_wait Dbg32_util_wait
+
+#define Dbg_unused_file Dbg32_unused_file
+#define Dbg_unused_lcinterface Dbg32_unused_lcinterface
+#define Dbg_unused_path Dbg32_unused_path
+#define Dbg_unused_sec Dbg32_unused_sec
+#define Dbg_unused_unref Dbg32_unused_unref
+
+#define Dbg_ver_avail_entry Dbg32_ver_avail_entry
+#define Dbg_ver_avail_title Dbg32_ver_avail_title
+#define Dbg_ver_def_title Dbg32_ver_def_title
+#define Dbg_ver_desc_entry Dbg32_ver_desc_entry
+#define Dbg_ver_need_entry Dbg32_ver_need_entry
+#define Dbg_ver_need_title Dbg32_ver_need_title
+#define Dbg_ver_nointerface Dbg32_ver_nointerface
+#define Dbg_ver_symbol Dbg32_ver_symbol
+
+#endif
+
+/*
+ * External Dbg_*() interface routines.
+ */
+extern void Dbg_args_files(Lm_list *, int, char *);
+extern void Dbg_args_flags(Lm_list *, int, int);
+extern void Dbg_audit_ignore(Rt_map *);
+extern void Dbg_audit_interface(Lm_list *, const char *, const char *);
+extern void Dbg_audit_lib(Lm_list *, const char *);
+extern void Dbg_audit_object(Lm_list *, const char *, const char *);
+extern void Dbg_audit_symval(Lm_list *, const char *, const char *,
+ const char *, Addr, Addr);
+extern void Dbg_audit_skip(Lm_list *, const char *, const char *);
+extern void Dbg_audit_terminate(Lm_list *, const char *);
+extern void Dbg_audit_version(Lm_list *, const char *, ulong_t);
+
+extern void Dbg_bind_global(Rt_map *, Addr, Off, Xword, Pltbindtype,
+ Rt_map *, Addr, Off, const char *, uint_t);
+extern void Dbg_bind_plt_summary(Lm_list *, Half, Word, Word, Word, Word,
+ Word, Word);
+#if defined(_ELF64)
+extern void Dbg_bind_pltpad_from(Rt_map *, Addr, const char *);
+extern void Dbg_bind_pltpad_to(Rt_map *, Addr, const char *, const char *);
+#endif
+extern void Dbg_bind_reject(Rt_map *, Rt_map *, const char *, int);
+extern void Dbg_bind_weak(Rt_map *, Addr, Addr, const char *);
+
+extern void Dbg_cap_hw_candidate(Lm_list *, const char *);
+extern void Dbg_cap_hw_filter(Lm_list *, const char *, Rt_map *);
+extern void Dbg_cap_mapfile(Lm_list *, Xword, Xword, Half);
+extern void Dbg_cap_sec_entry(Lm_list *, uint_t, Xword, Xword, Half);
+extern void Dbg_cap_sec_title(Ofl_desc *);
+extern void Dbg_cap_val_hw1(Lm_list *, Xword, Half);
+
+extern const char *
+ Dbg_demangle_name(const char *);
+
+extern void Dbg_ent_entry(Lm_list *, Half, Ent_desc *);
+extern void Dbg_ent_print(Lm_list *, Half, List *, Boolean);
+
+extern void Dbg_file_analyze(Rt_map *);
+extern void Dbg_file_aout(Lm_list *, const char *, ulong_t, ulong_t,
+ ulong_t, const char *, Aliste);
+extern void Dbg_file_ar(Lm_list *, const char *, int);
+extern void Dbg_file_ar_rescan(Lm_list *);
+extern void Dbg_file_bind_entry(Lm_list *, Bnd_desc *);
+extern void Dbg_file_bindings(Rt_map *, int);
+extern void Dbg_file_cleanup(Lm_list *, const char *, Aliste);
+extern void Dbg_file_cntl(Lm_list *, Aliste, Aliste);
+extern void Dbg_file_config_dis(Lm_list *, const char *, int);
+extern void Dbg_file_config_obj(Lm_list *, const char *, const char *,
+ const char *);
+extern void Dbg_file_del_rescan(Lm_list *);
+extern void Dbg_file_delete(Rt_map *);
+extern void Dbg_file_dlclose(Lm_list *, const char *, int);
+extern void Dbg_file_dldump(Rt_map *, const char *, int);
+extern void Dbg_file_dlopen(Rt_map *, const char *, int *, int);
+extern void Dbg_file_elf(Lm_list *, const char *, ulong_t, ulong_t,
+ ulong_t, ulong_t, const char *, Aliste);
+extern void Dbg_file_filtee(Lm_list *, const char *, const char *, int);
+extern void Dbg_file_filter(Lm_list *, const char *, const char *, int);
+extern void Dbg_file_fixname(Lm_list *, const char *, const char *);
+extern void Dbg_file_generic(Lm_list *, Ifl_desc *);
+extern void Dbg_file_hdl_action(Grp_hdl *, Rt_map *, int, uint_t);
+extern void Dbg_file_hdl_collect(Grp_hdl *, const char *);
+extern void Dbg_file_hdl_title(int);
+extern void Dbg_file_lazyload(Rt_map *, const char *, const char *);
+extern void Dbg_file_ldso(Rt_map *, char **, auxv_t *, const char *,
+ Aliste);
+extern void Dbg_file_mode_promote(Rt_map *, int);
+extern void Dbg_file_modified(Lm_list *, const char *, const char *,
+ const char *, int, int, Elf *, Elf *);
+extern void Dbg_file_needed(Rt_map *, const char *);
+extern void Dbg_file_output(Ofl_desc *);
+extern void Dbg_file_preload(Lm_list *, const char *);
+extern void Dbg_file_prot(Rt_map *, int);
+extern void Dbg_file_rejected(Lm_list *, Rej_desc *, Half mach);
+extern void Dbg_file_reuse(Lm_list *, const char *, const char *);
+extern void Dbg_file_skip(Lm_list *, const char *, const char *);
+
+extern void Dbg_got_display(Ofl_desc *, Off, int, Word, size_t);
+
+extern void Dbg_libs_audit(Lm_list *, const char *, const char *);
+extern void Dbg_libs_find(Lm_list *, const char *);
+extern void Dbg_libs_found(Lm_list *, const char *, int);
+extern void Dbg_libs_ignore(Lm_list *, const char *);
+extern void Dbg_libs_init(Lm_list *, List *, List *);
+extern void Dbg_libs_l(Lm_list *, const char *, const char *);
+extern void Dbg_libs_path(Lm_list *, const char *, uint_t, const char *);
+extern void Dbg_libs_req(Lm_list *, const char *, const char *,
+ const char *);
+extern void Dbg_libs_update(Lm_list *, List *, List *);
+extern void Dbg_libs_yp(Lm_list *, const char *);
+extern void Dbg_libs_ylu(Lm_list *, const char *, const char *, int);
+
+extern void Dbg_map_dash(Lm_list *, const char *, Sdf_desc *);
+extern void Dbg_map_ent(Lm_list *, Boolean, Ent_desc *, Ofl_desc *);
+extern void Dbg_map_parse(Lm_list *, const char *);
+extern void Dbg_map_pipe(Lm_list *, Sg_desc *, const char *, const Word);
+extern void Dbg_map_seg(Ofl_desc *, int, Sg_desc *);
+extern void Dbg_map_set_atsign(Boolean);
+extern void Dbg_map_set_equal(Boolean);
+extern void Dbg_map_size_new(Lm_list *, const char *);
+extern void Dbg_map_size_old(Ofl_desc *, Sym_desc *);
+extern void Dbg_map_sort_fini(Lm_list *, Sg_desc *);
+extern void Dbg_map_sort_orig(Lm_list *, Sg_desc *);
+extern void Dbg_map_symbol(Ofl_desc *, Sym_desc *);
+extern void Dbg_map_version(Lm_list *, const char *, const char *, int);
+
+extern void Dbg_move_adjexpandreloc(Lm_list *, Xword, const char *);
+extern void Dbg_move_adjmovereloc(Lm_list *, Xword, Xword, const char *);
+extern void Dbg_move_data(Rt_map *);
+extern void Dbg_move_entry1(Lm_list *, int, Move *, Sym_desc *);
+extern void Dbg_move_entry2(Lm_list *, Move *, Word, const char *);
+extern void Dbg_move_expand(Lm_list *, Move *, Addr);
+extern void Dbg_move_input(Lm_list *, const char *);
+extern void Dbg_move_outmove(Lm_list *, const char *);
+extern void Dbg_move_outsctadj(Lm_list *, Sym_desc *);
+extern void Dbg_move_parexpn(Lm_list *, const char *, const char *);
+
+extern void Dbg_reloc_apply_reg(Lm_list *, int, Half, Xword, Xword);
+extern void Dbg_reloc_apply_val(Lm_list *, int, Xword, Xword);
+extern void Dbg_reloc_ars_entry(Lm_list *, int, Word, Half, Rel_desc *);
+extern void Dbg_reloc_copy(Rt_map *, Rt_map *, const char *, int);
+extern void Dbg_reloc_discard(Lm_list *, Half, Rel_desc *);
+extern void Dbg_reloc_doact(Lm_list *, int, Half, Word, Word, Xword, Xword,
+ const char *, Os_desc *);
+extern void Dbg_reloc_doact_title(Lm_list *);
+extern void Dbg_reloc_dooutrel(Lm_list *, Word);
+extern void Dbg_reloc_entry(Lm_list *, const char *, Half, Word, void *,
+ const char *, const char *, const char *);
+extern void Dbg_reloc_error(Lm_list *, int, Half, Word, void *,
+ const char *);
+extern void Dbg_reloc_generate(Lm_list *, Os_desc *, Word);
+extern void Dbg_reloc_in(Lm_list *, int, Half, Word, void *, const char *,
+ const char *);
+extern void Dbg_reloc_ors_entry(Lm_list *, int, Word, Half, Rel_desc *);
+extern void Dbg_reloc_out(Ofl_desc *, int, Word, void *, const char *,
+ const char *);
+extern void Dbg_reloc_proc(Lm_list *, Os_desc *, Is_desc *, Is_desc *);
+extern void Dbg_reloc_run(Rt_map *, uint_t, int, int);
+extern void Dbg_reloc_transition(Lm_list *, Half, Word, Rel_desc *);
+extern void Dbg_reloc_sloppycomdat(Lm_list *, const char *, Sym_desc *);
+
+extern void Dbg_sec_added(Lm_list *, Os_desc *, Sg_desc *);
+extern void Dbg_sec_created(Lm_list *, Os_desc *, Sg_desc *);
+extern void Dbg_sec_discarded(Lm_list *, Is_desc *, Is_desc *);
+extern void Dbg_sec_genstr_compress(Lm_list *, const char *,
+ Xword, Xword);
+extern void Dbg_sec_group(Lm_list *, Is_desc *, Group_desc *);
+extern void Dbg_sec_in(Lm_list *, Is_desc *);
+extern void Dbg_sec_order_error(Lm_list *, Ifl_desc *, Word, int);
+extern void Dbg_sec_order_list(Ofl_desc *, int);
+extern void Dbg_sec_strtab(Lm_list *, Os_desc *, Str_tbl *);
+extern void Dbg_sec_unsup_strmerge(Lm_list *, Is_desc *);
+
+extern void Dbg_seg_desc_entry(Lm_list *, Half, int, Sg_desc *);
+extern void Dbg_seg_entry(Ofl_desc *, int, Sg_desc *);
+extern void Dbg_seg_list(Lm_list *, Half, List *);
+extern void Dbg_seg_os(Ofl_desc *, Os_desc *, int);
+extern void Dbg_seg_title(Lm_list *);
+
+extern void Dbg_shdr_modified(Lm_list *, const char *, Half, Shdr *, Shdr *,
+ const char *);
+
+extern void Dbg_statistics_ar(Ofl_desc *);
+extern void Dbg_statistics_ld(Ofl_desc *);
+
+extern void Dbg_support_action(Lm_list *, const char *, const char *,
+ Support_ndx, const char *);
+extern void Dbg_support_load(Lm_list *, const char *, const char *);
+extern void Dbg_support_req(Lm_list *, const char *, int);
+
+extern void Dbg_syminfo_entry(Lm_list *, Word, Syminfo *, Sym *,
+ const char *, Dyn *);
+extern void Dbg_syminfo_title(Lm_list *);
+
+extern void Dbg_syms_ar_checking(Lm_list *, Xword, Elf_Arsym *,
+ const char *);
+extern void Dbg_syms_ar_entry(Lm_list *, Xword, Elf_Arsym *);
+extern void Dbg_syms_ar_resolve(Lm_list *, Xword, Elf_Arsym *,
+ const char *, int);
+extern void Dbg_syms_ar_title(Lm_list *, const char *, int);
+extern void Dbg_syms_created(Lm_list *, const char *);
+extern void Dbg_syms_discarded(Lm_list *, Sym_desc *);
+extern void Dbg_syms_dlsym(Rt_map *, const char *, int *, const char *,
+ int);
+extern void Dbg_syms_dup_sort_addr(Lm_list *, const char *, const char *,
+ const char *, Addr);
+extern void Dbg_syms_entered(Ofl_desc *, Sym *, Sym_desc *);
+extern void Dbg_syms_entry(Lm_list *, Word, Sym_desc *);
+extern void Dbg_syms_global(Lm_list *, Word, const char *);
+extern void Dbg_syms_ignore(Ofl_desc *, Sym_desc *);
+extern void Dbg_syms_ignore_gnuver(Rt_map *, const char *, Word, Versym);
+extern void Dbg_syms_lazy_rescan(Lm_list *, const char *);
+extern void Dbg_syms_lookup(Rt_map *, const char *, const char *);
+#if !(defined(_ELF64))
+extern void Dbg_syms_lookup_aout(Lm_list *, const char *);
+#endif
+extern void Dbg_syms_new(Ofl_desc *, Sym *, Sym_desc *);
+extern void Dbg_syms_old(Ofl_desc *, Sym_desc *);
+extern void Dbg_syms_process(Lm_list *, Ifl_desc *);
+extern void Dbg_syms_reduce(Ofl_desc *, int, Sym_desc *, int,
+ const char *);
+extern void Dbg_syms_reloc(Ofl_desc *, Sym_desc *);
+extern void Dbg_syms_resolved(Ofl_desc *, Sym_desc *);
+extern void Dbg_syms_resolving(Ofl_desc *, Word, const char *, int, int,
+ Sym *, Sym *, Sym_desc *, Ifl_desc *);
+extern void Dbg_syms_sec_entry(Lm_list *, Word, Sg_desc *, Os_desc *);
+extern void Dbg_syms_sec_title(Lm_list *);
+extern void Dbg_syms_spec_title(Lm_list *);
+extern void Dbg_syms_updated(Ofl_desc *, Sym_desc *, const char *);
+extern void Dbg_syms_up_title(Lm_list *);
+
+extern void Dbg_tls_modactivity(Lm_list *, void *, uint_t);
+extern void Dbg_tls_static_block(Lm_list *, void *, ulong_t, ulong_t);
+extern void Dbg_tls_static_resv(Rt_map *, ulong_t, ulong_t);
+
+extern void Dbg_util_broadcast(Rt_map *);
+extern void Dbg_util_call_array(Rt_map *, void *, int, Word);
+extern void Dbg_util_call_fini(Rt_map *);
+extern void Dbg_util_call_init(Rt_map *, int);
+extern void Dbg_util_call_main(Rt_map *);
+extern void Dbg_util_collect(Rt_map *, int, int);
+extern void Dbg_util_dbnotify(Lm_list *, rd_event_e, r_state_e);
+extern void Dbg_util_edge_in(Lm_list *, Rt_map *, uint_t, Rt_map *,
+ int, int);
+extern void Dbg_util_edge_out(Rt_map *, Rt_map *);
+extern void Dbg_util_intoolate(Rt_map *);
+extern void Dbg_util_lcinterface(Rt_map *, int, char *);
+extern void Dbg_util_nl(Lm_list *, int);
+extern void Dbg_util_no_init(Rt_map *);
+extern void Dbg_util_str(Lm_list *, const char *);
+extern void Dbg_util_scc_entry(Rt_map *, uint_t);
+extern void Dbg_util_scc_title(Lm_list *, int);
+extern void Dbg_util_wait(Rt_map *, Rt_map *, int);
+
+extern void Dbg_unused_file(Lm_list *, const char *, int, uint_t);
+extern void Dbg_unused_lcinterface(Rt_map *, Rt_map *, int);
+extern void Dbg_unused_path(Lm_list *, const char *, uint_t, uint_t,
+ const char *);
+extern void Dbg_unused_sec(Lm_list *, Is_desc *);
+extern void Dbg_unused_unref(Rt_map *, const char *);
+
+extern void Dbg_ver_avail_entry(Lm_list *, Ver_index *, const char *);
+extern void Dbg_ver_avail_title(Lm_list *, const char *);
+extern void Dbg_ver_def_title(Lm_list *, const char *);
+extern void Dbg_ver_desc_entry(Lm_list *, Ver_desc *);
+extern void Dbg_ver_need_entry(Lm_list *, Half, const char *,
+ const char *);
+extern void Dbg_ver_need_title(Lm_list *, const char *);
+extern void Dbg_ver_nointerface(Lm_list *, const char *);
+extern void Dbg_ver_symbol(Lm_list *, const char *);
+
+/*
+ * Define Elf_*() interface flags.
+ */
+#define ELF_DBG_ELFDUMP 1
+#define ELF_DBG_RTLD 2
+#define ELF_DBG_LD 3
+
+/*
+ * Define generic Elf_*() interfaces.
+ */
+extern void Elf_syminfo_entry(Lm_list *, Word, Syminfo *, const char *,
+ const char *);
+extern void Elf_syminfo_title(Lm_list *);
+
+/*
+ * Establish ELF32 and ELF64 class Elf_*() interfaces.
+ */
+#if defined(_ELF64)
+
+#define Elf_cap_entry Elf64_cap_entry
+#define Elf_cap_title Elf64_cap_title
+
+#define Elf_demangle_name Elf64_demangle_name
+#define Elf_dyn_entry Elf64_dyn_entry
+#define Elf_dyn_null_entry Elf64_dyn_null_entry
+#define Elf_dyn_title Elf64_dyn_title
+
+#define Elf_ehdr Elf64_ehdr
+
+#define Elf_got_entry Elf64_got_entry
+#define Elf_got_title Elf64_got_title
+
+#define Elf_reloc_apply_reg Elf64_reloc_apply_reg
+#define Elf_reloc_apply_val Elf64_reloc_apply_val
+#define Elf_reloc_entry_1 Elf64_reloc_entry_1
+#define Elf_reloc_entry_2 Elf64_reloc_entry_2
+#define Elf_reloc_title Elf64_reloc_title
+
+#define Elf_phdr Elf64_phdr
+
+#define Elf_shdr Elf64_shdr
+
+#define Elf_syms_table_entry Elf64_syms_table_entry
+#define Elf_syms_table_title Elf64_syms_table_title
+
+#define Elf_ver_def_title Elf64_ver_def_title
+#define Elf_ver_line_1 Elf64_ver_line_1
+#define Elf_ver_line_2 Elf64_ver_line_2
+#define Elf_ver_line_3 Elf64_ver_line_3
+#define Elf_ver_line_4 Elf64_ver_line_4
+#define Elf_ver_line_5 Elf64_ver_line_5
+#define Elf_ver_need_title Elf64_ver_need_title
+
+#else
+
+#define Elf_cap_entry Elf32_cap_entry
+#define Elf_cap_title Elf32_cap_title
+
+#define Elf_demangle_name Elf32_demangle_name
+#define Elf_dyn_entry Elf32_dyn_entry
+#define Elf_dyn_null_entry Elf32_dyn_null_entry
+#define Elf_dyn_title Elf32_dyn_title
+
+#define Elf_ehdr Elf32_ehdr
+
+#define Elf_got_entry Elf32_got_entry
+#define Elf_got_title Elf32_got_title
+
+#define Elf_reloc_apply_reg Elf32_reloc_apply_reg
+#define Elf_reloc_apply_val Elf32_reloc_apply_val
+#define Elf_reloc_entry_1 Elf32_reloc_entry_1
+#define Elf_reloc_entry_2 Elf32_reloc_entry_2
+#define Elf_reloc_title Elf32_reloc_title
+
+#define Elf_phdr Elf32_phdr
+
+#define Elf_shdr Elf32_shdr
+
+#define Elf_syms_table_entry Elf32_syms_table_entry
+#define Elf_syms_table_title Elf32_syms_table_title
+
+#define Elf_ver_def_title Elf32_ver_def_title
+#define Elf_ver_line_1 Elf32_ver_line_1
+#define Elf_ver_line_2 Elf32_ver_line_2
+#define Elf_ver_line_3 Elf32_ver_line_3
+#define Elf_ver_line_4 Elf32_ver_line_4
+#define Elf_ver_line_5 Elf32_ver_line_5
+#define Elf_ver_need_title Elf32_ver_need_title
+
+#endif
+
+extern void Elf_cap_entry(Lm_list *, Cap *, int, Half);
+extern void Elf_cap_title(Lm_list *);
+
+extern const char \
+ *Elf_demangle_name(const char *);
+extern void Elf_dyn_entry(Lm_list *, Dyn *, int, const char *, Half);
+extern void Elf_dyn_null_entry(Lm_list *, Dyn *, int, int);
+extern void Elf_dyn_title(Lm_list *);
+
+extern void Elf_ehdr(Lm_list *, Ehdr *, Shdr *);
+
+extern void Elf_got_entry(Lm_list *, Sword, Addr, Xword, Half,
+ uchar_t, uchar_t, Word, void *, const char *);
+extern void Elf_got_title(Lm_list *);
+
+extern void Elf_phdr(Lm_list *, Half, Phdr *);
+
+extern void Elf_reloc_apply_val(Lm_list *, int, Xword, Xword);
+extern void Elf_reloc_apply_reg(Lm_list *, int, Half, Xword, Xword);
+extern void Elf_reloc_entry_1(Lm_list *, int, const char *, Half, Word,
+ void *, const char *, const char *, const char *);
+extern void Elf_reloc_entry_2(Lm_list *, int, const char *, Word,
+ const char *, Off, Sxword, const char *, const char *,
+ const char *);
+extern void Elf_reloc_title(Lm_list *, int, Word);
+
+extern void Elf_shdr(Lm_list *, Half, Shdr *);
+
+extern void Elf_syms_table_entry(Lm_list *, int, const char *, Half, Sym *,
+ Versym, int, const char *, const char *);
+extern void Elf_syms_table_title(Lm_list *, int);
+
+extern void Elf_ver_def_title(Lm_list *);
+extern void Elf_ver_line_1(Lm_list *, const char *, const char *,
+ const char *, const char *);
+extern void Elf_ver_line_2(Lm_list *, const char *, const char *);
+extern void Elf_ver_line_3(Lm_list *, const char *, const char *,
+ const char *);
+extern void Elf_ver_line_4(Lm_list *, const char *);
+extern void Elf_ver_line_5(Lm_list *, const char *, const char *);
+extern void Elf_ver_need_title(Lm_list *, int);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DEBUG_H */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h b/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h
new file mode 100644
index 0000000..9c37af2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/include/sgs.h
@@ -0,0 +1,296 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1988 AT&T
+ * All Rights Reserved
+ *
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Global include file for all sgs.
+ */
+
+#ifndef _SGS_H
+#define _SGS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* <assert.h> keys off of NDEBUG */
+#ifdef DEBUG
+#undef NDEBUG
+#else
+#define NDEBUG
+#endif
+
+#ifndef _ASM
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/machelf.h>
+#else
+#include <elf.h>
+#endif
+#include <stdlib.h>
+#include <libelf.h>
+#include <assert.h>
+#include <alist.h>
+#endif /* _ASM */
+
+/*
+ * Software identification.
+ */
+#define SGS ""
+#define SGU_PKG "Software Generation Utilities"
+#define SGU_REL "(SGU) Solaris-ELF (4.0)"
+
+
+#ifndef _ASM
+
+/*
+ * link_ver_string[] contains a version string for use by the link-editor
+ * and all other linker components. It is found in libconv, and is
+ * generated by sgs/libconv/common/bld_vernote.ksh. That script produces
+ * libconv/{plat}/vernote.s, which is in turn assembled/linked into
+ * libconv.
+ */
+extern const char link_ver_string[];
+/*
+ * Macro to round to next double word boundary.
+ */
+#define S_DROUND(x) (((x) + sizeof (double) - 1) & ~(sizeof (double) - 1))
+
+/*
+ * General align and round macros.
+ */
+#define S_ALIGN(x, a) ((x) & ~(((a) ? (a) : 1) - 1))
+#define S_ROUND(x, a) ((x) + (((a) ? (a) : 1) - 1) & ~(((a) ? (a) : 1) - 1))
+
+/*
+ * Bit manipulation macros; generic bit mask and is `v' in the range
+ * supportable in `n' bits?
+ */
+#define S_MASK(n) ((1 << (n)) -1)
+#define S_INRANGE(v, n) (((-(1 << (n)) - 1) < (v)) && ((v) < (1 << (n))))
+
+
+/*
+ * Yet another definition of the OFFSETOF macro, used with the AVL routines.
+ */
+#define SGSOFFSETOF(s, m) ((size_t)(&(((s *)0)->m)))
+
+/*
+ * When casting between integer and pointer types, gcc will complain
+ * if the integer type used is not large enough to hold the pointer
+ * value without loss. Although a dubious practice in general, this
+ * is sometimes done by design. In those cases, the general solution
+ * is to introduce an intermediate cast to widen the integer value. The
+ * CAST_PTRINT macro does this, and its use documents the fact that
+ * the programmer is doing that sort of cast.
+ */
+#ifdef __GNUC__
+#define CAST_PTRINT(cast, value) ((cast)(uintptr_t)value)
+#else
+#define CAST_PTRINT(cast, value) ((cast)value)
+#endif
+
+/*
+ * General typedefs.
+ */
+typedef enum {
+ FALSE = 0,
+ TRUE = 1
+} Boolean;
+
+/*
+ * Types of errors (used by eprintf()), together with a generic error return
+ * value.
+ */
+typedef enum {
+ ERR_NONE,
+ ERR_WARNING,
+ ERR_FATAL,
+ ERR_ELF,
+ ERR_NUM /* Must be last */
+} Error;
+
+#if defined(_LP64) && !defined(_ELF64)
+#define S_ERROR (~(uint_t)0)
+#else
+#define S_ERROR (~(uintptr_t)0)
+#endif
+
+/*
+ * LIST_TRAVERSE() is used as the only "argument" of a "for" loop to
+ * traverse a linked list. The node pointer `node' is set to each node in
+ * turn and the corresponding data pointer is copied to `data'. The macro
+ * is used as in
+ * for (LIST_TRAVERSE(List *list, Listnode *node, void *data)) {
+ * process(data);
+ * }
+ */
+#define LIST_TRAVERSE(L, N, D) \
+ (void) (((N) = (L)->head) != NULL && ((D) = (N)->data) != NULL); \
+ (N) != NULL; \
+ (void) (((N) = (N)->next) != NULL && ((D) = (N)->data) != NULL)
+
+typedef struct listnode Listnode;
+typedef struct list List;
+
+struct listnode { /* a node on a linked list */
+ void *data; /* the data item */
+ Listnode *next; /* the next element */
+};
+
+struct list { /* a linked list */
+ Listnode *head; /* the first element */
+ Listnode *tail; /* the last element */
+};
+
+
+#ifdef _SYSCALL32
+typedef struct listnode32 Listnode32;
+typedef struct list32 List32;
+
+struct listnode32 { /* a node on a linked list */
+ Elf32_Addr data; /* the data item */
+ Elf32_Addr next; /* the next element */
+};
+
+struct list32 { /* a linked list */
+ Elf32_Addr head; /* the first element */
+ Elf32_Addr tail; /* the last element */
+};
+#endif /* _SYSCALL32 */
+
+
+/*
+ * Structure to maintain rejected files elf information. Files that are not
+ * applicable to the present link-edit are rejected and a search for an
+ * appropriate file may be resumed. The first rejected files information is
+ * retained so that a better error diagnostic can be given should an appropriate
+ * file not be located.
+ */
+typedef struct {
+ ushort_t rej_type; /* SGS_REJ_ value */
+ ushort_t rej_flag; /* additional information */
+ uint_t rej_info; /* numeric and string information */
+ const char *rej_str; /* associated with error */
+ const char *rej_name; /* object name - expanded library */
+ /* name and archive members */
+} Rej_desc;
+
+#define SGS_REJ_NONE 0
+#define SGS_REJ_MACH 1 /* wrong ELF machine type */
+#define SGS_REJ_CLASS 2 /* wrong ELF class (32-bit/64-bit) */
+#define SGS_REJ_DATA 3 /* wrong ELF data format (MSG/LSB) */
+#define SGS_REJ_TYPE 4 /* bad ELF type */
+#define SGS_REJ_BADFLAG 5 /* bad ELF flags value */
+#define SGS_REJ_MISFLAG 6 /* mismatched ELF flags value */
+#define SGS_REJ_VERSION 7 /* mismatched ELF/lib version */
+#define SGS_REJ_HAL 8 /* HAL R1 extensions required */
+#define SGS_REJ_US3 9 /* Sun UltraSPARC III extensions */
+ /* required */
+#define SGS_REJ_STR 10 /* generic error - info is a string */
+#define SGS_REJ_UNKFILE 11 /* unknown file type */
+#define SGS_REJ_HWCAP_1 12 /* hardware capabilities mismatch */
+
+/*
+ * For those source files used both inside and outside of the
+ * libld source base (tools/common/string_table.c) we can
+ * automatically switch between the allocation models
+ * based off of the 'cc -DUSE_LIBLD_MALLOC' flag.
+ */
+#ifdef USE_LIBLD_MALLOC
+#define calloc(x, a) libld_malloc(((size_t)x) * ((size_t)a))
+#define free libld_free
+#define malloc libld_malloc
+#define realloc libld_realloc
+
+#define libld_calloc(x, a) libld_malloc(((size_t)x) * ((size_t)a))
+extern void libld_free(void *);
+extern void *libld_malloc(size_t);
+extern void *libld_realloc(void *, size_t);
+#endif
+
+
+/*
+ * Data structures (defined in libld.h).
+ */
+typedef struct ent_desc Ent_desc;
+typedef struct group_desc Group_desc;
+typedef struct ifl_desc Ifl_desc;
+typedef struct is_desc Is_desc;
+typedef struct isa_desc Isa_desc;
+typedef struct isa_opt Isa_opt;
+typedef struct mv_desc Mv_desc;
+typedef struct ofl_desc Ofl_desc;
+typedef struct os_desc Os_desc;
+typedef struct rel_cache Rel_cache;
+typedef struct sdf_desc Sdf_desc;
+typedef struct sdv_desc Sdv_desc;
+typedef struct sg_desc Sg_desc;
+typedef struct sort_desc Sort_desc;
+typedef struct sec_order Sec_order;
+typedef struct sym_desc Sym_desc;
+typedef struct sym_aux Sym_aux;
+typedef struct sym_avlnode Sym_avlnode;
+typedef struct uts_desc Uts_desc;
+typedef struct ver_desc Ver_desc;
+typedef struct ver_index Ver_index;
+typedef struct audit_desc Audit_desc;
+typedef struct audit_info Audit_info;
+typedef struct audit_list Audit_list;
+
+/*
+ * Data structures defined in machrel.h.
+ */
+typedef struct rel_desc Rel_desc;
+
+/*
+ * Data structures defined in rtld.h.
+ */
+typedef struct lm_list Lm_list;
+#ifdef _SYSCALL32
+typedef struct lm_list32 Lm_list32;
+#endif /* _SYSCALL32 */
+
+/*
+ * For the various utilities that include sgs.h
+ */
+extern int assfail(const char *, const char *, int);
+extern void eprintf(Lm_list *, Error, const char *, ...);
+extern char *sgs_demangle(char *);
+extern uint_t sgs_str_hash(const char *);
+extern uint_t findprime(uint_t);
+
+#endif /* _ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _SGS_H */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h b/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h
new file mode 100644
index 0000000..e42f817
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/include/string_table.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _STRING_TABLE_DOT_H
+#define _STRING_TABLE_DOT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported, opaque string table handle.
+ */
+typedef struct str_tbl Str_tbl;
+
+/*
+ * Exported string table functions.
+ */
+extern int st_delstring(Str_tbl *, const char *);
+extern void st_destroy(Str_tbl *);
+extern size_t st_getstrtab_sz(Str_tbl *);
+extern const char *st_getstrbuf(Str_tbl *);
+extern int st_insert(Str_tbl *, const char *);
+extern Str_tbl *st_new(uint_t);
+extern int st_setstrbuf(Str_tbl *, char *, size_t);
+extern int st_setstring(Str_tbl *, const char *, size_t *);
+
+/*
+ * Exported flags values for st_new().
+ */
+#define FLG_STNEW_COMPRESS 0x01 /* compressed string table */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STRING_TABLE_DOT_H */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident b/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident
new file mode 100644
index 0000000..6afbf5f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/messages/sgs.ident
@@ -0,0 +1,62 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# Global message identifiers for the sgs utilities. This information is read
+# by sgsmsg(1l) using the -i option.
+# Each utilities message file references one of the `MSGID' identifiers. Its
+# associated numeric setid is used when creating catgets(3c) messages, the
+# string domain is used when creating gettext(3i) messages.
+#
+
+mesgid setid domain
+
+MSG_ID_RTLD 1 SUNW_OST_SGS /* sgs/rtld */
+MSG_ID_LIBRTLD 2 SUNW_OST_SGS /* sgs/librtld */
+MSG_ID_LIBLD 3 SUNW_OST_SGS /* sgs/libld */
+MSG_ID_LIBLDDBG 4 SUNW_OST_SGS /* sgs/liblddbg */
+MSG_ID_LIBLDSTAB 5 SUNW_OST_SGS /* sgs/libldstab */
+MSG_ID_LIBRTLD_DB 6 SUNW_OST_SGS /* sgs/librtld_db */
+MSG_ID_LIBPROF 7 SUNW_OST_SGS /* sgs/libprof */
+MSG_ID_LIBCRLE 8 SUNW_OST_SGS /* sgs/libcrle */
+
+MSG_ID_LIBELF 10 SUNW_OST_SGS /* sgs/libelf */
+
+MSG_ID_LD 20 SUNW_OST_SGS /* sgs/ld */
+MSG_ID_LDD 21 SUNW_OST_SGS /* sgs/ldd */
+MSG_ID_PVS 22 SUNW_OST_SGS /* sgs/pvs */
+MSG_ID_CRLE 23 SUNW_OST_SGS /* sgs/crle */
+MSG_ID_ELFDUMP 24 SUNW_OST_SGS /* sgs/elfdump */
+MSG_ID_MOE 25 SUNW_OST_SGS /* sgs/moe */
+MSG_ID_ELFEDIT 26 SUNW_OST_SGS /* sgs/elfedit */
+MSG_ID_ELFEDIT_CAP 27 SUNW_OST_SGS /* cap: */
+MSG_ID_ELFEDIT_DYN 27 SUNW_OST_SGS /* dyn: */
+MSG_ID_ELFEDIT_EHDR 27 SUNW_OST_SGS /* ehdr: */
+MSG_ID_ELFEDIT_PHDR 27 SUNW_OST_SGS /* phdr: */
+MSG_ID_ELFEDIT_SHDR 27 SUNW_OST_SGS /* shdr: */
+MSG_ID_ELFEDIT_STR 27 SUNW_OST_SGS /* str: */
+MSG_ID_ELFEDIT_SYM 27 SUNW_OST_SGS /* sym: */
+MSG_ID_ELFEDIT_SYMINFO 27 SUNW_OST_SGS /* syminfo: */
+MSG_ID_ELFWRAP 28 SUNW_OST_SGS /* sgs/elfwrap */
diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c
new file mode 100644
index 0000000..299fa21
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/tools/common/findprime.c
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sgs.h>
+
+/*
+ * function that will find a prime'ish number. Usefull for
+ * hashbuckets and related things.
+ */
+uint_t
+findprime(uint_t count)
+{
+ uint_t h, f;
+
+ if (count <= 3)
+ return (3);
+
+
+ /*
+ * Check to see if divisible by two, if so
+ * increment.
+ */
+ if ((count & 0x1) == 0)
+ count++;
+
+ for (h = count, f = 2; f * f <= h; f++)
+ if ((h % f) == 0)
+ h += f = 1;
+ return (h);
+}
diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c
new file mode 100644
index 0000000..9b2e37b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c
@@ -0,0 +1,1210 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * sgsmsg generates several message files from an input template file. Messages
+ * are constructed for use with gettext(3i) - the default - or catgets(3c). The
+ * files generate are:
+ *
+ * msg.h a header file containing definitions for each message. The -h
+ * option triggers the creation of these definitions and specifies
+ * the name to use.
+ *
+ * msg.c a data array of message strings. The msg.h definitions are
+ * offsets into this array. The -d option triggers the creation of
+ * these definitions and specifies the name to use.
+ *
+ * messages a message file suitable for catgets(3c) or gettext(3i) use. The
+ * -m option triggers this output and specifies the filename to be
+ * used.
+ *
+ * The template file is processed based on the first character of each line:
+ *
+ * # or $ entries are copied (as is) to the message file (messages).
+ *
+ * @ token(s) entries are translated. Two translations are possible dependent
+ * on whether one or more tokens are supplied:
+ *
+ * A single token is interpreted as one of two reserved message
+ * output indicators, or a message identifier. The reserved output
+ * indicator _START_ enables output to the message file - Note that
+ * the occurance of any other @ token will also enable message
+ * output. The reserved output indicator _END_ disables output to
+ * the message file. The use of these two indicators provides for
+ * only those message strings that require translation to be output
+ * to the message file.
+ *
+ * Besides the reserved output indicators, a single token is taken
+ * to be a message identifier which will be subsituted for a
+ * `setid' for catgets(3c) output, or a `domain' name for
+ * gettext(3i) output. This value is determine by substituting the
+ * token for the associated definition found in the message
+ * identifier file (specified with the -i option).
+ *
+ * Multiple tokens are taken to be a message definition followed by
+ * the associated message string. The message string is copied to
+ * the data array being built in msg.c. The index into this array
+ * becomes the `message' identifier created in the msg.h file.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/param.h>
+
+#include <sgs.h>
+#include <_string_table.h>
+
+/*
+ * Define any error message strings.
+ */
+static const char
+ * Errmsg_malt = "sgsmsg: file %s: line %d: malformed input "
+ "at line\n",
+ * Errmsg_nmem = "sgsmsg: memory allocation failed: %s\n",
+ * Errmsg_opne = "sgsmsg: file %s: open failed: %s\n",
+ * Errmsg_wrte = "sgsmsg: file %s: write failed: %s\n",
+ * Errmsg_read = "sgsmsg: file %s: read failed %s\n",
+ * Errmsg_stnw = "sgsmsg: st_new(): failed: %s\n",
+ * Errmsg_stin = "sgsmsg: Str_tbl insert failed: %s\n",
+ * Errmsg_mnfn = "sgsmsg: message not found in Str_tbl: %s\n",
+ * Errmsg_use = "usage: sgsmsg [-clv] [-d mesgdata] [-h mesgdefs] "
+ "[-m messages] [-n name] [-i mesgident] file ...\n";
+
+/*
+ * Define all output filenames and associated descriptors.
+ */
+static FILE *fddefs, *fddata, *fdmsgs, *fdmids, *fddesc;
+static char *fldefs, *fldata, *flmsgs, *flmids, *fldesc;
+static FILE *fdlint;
+static char fllint[MAXPATHLEN];
+
+static uint_t vflag; /* verbose flag */
+static Str_tbl *stp; /* string table */
+
+/*
+ * Define any default strings.
+ */
+static const char
+ *nmlint = "/tmp/sgsmsg.lint",
+ *interface = "sgs_msg",
+ *start = "_START_",
+ *end = "_END_";
+
+/*
+ * Define any default flags and data items.
+ */
+static int cflag = 0, lflag = 0, prtmsgs = 0, line, ptr = 1, msgid = 0;
+static char *mesgid = 0, *setid = 0, *domain = 0;
+
+typedef struct msg_string {
+ char *ms_defn;
+ char *ms_message;
+ struct msg_string *ms_next;
+} msg_string;
+
+static msg_string *msg_head;
+static msg_string *msg_tail;
+
+/*
+ * message_append() is responsible for both inserting strings into
+ * the master Str_tbl as well as maintaining a list of the
+ * DEFINITIONS associated with each string.
+ *
+ * The list of strings is traversed at the end once the full
+ * Str_tbl has been constructed - and string offsets can be
+ * assigned.
+ */
+static void
+message_append(const char *defn, const char *message)
+{
+ msg_string *msg;
+ if ((msg = calloc(sizeof (msg_string), 1)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Initialize the string table.
+ */
+ if ((stp == 0) && ((stp = st_new(FLG_STNEW_COMPRESS)) == NULL)) {
+ (void) fprintf(stderr, Errmsg_stnw, strerror(errno));
+ exit(1);
+ }
+
+
+ if ((msg->ms_defn = strdup(defn)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ exit(1);
+ }
+ if ((msg->ms_message = strdup(message)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ exit(1);
+ }
+
+ if (st_insert(stp, msg->ms_message) == -1) {
+ (void) fprintf(stderr, Errmsg_stin,
+ message);
+ exit(1);
+ }
+
+ if (msg_head == 0) {
+ msg_head = msg_tail = msg;
+ return;
+ }
+ msg_tail->ms_next = msg;
+ msg_tail = msg;
+}
+
+/*
+ * Initialize a setid value. Given a setid definition determine its numeric
+ * value from the specified message identifier file (specified with the -i
+ * option). Return a pointer to the numeric string.
+ */
+static int
+getmesgid(char *id)
+{
+ char *buffer, *token, *_mesgid = 0, *_setid = 0, *_domain = 0;
+
+ /*
+ * If we're being asked to interpret a message id but the user didn't
+ * provide the required message identifier file (-i option) we're in
+ * trouble.
+ */
+ if (flmids == 0) {
+ (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: "
+ "unable to process mesgid\n\t"
+ "no message identifier file specified "
+ "(see -i option)\n", fldesc, line, id);
+ return (1);
+ }
+
+ if ((buffer = malloc(LINE_MAX)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * Read the message identifier file and locate the required mesgid.
+ */
+ rewind(fdmids);
+ while (fgets(buffer, LINE_MAX, fdmids) != NULL) {
+ if ((token = strstr(buffer, id)) == NULL)
+ continue;
+
+ /*
+ * Establish individual strings for the mesgid, setid and domain
+ * values.
+ */
+ _mesgid = token;
+ while (!(isspace(*token)))
+ token++;
+ *token++ = 0;
+
+ while (isspace(*token))
+ token++;
+ _setid = token;
+ while (!(isspace(*token)))
+ token++;
+ *token++ = 0;
+
+ while (isspace(*token))
+ token++;
+ _domain = token;
+ while (!(isspace(*token)))
+ token++;
+ *token = 0;
+ break;
+ }
+
+ /*
+ * Did we find a match?
+ */
+ if ((_mesgid == 0) || (_setid == 0) || (_domain == 0)) {
+ (void) fprintf(stderr, "sgsmsg: file %s: line %d: mesgid %s: "
+ "unable to process mesgid\n\t"
+ "identifier does not exist in file %s\n",
+ fldesc, line, id, flmids);
+ return (1);
+ }
+
+ /*
+ * Have we been here before?
+ */
+ if (mesgid) {
+ if (cflag == 1) {
+ /*
+ * If we're being asked to process more than one mesgid
+ * warn the user that only one mesgid can be used for
+ * the catgets(3c) call.
+ */
+ (void) fprintf(stderr, "sgsmsg: file %s: line %d: "
+ "setid %s: warning: multiple mesgids "
+ "encountered\n\t"
+ "last setting used in messaging code\n",
+ fldesc, line, id);
+ }
+ }
+
+ mesgid = _mesgid;
+ setid = _setid;
+ domain = _domain;
+
+ /*
+ * Generate the message file output (insure output flag is enabled).
+ */
+ if (prtmsgs != -1)
+ prtmsgs = 1;
+ if (fdmsgs && (prtmsgs == 1)) {
+ if (cflag == 1) {
+ if (fprintf(fdmsgs, "$quote \"\n$set %s\n",
+ setid) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ } else {
+ if (fprintf(fdmsgs, "domain\t\"%s\"\n", domain) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ }
+ }
+
+ /*
+ * For catgets(3c) output generate a setid definition in the message
+ * definition file.
+ */
+ if (fddefs && (cflag == 1) &&
+ (fprintf(fddefs, "#define\t%s\t%s\n\n", mesgid, setid) < 0)) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Dump contents of String Table to standard out
+ */
+static void
+dump_stringtab(Str_tbl *stp)
+{
+ uint_t cnt;
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) {
+ (void) printf("string table full size: %ld: uncompressed\n",
+ stp->st_fullstrsize);
+ return;
+ }
+
+ (void) printf("string table full size: %ld compressed down to: %ld\n\n",
+ stp->st_fullstrsize, stp->st_strsize);
+ (void) printf("string table compression information [%d buckets]:\n",
+ stp->st_hbckcnt);
+
+ for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) {
+ Str_hash *sthash = stp->st_hashbcks[cnt];
+
+ if (sthash == 0)
+ continue;
+
+ (void) printf(" bucket: [%d]\n", cnt);
+
+ while (sthash) {
+ size_t stroff = sthash->hi_mstr->sm_strlen -
+ sthash->hi_strlen;
+
+ if (stroff == 0) {
+ (void) printf(" [%ld]: '%s' <master>\n",
+ sthash->hi_refcnt, sthash->hi_mstr->sm_str);
+ } else {
+ (void) printf(" [%ld]: '%s' <suffix of: "
+ "'%s'>\n", sthash->hi_refcnt,
+ &sthash->hi_mstr->sm_str[stroff],
+ sthash->hi_mstr->sm_str);
+ }
+ sthash = sthash->hi_next;
+ }
+ }
+}
+
+/*
+ * Initialize the message definition header file stream.
+ */
+static int
+init_defs(void)
+{
+ static char guard[FILENAME_MAX + 6];
+ char *optr;
+ const char *iptr, *_ptr;
+
+ /*
+ * Establish a header guard name using the files basename.
+ */
+ for (iptr = 0, _ptr = fldefs; _ptr && (*_ptr != '\0'); _ptr++) {
+ if (*_ptr == '/')
+ iptr = _ptr + 1;
+ }
+ if (iptr == 0)
+ iptr = fldefs;
+
+ optr = guard;
+ for (*optr++ = '_'; iptr && (*iptr != '\0'); iptr++, optr++) {
+ if (*iptr == '.') {
+ *optr++ = '_';
+ *optr++ = 'D';
+ *optr++ = 'O';
+ *optr++ = 'T';
+ *optr = '_';
+ } else
+ *optr = toupper(*iptr);
+ }
+
+ if (fprintf(fddefs, "#ifndef\t%s\n#define\t%s\n\n", guard, guard) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ if (fprintf(fddefs, "#ifndef\t__lint\n\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * add "typedef int Msg;"
+ */
+ if (fprintf(fddefs, "typedef int\tMsg;\n\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * If the associated data array is global define a prototype.
+ * Define a macro to access the array elements.
+ */
+ if (lflag == 0) {
+ if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs,
+ strerror(errno));
+ return (1);
+ }
+ }
+ if (fprintf(fddefs, "#define\tMSG_ORIG(x)\t&__%s[x]\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * Generate a prototype to access the associated data array.
+ */
+ if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+ if (fprintf(fddefs, "#define\tMSG_INTL(x)\t_%s(x)\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Finish the message definition header file.
+ */
+static int
+fini_defs(void)
+{
+ if (fprintf(fddefs, "\n#else\t/* __lint */\n\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * When __lint is defined, Msg is a char *. This allows lint to
+ * check our format strings against it's arguments.
+ */
+ if (fprintf(fddefs, "\ntypedef char *\tMsg;\n\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ if (fprintf(fddefs, "extern\tconst char *\t_%s(Msg);\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ if (lflag == 0) {
+ if (fprintf(fddefs, "extern\tconst char\t__%s[];\n\n",
+ interface) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs,
+ strerror(errno));
+ return (1);
+ }
+ }
+
+ if (fprintf(fddefs,
+ "#define MSG_ORIG(x)\tx\n#define MSG_INTL(x)\tx\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ /*
+ * Copy the temporary lint defs file into the new header.
+ */
+ if (fdlint) {
+ long size;
+ char *buf;
+
+ size = ftell(fdlint);
+ (void) rewind(fdlint);
+
+ if ((buf = malloc(size)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ return (1);
+ }
+ if (fread(buf, size, 1, fdlint) == 0) {
+ (void) fprintf(stderr, Errmsg_read, fllint,
+ strerror(errno));
+ return (1);
+ }
+ if (fwrite(buf, size, 1, fddefs) == 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs,
+ strerror(errno));
+ return (1);
+ }
+ (void) free(buf);
+ }
+
+ if (fprintf(fddefs, "\n#endif\t/* __lint */\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ if (fprintf(fddefs, "\n#endif\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldefs, strerror(errno));
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * The entire messaging file has been scanned - and all strings have been
+ * inserted into the string_table. We can now walk the message queue
+ * and create the '#define <DEFN>' for each string - with the strings
+ * assigned offset into the string_table.
+ */
+static int
+output_defs(void)
+{
+ msg_string *msg;
+ size_t stbufsize;
+ char *stbuf;
+
+ stbufsize = st_getstrtab_sz(stp);
+ if ((stbuf = malloc(stbufsize)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ exit(1);
+ }
+ (void) st_setstrbuf(stp, stbuf, stbufsize);
+ for (msg = msg_head; msg; msg = msg->ms_next) {
+ size_t stoff;
+ if ((st_setstring(stp, msg->ms_message, &stoff)) == -1) {
+ (void) fprintf(stderr, Errmsg_mnfn, msg->ms_message);
+ return (1);
+ }
+ if (fprintf(fddefs, "\n#define\t%s\t%ld\n",
+ msg->ms_defn, stoff) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fldefs, strerror(errno));
+ return (1);
+ }
+ if (fddefs && fprintf(fddefs, "#define\t%s_SIZE\t%d\n",
+ msg->ms_defn, strlen(msg->ms_message)) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fldefs, strerror(errno));
+ return (1);
+ }
+ }
+ return (0);
+}
+
+
+/*
+ * Finish off the data structure definition.
+ */
+static int
+output_data(void)
+{
+ size_t stbufsize;
+ size_t ndx;
+ size_t column = 1;
+ const char *stbuf;
+ const char *fmtstr;
+
+ stbufsize = st_getstrtab_sz(stp);
+ stbuf = st_getstrbuf(stp);
+
+ assert(stbuf);
+
+ /*
+ * Determine from the local flag whether the data declaration should
+ * be static.
+ */
+ if (lflag)
+ fmtstr = (const char *)"static const";
+ else
+ fmtstr = (const char *)"const";
+
+ if (fprintf(fddata, "\n%s char __%s[%ld] = { ",
+ fmtstr, interface, stbufsize) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno));
+ return (1);
+ }
+
+ for (ndx = 0; ndx < (stbufsize - 1); ndx++) {
+ if (column == 1) {
+ if (fddata && fprintf(fddata,
+ "\n/* %4ld */ 0x%.2x,", ndx,
+ (unsigned char)stbuf[ndx]) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fldata, strerror(errno));
+ return (1);
+ }
+ } else {
+ if (fddata && fprintf(fddata, " 0x%.2x,",
+ (unsigned char)stbuf[ndx]) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fldata, strerror(errno));
+ return (1);
+ }
+ }
+
+ if (column++ == 10)
+ column = 1;
+ }
+
+ if (column == 1)
+ fmtstr = "\n\t0x%.2x };\n";
+ else
+ fmtstr = " 0x%.2x };\n";
+
+ if (fprintf(fddata, fmtstr, (unsigned char)stbuf[stbufsize - 1]) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, fldata, strerror(errno));
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+file()
+{
+ char buffer[LINE_MAX], * token;
+ uint_t bufsize;
+ char *token_buffer;
+ int escape = 0;
+
+ if ((token_buffer = malloc(LINE_MAX)) == 0) {
+ (void) fprintf(stderr, Errmsg_nmem, strerror(errno));
+ return (1);
+ }
+ bufsize = LINE_MAX;
+
+ line = 1;
+
+ while ((token = fgets(buffer, LINE_MAX, fddesc)) != NULL) {
+ char defn[PATH_MAX], * _defn, * str;
+ int len;
+
+ switch (*token) {
+ case '#':
+ case '$':
+ if (escape) {
+ (void) fprintf(stderr, Errmsg_malt, fldesc,
+ line);
+ return (1);
+ }
+
+ /*
+ * If a msgid has been output a msgstr must follow
+ * before we digest the new token. A msgid is only set
+ * if fdmsgs is in use.
+ */
+ if (msgid) {
+ msgid = 0;
+ if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ flmsgs, strerror(errno));
+ return (1);
+ }
+ }
+
+ /*
+ * Pass lines directly through to the output message
+ * file.
+ */
+ if (fdmsgs && (prtmsgs == 1)) {
+ char comment;
+
+ if (cflag == 0)
+ comment = '#';
+ else
+ comment = '$';
+
+ if (fprintf(fdmsgs, "%c%s", comment,
+ ++token) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ flmsgs, strerror(errno));
+ return (1);
+ }
+ }
+ break;
+
+ case '@':
+ if (escape) {
+ (void) fprintf(stderr, Errmsg_malt, fldesc,
+ line);
+ return (1);
+ }
+
+ /*
+ * If a msgid has been output a msgstr must follow
+ * before we digest the new token.
+ */
+ if (msgid) {
+ msgid = 0;
+ if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ flmsgs, strerror(errno));
+ return (1);
+ }
+ }
+
+ /*
+ * Determine whether we have one or more tokens.
+ */
+ token++;
+ while (isspace(*token)) /* rid any whitespace */
+ token++;
+ _defn = token; /* definition start */
+ while (!(isspace(*token)))
+ token++;
+ *token++ = 0;
+
+ while (isspace(*token)) /* rid any whitespace */
+ token++;
+
+ /*
+ * Determine whether the single token is one of the
+ * reserved message output delimiters otherwise
+ * translate it as a message identifier.
+ */
+ if (*token == 0) {
+ if (strcmp(_defn, start) == 0)
+ prtmsgs = 1;
+ else if (strcmp(_defn, end) == 0)
+ prtmsgs = -1;
+ else if (getmesgid(_defn) == 1)
+ return (1);
+ break;
+ }
+
+ /*
+ * Multiple tokens are translated by taking the first
+ * token as the message definition, and the rest of the
+ * line as the message itself. A message line ending
+ * with an escape ('\') is expected to be continued on
+ * the next line.
+ */
+ if (prtmsgs != -1)
+ prtmsgs = 1;
+ if (fdmsgs && (prtmsgs == 1)) {
+ /*
+ * For catgets(3c) make sure a message
+ * identifier has been established (this is
+ * normally a domain for gettext(3i), but for
+ * sgsmsg use this could be argued as being
+ * redundent). Also make sure that the message
+ * definitions haven't exceeeded the maximum
+ * value allowed by gencat(1) before generating
+ * any message file entries.
+ */
+ if (cflag == 1) {
+ if (setid == 0) {
+ (void) fprintf(stderr, "file "
+ "%s: no message identifier "
+ "has been established\n",
+ fldesc);
+ return (1);
+ }
+ if (ptr > NL_MSGMAX) {
+ (void) fprintf(stderr, "file "
+ "%s: message definition "
+ "(%d) exceeds allowable "
+ "limit (NL_MSGMAX)\n",
+ fldesc, ptr);
+ return (1);
+ }
+ }
+
+ /*
+ * For catgets(3c) write the definition and the
+ * message string to the message file. For
+ * gettext(3i) write the message string as a
+ * mesgid - indicate a mesgid has been output
+ * so that a msgstr can follow.
+ */
+ if (cflag == 1) {
+ if (fprintf(fdmsgs, "%d\t%s", ptr,
+ token) < 0) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ } else {
+ if (fprintf(fdmsgs, "msgid\t\"") < 0) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ msgid = 1;
+ }
+ }
+
+ /*
+ * The message itself is a quoted string as this makes
+ * embedding spaces at the start (or the end) of the
+ * string very easy.
+ */
+ if (*token != '"') {
+ (void) fprintf(stderr, Errmsg_malt, fldesc,
+ line);
+ return (1);
+ }
+
+ (void) strcpy(defn, _defn);
+
+ /*
+ * Write the tag to the lint definitions.
+ */
+ if (fdlint) {
+ if (fprintf(fdlint, "\n#define\t%s\t",
+ _defn) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fllint, strerror(errno));
+ return (1);
+ }
+ }
+
+ len = 0;
+
+ /*
+ * Write each character of the message string to the
+ * data array. Translate any escaped characters - use
+ * the same specially recognized characters as defined
+ * by gencat(1).
+ */
+message:
+ if (*token == '"') {
+ if (fdlint &&
+ (fprintf(fdlint, "%c", *token) < 0)) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fllint, strerror(errno));
+ return (1);
+ }
+ token++;
+ }
+ while (*token) {
+ char _token;
+
+ if ((*token == '\\') && (escape == 0)) {
+ escape = 1;
+ if (fdlint && (*(token + 1) != '\n') &&
+ fprintf(fdlint, "%c", *token) < 0) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, fllint,
+ strerror(errno));
+ return (1);
+ }
+ token++;
+ continue;
+ }
+ if (escape) {
+ if (*token == 'n')
+ _token = '\n';
+ else if (*token == 't')
+ _token = '\t';
+ else if (*token == 'v')
+ _token = '\v';
+ else if (*token == 'b')
+ _token = '\b';
+ else if (*token == 'f')
+ _token = '\f';
+ else if (*token == '\\')
+ _token = '\\';
+ else if (*token == '"')
+ _token = '"';
+ else if (*token == '\n')
+ break;
+ else
+ _token = *token;
+
+ if (fdmsgs && (prtmsgs == 1) &&
+ (fprintf(fdmsgs, "\\") < 0)) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ } else {
+ /*
+ * If this is the trailing quote then
+ * thats the last of the message string.
+ * Eat up any remaining white space and
+ * unless an escape character is found
+ * terminate the data string with a 0.
+ */
+ /* BEGIN CSTYLED */
+ if (*token == '"') {
+ if (fdlint && (fprintf(fdlint,
+ "%c", *token) < 0)) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, fllint,
+ strerror(errno));
+ return (1);
+ }
+
+ if (fdmsgs && (prtmsgs == 1) &&
+ (fprintf(fdmsgs, "%c",
+ *token) < 0)) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+
+ while (*++token) {
+ if (*token == '\n')
+ break;
+ }
+ _token = '\0';
+ } else
+ _token = *token;
+ /* END CSTYLED */
+ }
+
+ if (fdmsgs && (prtmsgs == 1) &&
+ (fprintf(fdmsgs, "%c", *token) < 0)) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ flmsgs, strerror(errno));
+ return (1);
+ }
+
+ if (fdlint && fprintf(fdlint,
+ "%c", *token) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fllint, strerror(errno));
+ return (1);
+ }
+
+ if (len >= bufsize) {
+ bufsize += LINE_MAX;
+ if ((token_buffer = realloc(
+ token_buffer, bufsize)) == 0) {
+ (void) fprintf(stderr,
+ Errmsg_nmem,
+ strerror(errno));
+ return (1);
+ }
+ }
+ token_buffer[len] = _token;
+ ptr++, token++, len++;
+ escape = 0;
+
+ if (_token == '\0')
+ break;
+ }
+
+ /*
+ * After the complete message string has been processed
+ * (including its continuation beyond one line), create
+ * a string size definition.
+ */
+ if (escape == 0) {
+ const char *form = "#define\t%s_SIZE\t%d\n";
+
+ token_buffer[len] = '\0';
+
+ message_append(defn, token_buffer);
+
+ if (fdlint && fprintf(fdlint, form, defn,
+ (len - 1)) < 0) {
+ (void) fprintf(stderr, Errmsg_wrte,
+ fllint, strerror(errno));
+ return (1);
+ }
+ }
+ break;
+
+ default:
+ /*
+ * Empty lines are passed through to the message file.
+ */
+ while (isspace(*token))
+ token++;
+
+ if (*token == 0) {
+ if (msgid || (fdmsgs && (prtmsgs == 1))) {
+ /*
+ * If a msgid has been output a msgstr
+ * must follow before we digest the new
+ * token.
+ */
+ if (msgid) {
+ msgid = 0;
+ str = "msgstr\t\"\"\n\n";
+ } else
+ str = "\n";
+
+ if (fprintf(fdmsgs, str) < 0) {
+ (void) fprintf(stderr,
+ Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ }
+ break;
+ }
+
+ /*
+ * If an escape is in effect then any tokens are taken
+ * to be message continuations.
+ */
+ if (escape) {
+ escape = 0;
+ goto message;
+ }
+
+ (void) fprintf(stderr, "file %s: line %d: invalid "
+ "input does not start with #, $ or @\n", fldesc,
+ line);
+ return (1);
+ }
+ line++;
+ }
+
+ free(token_buffer);
+
+ return (0);
+}
+
+int
+main(int argc, char ** argv)
+{
+ opterr = 0;
+ while ((line = getopt(argc, argv, "cd:h:lm:n:i:v")) != EOF) {
+ switch (line) {
+ case 'c': /* catgets instead of gettext */
+ cflag = 1;
+ break;
+ case 'd': /* new message data filename */
+ fldata = optarg; /* (msg.c is default) */
+ break;
+ case 'h': /* new message defs filename */
+ fldefs = optarg; /* (msg.h is default) */
+ break;
+ case 'i': /* input message ids from */
+ flmids = optarg; /* from this file */
+ break;
+ case 'l': /* define message data arrays */
+ lflag = 1; /* to be local (static) */
+ break;
+ case 'm': /* generate message database */
+ flmsgs = optarg; /* to this file */
+ break;
+ case 'n': /* new data array and func */
+ interface = optarg; /* name (msg is default) */
+ break;
+ case 'v':
+ vflag = 1; /* set verbose flag */
+ break;
+ case '?':
+ (void) fprintf(stderr, Errmsg_use, argv[0]);
+ exit(1);
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Validate the we have been given at least one input file.
+ */
+ if ((argc - optind) < 1) {
+ (void) fprintf(stderr, Errmsg_use);
+ exit(1);
+ }
+
+ /*
+ * Open all the required output files.
+ */
+ if (fldefs) {
+ if ((fddefs = fopen(fldefs, "w+")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, fldefs,
+ strerror(errno));
+ return (1);
+ }
+ }
+ if (fldata) {
+ if (fldefs && (strcmp(fldefs, fldata) == 0))
+ fddata = fddefs;
+ else if ((fddata = fopen(fldata, "w+")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, fldata,
+ strerror(errno));
+ return (1);
+ }
+ }
+ if (fddefs && fddata) {
+ (void) sprintf(fllint, "%s.%d", nmlint, (int)getpid());
+ if ((fdlint = fopen(fllint, "w+")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, fllint,
+ strerror(errno));
+ return (1);
+ }
+ }
+ if (flmsgs) {
+ if ((fdmsgs = fopen(flmsgs, "w+")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ }
+ if (flmids) {
+ if ((fdmids = fopen(flmids, "r")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, flmids,
+ strerror(errno));
+ return (1);
+ }
+ }
+
+
+ /*
+ * Initialize the message definition and message data streams.
+ */
+ if (fddefs) {
+ if (init_defs())
+ return (1);
+ }
+
+ /*
+ * Read the input message file, and for each line process accordingly.
+ */
+ for (; optind < argc; optind++) {
+ int err;
+
+ fldesc = argv[optind];
+
+ if ((fddesc = fopen(fldesc, "r")) == NULL) {
+ (void) fprintf(stderr, Errmsg_opne, fldesc,
+ strerror(errno));
+ return (1);
+ }
+ err = file();
+ (void) fclose(fddesc);
+
+ if (err != 0)
+ return (1);
+ }
+
+ /*
+ * If a msgid has been output a msgstr must follow before we end the
+ * file.
+ */
+ if (msgid) {
+ msgid = 0;
+ if (fprintf(fdmsgs, "msgstr\t\"\"\n") < 0) {
+ (void) fprintf(stderr, Errmsg_wrte, flmsgs,
+ strerror(errno));
+ return (1);
+ }
+ }
+
+ if (fdmids)
+ (void) fclose(fdmids);
+ if (fdmsgs)
+ (void) fclose(fdmsgs);
+
+ if (fddefs) {
+ if (output_defs())
+ return (1);
+ }
+
+ /*
+ * Finish off any generated data and header file.
+ */
+ if (fldata) {
+ if (output_data())
+ return (1);
+ }
+ if (fddefs) {
+ if (fini_defs())
+ return (1);
+ }
+
+ if (vflag)
+ dump_stringtab(stp);
+
+ /*
+ * Close up everything and go home.
+ */
+ if (fddata)
+ (void) fclose(fddata);
+ if (fddefs && (fddefs != fddata))
+ (void) fclose(fddefs);
+ if (fddefs && fddata) {
+ (void) fclose(fdlint);
+ (void) unlink(fllint);
+ }
+
+ if (stp)
+ st_destroy(stp);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c b/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c
new file mode 100644
index 0000000..e174aca
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/sgs/tools/common/string_table.c
@@ -0,0 +1,685 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <_string_table.h>
+#include <strings.h>
+#include <sgs.h>
+#include <stdio.h>
+
+/*
+ * This file provides the interfaces to build a Str_tbl suitable for use by
+ * either the sgsmsg message system, or a standard ELF string table (SHT_STRTAB)
+ * as created by ld(1).
+ *
+ * There are two modes which can be used when constructing a string table:
+ *
+ * st_new(0)
+ * standard string table - no compression. This is the
+ * traditional, fast method.
+ *
+ * st_new(FLG_STTAB_COMPRESS)
+ * builds a compressed string table which both eliminates
+ * duplicate strings, and permits strings with common suffixes
+ * (atexit vs. exit) to overlap in the table. This provides space
+ * savings for many string tables. Although more work than the
+ * traditional method, the algorithms used are designed to scale
+ * and keep any overhead at a minimum.
+ *
+ * These string tables are built with a common interface in a two-pass manner.
+ * The first pass finds all of the strings required for the string-table and
+ * calculates the size required for the final string table.
+ *
+ * The second pass allocates the string table, populates the strings into the
+ * table and returns the offsets the strings have been assigned.
+ *
+ * The calling sequence to build and populate a string table is:
+ *
+ * st_new(); // initialize strtab
+ *
+ * st_insert(st1); // first pass of strings ...
+ * // calculates size required for
+ * // string table
+ *
+ * st_delstring(st?); // remove string previously
+ * // inserted
+ * st_insert(stN);
+ *
+ * st_getstrtab_sz(); // freezes strtab and computes
+ * // size of table.
+ *
+ * st_setstrbuf(); // associates a final destination
+ * // for the string table
+ *
+ * st_setstring(st1); // populate the string table
+ * ... // offsets are based off of second
+ * // pass through the string table
+ * st_setstring(stN);
+ *
+ * st_destroy(); // tear down string table
+ * // structures.
+ *
+ * String Suffix Compression Algorithm:
+ *
+ * Here's a quick high level overview of the Suffix String
+ * compression algorithm used. First - the heart of the algorithm
+ * is a Hash table list which represents a dictionary of all unique
+ * strings inserted into the string table. The hash function for
+ * this table is a standard string hash except that the hash starts
+ * at the last character in the string (&str[n - 1]) and works towards
+ * the first character in the function (&str[0]). As we compute the
+ * HASH value for a given string, we also compute the hash values
+ * for all of the possible suffix strings for that string.
+ *
+ * As we compute the hash - at each character see if the current
+ * suffix string for that hash is already present in the table. If
+ * it is, and the string is a master string. Then change that
+ * string to a suffix string of the new string being inserted.
+ *
+ * When the final hash value is found (hash for str[0...n]), check
+ * to see if it is in the hash table - if so increment the reference
+ * count for the string. If it is not yet in the table, insert a
+ * new hash table entry for a master string.
+ *
+ * The above method will find all suffixes of a given string given
+ * that the strings are inserted from shortest to longest. That is
+ * why this is a two phase method, we first collect all of the
+ * strings and store them based off of their length in an AVL tree.
+ * Once all of the strings have been submitted we then start the
+ * hash table build by traversing the AVL tree in order and
+ * inserting the strings from shortest to longest as described
+ * above.
+ */
+
+/* LINTLIBRARY */
+
+static int
+avl_len_compare(const void *n1, const void *n2)
+{
+ size_t len1, len2;
+
+ len1 = ((LenNode *)n1)->ln_strlen;
+ len2 = ((LenNode *)n2)->ln_strlen;
+
+ if (len1 == len2)
+ return (0);
+ if (len2 < len1)
+ return (1);
+ return (-1);
+}
+
+static int
+avl_str_compare(const void *n1, const void *n2)
+{
+ const char *str1, *str2;
+ int rc;
+
+ str1 = ((StrNode *)n1)->sn_str;
+ str2 = ((StrNode *)n2)->sn_str;
+
+ rc = strcmp(str1, str2);
+ if (rc > 0)
+ return (1);
+ if (rc < 0)
+ return (-1);
+ return (0);
+}
+
+/*
+ * Return an initialized Str_tbl - returns NULL on failure.
+ *
+ * flags:
+ * FLG_STTAB_COMPRESS - build a compressed string table
+ */
+Str_tbl *
+st_new(uint_t flags)
+{
+ Str_tbl *stp;
+
+ if ((stp = calloc(sizeof (Str_tbl), 1)) == NULL)
+ return (NULL);
+
+ /*
+ * Start with a leading '\0' - it's tradition.
+ */
+ stp->st_strsize = stp->st_fullstrsize = stp->st_nextoff = 1;
+
+ /*
+ * Do we compress this string table?
+ */
+ stp->st_flags = flags;
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)
+ return (stp);
+
+ if ((stp->st_lentree = calloc(sizeof (avl_tree_t), 1)) == NULL)
+ return (NULL);
+
+ avl_create(stp->st_lentree, &avl_len_compare, sizeof (LenNode),
+ SGSOFFSETOF(LenNode, ln_avlnode));
+
+ return (stp);
+}
+
+/*
+ * Insert a new string into the Str_tbl. There are two AVL trees used.
+ *
+ * . The first LenNode AVL tree maintains a tree of nodes based on string
+ * sizes.
+ * . Each LenNode maintains a StrNode AVL tree for each string. Large
+ * applications have been known to contribute thousands of strings of
+ * the same size. Should strings need to be removed (-z ignore), then
+ * the string AVL tree makes this removal efficient and scalable.
+ */
+int
+st_insert(Str_tbl *stp, const char *str)
+{
+ size_t len;
+ StrNode *snp, sn = { 0 };
+ LenNode *lnp, ln = { 0 };
+ avl_index_t where;
+
+ /*
+ * String table can't have been cooked
+ */
+ assert((stp->st_flags & FLG_STTAB_COOKED) == 0);
+
+ /*
+ * Null strings always point to the head of the string
+ * table - no reason to keep searching.
+ */
+ if ((len = strlen(str)) == 0)
+ return (0);
+
+ stp->st_fullstrsize += len + 1;
+ stp->st_strcnt++;
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)
+ return (0);
+
+ /*
+ * From the controlling string table, determine which LenNode AVL node
+ * provides for this string length. If the node doesn't exist, insert
+ * a new node to represent this string length.
+ */
+ ln.ln_strlen = len;
+ if ((lnp = avl_find(stp->st_lentree, &ln, &where)) == NULL) {
+ if ((lnp = calloc(sizeof (LenNode), 1)) == NULL)
+ return (-1);
+ lnp->ln_strlen = len;
+ avl_insert(stp->st_lentree, lnp, where);
+
+ if ((lnp->ln_strtree = calloc(sizeof (avl_tree_t), 1)) == NULL)
+ return (0);
+
+ avl_create(lnp->ln_strtree, &avl_str_compare, sizeof (StrNode),
+ SGSOFFSETOF(StrNode, sn_avlnode));
+ }
+
+ /*
+ * From the string length AVL node determine whether a StrNode AVL node
+ * provides this string. If the node doesn't exist, insert a new node
+ * to represent this string.
+ */
+ sn.sn_str = str;
+ if ((snp = avl_find(lnp->ln_strtree, &sn, &where)) == NULL) {
+ if ((snp = calloc(sizeof (StrNode), 1)) == NULL)
+ return (-1);
+ snp->sn_str = str;
+ avl_insert(lnp->ln_strtree, snp, where);
+ }
+ snp->sn_refcnt++;
+
+ return (0);
+}
+
+/*
+ * Remove a previously inserted string from the Str_tbl.
+ */
+int
+st_delstring(Str_tbl *stp, const char *str)
+{
+ size_t len;
+ LenNode *lnp, ln = { 0 };
+ StrNode *snp, sn = { 0 };
+
+ /*
+ * String table can't have been cooked
+ */
+ assert((stp->st_flags & FLG_STTAB_COOKED) == 0);
+
+ len = strlen(str);
+ stp->st_fullstrsize -= len + 1;
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)
+ return (0);
+
+ /*
+ * Determine which LenNode AVL node provides for this string length.
+ */
+ ln.ln_strlen = len;
+ if ((lnp = avl_find(stp->st_lentree, &ln, 0)) != NULL) {
+ sn.sn_str = str;
+ if ((snp = avl_find(lnp->ln_strtree, &sn, 0)) != NULL) {
+ /*
+ * Reduce the reference count, and if zero remove the
+ * node.
+ */
+ if (--snp->sn_refcnt == 0)
+ avl_remove(lnp->ln_strtree, snp);
+ return (0);
+ }
+ }
+
+ /*
+ * No strings of this length, or no string itself - someone goofed.
+ */
+ return (-1);
+}
+
+/*
+ * Tear down a String_Table structure.
+ */
+void
+st_destroy(Str_tbl *stp)
+{
+ Str_hash *sthash, *psthash;
+ Str_master *mstr, *pmstr;
+ uint_t i;
+
+ /*
+ * cleanup the master strings
+ */
+ for (mstr = stp->st_mstrlist, pmstr = 0; mstr;
+ mstr = mstr->sm_next) {
+ if (pmstr)
+ free(pmstr);
+ pmstr = mstr;
+ }
+ if (pmstr)
+ free(pmstr);
+
+ if (stp->st_hashbcks) {
+ for (i = 0; i < stp->st_hbckcnt; i++) {
+ for (sthash = stp->st_hashbcks[i], psthash = 0;
+ sthash; sthash = sthash->hi_next) {
+ if (psthash)
+ free(psthash);
+ psthash = sthash;
+ }
+ if (psthash)
+ free(psthash);
+ }
+ free(stp->st_hashbcks);
+ }
+ free(stp);
+}
+
+
+/*
+ * For a given string - copy it into the buffer associated with
+ * the string table - and return the offset it has been assigned.
+ *
+ * If a value of '-1' is returned - the string was not found in
+ * the Str_tbl.
+ */
+int
+st_setstring(Str_tbl *stp, const char *str, size_t *stoff)
+{
+ size_t stlen;
+ uint_t hashval;
+ Str_hash *sthash;
+ Str_master *mstr;
+ int i;
+
+ /*
+ * String table *must* have been previously cooked
+ */
+ assert(stp->st_strbuf);
+
+ assert(stp->st_flags & FLG_STTAB_COOKED);
+ stlen = strlen(str);
+ /*
+ * Null string always points to head of string table
+ */
+ if (stlen == 0) {
+ *stoff = 0;
+ return (0);
+ }
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) {
+ size_t _stoff;
+
+ stlen++; /* count for trailing '\0' */
+ _stoff = stp->st_nextoff;
+ /*
+ * Have we overflowed our assigned buffer?
+ */
+ if ((_stoff + stlen) > stp->st_fullstrsize)
+ return (-1);
+ memcpy(stp->st_strbuf + _stoff, str, stlen);
+ *stoff = _stoff;
+ stp->st_nextoff += stlen;
+ return (0);
+ }
+
+ /*
+ * Calculate reverse hash for string.
+ */
+ hashval = HASHSEED;
+ for (i = stlen; i >= 0; i--) {
+ hashval = ((hashval << 5) + hashval) +
+ str[i]; /* h = ((h * 33) + c) */
+ }
+
+ for (sthash = stp->st_hashbcks[hashval % stp->st_hbckcnt]; sthash;
+ sthash = sthash->hi_next) {
+ const char *hstr;
+
+ if (sthash->hi_hashval != hashval)
+ continue;
+
+ hstr = &sthash->hi_mstr->sm_str[sthash->hi_mstr->sm_strlen -
+ sthash->hi_strlen];
+ if (strcmp(str, hstr) == 0)
+ break;
+ }
+
+ /*
+ * Did we find the string?
+ */
+ if (sthash == 0)
+ return (-1);
+
+ /*
+ * Has this string been copied into the string table?
+ */
+ mstr = sthash->hi_mstr;
+ if (mstr->sm_stroff == 0) {
+ size_t mstrlen = mstr->sm_strlen + 1;
+
+ mstr->sm_stroff = stp->st_nextoff;
+
+ /*
+ * Have we overflowed our assigned buffer?
+ */
+ if ((mstr->sm_stroff + mstrlen) > stp->st_fullstrsize)
+ return (-1);
+
+ (void) memcpy(stp->st_strbuf + mstr->sm_stroff,
+ mstr->sm_str, mstrlen);
+ stp->st_nextoff += mstrlen;
+ }
+
+ /*
+ * Calculate offset of (sub)string.
+ */
+ *stoff = mstr->sm_stroff + mstr->sm_strlen - sthash->hi_strlen;
+
+ return (0);
+}
+
+
+static int
+st_hash_insert(Str_tbl *stp, const char *str, size_t len)
+{
+ int i;
+ uint_t hashval = HASHSEED;
+ uint_t bckcnt = stp->st_hbckcnt;
+ Str_hash **hashbcks = stp->st_hashbcks;
+ Str_hash *sthash;
+ Str_master *mstr = 0;
+
+ /*
+ * We use a classic 'Bernstein k=33' hash function. But
+ * instead of hashing from the start of the string to the
+ * end, we do it in reverse.
+ *
+ * This way - we are essentially building all of the
+ * suffix hashvalues as we go. We can check to see if
+ * any suffixes already exist in the tree as we generate
+ * the hash.
+ */
+ for (i = len; i >= 0; i--) {
+ hashval = ((hashval << 5) + hashval) +
+ str[i]; /* h = ((h * 33) + c) */
+
+ for (sthash = hashbcks[hashval % bckcnt];
+ sthash; sthash = sthash->hi_next) {
+ const char *hstr;
+ Str_master *_mstr;
+
+ if (sthash->hi_hashval != hashval)
+ continue;
+
+ _mstr = sthash->hi_mstr;
+ hstr = &_mstr->sm_str[_mstr->sm_strlen -
+ sthash->hi_strlen];
+
+ if (strcmp(&str[i], hstr))
+ continue;
+
+ if (i == 0) {
+ /*
+ * Entry already in table, increment refcnt and
+ * get out.
+ */
+ sthash->hi_refcnt++;
+ return (0);
+ } else {
+ /*
+ * If this 'suffix' is presently a 'master
+ * string, then take over it's record.
+ */
+ if (sthash->hi_strlen == _mstr->sm_strlen) {
+ /*
+ * we should only do this once.
+ */
+ assert(mstr == 0);
+ mstr = _mstr;
+ }
+ }
+ }
+ }
+
+ /*
+ * Do we need a new master string, or can we take over
+ * one we already found in the table?
+ */
+ if (mstr == 0) {
+ /*
+ * allocate a new master string
+ */
+ if ((mstr = calloc(sizeof (Str_hash), 1)) == 0)
+ return (-1);
+ mstr->sm_next = stp->st_mstrlist;
+ stp->st_mstrlist = mstr;
+ stp->st_strsize += len + 1;
+ } else {
+ /*
+ * We are taking over a existing master string, the string size
+ * only increments by the difference between the current string
+ * and the previous master.
+ */
+ assert(len > mstr->sm_strlen);
+ stp->st_strsize += len - mstr->sm_strlen;
+ }
+
+ if ((sthash = calloc(sizeof (Str_hash), 1)) == 0)
+ return (-1);
+
+ mstr->sm_hashval = sthash->hi_hashval = hashval;
+ mstr->sm_strlen = sthash->hi_strlen = len;
+ mstr->sm_str = str;
+ sthash->hi_refcnt = 1;
+ sthash->hi_mstr = mstr;
+
+ /*
+ * Insert string element into head of hash list
+ */
+ hashval = hashval % bckcnt;
+ sthash->hi_next = hashbcks[hashval];
+ hashbcks[hashval] = sthash;
+ return (0);
+}
+
+/*
+ * Return amount of space required for the string table.
+ */
+size_t
+st_getstrtab_sz(Str_tbl *stp)
+{
+ assert(stp->st_fullstrsize > 0);
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) {
+ stp->st_flags |= FLG_STTAB_COOKED;
+ return (stp->st_fullstrsize);
+ }
+
+ if ((stp->st_flags & FLG_STTAB_COOKED) == 0) {
+ LenNode *lnp;
+ void *cookie;
+
+ stp->st_flags |= FLG_STTAB_COOKED;
+ /*
+ * allocate a hash table about the size of # of
+ * strings input.
+ */
+ stp->st_hbckcnt = findprime(stp->st_strcnt);
+ if ((stp->st_hashbcks =
+ calloc(sizeof (Str_hash), stp->st_hbckcnt)) == NULL)
+ return (0);
+
+ /*
+ * We now walk all of the strings in the list, from shortest to
+ * longest, and insert them into the hashtable.
+ */
+ if ((lnp = avl_first(stp->st_lentree)) == NULL) {
+ /*
+ * Is it possible we have an empty string table, if so,
+ * the table still contains '\0', so return the size.
+ */
+ if (avl_numnodes(stp->st_lentree) == 0) {
+ assert(stp->st_strsize == 1);
+ return (stp->st_strsize);
+ }
+ return (0);
+ }
+
+ while (lnp) {
+ StrNode *snp;
+
+ /*
+ * Walk the string lists and insert them into the hash
+ * list. Once a string is inserted we no longer need
+ * it's entry, so the string can be freed.
+ */
+ for (snp = avl_first(lnp->ln_strtree); snp;
+ snp = AVL_NEXT(lnp->ln_strtree, snp)) {
+ if (st_hash_insert(stp, snp->sn_str,
+ lnp->ln_strlen) == -1)
+ return (0);
+ }
+
+ /*
+ * Now that the strings have been copied, walk the
+ * StrNode tree and free all the AVL nodes. Note,
+ * avl_destroy_nodes() beats avl_remove() as the
+ * latter balances the nodes as they are removed.
+ * We just want to tear the whole thing down fast.
+ */
+ cookie = NULL;
+ while ((snp = avl_destroy_nodes(lnp->ln_strtree,
+ &cookie)) != NULL)
+ free(snp);
+ avl_destroy(lnp->ln_strtree);
+ free(lnp->ln_strtree);
+ lnp->ln_strtree = NULL;
+
+ /*
+ * Move on to the next LenNode.
+ */
+ lnp = AVL_NEXT(stp->st_lentree, lnp);
+ }
+
+ /*
+ * Now that all of the strings have been freed, walk the
+ * LenNode tree and free all of the AVL nodes. Note,
+ * avl_destroy_nodes() beats avl_remove() as the latter
+ * balances the nodes as they are removed. We just want to
+ * tear the whole thing down fast.
+ */
+ cookie = NULL;
+ while ((lnp = avl_destroy_nodes(stp->st_lentree,
+ &cookie)) != NULL)
+ free(lnp);
+ avl_destroy(stp->st_lentree);
+ free(stp->st_lentree);
+ stp->st_lentree = 0;
+ }
+
+ assert(stp->st_strsize > 0);
+ assert(stp->st_fullstrsize >= stp->st_strsize);
+
+ return (stp->st_strsize);
+}
+
+/*
+ * Associate a buffer with a string table.
+ */
+const char *
+st_getstrbuf(Str_tbl *stp)
+{
+ return (stp->st_strbuf);
+}
+
+int
+st_setstrbuf(Str_tbl *stp, char *stbuf, size_t bufsize)
+{
+ assert(stp->st_flags & FLG_STTAB_COOKED);
+
+ if ((stp->st_flags & FLG_STTAB_COMPRESS) == 0) {
+ if (bufsize < stp->st_fullstrsize)
+ return (-1);
+ } else {
+ if (bufsize < stp->st_strsize)
+ return (-1);
+ }
+
+ stp->st_strbuf = stbuf;
+#ifdef DEBUG
+ /*
+ * for debug builds - start with a stringtable filled in
+ * with '0xff'. This makes it very easy to find wholes
+ * which we failed to fill in - in the strtab.
+ */
+ memset(stbuf, 0xff, bufsize);
+ stbuf[0] = '\0';
+#else
+ memset(stbuf, 0x0, bufsize);
+#endif
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/stat/common/statcommon.h b/cddl/contrib/opensolaris/cmd/stat/common/statcommon.h
new file mode 100644
index 0000000..f82495f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/stat/common/statcommon.h
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Common routines for acquiring snapshots of kstats for
+ * iostat, mpstat, and vmstat.
+ */
+
+#ifndef _STATCOMMON_H
+#define _STATCOMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+
+#define NODATE 0 /* Default: No time stamp */
+#define DDATE 1 /* Standard date format */
+#define UDATE 2 /* Internal representation of Unix time */
+
+/* Print a timestamp in either Unix or standard format. */
+void print_timestamp(uint_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STATCOMMON_H */
diff --git a/cddl/contrib/opensolaris/cmd/stat/common/timestamp.c b/cddl/contrib/opensolaris/cmd/stat/common/timestamp.c
new file mode 100644
index 0000000..be7b30c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/stat/common/timestamp.c
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include "statcommon.h"
+
+#include <langinfo.h>
+
+/*
+ * Print timestamp as decimal reprentation of time_t value (-T u was specified)
+ * or in date(1) format (-T d was specified).
+ */
+void
+print_timestamp(uint_t timestamp_fmt)
+{
+ time_t t = time(NULL);
+
+ if (timestamp_fmt == UDATE) {
+ (void) printf("%ld\n", t);
+ } else if (timestamp_fmt == DDATE) {
+ char dstr[64];
+ int len;
+
+ len = strftime(dstr, sizeof (dstr), "%+", localtime(&t));
+ if (len > 0)
+ (void) printf("%s\n", dstr);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 b/cddl/contrib/opensolaris/cmd/zdb/zdb.8
new file mode 100644
index 0000000..e036b96
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.8
@@ -0,0 +1,306 @@
+'\" te
+.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2012, Richard Lowe.
+.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 10, 2012
+.Dt ZDB 8
+.Os
+.Sh NAME
+.Nm zdb
+.Nd Display zpool debugging and consistency information
+.Sh SYNOPSIS
+.Nm
+.Op Fl CumdibcsDvhLXFPA
+.Op Fl e Op Fl p Ar path...
+.Op Fl t Ar txg
+.Ar poolname
+.Op Ar object ...
+.Nm
+.Op Fl divPA
+.Op Fl e Op Fl p Ar path...
+.Ar dataset
+.Op Ar object ...
+.Nm
+.Fl m Op Fl LXFPA
+.Op Fl t Ar txg
+.Op Fl e Op Fl p Ar path...
+.Ar poolname
+.Nm
+.Fl R Op Fl A
+.Op Fl e Op Fl p Ar path...
+.Ar poolname
+.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
+.Nm
+.Fl S
+.Op Fl AP
+.Op Fl e Op Fl p Ar path...
+.Ar poolname
+.Nm
+.Fl l
+.Op Fl uA
+.Ar device
+.Nm
+.Fl C
+.Op Fl A
+.Op Fl U Ar cache
+.Sh DESCRIPTION
+The
+.Nm
+utility displays information about a ZFS pool useful for debugging and
+performs some amount of consistency checking.
+It is a not a general purpose tool and options (and facilities) may change.
+This is neither a
+.Xr fsck 8
+nor a
+.Xr fsdb 8
+utility.
+.Pp
+The output of this command in general reflects the on-disk structure of a ZFS
+pool, and is inherently unstable.
+The precise output of most invocations is not documented, a knowledge of ZFS
+internals is assumed.
+.Pp
+When operating on an imported and active pool it is possible, though unlikely,
+that zdb may interpret inconsistent pool data and behave erratically.
+.Sh OPTIONS
+Display options:
+.Bl -tag -width indent
+.It Fl b
+Display statistics regarding the number, size (logical, physical and
+allocated) and deduplication of blocks.
+.It Fl c
+Verify the checksum of all metadata blocks while printing block statistics
+(see
+.Fl b Ns ).
+.Pp
+If specified multiple times, verify the checksums of all blocks.
+.It Fl C
+Display information about the configuration. If specified with no other
+options, instead display information about the cache file
+.Po Pa /etc/zfs/zpool.cache Pc .
+To specify the cache file to display, see
+.Fl U
+.Pp
+If specified multiple times, and a pool name is also specified display both
+the cached configuration and the on-disk configuration.
+If specified multiple times with
+.Fl e
+also display the configuration that would be used were the pool to be
+imported.
+.It Fl d
+Display information about datasets. Specified once, displays basic dataset
+information: ID, create transaction, size, and object count.
+.Pp
+If specified multiple times provides greater and greater verbosity.
+.Pp
+If object IDs are specified, display information about those specific objects only.
+.It Fl D
+Display deduplication statistics, including the deduplication ratio (dedup),
+compression ratio (compress), inflation due to the zfs copies property
+(copies), and an overall effective ratio (dedup * compress / copies).
+.Pp
+If specified twice, display a histogram of deduplication statistics, showing
+the allocated (physically present on disk) and referenced (logically
+referenced in the pool) block counts and sizes by reference count.
+.It Fl h
+Display pool history similar to
+.Cm zpool history ,
+but include internal changes, transaction, and dataset information.
+.It Fl i
+Display information about intent log (ZIL) entries relating to each
+dataset.
+If specified multiple times, display counts of each intent log transaction
+type.
+.It Fl l Ar device
+Display the vdev labels from the specified device.
+If the
+.Fl u
+option is also specified, also display the uberblocks on this device.
+.It Fl L
+Disable leak tracing and the loading of space maps.
+By default,
+.Nm
+verifies that all non-free blocks are referenced, which can be very expensive.
+.It Fl m
+Display the offset, spacemap, and free space of each metaslab.
+When specified twice, also display information about the maximum contiguous
+free space and the percentage of free space in each space map.
+When specified three times display every spacemap record.
+.It Xo
+.Fl R Ar poolname
+.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
+.Xc
+Read and display a block from the specified device. By default the block is
+displayed as a hex dump, but see the description of the
+.Fl r
+flag, below.
+.Pp
+The block is specified in terms of a colon-separated tuple
+.Ar vdev
+(an integer vdev identifier)
+.Ar offset
+(the offset within the vdev)
+.Ar size
+(the size of the block to read) and, optionally,
+.Ar flags
+(a set of flags, described below).
+.Bl -tag -width indent
+.It Sy b offset
+Print block pointer
+.It Sy d
+Decompress the block
+.It Sy e
+Byte swap the block
+.It Sy g
+Dump gang block header
+.It Sy i
+Dump indirect block
+.It Sy r
+Dump raw uninterpreted block data
+.El
+.It Fl s
+Report statistics on
+.Nm Ns 's
+I/O.
+Display operation counts, bandwidth, and error counts of I/O to the pool from
+.Nm .
+.It Fl S
+Simulate the effects of deduplication, constructing a DDT and then display
+that DDT as with \fB-DD\fR.
+.It Fl u
+Display the current uberblock.
+.El
+.Pp
+Other options:
+.Bl -tag -width indent
+.It Fl A
+Do not abort should any assertion fail.
+.It Fl AA
+Enable panic recovery, certain errors which would otherwise be fatal are
+demoted to warnings.
+.It Fl AAA
+Do not abort if asserts fail and also enable panic recovery.
+.It Fl e Op Fl p Ar path...
+Operate on an exported pool, not present in
+.Pa /etc/zfs/zpool.cache .
+The
+.Fl p
+flag specifies the path under which devices are to be searched.
+.It Fl F
+Attempt to make an unreadable pool readable by trying progressively older
+transactions.
+.It Fl P
+Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
+than 1M.
+.It Fl t Ar transaction
+Specify the highest transaction to use when searching for uberblocks.
+See also the
+.Fl u
+and
+.Fl l
+options for a means to see the available uberblocks and their associated
+transaction numbers.
+.It Fl U Ar cachefile
+Use a cache file other than
+.Pa /etc/zfs/zpool.cache .
+This option is only valid with
+.Fl C
+.It Fl v
+Enable verbosity.
+Specify multiple times for increased verbosity.
+.It Fl X
+Attempt
+.Ql extreme
+transaction rewind, that is attempt the same recovery as
+.Fl F
+but read transactions otherwise deemed too old.
+.El
+.Pp
+Specifying a display option more than once enables verbosity for only that
+option, with more occurrences enabling more verbosity.
+.Pp
+If no options are specified, all information about the named pool will be
+displayed at default verbosity.
+.Sh EXAMPLES
+.Bl -tag -width 0n
+.It Sy Example 1 Display the configuration of imported pool 'rpool'
+.Bd -literal -offset 2n
+.Li # Ic zdb -C rpool
+
+MOS Configuration:
+ version: 28
+ name: 'rpool'
+ ...
+.Ed
+.It Sy Example 2 Display basic dataset information about 'rpool'
+.Bd -literal -offset 2n
+.Li # Ic zdb -d rpool
+Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects
+Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects
+ ...
+.Ed
+.It Xo Sy Example 3 Display basic information about object 0 in
+.Sy 'rpool/export/home'
+.Xc
+.Bd -literal -offset 2n
+.Li # Ic zdb -d rpool/export/home 0
+Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects
+
+ Object lvl iblk dblk dsize lsize %full type
+ 0 7 16K 16K 15.0K 16K 25.00 DMU dnode
+.Ed
+.It Xo Sy Example 4 Display the predicted effect of enabling deduplication on
+.Sy 'rpool'
+.Xc
+.Bd -literal -offset 2n
+.Li # Ic zdb -S rpool
+Simulated DDT histogram:
+
+bucket allocated referenced
+______ ______________________________ ______________________________
+refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
+------ ------ ----- ----- ----- ------ ----- ----- -----
+ 1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G
+ 2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G
+ ...
+dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00
+.Ed
+.El
+.Sh SEE ALSO
+.Xr zfs 8 ,
+.Xr zpool 8
+.Sh AUTHORS
+This manual page is a
+.Xr mdoc 7
+reimplementation of the
+.Tn illumos
+manual page
+.Em zdb(1M) ,
+modified and customized for
+.Fx
+and licensed under the
+Common Development and Distribution License
+.Pq Tn CDDL .
+.Pp
+The
+.Xr mdoc 7
+implementation of this manual page was initially written by
+.An Martin Matuska Aq mm@FreeBSD.org
+and
+.An Marcelo Araujo Aq araujo@FreeBSD.org .
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
new file mode 100644
index 0000000..1d56407
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -0,0 +1,3299 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu.h>
+#include <sys/zap.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_sa.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/vdev.h>
+#include <sys/vdev_impl.h>
+#include <sys/metaslab_impl.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_pool.h>
+#include <sys/dbuf.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/dmu_traverse.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/zfs_fuid.h>
+#include <sys/arc.h>
+#include <sys/ddt.h>
+#include <sys/zfeature.h>
+#include <zfs_comutil.h>
+#undef ZFS_MAXNAMELEN
+#undef verify
+#include <libzfs.h>
+
+#define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \
+ zio_compress_table[(idx)].ci_name : "UNKNOWN")
+#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
+ zio_checksum_table[(idx)].ci_name : "UNKNOWN")
+#define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
+ dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \
+ dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
+#define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : \
+ (((idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA) ? \
+ DMU_OT_ZAP_OTHER : DMU_OT_NUMTYPES))
+
+#ifndef lint
+extern int zfs_recover;
+#else
+int zfs_recover;
+#endif
+
+const char cmdname[] = "zdb";
+uint8_t dump_opt[256];
+
+typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
+
+extern void dump_intent_log(zilog_t *);
+uint64_t *zopt_object = NULL;
+int zopt_objects = 0;
+libzfs_handle_t *g_zfs;
+
+/*
+ * These libumem hooks provide a reasonable set of defaults for the allocator's
+ * debugging facilities.
+ */
+const char *
+_umem_debug_init()
+{
+ return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+ return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]]"
+ "poolname [object...]\n"
+ " %s [-divPA] [-e -p path...] dataset [object...]\n"
+ " %s -m [-LXFPA] [-t txg] [-e [-p path...]]"
+ "poolname [vdev [metaslab...]]\n"
+ " %s -R [-A] [-e [-p path...]] poolname "
+ "vdev:offset:size[:flags]\n"
+ " %s -S [-PA] [-e [-p path...]] poolname\n"
+ " %s -l [-uA] device\n"
+ " %s -C [-A] [-U config]\n\n",
+ cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
+
+ (void) fprintf(stderr, " Dataset name must include at least one "
+ "separator character '/' or '@'\n");
+ (void) fprintf(stderr, " If dataset name is specified, only that "
+ "dataset is dumped\n");
+ (void) fprintf(stderr, " If object numbers are specified, only "
+ "those objects are dumped\n\n");
+ (void) fprintf(stderr, " Options to control amount of output:\n");
+ (void) fprintf(stderr, " -u uberblock\n");
+ (void) fprintf(stderr, " -d dataset(s)\n");
+ (void) fprintf(stderr, " -i intent logs\n");
+ (void) fprintf(stderr, " -C config (or cachefile if alone)\n");
+ (void) fprintf(stderr, " -h pool history\n");
+ (void) fprintf(stderr, " -b block statistics\n");
+ (void) fprintf(stderr, " -m metaslabs\n");
+ (void) fprintf(stderr, " -c checksum all metadata (twice for "
+ "all data) blocks\n");
+ (void) fprintf(stderr, " -s report stats on zdb's I/O\n");
+ (void) fprintf(stderr, " -D dedup statistics\n");
+ (void) fprintf(stderr, " -S simulate dedup to measure effect\n");
+ (void) fprintf(stderr, " -v verbose (applies to all others)\n");
+ (void) fprintf(stderr, " -l dump label contents\n");
+ (void) fprintf(stderr, " -L disable leak tracking (do not "
+ "load spacemaps)\n");
+ (void) fprintf(stderr, " -R read and display block from a "
+ "device\n\n");
+ (void) fprintf(stderr, " Below options are intended for use "
+ "with other options (except -l):\n");
+ (void) fprintf(stderr, " -A ignore assertions (-A), enable "
+ "panic recovery (-AA) or both (-AAA)\n");
+ (void) fprintf(stderr, " -F attempt automatic rewind within "
+ "safe range of transaction groups\n");
+ (void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
+ "cachefile\n");
+ (void) fprintf(stderr, " -X attempt extreme rewind (does not "
+ "work with dataset)\n");
+ (void) fprintf(stderr, " -e pool is exported/destroyed/"
+ "has altroot/not in a cachefile\n");
+ (void) fprintf(stderr, " -p <path> -- use one or more with "
+ "-e to specify path to vdev dir\n");
+ (void) fprintf(stderr, " -P print numbers in parseable form\n");
+ (void) fprintf(stderr, " -t <txg> -- highest txg to use when "
+ "searching for uberblocks\n");
+ (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
+ "to make only that option verbose\n");
+ (void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
+ exit(1);
+}
+
+/*
+ * Called for usage errors that are discovered after a call to spa_open(),
+ * dmu_bonus_hold(), or pool_match(). abort() is called for other errors.
+ */
+
+static void
+fatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void) fprintf(stderr, "%s: ", cmdname);
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void) fprintf(stderr, "\n");
+
+ exit(1);
+}
+
+/* ARGSUSED */
+static void
+dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ nvlist_t *nv;
+ size_t nvsize = *(uint64_t *)data;
+ char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
+
+ VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
+
+ VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
+
+ umem_free(packed, nvsize);
+
+ dump_nvlist(nv, 8);
+
+ nvlist_free(nv);
+}
+
+/* ARGSUSED */
+static void
+dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ spa_history_phys_t *shp = data;
+
+ if (shp == NULL)
+ return;
+
+ (void) printf("\t\tpool_create_len = %llu\n",
+ (u_longlong_t)shp->sh_pool_create_len);
+ (void) printf("\t\tphys_max_off = %llu\n",
+ (u_longlong_t)shp->sh_phys_max_off);
+ (void) printf("\t\tbof = %llu\n",
+ (u_longlong_t)shp->sh_bof);
+ (void) printf("\t\teof = %llu\n",
+ (u_longlong_t)shp->sh_eof);
+ (void) printf("\t\trecords_lost = %llu\n",
+ (u_longlong_t)shp->sh_records_lost);
+}
+
+static void
+zdb_nicenum(uint64_t num, char *buf)
+{
+ if (dump_opt['P'])
+ (void) sprintf(buf, "%llu", (longlong_t)num);
+ else
+ nicenum(num, buf);
+}
+
+const char dump_zap_stars[] = "****************************************";
+const int dump_zap_width = sizeof (dump_zap_stars) - 1;
+
+static void
+dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
+{
+ int i;
+ int minidx = ZAP_HISTOGRAM_SIZE - 1;
+ int maxidx = 0;
+ uint64_t max = 0;
+
+ for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
+ if (histo[i] > max)
+ max = histo[i];
+ if (histo[i] > 0 && i > maxidx)
+ maxidx = i;
+ if (histo[i] > 0 && i < minidx)
+ minidx = i;
+ }
+
+ if (max < dump_zap_width)
+ max = dump_zap_width;
+
+ for (i = minidx; i <= maxidx; i++)
+ (void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
+ &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
+}
+
+static void
+dump_zap_stats(objset_t *os, uint64_t object)
+{
+ int error;
+ zap_stats_t zs;
+
+ error = zap_get_stats(os, object, &zs);
+ if (error)
+ return;
+
+ if (zs.zs_ptrtbl_len == 0) {
+ ASSERT(zs.zs_num_blocks == 1);
+ (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
+ (u_longlong_t)zs.zs_blocksize,
+ (u_longlong_t)zs.zs_num_entries);
+ return;
+ }
+
+ (void) printf("\tFat ZAP stats:\n");
+
+ (void) printf("\t\tPointer table:\n");
+ (void) printf("\t\t\t%llu elements\n",
+ (u_longlong_t)zs.zs_ptrtbl_len);
+ (void) printf("\t\t\tzt_blk: %llu\n",
+ (u_longlong_t)zs.zs_ptrtbl_zt_blk);
+ (void) printf("\t\t\tzt_numblks: %llu\n",
+ (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
+ (void) printf("\t\t\tzt_shift: %llu\n",
+ (u_longlong_t)zs.zs_ptrtbl_zt_shift);
+ (void) printf("\t\t\tzt_blks_copied: %llu\n",
+ (u_longlong_t)zs.zs_ptrtbl_blks_copied);
+ (void) printf("\t\t\tzt_nextblk: %llu\n",
+ (u_longlong_t)zs.zs_ptrtbl_nextblk);
+
+ (void) printf("\t\tZAP entries: %llu\n",
+ (u_longlong_t)zs.zs_num_entries);
+ (void) printf("\t\tLeaf blocks: %llu\n",
+ (u_longlong_t)zs.zs_num_leafs);
+ (void) printf("\t\tTotal blocks: %llu\n",
+ (u_longlong_t)zs.zs_num_blocks);
+ (void) printf("\t\tzap_block_type: 0x%llx\n",
+ (u_longlong_t)zs.zs_block_type);
+ (void) printf("\t\tzap_magic: 0x%llx\n",
+ (u_longlong_t)zs.zs_magic);
+ (void) printf("\t\tzap_salt: 0x%llx\n",
+ (u_longlong_t)zs.zs_salt);
+
+ (void) printf("\t\tLeafs with 2^n pointers:\n");
+ dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
+
+ (void) printf("\t\tBlocks with n*5 entries:\n");
+ dump_zap_histogram(zs.zs_blocks_with_n5_entries);
+
+ (void) printf("\t\tBlocks n/10 full:\n");
+ dump_zap_histogram(zs.zs_blocks_n_tenths_full);
+
+ (void) printf("\t\tEntries with n chunks:\n");
+ dump_zap_histogram(zs.zs_entries_using_n_chunks);
+
+ (void) printf("\t\tBuckets with n entries:\n");
+ dump_zap_histogram(zs.zs_buckets_with_n_entries);
+}
+
+/*ARGSUSED*/
+static void
+dump_none(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ (void) printf("\tUNKNOWN OBJECT TYPE\n");
+}
+
+/*ARGSUSED*/
+void
+dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ zap_cursor_t zc;
+ zap_attribute_t attr;
+ void *prop;
+ int i;
+
+ dump_zap_stats(os, object);
+ (void) printf("\n");
+
+ for (zap_cursor_init(&zc, os, object);
+ zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_advance(&zc)) {
+ (void) printf("\t\t%s = ", attr.za_name);
+ if (attr.za_num_integers == 0) {
+ (void) printf("\n");
+ continue;
+ }
+ prop = umem_zalloc(attr.za_num_integers *
+ attr.za_integer_length, UMEM_NOFAIL);
+ (void) zap_lookup(os, object, attr.za_name,
+ attr.za_integer_length, attr.za_num_integers, prop);
+ if (attr.za_integer_length == 1) {
+ (void) printf("%s", (char *)prop);
+ } else {
+ for (i = 0; i < attr.za_num_integers; i++) {
+ switch (attr.za_integer_length) {
+ case 2:
+ (void) printf("%u ",
+ ((uint16_t *)prop)[i]);
+ break;
+ case 4:
+ (void) printf("%u ",
+ ((uint32_t *)prop)[i]);
+ break;
+ case 8:
+ (void) printf("%lld ",
+ (u_longlong_t)((int64_t *)prop)[i]);
+ break;
+ }
+ }
+ }
+ (void) printf("\n");
+ umem_free(prop, attr.za_num_integers * attr.za_integer_length);
+ }
+ zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ dump_zap_stats(os, object);
+ /* contents are printed elsewhere, properly decoded */
+}
+
+/*ARGSUSED*/
+static void
+dump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ zap_cursor_t zc;
+ zap_attribute_t attr;
+
+ dump_zap_stats(os, object);
+ (void) printf("\n");
+
+ for (zap_cursor_init(&zc, os, object);
+ zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_advance(&zc)) {
+ (void) printf("\t\t%s = ", attr.za_name);
+ if (attr.za_num_integers == 0) {
+ (void) printf("\n");
+ continue;
+ }
+ (void) printf(" %llx : [%d:%d:%d]\n",
+ (u_longlong_t)attr.za_first_integer,
+ (int)ATTR_LENGTH(attr.za_first_integer),
+ (int)ATTR_BSWAP(attr.za_first_integer),
+ (int)ATTR_NUM(attr.za_first_integer));
+ }
+ zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ zap_cursor_t zc;
+ zap_attribute_t attr;
+ uint16_t *layout_attrs;
+ int i;
+
+ dump_zap_stats(os, object);
+ (void) printf("\n");
+
+ for (zap_cursor_init(&zc, os, object);
+ zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_advance(&zc)) {
+ (void) printf("\t\t%s = [", attr.za_name);
+ if (attr.za_num_integers == 0) {
+ (void) printf("\n");
+ continue;
+ }
+
+ VERIFY(attr.za_integer_length == 2);
+ layout_attrs = umem_zalloc(attr.za_num_integers *
+ attr.za_integer_length, UMEM_NOFAIL);
+
+ VERIFY(zap_lookup(os, object, attr.za_name,
+ attr.za_integer_length,
+ attr.za_num_integers, layout_attrs) == 0);
+
+ for (i = 0; i != attr.za_num_integers; i++)
+ (void) printf(" %d ", (int)layout_attrs[i]);
+ (void) printf("]\n");
+ umem_free(layout_attrs,
+ attr.za_num_integers * attr.za_integer_length);
+ }
+ zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ zap_cursor_t zc;
+ zap_attribute_t attr;
+ const char *typenames[] = {
+ /* 0 */ "not specified",
+ /* 1 */ "FIFO",
+ /* 2 */ "Character Device",
+ /* 3 */ "3 (invalid)",
+ /* 4 */ "Directory",
+ /* 5 */ "5 (invalid)",
+ /* 6 */ "Block Device",
+ /* 7 */ "7 (invalid)",
+ /* 8 */ "Regular File",
+ /* 9 */ "9 (invalid)",
+ /* 10 */ "Symbolic Link",
+ /* 11 */ "11 (invalid)",
+ /* 12 */ "Socket",
+ /* 13 */ "Door",
+ /* 14 */ "Event Port",
+ /* 15 */ "15 (invalid)",
+ };
+
+ dump_zap_stats(os, object);
+ (void) printf("\n");
+
+ for (zap_cursor_init(&zc, os, object);
+ zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_advance(&zc)) {
+ (void) printf("\t\t%s = %lld (type: %s)\n",
+ attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
+ typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
+ }
+ zap_cursor_fini(&zc);
+}
+
+static void
+dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
+{
+ uint64_t alloc, offset, entry;
+ uint8_t mapshift = sm->sm_shift;
+ uint64_t mapstart = sm->sm_start;
+ char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
+ "INVALID", "INVALID", "INVALID", "INVALID" };
+
+ if (smo->smo_object == 0)
+ return;
+
+ /*
+ * Print out the freelist entries in both encoded and decoded form.
+ */
+ alloc = 0;
+ for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
+ VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
+ sizeof (entry), &entry, DMU_READ_PREFETCH));
+ if (SM_DEBUG_DECODE(entry)) {
+ (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
+ (u_longlong_t)(offset / sizeof (entry)),
+ ddata[SM_DEBUG_ACTION_DECODE(entry)],
+ (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
+ (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
+ } else {
+ (void) printf("\t [%6llu] %c range:"
+ " %010llx-%010llx size: %06llx\n",
+ (u_longlong_t)(offset / sizeof (entry)),
+ SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
+ (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
+ mapshift) + mapstart),
+ (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
+ mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
+ mapshift)),
+ (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
+ if (SM_TYPE_DECODE(entry) == SM_ALLOC)
+ alloc += SM_RUN_DECODE(entry) << mapshift;
+ else
+ alloc -= SM_RUN_DECODE(entry) << mapshift;
+ }
+ }
+ if (alloc != smo->smo_alloc) {
+ (void) printf("space_map_object alloc (%llu) INCONSISTENT "
+ "with space map summary (%llu)\n",
+ (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
+ }
+}
+
+static void
+dump_metaslab_stats(metaslab_t *msp)
+{
+ char maxbuf[32];
+ space_map_t *sm = msp->ms_map;
+ avl_tree_t *t = sm->sm_pp_root;
+ int free_pct = sm->sm_space * 100 / sm->sm_size;
+
+ zdb_nicenum(space_map_maxsize(sm), maxbuf);
+
+ (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
+ "segments", avl_numnodes(t), "maxsize", maxbuf,
+ "freepct", free_pct);
+}
+
+static void
+dump_metaslab(metaslab_t *msp)
+{
+ vdev_t *vd = msp->ms_group->mg_vd;
+ spa_t *spa = vd->vdev_spa;
+ space_map_t *sm = msp->ms_map;
+ space_map_obj_t *smo = &msp->ms_smo;
+ char freebuf[32];
+
+ zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
+
+ (void) printf(
+ "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
+ (u_longlong_t)(sm->sm_start / sm->sm_size),
+ (u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf);
+
+ if (dump_opt['m'] > 1 && !dump_opt['L']) {
+ mutex_enter(&msp->ms_lock);
+ space_map_load_wait(sm);
+ if (!sm->sm_loaded)
+ VERIFY(space_map_load(sm, zfs_metaslab_ops,
+ SM_FREE, smo, spa->spa_meta_objset) == 0);
+ dump_metaslab_stats(msp);
+ space_map_unload(sm);
+ mutex_exit(&msp->ms_lock);
+ }
+
+ if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
+ ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));
+
+ mutex_enter(&msp->ms_lock);
+ dump_spacemap(spa->spa_meta_objset, smo, sm);
+ mutex_exit(&msp->ms_lock);
+ }
+}
+
+static void
+print_vdev_metaslab_header(vdev_t *vd)
+{
+ (void) printf("\tvdev %10llu\n\t%-10s%5llu %-19s %-15s %-10s\n",
+ (u_longlong_t)vd->vdev_id,
+ "metaslabs", (u_longlong_t)vd->vdev_ms_count,
+ "offset", "spacemap", "free");
+ (void) printf("\t%15s %19s %15s %10s\n",
+ "---------------", "-------------------",
+ "---------------", "-------------");
+}
+
+static void
+dump_metaslabs(spa_t *spa)
+{
+ vdev_t *vd, *rvd = spa->spa_root_vdev;
+ uint64_t m, c = 0, children = rvd->vdev_children;
+
+ (void) printf("\nMetaslabs:\n");
+
+ if (!dump_opt['d'] && zopt_objects > 0) {
+ c = zopt_object[0];
+
+ if (c >= children)
+ (void) fatal("bad vdev id: %llu", (u_longlong_t)c);
+
+ if (zopt_objects > 1) {
+ vd = rvd->vdev_child[c];
+ print_vdev_metaslab_header(vd);
+
+ for (m = 1; m < zopt_objects; m++) {
+ if (zopt_object[m] < vd->vdev_ms_count)
+ dump_metaslab(
+ vd->vdev_ms[zopt_object[m]]);
+ else
+ (void) fprintf(stderr, "bad metaslab "
+ "number %llu\n",
+ (u_longlong_t)zopt_object[m]);
+ }
+ (void) printf("\n");
+ return;
+ }
+ children = c + 1;
+ }
+ for (; c < children; c++) {
+ vd = rvd->vdev_child[c];
+ print_vdev_metaslab_header(vd);
+
+ for (m = 0; m < vd->vdev_ms_count; m++)
+ dump_metaslab(vd->vdev_ms[m]);
+ (void) printf("\n");
+ }
+}
+
+static void
+dump_dde(const ddt_t *ddt, const ddt_entry_t *dde, uint64_t index)
+{
+ const ddt_phys_t *ddp = dde->dde_phys;
+ const ddt_key_t *ddk = &dde->dde_key;
+ char *types[4] = { "ditto", "single", "double", "triple" };
+ char blkbuf[BP_SPRINTF_LEN];
+ blkptr_t blk;
+
+ for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+ if (ddp->ddp_phys_birth == 0)
+ continue;
+ ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
+ sprintf_blkptr(blkbuf, &blk);
+ (void) printf("index %llx refcnt %llu %s %s\n",
+ (u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
+ types[p], blkbuf);
+ }
+}
+
+static void
+dump_dedup_ratio(const ddt_stat_t *dds)
+{
+ double rL, rP, rD, D, dedup, compress, copies;
+
+ if (dds->dds_blocks == 0)
+ return;
+
+ rL = (double)dds->dds_ref_lsize;
+ rP = (double)dds->dds_ref_psize;
+ rD = (double)dds->dds_ref_dsize;
+ D = (double)dds->dds_dsize;
+
+ dedup = rD / D;
+ compress = rL / rP;
+ copies = rD / rP;
+
+ (void) printf("dedup = %.2f, compress = %.2f, copies = %.2f, "
+ "dedup * compress / copies = %.2f\n\n",
+ dedup, compress, copies, dedup * compress / copies);
+}
+
+static void
+dump_ddt(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
+{
+ char name[DDT_NAMELEN];
+ ddt_entry_t dde;
+ uint64_t walk = 0;
+ dmu_object_info_t doi;
+ uint64_t count, dspace, mspace;
+ int error;
+
+ error = ddt_object_info(ddt, type, class, &doi);
+
+ if (error == ENOENT)
+ return;
+ ASSERT(error == 0);
+
+ error = ddt_object_count(ddt, type, class, &count);
+ ASSERT(error == 0);
+ if (count == 0)
+ return;
+
+ dspace = doi.doi_physical_blocks_512 << 9;
+ mspace = doi.doi_fill_count * doi.doi_data_block_size;
+
+ ddt_object_name(ddt, type, class, name);
+
+ (void) printf("%s: %llu entries, size %llu on disk, %llu in core\n",
+ name,
+ (u_longlong_t)count,
+ (u_longlong_t)(dspace / count),
+ (u_longlong_t)(mspace / count));
+
+ if (dump_opt['D'] < 3)
+ return;
+
+ zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
+
+ if (dump_opt['D'] < 4)
+ return;
+
+ if (dump_opt['D'] < 5 && class == DDT_CLASS_UNIQUE)
+ return;
+
+ (void) printf("%s contents:\n\n", name);
+
+ while ((error = ddt_object_walk(ddt, type, class, &walk, &dde)) == 0)
+ dump_dde(ddt, &dde, walk);
+
+ ASSERT(error == ENOENT);
+
+ (void) printf("\n");
+}
+
+static void
+dump_all_ddts(spa_t *spa)
+{
+ ddt_histogram_t ddh_total = { 0 };
+ ddt_stat_t dds_total = { 0 };
+
+ for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
+ ddt_t *ddt = spa->spa_ddt[c];
+ for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
+ for (enum ddt_class class = 0; class < DDT_CLASSES;
+ class++) {
+ dump_ddt(ddt, type, class);
+ }
+ }
+ }
+
+ ddt_get_dedup_stats(spa, &dds_total);
+
+ if (dds_total.dds_blocks == 0) {
+ (void) printf("All DDTs are empty\n");
+ return;
+ }
+
+ (void) printf("\n");
+
+ if (dump_opt['D'] > 1) {
+ (void) printf("DDT histogram (aggregated over all DDTs):\n");
+ ddt_get_dedup_histogram(spa, &ddh_total);
+ zpool_dump_ddt(&dds_total, &ddh_total);
+ }
+
+ dump_dedup_ratio(&dds_total);
+}
+
+static void
+dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
+{
+ char *prefix = (void *)sm;
+
+ (void) printf("%s [%llu,%llu) length %llu\n",
+ prefix,
+ (u_longlong_t)start,
+ (u_longlong_t)(start + size),
+ (u_longlong_t)(size));
+}
+
+static void
+dump_dtl(vdev_t *vd, int indent)
+{
+ spa_t *spa = vd->vdev_spa;
+ boolean_t required;
+ char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
+ char prefix[256];
+
+ spa_vdev_state_enter(spa, SCL_NONE);
+ required = vdev_dtl_required(vd);
+ (void) spa_vdev_state_exit(spa, NULL, 0);
+
+ if (indent == 0)
+ (void) printf("\nDirty time logs:\n\n");
+
+ (void) printf("\t%*s%s [%s]\n", indent, "",
+ vd->vdev_path ? vd->vdev_path :
+ vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
+ required ? "DTL-required" : "DTL-expendable");
+
+ for (int t = 0; t < DTL_TYPES; t++) {
+ space_map_t *sm = &vd->vdev_dtl[t];
+ if (sm->sm_space == 0)
+ continue;
+ (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
+ indent + 2, "", name[t]);
+ mutex_enter(sm->sm_lock);
+ space_map_walk(sm, dump_dtl_seg, (void *)prefix);
+ mutex_exit(sm->sm_lock);
+ if (dump_opt['d'] > 5 && vd->vdev_children == 0)
+ dump_spacemap(spa->spa_meta_objset,
+ &vd->vdev_dtl_smo, sm);
+ }
+
+ for (int c = 0; c < vd->vdev_children; c++)
+ dump_dtl(vd->vdev_child[c], indent + 4);
+}
+
+static void
+dump_history(spa_t *spa)
+{
+ nvlist_t **events = NULL;
+ char buf[SPA_MAXBLOCKSIZE];
+ uint64_t resid, len, off = 0;
+ uint_t num = 0;
+ int error;
+ time_t tsec;
+ struct tm t;
+ char tbuf[30];
+ char internalstr[MAXPATHLEN];
+
+ do {
+ len = sizeof (buf);
+
+ if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
+ (void) fprintf(stderr, "Unable to read history: "
+ "error %d\n", error);
+ return;
+ }
+
+ if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0)
+ break;
+
+ off -= resid;
+ } while (len != 0);
+
+ (void) printf("\nHistory:\n");
+ for (int i = 0; i < num; i++) {
+ uint64_t time, txg, ievent;
+ char *cmd, *intstr;
+ boolean_t printed = B_FALSE;
+
+ if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
+ &time) != 0)
+ goto next;
+ if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
+ &cmd) != 0) {
+ if (nvlist_lookup_uint64(events[i],
+ ZPOOL_HIST_INT_EVENT, &ievent) != 0)
+ goto next;
+ verify(nvlist_lookup_uint64(events[i],
+ ZPOOL_HIST_TXG, &txg) == 0);
+ verify(nvlist_lookup_string(events[i],
+ ZPOOL_HIST_INT_STR, &intstr) == 0);
+ if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS)
+ goto next;
+
+ (void) snprintf(internalstr,
+ sizeof (internalstr),
+ "[internal %s txg:%lld] %s",
+ zfs_history_event_names[ievent], txg,
+ intstr);
+ cmd = internalstr;
+ }
+ tsec = time;
+ (void) localtime_r(&tsec, &t);
+ (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
+ (void) printf("%s %s\n", tbuf, cmd);
+ printed = B_TRUE;
+
+next:
+ if (dump_opt['h'] > 1) {
+ if (!printed)
+ (void) printf("unrecognized record:\n");
+ dump_nvlist(events[i], 2);
+ }
+ }
+}
+
+/*ARGSUSED*/
+static void
+dump_dnode(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+static uint64_t
+blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb)
+{
+ if (dnp == NULL) {
+ ASSERT(zb->zb_level < 0);
+ if (zb->zb_object == 0)
+ return (zb->zb_blkid);
+ return (zb->zb_blkid * BP_GET_LSIZE(bp));
+ }
+
+ ASSERT(zb->zb_level >= 0);
+
+ return ((zb->zb_blkid <<
+ (zb->zb_level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) *
+ dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+}
+
+static void
+sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
+{
+ const dva_t *dva = bp->blk_dva;
+ int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
+
+ if (dump_opt['b'] >= 5) {
+ sprintf_blkptr(blkbuf, bp);
+ return;
+ }
+
+ blkbuf[0] = '\0';
+
+ for (int i = 0; i < ndvas; i++)
+ (void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ",
+ (u_longlong_t)DVA_GET_VDEV(&dva[i]),
+ (u_longlong_t)DVA_GET_OFFSET(&dva[i]),
+ (u_longlong_t)DVA_GET_ASIZE(&dva[i]));
+
+ (void) sprintf(blkbuf + strlen(blkbuf),
+ "%llxL/%llxP F=%llu B=%llu/%llu",
+ (u_longlong_t)BP_GET_LSIZE(bp),
+ (u_longlong_t)BP_GET_PSIZE(bp),
+ (u_longlong_t)bp->blk_fill,
+ (u_longlong_t)bp->blk_birth,
+ (u_longlong_t)BP_PHYSICAL_BIRTH(bp));
+}
+
+static void
+print_indirect(blkptr_t *bp, const zbookmark_t *zb,
+ const dnode_phys_t *dnp)
+{
+ char blkbuf[BP_SPRINTF_LEN];
+ int l;
+
+ ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
+ ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
+
+ (void) printf("%16llx ", (u_longlong_t)blkid2offset(dnp, bp, zb));
+
+ ASSERT(zb->zb_level >= 0);
+
+ for (l = dnp->dn_nlevels - 1; l >= -1; l--) {
+ if (l == zb->zb_level) {
+ (void) printf("L%llx", (u_longlong_t)zb->zb_level);
+ } else {
+ (void) printf(" ");
+ }
+ }
+
+ sprintf_blkptr_compact(blkbuf, bp);
+ (void) printf("%s\n", blkbuf);
+}
+
+static int
+visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
+ blkptr_t *bp, const zbookmark_t *zb)
+{
+ int err = 0;
+
+ if (bp->blk_birth == 0)
+ return (0);
+
+ print_indirect(bp, zb, dnp);
+
+ if (BP_GET_LEVEL(bp) > 0) {
+ uint32_t flags = ARC_WAIT;
+ int i;
+ blkptr_t *cbp;
+ int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
+ arc_buf_t *buf;
+ uint64_t fill = 0;
+
+ err = arc_read(NULL, spa, bp, arc_getbuf_func, &buf,
+ ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
+ if (err)
+ return (err);
+ ASSERT(buf->b_data);
+
+ /* recursively visit blocks below this */
+ cbp = buf->b_data;
+ for (i = 0; i < epb; i++, cbp++) {
+ zbookmark_t czb;
+
+ SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
+ zb->zb_level - 1,
+ zb->zb_blkid * epb + i);
+ err = visit_indirect(spa, dnp, cbp, &czb);
+ if (err)
+ break;
+ fill += cbp->blk_fill;
+ }
+ if (!err)
+ ASSERT3U(fill, ==, bp->blk_fill);
+ (void) arc_buf_remove_ref(buf, &buf);
+ }
+
+ return (err);
+}
+
+/*ARGSUSED*/
+static void
+dump_indirect(dnode_t *dn)
+{
+ dnode_phys_t *dnp = dn->dn_phys;
+ int j;
+ zbookmark_t czb;
+
+ (void) printf("Indirect blocks:\n");
+
+ SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
+ dn->dn_object, dnp->dn_nlevels - 1, 0);
+ for (j = 0; j < dnp->dn_nblkptr; j++) {
+ czb.zb_blkid = j;
+ (void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
+ &dnp->dn_blkptr[j], &czb);
+ }
+
+ (void) printf("\n");
+}
+
+/*ARGSUSED*/
+static void
+dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ dsl_dir_phys_t *dd = data;
+ time_t crtime;
+ char nice[32];
+
+ if (dd == NULL)
+ return;
+
+ ASSERT3U(size, >=, sizeof (dsl_dir_phys_t));
+
+ crtime = dd->dd_creation_time;
+ (void) printf("\t\tcreation_time = %s", ctime(&crtime));
+ (void) printf("\t\thead_dataset_obj = %llu\n",
+ (u_longlong_t)dd->dd_head_dataset_obj);
+ (void) printf("\t\tparent_dir_obj = %llu\n",
+ (u_longlong_t)dd->dd_parent_obj);
+ (void) printf("\t\torigin_obj = %llu\n",
+ (u_longlong_t)dd->dd_origin_obj);
+ (void) printf("\t\tchild_dir_zapobj = %llu\n",
+ (u_longlong_t)dd->dd_child_dir_zapobj);
+ zdb_nicenum(dd->dd_used_bytes, nice);
+ (void) printf("\t\tused_bytes = %s\n", nice);
+ zdb_nicenum(dd->dd_compressed_bytes, nice);
+ (void) printf("\t\tcompressed_bytes = %s\n", nice);
+ zdb_nicenum(dd->dd_uncompressed_bytes, nice);
+ (void) printf("\t\tuncompressed_bytes = %s\n", nice);
+ zdb_nicenum(dd->dd_quota, nice);
+ (void) printf("\t\tquota = %s\n", nice);
+ zdb_nicenum(dd->dd_reserved, nice);
+ (void) printf("\t\treserved = %s\n", nice);
+ (void) printf("\t\tprops_zapobj = %llu\n",
+ (u_longlong_t)dd->dd_props_zapobj);
+ (void) printf("\t\tdeleg_zapobj = %llu\n",
+ (u_longlong_t)dd->dd_deleg_zapobj);
+ (void) printf("\t\tflags = %llx\n",
+ (u_longlong_t)dd->dd_flags);
+
+#define DO(which) \
+ zdb_nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice); \
+ (void) printf("\t\tused_breakdown[" #which "] = %s\n", nice)
+ DO(HEAD);
+ DO(SNAP);
+ DO(CHILD);
+ DO(CHILD_RSRV);
+ DO(REFRSRV);
+#undef DO
+}
+
+/*ARGSUSED*/
+static void
+dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ dsl_dataset_phys_t *ds = data;
+ time_t crtime;
+ char used[32], compressed[32], uncompressed[32], unique[32];
+ char blkbuf[BP_SPRINTF_LEN];
+
+ if (ds == NULL)
+ return;
+
+ ASSERT(size == sizeof (*ds));
+ crtime = ds->ds_creation_time;
+ zdb_nicenum(ds->ds_referenced_bytes, used);
+ zdb_nicenum(ds->ds_compressed_bytes, compressed);
+ zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
+ zdb_nicenum(ds->ds_unique_bytes, unique);
+ sprintf_blkptr(blkbuf, &ds->ds_bp);
+
+ (void) printf("\t\tdir_obj = %llu\n",
+ (u_longlong_t)ds->ds_dir_obj);
+ (void) printf("\t\tprev_snap_obj = %llu\n",
+ (u_longlong_t)ds->ds_prev_snap_obj);
+ (void) printf("\t\tprev_snap_txg = %llu\n",
+ (u_longlong_t)ds->ds_prev_snap_txg);
+ (void) printf("\t\tnext_snap_obj = %llu\n",
+ (u_longlong_t)ds->ds_next_snap_obj);
+ (void) printf("\t\tsnapnames_zapobj = %llu\n",
+ (u_longlong_t)ds->ds_snapnames_zapobj);
+ (void) printf("\t\tnum_children = %llu\n",
+ (u_longlong_t)ds->ds_num_children);
+ (void) printf("\t\tuserrefs_obj = %llu\n",
+ (u_longlong_t)ds->ds_userrefs_obj);
+ (void) printf("\t\tcreation_time = %s", ctime(&crtime));
+ (void) printf("\t\tcreation_txg = %llu\n",
+ (u_longlong_t)ds->ds_creation_txg);
+ (void) printf("\t\tdeadlist_obj = %llu\n",
+ (u_longlong_t)ds->ds_deadlist_obj);
+ (void) printf("\t\tused_bytes = %s\n", used);
+ (void) printf("\t\tcompressed_bytes = %s\n", compressed);
+ (void) printf("\t\tuncompressed_bytes = %s\n", uncompressed);
+ (void) printf("\t\tunique = %s\n", unique);
+ (void) printf("\t\tfsid_guid = %llu\n",
+ (u_longlong_t)ds->ds_fsid_guid);
+ (void) printf("\t\tguid = %llu\n",
+ (u_longlong_t)ds->ds_guid);
+ (void) printf("\t\tflags = %llx\n",
+ (u_longlong_t)ds->ds_flags);
+ (void) printf("\t\tnext_clones_obj = %llu\n",
+ (u_longlong_t)ds->ds_next_clones_obj);
+ (void) printf("\t\tprops_obj = %llu\n",
+ (u_longlong_t)ds->ds_props_obj);
+ (void) printf("\t\tbp = %s\n", blkbuf);
+}
+
+/* ARGSUSED */
+static int
+dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+ char blkbuf[BP_SPRINTF_LEN];
+
+ if (bp->blk_birth != 0) {
+ sprintf_blkptr(blkbuf, bp);
+ (void) printf("\t%s\n", blkbuf);
+ }
+ return (0);
+}
+
+static void
+dump_bptree(objset_t *os, uint64_t obj, char *name)
+{
+ char bytes[32];
+ bptree_phys_t *bt;
+ dmu_buf_t *db;
+
+ if (dump_opt['d'] < 3)
+ return;
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
+ bt = db->db_data;
+ zdb_nicenum(bt->bt_bytes, bytes);
+ (void) printf("\n %s: %llu datasets, %s\n",
+ name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes);
+ dmu_buf_rele(db, FTAG);
+
+ if (dump_opt['d'] < 5)
+ return;
+
+ (void) printf("\n");
+
+ (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL);
+}
+
+/* ARGSUSED */
+static int
+dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+ char blkbuf[BP_SPRINTF_LEN];
+
+ ASSERT(bp->blk_birth != 0);
+ sprintf_blkptr_compact(blkbuf, bp);
+ (void) printf("\t%s\n", blkbuf);
+ return (0);
+}
+
+static void
+dump_bpobj(bpobj_t *bpo, char *name, int indent)
+{
+ char bytes[32];
+ char comp[32];
+ char uncomp[32];
+
+ if (dump_opt['d'] < 3)
+ return;
+
+ zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes);
+ if (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_subobjs != 0) {
+ zdb_nicenum(bpo->bpo_phys->bpo_comp, comp);
+ zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp);
+ (void) printf(" %*s: object %llu, %llu local blkptrs, "
+ "%llu subobjs, %s (%s/%s comp)\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_subobjs,
+ bytes, comp, uncomp);
+
+ for (uint64_t i = 0; i < bpo->bpo_phys->bpo_num_subobjs; i++) {
+ uint64_t subobj;
+ bpobj_t subbpo;
+ int error;
+ VERIFY0(dmu_read(bpo->bpo_os,
+ bpo->bpo_phys->bpo_subobjs,
+ i * sizeof (subobj), sizeof (subobj), &subobj, 0));
+ error = bpobj_open(&subbpo, bpo->bpo_os, subobj);
+ if (error != 0) {
+ (void) printf("ERROR %u while trying to open "
+ "subobj id %llu\n",
+ error, (u_longlong_t)subobj);
+ continue;
+ }
+ dump_bpobj(&subbpo, "subobj", indent + 1);
+ bpobj_close(&subbpo);
+ }
+ } else {
+ (void) printf(" %*s: object %llu, %llu blkptrs, %s\n",
+ indent * 8, name,
+ (u_longlong_t)bpo->bpo_object,
+ (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
+ bytes);
+ }
+
+ if (dump_opt['d'] < 5)
+ return;
+
+
+ if (indent == 0) {
+ (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
+ (void) printf("\n");
+ }
+}
+
+static void
+dump_deadlist(dsl_deadlist_t *dl)
+{
+ dsl_deadlist_entry_t *dle;
+ uint64_t unused;
+ char bytes[32];
+ char comp[32];
+ char uncomp[32];
+
+ if (dump_opt['d'] < 3)
+ return;
+
+ zdb_nicenum(dl->dl_phys->dl_used, bytes);
+ zdb_nicenum(dl->dl_phys->dl_comp, comp);
+ zdb_nicenum(dl->dl_phys->dl_uncomp, uncomp);
+ (void) printf("\n Deadlist: %s (%s/%s comp)\n",
+ bytes, comp, uncomp);
+
+ if (dump_opt['d'] < 4)
+ return;
+
+ (void) printf("\n");
+
+ /* force the tree to be loaded */
+ dsl_deadlist_space_range(dl, 0, UINT64_MAX, &unused, &unused, &unused);
+
+ for (dle = avl_first(&dl->dl_tree); dle;
+ dle = AVL_NEXT(&dl->dl_tree, dle)) {
+ if (dump_opt['d'] >= 5) {
+ char buf[128];
+ (void) snprintf(buf, sizeof (buf), "mintxg %llu -> ",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
+
+ dump_bpobj(&dle->dle_bpobj, buf, 0);
+ } else {
+ (void) printf("mintxg %llu -> obj %llu\n",
+ (longlong_t)dle->dle_mintxg,
+ (longlong_t)dle->dle_bpobj.bpo_object);
+
+ }
+ }
+}
+
+static avl_tree_t idx_tree;
+static avl_tree_t domain_tree;
+static boolean_t fuid_table_loaded;
+static boolean_t sa_loaded;
+sa_attr_type_t *sa_attr_table;
+
+static void
+fuid_table_destroy()
+{
+ if (fuid_table_loaded) {
+ zfs_fuid_table_destroy(&idx_tree, &domain_tree);
+ fuid_table_loaded = B_FALSE;
+ }
+}
+
+/*
+ * print uid or gid information.
+ * For normal POSIX id just the id is printed in decimal format.
+ * For CIFS files with FUID the fuid is printed in hex followed by
+ * the domain-rid string.
+ */
+static void
+print_idstr(uint64_t id, const char *id_type)
+{
+ if (FUID_INDEX(id)) {
+ char *domain;
+
+ domain = zfs_fuid_idx_domain(&idx_tree, FUID_INDEX(id));
+ (void) printf("\t%s %llx [%s-%d]\n", id_type,
+ (u_longlong_t)id, domain, (int)FUID_RID(id));
+ } else {
+ (void) printf("\t%s %llu\n", id_type, (u_longlong_t)id);
+ }
+
+}
+
+static void
+dump_uidgid(objset_t *os, uint64_t uid, uint64_t gid)
+{
+ uint32_t uid_idx, gid_idx;
+
+ uid_idx = FUID_INDEX(uid);
+ gid_idx = FUID_INDEX(gid);
+
+ /* Load domain table, if not already loaded */
+ if (!fuid_table_loaded && (uid_idx || gid_idx)) {
+ uint64_t fuid_obj;
+
+ /* first find the fuid object. It lives in the master node */
+ VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES,
+ 8, 1, &fuid_obj) == 0);
+ zfs_fuid_avl_tree_create(&idx_tree, &domain_tree);
+ (void) zfs_fuid_table_load(os, fuid_obj,
+ &idx_tree, &domain_tree);
+ fuid_table_loaded = B_TRUE;
+ }
+
+ print_idstr(uid, "uid");
+ print_idstr(gid, "gid");
+}
+
+/*ARGSUSED*/
+static void
+dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
+{
+ char path[MAXPATHLEN * 2]; /* allow for xattr and failure prefix */
+ sa_handle_t *hdl;
+ uint64_t xattr, rdev, gen;
+ uint64_t uid, gid, mode, fsize, parent, links;
+ uint64_t pflags;
+ uint64_t acctm[2], modtm[2], chgtm[2], crtm[2];
+ time_t z_crtime, z_atime, z_mtime, z_ctime;
+ sa_bulk_attr_t bulk[12];
+ int idx = 0;
+ int error;
+
+ if (!sa_loaded) {
+ uint64_t sa_attrs = 0;
+ uint64_t version;
+
+ VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
+ 8, 1, &version) == 0);
+ if (version >= ZPL_VERSION_SA) {
+ VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
+ 8, 1, &sa_attrs) == 0);
+ }
+ if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
+ ZPL_END, &sa_attr_table)) != 0) {
+ (void) printf("sa_setup failed errno %d, can't "
+ "display znode contents\n", error);
+ return;
+ }
+ sa_loaded = B_TRUE;
+ }
+
+ if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) {
+ (void) printf("Failed to get handle for SA znode\n");
+ return;
+ }
+
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_UID], NULL, &uid, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_GID], NULL, &gid, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_LINKS], NULL,
+ &links, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_GEN], NULL, &gen, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_MODE], NULL,
+ &mode, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_PARENT],
+ NULL, &parent, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_SIZE], NULL,
+ &fsize, 8);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_ATIME], NULL,
+ acctm, 16);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_MTIME], NULL,
+ modtm, 16);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_CRTIME], NULL,
+ crtm, 16);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_CTIME], NULL,
+ chgtm, 16);
+ SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_FLAGS], NULL,
+ &pflags, 8);
+
+ if (sa_bulk_lookup(hdl, bulk, idx)) {
+ (void) sa_handle_destroy(hdl);
+ return;
+ }
+
+ error = zfs_obj_to_path(os, object, path, sizeof (path));
+ if (error != 0) {
+ (void) snprintf(path, sizeof (path), "\?\?\?<object#%llu>",
+ (u_longlong_t)object);
+ }
+ if (dump_opt['d'] < 3) {
+ (void) printf("\t%s\n", path);
+ (void) sa_handle_destroy(hdl);
+ return;
+ }
+
+ z_crtime = (time_t)crtm[0];
+ z_atime = (time_t)acctm[0];
+ z_mtime = (time_t)modtm[0];
+ z_ctime = (time_t)chgtm[0];
+
+ (void) printf("\tpath %s\n", path);
+ dump_uidgid(os, uid, gid);
+ (void) printf("\tatime %s", ctime(&z_atime));
+ (void) printf("\tmtime %s", ctime(&z_mtime));
+ (void) printf("\tctime %s", ctime(&z_ctime));
+ (void) printf("\tcrtime %s", ctime(&z_crtime));
+ (void) printf("\tgen %llu\n", (u_longlong_t)gen);
+ (void) printf("\tmode %llo\n", (u_longlong_t)mode);
+ (void) printf("\tsize %llu\n", (u_longlong_t)fsize);
+ (void) printf("\tparent %llu\n", (u_longlong_t)parent);
+ (void) printf("\tlinks %llu\n", (u_longlong_t)links);
+ (void) printf("\tpflags %llx\n", (u_longlong_t)pflags);
+ if (sa_lookup(hdl, sa_attr_table[ZPL_XATTR], &xattr,
+ sizeof (uint64_t)) == 0)
+ (void) printf("\txattr %llu\n", (u_longlong_t)xattr);
+ if (sa_lookup(hdl, sa_attr_table[ZPL_RDEV], &rdev,
+ sizeof (uint64_t)) == 0)
+ (void) printf("\trdev 0x%016llx\n", (u_longlong_t)rdev);
+ sa_handle_destroy(hdl);
+}
+
+/*ARGSUSED*/
+static void
+dump_acl(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_dmu_objset(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
+ dump_none, /* unallocated */
+ dump_zap, /* object directory */
+ dump_uint64, /* object array */
+ dump_none, /* packed nvlist */
+ dump_packed_nvlist, /* packed nvlist size */
+ dump_none, /* bplist */
+ dump_none, /* bplist header */
+ dump_none, /* SPA space map header */
+ dump_none, /* SPA space map */
+ dump_none, /* ZIL intent log */
+ dump_dnode, /* DMU dnode */
+ dump_dmu_objset, /* DMU objset */
+ dump_dsl_dir, /* DSL directory */
+ dump_zap, /* DSL directory child map */
+ dump_zap, /* DSL dataset snap map */
+ dump_zap, /* DSL props */
+ dump_dsl_dataset, /* DSL dataset */
+ dump_znode, /* ZFS znode */
+ dump_acl, /* ZFS V0 ACL */
+ dump_uint8, /* ZFS plain file */
+ dump_zpldir, /* ZFS directory */
+ dump_zap, /* ZFS master node */
+ dump_zap, /* ZFS delete queue */
+ dump_uint8, /* zvol object */
+ dump_zap, /* zvol prop */
+ dump_uint8, /* other uint8[] */
+ dump_uint64, /* other uint64[] */
+ dump_zap, /* other ZAP */
+ dump_zap, /* persistent error log */
+ dump_uint8, /* SPA history */
+ dump_history_offsets, /* SPA history offsets */
+ dump_zap, /* Pool properties */
+ dump_zap, /* DSL permissions */
+ dump_acl, /* ZFS ACL */
+ dump_uint8, /* ZFS SYSACL */
+ dump_none, /* FUID nvlist */
+ dump_packed_nvlist, /* FUID nvlist size */
+ dump_zap, /* DSL dataset next clones */
+ dump_zap, /* DSL scrub queue */
+ dump_zap, /* ZFS user/group used */
+ dump_zap, /* ZFS user/group quota */
+ dump_zap, /* snapshot refcount tags */
+ dump_ddt_zap, /* DDT ZAP object */
+ dump_zap, /* DDT statistics */
+ dump_znode, /* SA object */
+ dump_zap, /* SA Master Node */
+ dump_sa_attrs, /* SA attribute registration */
+ dump_sa_layouts, /* SA attribute layouts */
+ dump_zap, /* DSL scrub translations */
+ dump_none, /* fake dedup BP */
+ dump_zap, /* deadlist */
+ dump_none, /* deadlist hdr */
+ dump_zap, /* dsl clones */
+ dump_none, /* bpobj subobjs */
+ dump_unknown, /* Unknown type, must be last */
+};
+
+static void
+dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
+{
+ dmu_buf_t *db = NULL;
+ dmu_object_info_t doi;
+ dnode_t *dn;
+ void *bonus = NULL;
+ size_t bsize = 0;
+ char iblk[32], dblk[32], lsize[32], asize[32], fill[32];
+ char bonus_size[32];
+ char aux[50];
+ int error;
+
+ if (*print_header) {
+ (void) printf("\n%10s %3s %5s %5s %5s %5s %6s %s\n",
+ "Object", "lvl", "iblk", "dblk", "dsize", "lsize",
+ "%full", "type");
+ *print_header = 0;
+ }
+
+ if (object == 0) {
+ dn = DMU_META_DNODE(os);
+ } else {
+ error = dmu_bonus_hold(os, object, FTAG, &db);
+ if (error)
+ fatal("dmu_bonus_hold(%llu) failed, errno %u",
+ object, error);
+ bonus = db->db_data;
+ bsize = db->db_size;
+ dn = DB_DNODE((dmu_buf_impl_t *)db);
+ }
+ dmu_object_info_from_dnode(dn, &doi);
+
+ zdb_nicenum(doi.doi_metadata_block_size, iblk);
+ zdb_nicenum(doi.doi_data_block_size, dblk);
+ zdb_nicenum(doi.doi_max_offset, lsize);
+ zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize);
+ zdb_nicenum(doi.doi_bonus_size, bonus_size);
+ (void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count *
+ doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) /
+ doi.doi_max_offset);
+
+ aux[0] = '\0';
+
+ if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) {
+ (void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)",
+ ZDB_CHECKSUM_NAME(doi.doi_checksum));
+ }
+
+ if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) {
+ (void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)",
+ ZDB_COMPRESS_NAME(doi.doi_compress));
+ }
+
+ (void) printf("%10lld %3u %5s %5s %5s %5s %6s %s%s\n",
+ (u_longlong_t)object, doi.doi_indirection, iblk, dblk,
+ asize, lsize, fill, ZDB_OT_NAME(doi.doi_type), aux);
+
+ if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
+ (void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n",
+ "", "", "", "", "", bonus_size, "bonus",
+ ZDB_OT_NAME(doi.doi_bonus_type));
+ }
+
+ if (verbosity >= 4) {
+ (void) printf("\tdnode flags: %s%s%s\n",
+ (dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES) ?
+ "USED_BYTES " : "",
+ (dn->dn_phys->dn_flags & DNODE_FLAG_USERUSED_ACCOUNTED) ?
+ "USERUSED_ACCOUNTED " : "",
+ (dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR) ?
+ "SPILL_BLKPTR" : "");
+ (void) printf("\tdnode maxblkid: %llu\n",
+ (longlong_t)dn->dn_phys->dn_maxblkid);
+
+ object_viewer[ZDB_OT_TYPE(doi.doi_bonus_type)](os, object,
+ bonus, bsize);
+ object_viewer[ZDB_OT_TYPE(doi.doi_type)](os, object, NULL, 0);
+ *print_header = 1;
+ }
+
+ if (verbosity >= 5)
+ dump_indirect(dn);
+
+ if (verbosity >= 5) {
+ /*
+ * Report the list of segments that comprise the object.
+ */
+ uint64_t start = 0;
+ uint64_t end;
+ uint64_t blkfill = 1;
+ int minlvl = 1;
+
+ if (dn->dn_type == DMU_OT_DNODE) {
+ minlvl = 0;
+ blkfill = DNODES_PER_BLOCK;
+ }
+
+ for (;;) {
+ char segsize[32];
+ error = dnode_next_offset(dn,
+ 0, &start, minlvl, blkfill, 0);
+ if (error)
+ break;
+ end = start;
+ error = dnode_next_offset(dn,
+ DNODE_FIND_HOLE, &end, minlvl, blkfill, 0);
+ zdb_nicenum(end - start, segsize);
+ (void) printf("\t\tsegment [%016llx, %016llx)"
+ " size %5s\n", (u_longlong_t)start,
+ (u_longlong_t)end, segsize);
+ if (error)
+ break;
+ start = end;
+ }
+ }
+
+ if (db != NULL)
+ dmu_buf_rele(db, FTAG);
+}
+
+static char *objset_types[DMU_OST_NUMTYPES] = {
+ "NONE", "META", "ZPL", "ZVOL", "OTHER", "ANY" };
+
+static void
+dump_dir(objset_t *os)
+{
+ dmu_objset_stats_t dds;
+ uint64_t object, object_count;
+ uint64_t refdbytes, usedobjs, scratch;
+ char numbuf[32];
+ char blkbuf[BP_SPRINTF_LEN + 20];
+ char osname[MAXNAMELEN];
+ char *type = "UNKNOWN";
+ int verbosity = dump_opt['d'];
+ int print_header = 1;
+ int i, error;
+
+ dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
+ dmu_objset_fast_stat(os, &dds);
+ dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
+
+ if (dds.dds_type < DMU_OST_NUMTYPES)
+ type = objset_types[dds.dds_type];
+
+ if (dds.dds_type == DMU_OST_META) {
+ dds.dds_creation_txg = TXG_INITIAL;
+ usedobjs = os->os_rootbp->blk_fill;
+ refdbytes = os->os_spa->spa_dsl_pool->
+ dp_mos_dir->dd_phys->dd_used_bytes;
+ } else {
+ dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch);
+ }
+
+ ASSERT3U(usedobjs, ==, os->os_rootbp->blk_fill);
+
+ zdb_nicenum(refdbytes, numbuf);
+
+ if (verbosity >= 4) {
+ (void) sprintf(blkbuf, ", rootbp ");
+ (void) sprintf_blkptr(blkbuf + strlen(blkbuf), os->os_rootbp);
+ } else {
+ blkbuf[0] = '\0';
+ }
+
+ dmu_objset_name(os, osname);
+
+ (void) printf("Dataset %s [%s], ID %llu, cr_txg %llu, "
+ "%s, %llu objects%s\n",
+ osname, type, (u_longlong_t)dmu_objset_id(os),
+ (u_longlong_t)dds.dds_creation_txg,
+ numbuf, (u_longlong_t)usedobjs, blkbuf);
+
+ if (zopt_objects != 0) {
+ for (i = 0; i < zopt_objects; i++)
+ dump_object(os, zopt_object[i], verbosity,
+ &print_header);
+ (void) printf("\n");
+ return;
+ }
+
+ if (dump_opt['i'] != 0 || verbosity >= 2)
+ dump_intent_log(dmu_objset_zil(os));
+
+ if (dmu_objset_ds(os) != NULL)
+ dump_deadlist(&dmu_objset_ds(os)->ds_deadlist);
+
+ if (verbosity < 2)
+ return;
+
+ if (os->os_rootbp->blk_birth == 0)
+ return;
+
+ dump_object(os, 0, verbosity, &print_header);
+ object_count = 0;
+ if (DMU_USERUSED_DNODE(os) != NULL &&
+ DMU_USERUSED_DNODE(os)->dn_type != 0) {
+ dump_object(os, DMU_USERUSED_OBJECT, verbosity, &print_header);
+ dump_object(os, DMU_GROUPUSED_OBJECT, verbosity, &print_header);
+ }
+
+ object = 0;
+ while ((error = dmu_object_next(os, &object, B_FALSE, 0)) == 0) {
+ dump_object(os, object, verbosity, &print_header);
+ object_count++;
+ }
+
+ ASSERT3U(object_count, ==, usedobjs);
+
+ (void) printf("\n");
+
+ if (error != ESRCH) {
+ (void) fprintf(stderr, "dmu_object_next() = %d\n", error);
+ abort();
+ }
+}
+
+static void
+dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
+{
+ time_t timestamp = ub->ub_timestamp;
+
+ (void) printf(header ? header : "");
+ (void) printf("\tmagic = %016llx\n", (u_longlong_t)ub->ub_magic);
+ (void) printf("\tversion = %llu\n", (u_longlong_t)ub->ub_version);
+ (void) printf("\ttxg = %llu\n", (u_longlong_t)ub->ub_txg);
+ (void) printf("\tguid_sum = %llu\n", (u_longlong_t)ub->ub_guid_sum);
+ (void) printf("\ttimestamp = %llu UTC = %s",
+ (u_longlong_t)ub->ub_timestamp, asctime(localtime(&timestamp)));
+ if (dump_opt['u'] >= 3) {
+ char blkbuf[BP_SPRINTF_LEN];
+ sprintf_blkptr(blkbuf, &ub->ub_rootbp);
+ (void) printf("\trootbp = %s\n", blkbuf);
+ }
+ (void) printf(footer ? footer : "");
+}
+
+static void
+dump_config(spa_t *spa)
+{
+ dmu_buf_t *db;
+ size_t nvsize = 0;
+ int error = 0;
+
+
+ error = dmu_bonus_hold(spa->spa_meta_objset,
+ spa->spa_config_object, FTAG, &db);
+
+ if (error == 0) {
+ nvsize = *(uint64_t *)db->db_data;
+ dmu_buf_rele(db, FTAG);
+
+ (void) printf("\nMOS Configuration:\n");
+ dump_packed_nvlist(spa->spa_meta_objset,
+ spa->spa_config_object, (void *)&nvsize, 1);
+ } else {
+ (void) fprintf(stderr, "dmu_bonus_hold(%llu) failed, errno %d",
+ (u_longlong_t)spa->spa_config_object, error);
+ }
+}
+
+static void
+dump_cachefile(const char *cachefile)
+{
+ int fd;
+ struct stat64 statbuf;
+ char *buf;
+ nvlist_t *config;
+
+ if ((fd = open64(cachefile, O_RDONLY)) < 0) {
+ (void) printf("cannot open '%s': %s\n", cachefile,
+ strerror(errno));
+ exit(1);
+ }
+
+ if (fstat64(fd, &statbuf) != 0) {
+ (void) printf("failed to stat '%s': %s\n", cachefile,
+ strerror(errno));
+ exit(1);
+ }
+
+ if ((buf = malloc(statbuf.st_size)) == NULL) {
+ (void) fprintf(stderr, "failed to allocate %llu bytes\n",
+ (u_longlong_t)statbuf.st_size);
+ exit(1);
+ }
+
+ if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
+ (void) fprintf(stderr, "failed to read %llu bytes\n",
+ (u_longlong_t)statbuf.st_size);
+ exit(1);
+ }
+
+ (void) close(fd);
+
+ if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
+ (void) fprintf(stderr, "failed to unpack nvlist\n");
+ exit(1);
+ }
+
+ free(buf);
+
+ dump_nvlist(config, 0);
+
+ nvlist_free(config);
+}
+
+#define ZDB_MAX_UB_HEADER_SIZE 32
+
+static void
+dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift)
+{
+ vdev_t vd;
+ vdev_t *vdp = &vd;
+ char header[ZDB_MAX_UB_HEADER_SIZE];
+
+ vd.vdev_ashift = ashift;
+ vdp->vdev_top = vdp;
+
+ for (int i = 0; i < VDEV_UBERBLOCK_COUNT(vdp); i++) {
+ uint64_t uoff = VDEV_UBERBLOCK_OFFSET(vdp, i);
+ uberblock_t *ub = (void *)((char *)lbl + uoff);
+
+ if (uberblock_verify(ub))
+ continue;
+ (void) snprintf(header, ZDB_MAX_UB_HEADER_SIZE,
+ "Uberblock[%d]\n", i);
+ dump_uberblock(ub, header, "");
+ }
+}
+
+static void
+dump_label(const char *dev)
+{
+ int fd;
+ vdev_label_t label;
+ char *path, *buf = label.vl_vdev_phys.vp_nvlist;
+ size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
+ struct stat64 statbuf;
+ uint64_t psize, ashift;
+ int len = strlen(dev) + 1;
+
+ if (strncmp(dev, "/dev/dsk/", 9) == 0) {
+ len++;
+ path = malloc(len);
+ (void) snprintf(path, len, "%s%s", "/dev/rdsk/", dev + 9);
+ } else {
+ path = strdup(dev);
+ }
+
+ if ((fd = open64(path, O_RDONLY)) < 0) {
+ (void) printf("cannot open '%s': %s\n", path, strerror(errno));
+ free(path);
+ exit(1);
+ }
+
+ if (fstat64(fd, &statbuf) != 0) {
+ (void) printf("failed to stat '%s': %s\n", path,
+ strerror(errno));
+ free(path);
+ (void) close(fd);
+ exit(1);
+ }
+
+ if (S_ISBLK(statbuf.st_mode)) {
+ (void) printf("cannot use '%s': character device required\n",
+ path);
+ free(path);
+ (void) close(fd);
+ exit(1);
+ }
+
+ psize = statbuf.st_size;
+ psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
+
+ for (int l = 0; l < VDEV_LABELS; l++) {
+ nvlist_t *config = NULL;
+
+ (void) printf("--------------------------------------------\n");
+ (void) printf("LABEL %d\n", l);
+ (void) printf("--------------------------------------------\n");
+
+ if (pread64(fd, &label, sizeof (label),
+ vdev_label_offset(psize, l, 0)) != sizeof (label)) {
+ (void) printf("failed to read label %d\n", l);
+ continue;
+ }
+
+ if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
+ (void) printf("failed to unpack label %d\n", l);
+ ashift = SPA_MINBLOCKSHIFT;
+ } else {
+ nvlist_t *vdev_tree = NULL;
+
+ dump_nvlist(config, 4);
+ if ((nvlist_lookup_nvlist(config,
+ ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) ||
+ (nvlist_lookup_uint64(vdev_tree,
+ ZPOOL_CONFIG_ASHIFT, &ashift) != 0))
+ ashift = SPA_MINBLOCKSHIFT;
+ nvlist_free(config);
+ }
+ if (dump_opt['u'])
+ dump_label_uberblocks(&label, ashift);
+ }
+
+ free(path);
+ (void) close(fd);
+}
+
+/*ARGSUSED*/
+static int
+dump_one_dir(const char *dsname, void *arg)
+{
+ int error;
+ objset_t *os;
+
+ error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
+ if (error) {
+ (void) printf("Could not open %s, error %d\n", dsname, error);
+ return (0);
+ }
+ dump_dir(os);
+ dmu_objset_disown(os, FTAG);
+ fuid_table_destroy();
+ sa_loaded = B_FALSE;
+ return (0);
+}
+
+/*
+ * Block statistics.
+ */
+typedef struct zdb_blkstats {
+ uint64_t zb_asize;
+ uint64_t zb_lsize;
+ uint64_t zb_psize;
+ uint64_t zb_count;
+} zdb_blkstats_t;
+
+/*
+ * Extended object types to report deferred frees and dedup auto-ditto blocks.
+ */
+#define ZDB_OT_DEFERRED (DMU_OT_NUMTYPES + 0)
+#define ZDB_OT_DITTO (DMU_OT_NUMTYPES + 1)
+#define ZDB_OT_OTHER (DMU_OT_NUMTYPES + 2)
+#define ZDB_OT_TOTAL (DMU_OT_NUMTYPES + 3)
+
+static char *zdb_ot_extname[] = {
+ "deferred free",
+ "dedup ditto",
+ "other",
+ "Total",
+};
+
+#define ZB_TOTAL DN_MAX_LEVELS
+
+typedef struct zdb_cb {
+ zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1];
+ uint64_t zcb_dedup_asize;
+ uint64_t zcb_dedup_blocks;
+ uint64_t zcb_errors[256];
+ int zcb_readfails;
+ int zcb_haderrors;
+ spa_t *zcb_spa;
+} zdb_cb_t;
+
+static void
+zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
+ dmu_object_type_t type)
+{
+ uint64_t refcnt = 0;
+
+ ASSERT(type < ZDB_OT_TOTAL);
+
+ if (zilog && zil_bp_tree_add(zilog, bp) != 0)
+ return;
+
+ for (int i = 0; i < 4; i++) {
+ int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL;
+ int t = (i & 1) ? type : ZDB_OT_TOTAL;
+ zdb_blkstats_t *zb = &zcb->zcb_type[l][t];
+
+ zb->zb_asize += BP_GET_ASIZE(bp);
+ zb->zb_lsize += BP_GET_LSIZE(bp);
+ zb->zb_psize += BP_GET_PSIZE(bp);
+ zb->zb_count++;
+ }
+
+ if (dump_opt['L'])
+ return;
+
+ if (BP_GET_DEDUP(bp)) {
+ ddt_t *ddt;
+ ddt_entry_t *dde;
+
+ ddt = ddt_select(zcb->zcb_spa, bp);
+ ddt_enter(ddt);
+ dde = ddt_lookup(ddt, bp, B_FALSE);
+
+ if (dde == NULL) {
+ refcnt = 0;
+ } else {
+ ddt_phys_t *ddp = ddt_phys_select(dde, bp);
+ ddt_phys_decref(ddp);
+ refcnt = ddp->ddp_refcnt;
+ if (ddt_phys_total_refcnt(dde) == 0)
+ ddt_remove(ddt, dde);
+ }
+ ddt_exit(ddt);
+ }
+
+ VERIFY3U(zio_wait(zio_claim(NULL, zcb->zcb_spa,
+ refcnt ? 0 : spa_first_txg(zcb->zcb_spa),
+ bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0);
+}
+
+static int
+zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+ const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+ zdb_cb_t *zcb = arg;
+ char blkbuf[BP_SPRINTF_LEN];
+ dmu_object_type_t type;
+ boolean_t is_metadata;
+
+ if (bp == NULL)
+ return (0);
+
+ type = BP_GET_TYPE(bp);
+
+ zdb_count_block(zcb, zilog, bp,
+ (type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type);
+
+ is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type));
+
+ if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) {
+ int ioerr;
+ size_t size = BP_GET_PSIZE(bp);
+ void *data = malloc(size);
+ int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;
+
+ /* If it's an intent log block, failure is expected. */
+ if (zb->zb_level == ZB_ZIL_LEVEL)
+ flags |= ZIO_FLAG_SPECULATIVE;
+
+ ioerr = zio_wait(zio_read(NULL, spa, bp, data, size,
+ NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb));
+
+ free(data);
+ if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) {
+ zcb->zcb_haderrors = 1;
+ zcb->zcb_errors[ioerr]++;
+
+ if (dump_opt['b'] >= 2)
+ sprintf_blkptr(blkbuf, bp);
+ else
+ blkbuf[0] = '\0';
+
+ (void) printf("zdb_blkptr_cb: "
+ "Got error %d reading "
+ "<%llu, %llu, %lld, %llx> %s -- skipping\n",
+ ioerr,
+ (u_longlong_t)zb->zb_objset,
+ (u_longlong_t)zb->zb_object,
+ (u_longlong_t)zb->zb_level,
+ (u_longlong_t)zb->zb_blkid,
+ blkbuf);
+ }
+ }
+
+ zcb->zcb_readfails = 0;
+
+ if (dump_opt['b'] >= 4) {
+ sprintf_blkptr(blkbuf, bp);
+ (void) printf("objset %llu object %llu "
+ "level %lld offset 0x%llx %s\n",
+ (u_longlong_t)zb->zb_objset,
+ (u_longlong_t)zb->zb_object,
+ (longlong_t)zb->zb_level,
+ (u_longlong_t)blkid2offset(dnp, bp, zb),
+ blkbuf);
+ }
+
+ return (0);
+}
+
+static void
+zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
+{
+ vdev_t *vd = sm->sm_ppd;
+
+ (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
+ (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
+}
+
+/* ARGSUSED */
+static void
+zdb_space_map_load(space_map_t *sm)
+{
+}
+
+static void
+zdb_space_map_unload(space_map_t *sm)
+{
+ space_map_vacate(sm, zdb_leak, sm);
+}
+
+/* ARGSUSED */
+static void
+zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
+{
+}
+
+static space_map_ops_t zdb_space_map_ops = {
+ zdb_space_map_load,
+ zdb_space_map_unload,
+ NULL, /* alloc */
+ zdb_space_map_claim,
+ NULL, /* free */
+ NULL /* maxsize */
+};
+
+static void
+zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
+{
+ ddt_bookmark_t ddb = { 0 };
+ ddt_entry_t dde;
+ int error;
+
+ while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
+ blkptr_t blk;
+ ddt_phys_t *ddp = dde.dde_phys;
+
+ if (ddb.ddb_class == DDT_CLASS_UNIQUE)
+ return;
+
+ ASSERT(ddt_phys_total_refcnt(&dde) > 1);
+
+ for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
+ if (ddp->ddp_phys_birth == 0)
+ continue;
+ ddt_bp_create(ddb.ddb_checksum,
+ &dde.dde_key, ddp, &blk);
+ if (p == DDT_PHYS_DITTO) {
+ zdb_count_block(zcb, NULL, &blk, ZDB_OT_DITTO);
+ } else {
+ zcb->zcb_dedup_asize +=
+ BP_GET_ASIZE(&blk) * (ddp->ddp_refcnt - 1);
+ zcb->zcb_dedup_blocks++;
+ }
+ }
+ if (!dump_opt['L']) {
+ ddt_t *ddt = spa->spa_ddt[ddb.ddb_checksum];
+ ddt_enter(ddt);
+ VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
+ ddt_exit(ddt);
+ }
+ }
+
+ ASSERT(error == ENOENT);
+}
+
+static void
+zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
+{
+ zcb->zcb_spa = spa;
+
+ if (!dump_opt['L']) {
+ vdev_t *rvd = spa->spa_root_vdev;
+ for (int c = 0; c < rvd->vdev_children; c++) {
+ vdev_t *vd = rvd->vdev_child[c];
+ for (int m = 0; m < vd->vdev_ms_count; m++) {
+ metaslab_t *msp = vd->vdev_ms[m];
+ mutex_enter(&msp->ms_lock);
+ space_map_unload(msp->ms_map);
+ VERIFY(space_map_load(msp->ms_map,
+ &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
+ spa->spa_meta_objset) == 0);
+ msp->ms_map->sm_ppd = vd;
+ mutex_exit(&msp->ms_lock);
+ }
+ }
+ }
+
+ spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+
+ zdb_ddt_leak_init(spa, zcb);
+
+ spa_config_exit(spa, SCL_CONFIG, FTAG);
+}
+
+static void
+zdb_leak_fini(spa_t *spa)
+{
+ if (!dump_opt['L']) {
+ vdev_t *rvd = spa->spa_root_vdev;
+ for (int c = 0; c < rvd->vdev_children; c++) {
+ vdev_t *vd = rvd->vdev_child[c];
+ for (int m = 0; m < vd->vdev_ms_count; m++) {
+ metaslab_t *msp = vd->vdev_ms[m];
+ mutex_enter(&msp->ms_lock);
+ space_map_unload(msp->ms_map);
+ mutex_exit(&msp->ms_lock);
+ }
+ }
+ }
+}
+
+/* ARGSUSED */
+static int
+count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+ zdb_cb_t *zcb = arg;
+
+ if (dump_opt['b'] >= 4) {
+ char blkbuf[BP_SPRINTF_LEN];
+ sprintf_blkptr(blkbuf, bp);
+ (void) printf("[%s] %s\n",
+ "deferred free", blkbuf);
+ }
+ zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
+ return (0);
+}
+
+static int
+dump_block_stats(spa_t *spa)
+{
+ zdb_cb_t zcb = { 0 };
+ zdb_blkstats_t *zb, *tzb;
+ uint64_t norm_alloc, norm_space, total_alloc, total_found;
+ int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
+ int leaks = 0;
+
+ (void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
+ (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
+ (dump_opt['c'] == 1) ? "metadata " : "",
+ dump_opt['c'] ? "checksums " : "",
+ (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
+ !dump_opt['L'] ? "nothing leaked " : "");
+
+ /*
+ * Load all space maps as SM_ALLOC maps, then traverse the pool
+ * claiming each block we discover. If the pool is perfectly
+ * consistent, the space maps will be empty when we're done.
+ * Anything left over is a leak; any block we can't claim (because
+ * it's not part of any space map) is a double allocation,
+ * reference to a freed block, or an unclaimed log block.
+ */
+ zdb_leak_init(spa, &zcb);
+
+ /*
+ * If there's a deferred-free bplist, process that first.
+ */
+ (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
+ count_block_cb, &zcb, NULL);
+ if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
+ (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
+ count_block_cb, &zcb, NULL);
+ }
+ if (spa_feature_is_active(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
+ spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
+ &zcb, NULL));
+ }
+
+ if (dump_opt['c'] > 1)
+ flags |= TRAVERSE_PREFETCH_DATA;
+
+ zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
+
+ if (zcb.zcb_haderrors) {
+ (void) printf("\nError counts:\n\n");
+ (void) printf("\t%5s %s\n", "errno", "count");
+ for (int e = 0; e < 256; e++) {
+ if (zcb.zcb_errors[e] != 0) {
+ (void) printf("\t%5d %llu\n",
+ e, (u_longlong_t)zcb.zcb_errors[e]);
+ }
+ }
+ }
+
+ /*
+ * Report any leaked segments.
+ */
+ zdb_leak_fini(spa);
+
+ tzb = &zcb.zcb_type[ZB_TOTAL][ZDB_OT_TOTAL];
+
+ norm_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
+ norm_space = metaslab_class_get_space(spa_normal_class(spa));
+
+ total_alloc = norm_alloc + metaslab_class_get_alloc(spa_log_class(spa));
+ total_found = tzb->zb_asize - zcb.zcb_dedup_asize;
+
+ if (total_found == total_alloc) {
+ if (!dump_opt['L'])
+ (void) printf("\n\tNo leaks (block sum matches space"
+ " maps exactly)\n");
+ } else {
+ (void) printf("block traversal size %llu != alloc %llu "
+ "(%s %lld)\n",
+ (u_longlong_t)total_found,
+ (u_longlong_t)total_alloc,
+ (dump_opt['L']) ? "unreachable" : "leaked",
+ (longlong_t)(total_alloc - total_found));
+ leaks = 1;
+ }
+
+ if (tzb->zb_count == 0)
+ return (2);
+
+ (void) printf("\n");
+ (void) printf("\tbp count: %10llu\n",
+ (u_longlong_t)tzb->zb_count);
+ (void) printf("\tbp logical: %10llu avg: %6llu\n",
+ (u_longlong_t)tzb->zb_lsize,
+ (u_longlong_t)(tzb->zb_lsize / tzb->zb_count));
+ (void) printf("\tbp physical: %10llu avg:"
+ " %6llu compression: %6.2f\n",
+ (u_longlong_t)tzb->zb_psize,
+ (u_longlong_t)(tzb->zb_psize / tzb->zb_count),
+ (double)tzb->zb_lsize / tzb->zb_psize);
+ (void) printf("\tbp allocated: %10llu avg:"
+ " %6llu compression: %6.2f\n",
+ (u_longlong_t)tzb->zb_asize,
+ (u_longlong_t)(tzb->zb_asize / tzb->zb_count),
+ (double)tzb->zb_lsize / tzb->zb_asize);
+ (void) printf("\tbp deduped: %10llu ref>1:"
+ " %6llu deduplication: %6.2f\n",
+ (u_longlong_t)zcb.zcb_dedup_asize,
+ (u_longlong_t)zcb.zcb_dedup_blocks,
+ (double)zcb.zcb_dedup_asize / tzb->zb_asize + 1.0);
+ (void) printf("\tSPA allocated: %10llu used: %5.2f%%\n",
+ (u_longlong_t)norm_alloc, 100.0 * norm_alloc / norm_space);
+
+ if (dump_opt['b'] >= 2) {
+ int l, t, level;
+ (void) printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
+ "\t avg\t comp\t%%Total\tType\n");
+
+ for (t = 0; t <= ZDB_OT_TOTAL; t++) {
+ char csize[32], lsize[32], psize[32], asize[32];
+ char avg[32];
+ char *typename;
+
+ if (t < DMU_OT_NUMTYPES)
+ typename = dmu_ot[t].ot_name;
+ else
+ typename = zdb_ot_extname[t - DMU_OT_NUMTYPES];
+
+ if (zcb.zcb_type[ZB_TOTAL][t].zb_asize == 0) {
+ (void) printf("%6s\t%5s\t%5s\t%5s"
+ "\t%5s\t%5s\t%6s\t%s\n",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ typename);
+ continue;
+ }
+
+ for (l = ZB_TOTAL - 1; l >= -1; l--) {
+ level = (l == -1 ? ZB_TOTAL : l);
+ zb = &zcb.zcb_type[level][t];
+
+ if (zb->zb_asize == 0)
+ continue;
+
+ if (dump_opt['b'] < 3 && level != ZB_TOTAL)
+ continue;
+
+ if (level == 0 && zb->zb_asize ==
+ zcb.zcb_type[ZB_TOTAL][t].zb_asize)
+ continue;
+
+ zdb_nicenum(zb->zb_count, csize);
+ zdb_nicenum(zb->zb_lsize, lsize);
+ zdb_nicenum(zb->zb_psize, psize);
+ zdb_nicenum(zb->zb_asize, asize);
+ zdb_nicenum(zb->zb_asize / zb->zb_count, avg);
+
+ (void) printf("%6s\t%5s\t%5s\t%5s\t%5s"
+ "\t%5.2f\t%6.2f\t",
+ csize, lsize, psize, asize, avg,
+ (double)zb->zb_lsize / zb->zb_psize,
+ 100.0 * zb->zb_asize / tzb->zb_asize);
+
+ if (level == ZB_TOTAL)
+ (void) printf("%s\n", typename);
+ else
+ (void) printf(" L%d %s\n",
+ level, typename);
+ }
+ }
+ }
+
+ (void) printf("\n");
+
+ if (leaks)
+ return (2);
+
+ if (zcb.zcb_haderrors)
+ return (3);
+
+ return (0);
+}
+
+typedef struct zdb_ddt_entry {
+ ddt_key_t zdde_key;
+ uint64_t zdde_ref_blocks;
+ uint64_t zdde_ref_lsize;
+ uint64_t zdde_ref_psize;
+ uint64_t zdde_ref_dsize;
+ avl_node_t zdde_node;
+} zdb_ddt_entry_t;
+
+/* ARGSUSED */
+static int
+zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
+ const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
+{
+ avl_tree_t *t = arg;
+ avl_index_t where;
+ zdb_ddt_entry_t *zdde, zdde_search;
+
+ if (bp == NULL)
+ return (0);
+
+ if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
+ (void) printf("traversing objset %llu, %llu objects, "
+ "%lu blocks so far\n",
+ (u_longlong_t)zb->zb_objset,
+ (u_longlong_t)bp->blk_fill,
+ avl_numnodes(t));
+ }
+
+ if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF ||
+ BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))
+ return (0);
+
+ ddt_key_fill(&zdde_search.zdde_key, bp);
+
+ zdde = avl_find(t, &zdde_search, &where);
+
+ if (zdde == NULL) {
+ zdde = umem_zalloc(sizeof (*zdde), UMEM_NOFAIL);
+ zdde->zdde_key = zdde_search.zdde_key;
+ avl_insert(t, zdde, where);
+ }
+
+ zdde->zdde_ref_blocks += 1;
+ zdde->zdde_ref_lsize += BP_GET_LSIZE(bp);
+ zdde->zdde_ref_psize += BP_GET_PSIZE(bp);
+ zdde->zdde_ref_dsize += bp_get_dsize_sync(spa, bp);
+
+ return (0);
+}
+
+static void
+dump_simulated_ddt(spa_t *spa)
+{
+ avl_tree_t t;
+ void *cookie = NULL;
+ zdb_ddt_entry_t *zdde;
+ ddt_histogram_t ddh_total = { 0 };
+ ddt_stat_t dds_total = { 0 };
+
+ avl_create(&t, ddt_entry_compare,
+ sizeof (zdb_ddt_entry_t), offsetof(zdb_ddt_entry_t, zdde_node));
+
+ spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+
+ (void) traverse_pool(spa, 0, TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
+ zdb_ddt_add_cb, &t);
+
+ spa_config_exit(spa, SCL_CONFIG, FTAG);
+
+ while ((zdde = avl_destroy_nodes(&t, &cookie)) != NULL) {
+ ddt_stat_t dds;
+ uint64_t refcnt = zdde->zdde_ref_blocks;
+ ASSERT(refcnt != 0);
+
+ dds.dds_blocks = zdde->zdde_ref_blocks / refcnt;
+ dds.dds_lsize = zdde->zdde_ref_lsize / refcnt;
+ dds.dds_psize = zdde->zdde_ref_psize / refcnt;
+ dds.dds_dsize = zdde->zdde_ref_dsize / refcnt;
+
+ dds.dds_ref_blocks = zdde->zdde_ref_blocks;
+ dds.dds_ref_lsize = zdde->zdde_ref_lsize;
+ dds.dds_ref_psize = zdde->zdde_ref_psize;
+ dds.dds_ref_dsize = zdde->zdde_ref_dsize;
+
+ ddt_stat_add(&ddh_total.ddh_stat[highbit(refcnt) - 1], &dds, 0);
+
+ umem_free(zdde, sizeof (*zdde));
+ }
+
+ avl_destroy(&t);
+
+ ddt_histogram_stat(&dds_total, &ddh_total);
+
+ (void) printf("Simulated DDT histogram:\n");
+
+ zpool_dump_ddt(&dds_total, &ddh_total);
+
+ dump_dedup_ratio(&dds_total);
+}
+
+static void
+dump_zpool(spa_t *spa)
+{
+ dsl_pool_t *dp = spa_get_dsl(spa);
+ int rc = 0;
+
+ if (dump_opt['S']) {
+ dump_simulated_ddt(spa);
+ return;
+ }
+
+ if (!dump_opt['e'] && dump_opt['C'] > 1) {
+ (void) printf("\nCached configuration:\n");
+ dump_nvlist(spa->spa_config, 8);
+ }
+
+ if (dump_opt['C'])
+ dump_config(spa);
+
+ if (dump_opt['u'])
+ dump_uberblock(&spa->spa_uberblock, "\nUberblock:\n", "\n");
+
+ if (dump_opt['D'])
+ dump_all_ddts(spa);
+
+ if (dump_opt['d'] > 2 || dump_opt['m'])
+ dump_metaslabs(spa);
+
+ if (dump_opt['d'] || dump_opt['i']) {
+ dump_dir(dp->dp_meta_objset);
+ if (dump_opt['d'] >= 3) {
+ dump_bpobj(&spa->spa_deferred_bpobj,
+ "Deferred frees", 0);
+ if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
+ dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
+ "Pool snapshot frees", 0);
+ }
+
+ if (spa_feature_is_active(spa,
+ &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ dump_bptree(spa->spa_meta_objset,
+ spa->spa_dsl_pool->dp_bptree_obj,
+ "Pool dataset frees");
+ }
+ dump_dtl(spa->spa_root_vdev, 0);
+ }
+ (void) dmu_objset_find(spa_name(spa), dump_one_dir,
+ NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
+ }
+ if (dump_opt['b'] || dump_opt['c'])
+ rc = dump_block_stats(spa);
+
+ if (dump_opt['s'])
+ show_pool_stats(spa);
+
+ if (dump_opt['h'])
+ dump_history(spa);
+
+ if (rc != 0)
+ exit(rc);
+}
+
+#define ZDB_FLAG_CHECKSUM 0x0001
+#define ZDB_FLAG_DECOMPRESS 0x0002
+#define ZDB_FLAG_BSWAP 0x0004
+#define ZDB_FLAG_GBH 0x0008
+#define ZDB_FLAG_INDIRECT 0x0010
+#define ZDB_FLAG_PHYS 0x0020
+#define ZDB_FLAG_RAW 0x0040
+#define ZDB_FLAG_PRINT_BLKPTR 0x0080
+
+int flagbits[256];
+
+static void
+zdb_print_blkptr(blkptr_t *bp, int flags)
+{
+ char blkbuf[BP_SPRINTF_LEN];
+
+ if (flags & ZDB_FLAG_BSWAP)
+ byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
+
+ sprintf_blkptr(blkbuf, bp);
+ (void) printf("%s\n", blkbuf);
+}
+
+static void
+zdb_dump_indirect(blkptr_t *bp, int nbps, int flags)
+{
+ int i;
+
+ for (i = 0; i < nbps; i++)
+ zdb_print_blkptr(&bp[i], flags);
+}
+
+static void
+zdb_dump_gbh(void *buf, int flags)
+{
+ zdb_dump_indirect((blkptr_t *)buf, SPA_GBH_NBLKPTRS, flags);
+}
+
+static void
+zdb_dump_block_raw(void *buf, uint64_t size, int flags)
+{
+ if (flags & ZDB_FLAG_BSWAP)
+ byteswap_uint64_array(buf, size);
+ (void) write(1, buf, size);
+}
+
+static void
+zdb_dump_block(char *label, void *buf, uint64_t size, int flags)
+{
+ uint64_t *d = (uint64_t *)buf;
+ int nwords = size / sizeof (uint64_t);
+ int do_bswap = !!(flags & ZDB_FLAG_BSWAP);
+ int i, j;
+ char *hdr, *c;
+
+
+ if (do_bswap)
+ hdr = " 7 6 5 4 3 2 1 0 f e d c b a 9 8";
+ else
+ hdr = " 0 1 2 3 4 5 6 7 8 9 a b c d e f";
+
+ (void) printf("\n%s\n%6s %s 0123456789abcdef\n", label, "", hdr);
+
+ for (i = 0; i < nwords; i += 2) {
+ (void) printf("%06llx: %016llx %016llx ",
+ (u_longlong_t)(i * sizeof (uint64_t)),
+ (u_longlong_t)(do_bswap ? BSWAP_64(d[i]) : d[i]),
+ (u_longlong_t)(do_bswap ? BSWAP_64(d[i + 1]) : d[i + 1]));
+
+ c = (char *)&d[i];
+ for (j = 0; j < 2 * sizeof (uint64_t); j++)
+ (void) printf("%c", isprint(c[j]) ? c[j] : '.');
+ (void) printf("\n");
+ }
+}
+
+/*
+ * There are two acceptable formats:
+ * leaf_name - For example: c1t0d0 or /tmp/ztest.0a
+ * child[.child]* - For example: 0.1.1
+ *
+ * The second form can be used to specify arbitrary vdevs anywhere
+ * in the heirarchy. For example, in a pool with a mirror of
+ * RAID-Zs, you can specify either RAID-Z vdev with 0.0 or 0.1 .
+ */
+static vdev_t *
+zdb_vdev_lookup(vdev_t *vdev, char *path)
+{
+ char *s, *p, *q;
+ int i;
+
+ if (vdev == NULL)
+ return (NULL);
+
+ /* First, assume the x.x.x.x format */
+ i = (int)strtoul(path, &s, 10);
+ if (s == path || (s && *s != '.' && *s != '\0'))
+ goto name;
+ if (i < 0 || i >= vdev->vdev_children)
+ return (NULL);
+
+ vdev = vdev->vdev_child[i];
+ if (*s == '\0')
+ return (vdev);
+ return (zdb_vdev_lookup(vdev, s+1));
+
+name:
+ for (i = 0; i < vdev->vdev_children; i++) {
+ vdev_t *vc = vdev->vdev_child[i];
+
+ if (vc->vdev_path == NULL) {
+ vc = zdb_vdev_lookup(vc, path);
+ if (vc == NULL)
+ continue;
+ else
+ return (vc);
+ }
+
+ p = strrchr(vc->vdev_path, '/');
+ p = p ? p + 1 : vc->vdev_path;
+ q = &vc->vdev_path[strlen(vc->vdev_path) - 2];
+
+ if (strcmp(vc->vdev_path, path) == 0)
+ return (vc);
+ if (strcmp(p, path) == 0)
+ return (vc);
+ if (strcmp(q, "s0") == 0 && strncmp(p, path, q - p) == 0)
+ return (vc);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Read a block from a pool and print it out. The syntax of the
+ * block descriptor is:
+ *
+ * pool:vdev_specifier:offset:size[:flags]
+ *
+ * pool - The name of the pool you wish to read from
+ * vdev_specifier - Which vdev (see comment for zdb_vdev_lookup)
+ * offset - offset, in hex, in bytes
+ * size - Amount of data to read, in hex, in bytes
+ * flags - A string of characters specifying options
+ * b: Decode a blkptr at given offset within block
+ * *c: Calculate and display checksums
+ * d: Decompress data before dumping
+ * e: Byteswap data before dumping
+ * g: Display data as a gang block header
+ * i: Display as an indirect block
+ * p: Do I/O to physical offset
+ * r: Dump raw data to stdout
+ *
+ * * = not yet implemented
+ */
+static void
+zdb_read_block(char *thing, spa_t *spa)
+{
+ blkptr_t blk, *bp = &blk;
+ dva_t *dva = bp->blk_dva;
+ int flags = 0;
+ uint64_t offset = 0, size = 0, psize = 0, lsize = 0, blkptr_offset = 0;
+ zio_t *zio;
+ vdev_t *vd;
+ void *pbuf, *lbuf, *buf;
+ char *s, *p, *dup, *vdev, *flagstr;
+ int i, error;
+
+ dup = strdup(thing);
+ s = strtok(dup, ":");
+ vdev = s ? s : "";
+ s = strtok(NULL, ":");
+ offset = strtoull(s ? s : "", NULL, 16);
+ s = strtok(NULL, ":");
+ size = strtoull(s ? s : "", NULL, 16);
+ s = strtok(NULL, ":");
+ flagstr = s ? s : "";
+
+ s = NULL;
+ if (size == 0)
+ s = "size must not be zero";
+ if (!IS_P2ALIGNED(size, DEV_BSIZE))
+ s = "size must be a multiple of sector size";
+ if (!IS_P2ALIGNED(offset, DEV_BSIZE))
+ s = "offset must be a multiple of sector size";
+ if (s) {
+ (void) printf("Invalid block specifier: %s - %s\n", thing, s);
+ free(dup);
+ return;
+ }
+
+ for (s = strtok(flagstr, ":"); s; s = strtok(NULL, ":")) {
+ for (i = 0; flagstr[i]; i++) {
+ int bit = flagbits[(uchar_t)flagstr[i]];
+
+ if (bit == 0) {
+ (void) printf("***Invalid flag: %c\n",
+ flagstr[i]);
+ continue;
+ }
+ flags |= bit;
+
+ /* If it's not something with an argument, keep going */
+ if ((bit & (ZDB_FLAG_CHECKSUM |
+ ZDB_FLAG_PRINT_BLKPTR)) == 0)
+ continue;
+
+ p = &flagstr[i + 1];
+ if (bit == ZDB_FLAG_PRINT_BLKPTR)
+ blkptr_offset = strtoull(p, &p, 16);
+ if (*p != ':' && *p != '\0') {
+ (void) printf("***Invalid flag arg: '%s'\n", s);
+ free(dup);
+ return;
+ }
+ }
+ }
+
+ vd = zdb_vdev_lookup(spa->spa_root_vdev, vdev);
+ if (vd == NULL) {
+ (void) printf("***Invalid vdev: %s\n", vdev);
+ free(dup);
+ return;
+ } else {
+ if (vd->vdev_path)
+ (void) fprintf(stderr, "Found vdev: %s\n",
+ vd->vdev_path);
+ else
+ (void) fprintf(stderr, "Found vdev type: %s\n",
+ vd->vdev_ops->vdev_op_type);
+ }
+
+ psize = size;
+ lsize = size;
+
+ pbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
+ lbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
+
+ BP_ZERO(bp);
+
+ DVA_SET_VDEV(&dva[0], vd->vdev_id);
+ DVA_SET_OFFSET(&dva[0], offset);
+ DVA_SET_GANG(&dva[0], !!(flags & ZDB_FLAG_GBH));
+ DVA_SET_ASIZE(&dva[0], vdev_psize_to_asize(vd, psize));
+
+ BP_SET_BIRTH(bp, TXG_INITIAL, TXG_INITIAL);
+
+ BP_SET_LSIZE(bp, lsize);
+ BP_SET_PSIZE(bp, psize);
+ BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF);
+ BP_SET_CHECKSUM(bp, ZIO_CHECKSUM_OFF);
+ BP_SET_TYPE(bp, DMU_OT_NONE);
+ BP_SET_LEVEL(bp, 0);
+ BP_SET_DEDUP(bp, 0);
+ BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
+
+ spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+ zio = zio_root(spa, NULL, NULL, 0);
+
+ if (vd == vd->vdev_top) {
+ /*
+ * Treat this as a normal block read.
+ */
+ zio_nowait(zio_read(zio, spa, bp, pbuf, psize, NULL, NULL,
+ ZIO_PRIORITY_SYNC_READ,
+ ZIO_FLAG_CANFAIL | ZIO_FLAG_RAW, NULL));
+ } else {
+ /*
+ * Treat this as a vdev child I/O.
+ */
+ zio_nowait(zio_vdev_child_io(zio, bp, vd, offset, pbuf, psize,
+ ZIO_TYPE_READ, ZIO_PRIORITY_SYNC_READ,
+ ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE |
+ ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY |
+ ZIO_FLAG_CANFAIL | ZIO_FLAG_RAW, NULL, NULL));
+ }
+
+ error = zio_wait(zio);
+ spa_config_exit(spa, SCL_STATE, FTAG);
+
+ if (error) {
+ (void) printf("Read of %s failed, error: %d\n", thing, error);
+ goto out;
+ }
+
+ if (flags & ZDB_FLAG_DECOMPRESS) {
+ /*
+ * We don't know how the data was compressed, so just try
+ * every decompress function at every inflated blocksize.
+ */
+ enum zio_compress c;
+ void *pbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
+ void *lbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
+
+ bcopy(pbuf, pbuf2, psize);
+
+ VERIFY(random_get_pseudo_bytes((uint8_t *)pbuf + psize,
+ SPA_MAXBLOCKSIZE - psize) == 0);
+
+ VERIFY(random_get_pseudo_bytes((uint8_t *)pbuf2 + psize,
+ SPA_MAXBLOCKSIZE - psize) == 0);
+
+ for (lsize = SPA_MAXBLOCKSIZE; lsize > psize;
+ lsize -= SPA_MINBLOCKSIZE) {
+ for (c = 0; c < ZIO_COMPRESS_FUNCTIONS; c++) {
+ if (zio_decompress_data(c, pbuf, lbuf,
+ psize, lsize) == 0 &&
+ zio_decompress_data(c, pbuf2, lbuf2,
+ psize, lsize) == 0 &&
+ bcmp(lbuf, lbuf2, lsize) == 0)
+ break;
+ }
+ if (c != ZIO_COMPRESS_FUNCTIONS)
+ break;
+ lsize -= SPA_MINBLOCKSIZE;
+ }
+
+ umem_free(pbuf2, SPA_MAXBLOCKSIZE);
+ umem_free(lbuf2, SPA_MAXBLOCKSIZE);
+
+ if (lsize <= psize) {
+ (void) printf("Decompress of %s failed\n", thing);
+ goto out;
+ }
+ buf = lbuf;
+ size = lsize;
+ } else {
+ buf = pbuf;
+ size = psize;
+ }
+
+ if (flags & ZDB_FLAG_PRINT_BLKPTR)
+ zdb_print_blkptr((blkptr_t *)(void *)
+ ((uintptr_t)buf + (uintptr_t)blkptr_offset), flags);
+ else if (flags & ZDB_FLAG_RAW)
+ zdb_dump_block_raw(buf, size, flags);
+ else if (flags & ZDB_FLAG_INDIRECT)
+ zdb_dump_indirect((blkptr_t *)buf, size / sizeof (blkptr_t),
+ flags);
+ else if (flags & ZDB_FLAG_GBH)
+ zdb_dump_gbh(buf, flags);
+ else
+ zdb_dump_block(thing, buf, size, flags);
+
+out:
+ umem_free(pbuf, SPA_MAXBLOCKSIZE);
+ umem_free(lbuf, SPA_MAXBLOCKSIZE);
+ free(dup);
+}
+
+static boolean_t
+pool_match(nvlist_t *cfg, char *tgt)
+{
+ uint64_t v, guid = strtoull(tgt, NULL, 0);
+ char *s;
+
+ if (guid != 0) {
+ if (nvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_GUID, &v) == 0)
+ return (v == guid);
+ } else {
+ if (nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &s) == 0)
+ return (strcmp(s, tgt) == 0);
+ }
+ return (B_FALSE);
+}
+
+static char *
+find_zpool(char **target, nvlist_t **configp, int dirc, char **dirv)
+{
+ nvlist_t *pools;
+ nvlist_t *match = NULL;
+ char *name = NULL;
+ char *sepp = NULL;
+ char sep;
+ int count = 0;
+ importargs_t args = { 0 };
+
+ args.paths = dirc;
+ args.path = dirv;
+ args.can_be_active = B_TRUE;
+
+ if ((sepp = strpbrk(*target, "/@")) != NULL) {
+ sep = *sepp;
+ *sepp = '\0';
+ }
+
+ pools = zpool_search_import(g_zfs, &args);
+
+ if (pools != NULL) {
+ nvpair_t *elem = NULL;
+ while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
+ verify(nvpair_value_nvlist(elem, configp) == 0);
+ if (pool_match(*configp, *target)) {
+ count++;
+ if (match != NULL) {
+ /* print previously found config */
+ if (name != NULL) {
+ (void) printf("%s\n", name);
+ dump_nvlist(match, 8);
+ name = NULL;
+ }
+ (void) printf("%s\n",
+ nvpair_name(elem));
+ dump_nvlist(*configp, 8);
+ } else {
+ match = *configp;
+ name = nvpair_name(elem);
+ }
+ }
+ }
+ }
+ if (count > 1)
+ (void) fatal("\tMatched %d pools - use pool GUID "
+ "instead of pool name or \n"
+ "\tpool name part of a dataset name to select pool", count);
+
+ if (sepp)
+ *sepp = sep;
+ /*
+ * If pool GUID was specified for pool id, replace it with pool name
+ */
+ if (name && (strstr(*target, name) != *target)) {
+ int sz = 1 + strlen(name) + ((sepp) ? strlen(sepp) : 0);
+
+ *target = umem_alloc(sz, UMEM_NOFAIL);
+ (void) snprintf(*target, sz, "%s%s", name, sepp ? sepp : "");
+ }
+
+ *configp = name ? match : NULL;
+
+ return (name);
+}
+
+int
+main(int argc, char **argv)
+{
+ int i, c;
+ struct rlimit rl = { 1024, 1024 };
+ spa_t *spa = NULL;
+ objset_t *os = NULL;
+ int dump_all = 1;
+ int verbose = 0;
+ int error = 0;
+ char **searchdirs = NULL;
+ int nsearch = 0;
+ char *target;
+ nvlist_t *policy = NULL;
+ uint64_t max_txg = UINT64_MAX;
+ int rewind = ZPOOL_NEVER_REWIND;
+
+ (void) setrlimit(RLIMIT_NOFILE, &rl);
+ (void) enable_extended_FILE_stdio(-1, -1);
+
+ dprintf_setup(&argc, argv);
+
+ while ((c = getopt(argc, argv, "bcdhilmsuCDRSAFLXevp:t:U:P")) != -1) {
+ switch (c) {
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'h':
+ case 'i':
+ case 'l':
+ case 'm':
+ case 's':
+ case 'u':
+ case 'C':
+ case 'D':
+ case 'R':
+ case 'S':
+ dump_opt[c]++;
+ dump_all = 0;
+ break;
+ case 'A':
+ case 'F':
+ case 'L':
+ case 'X':
+ case 'e':
+ case 'P':
+ dump_opt[c]++;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'p':
+ if (searchdirs == NULL) {
+ searchdirs = umem_alloc(sizeof (char *),
+ UMEM_NOFAIL);
+ } else {
+ char **tmp = umem_alloc((nsearch + 1) *
+ sizeof (char *), UMEM_NOFAIL);
+ bcopy(searchdirs, tmp, nsearch *
+ sizeof (char *));
+ umem_free(searchdirs,
+ nsearch * sizeof (char *));
+ searchdirs = tmp;
+ }
+ searchdirs[nsearch++] = optarg;
+ break;
+ case 't':
+ max_txg = strtoull(optarg, NULL, 0);
+ if (max_txg < TXG_INITIAL) {
+ (void) fprintf(stderr, "incorrect txg "
+ "specified: %s\n", optarg);
+ usage();
+ }
+ break;
+ case 'U':
+ spa_config_path = optarg;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (!dump_opt['e'] && searchdirs != NULL) {
+ (void) fprintf(stderr, "-p option requires use of -e\n");
+ usage();
+ }
+
+ kernel_init(FREAD);
+ g_zfs = libzfs_init();
+ ASSERT(g_zfs != NULL);
+
+ if (dump_all)
+ verbose = MAX(verbose, 1);
+
+ for (c = 0; c < 256; c++) {
+ if (dump_all && !strchr("elAFLRSXP", c))
+ dump_opt[c] = 1;
+ if (dump_opt[c])
+ dump_opt[c] += verbose;
+ }
+
+ aok = (dump_opt['A'] == 1) || (dump_opt['A'] > 2);
+ zfs_recover = (dump_opt['A'] > 1);
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 2 && dump_opt['R'])
+ usage();
+ if (argc < 1) {
+ if (!dump_opt['e'] && dump_opt['C']) {
+ dump_cachefile(spa_config_path);
+ return (0);
+ }
+ usage();
+ }
+
+ if (dump_opt['l']) {
+ dump_label(argv[0]);
+ return (0);
+ }
+
+ if (dump_opt['X'] || dump_opt['F'])
+ rewind = ZPOOL_DO_REWIND |
+ (dump_opt['X'] ? ZPOOL_EXTREME_REWIND : 0);
+
+ if (nvlist_alloc(&policy, NV_UNIQUE_NAME_TYPE, 0) != 0 ||
+ nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, max_txg) != 0 ||
+ nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind) != 0)
+ fatal("internal error: %s", strerror(ENOMEM));
+
+ error = 0;
+ target = argv[0];
+
+ if (dump_opt['e']) {
+ nvlist_t *cfg = NULL;
+ char *name = find_zpool(&target, &cfg, nsearch, searchdirs);
+
+ error = ENOENT;
+ if (name) {
+ if (dump_opt['C'] > 1) {
+ (void) printf("\nConfiguration for import:\n");
+ dump_nvlist(cfg, 8);
+ }
+ if (nvlist_add_nvlist(cfg,
+ ZPOOL_REWIND_POLICY, policy) != 0) {
+ fatal("can't open '%s': %s",
+ target, strerror(ENOMEM));
+ }
+ if ((error = spa_import(name, cfg, NULL,
+ ZFS_IMPORT_MISSING_LOG)) != 0) {
+ error = spa_import(name, cfg, NULL,
+ ZFS_IMPORT_VERBATIM);
+ }
+ }
+ }
+
+ if (error == 0) {
+ if (strpbrk(target, "/@") == NULL || dump_opt['R']) {
+ error = spa_open_rewind(target, &spa, FTAG, policy,
+ NULL);
+ if (error) {
+ /*
+ * If we're missing the log device then
+ * try opening the pool after clearing the
+ * log state.
+ */
+ mutex_enter(&spa_namespace_lock);
+ if ((spa = spa_lookup(target)) != NULL &&
+ spa->spa_log_state == SPA_LOG_MISSING) {
+ spa->spa_log_state = SPA_LOG_CLEAR;
+ error = 0;
+ }
+ mutex_exit(&spa_namespace_lock);
+
+ if (!error) {
+ error = spa_open_rewind(target, &spa,
+ FTAG, policy, NULL);
+ }
+ }
+ } else {
+ error = dmu_objset_own(target, DMU_OST_ANY,
+ B_TRUE, FTAG, &os);
+ }
+ }
+ nvlist_free(policy);
+
+ if (error)
+ fatal("can't open '%s': %s", target, strerror(error));
+
+ argv++;
+ argc--;
+ if (!dump_opt['R']) {
+ if (argc > 0) {
+ zopt_objects = argc;
+ zopt_object = calloc(zopt_objects, sizeof (uint64_t));
+ for (i = 0; i < zopt_objects; i++) {
+ errno = 0;
+ zopt_object[i] = strtoull(argv[i], NULL, 0);
+ if (zopt_object[i] == 0 && errno != 0)
+ fatal("bad number %s: %s",
+ argv[i], strerror(errno));
+ }
+ }
+ if (os != NULL) {
+ dump_dir(os);
+ } else if (zopt_objects > 0 && !dump_opt['m']) {
+ dump_dir(spa->spa_meta_objset);
+ } else {
+ dump_zpool(spa);
+ }
+ } else {
+ flagbits['b'] = ZDB_FLAG_PRINT_BLKPTR;
+ flagbits['c'] = ZDB_FLAG_CHECKSUM;
+ flagbits['d'] = ZDB_FLAG_DECOMPRESS;
+ flagbits['e'] = ZDB_FLAG_BSWAP;
+ flagbits['g'] = ZDB_FLAG_GBH;
+ flagbits['i'] = ZDB_FLAG_INDIRECT;
+ flagbits['p'] = ZDB_FLAG_PHYS;
+ flagbits['r'] = ZDB_FLAG_RAW;
+
+ for (i = 0; i < argc; i++)
+ zdb_read_block(argv[i], spa);
+ }
+
+ (os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG);
+
+ fuid_table_destroy();
+ sa_loaded = B_FALSE;
+
+ libzfs_fini(g_zfs);
+ kernel_fini();
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
new file mode 100644
index 0000000..a0ed985
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
@@ -0,0 +1,384 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Print intent log header and statistics.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+
+extern uint8_t dump_opt[256];
+
+static char prefix[4] = "\t\t\t";
+
+static void
+print_log_bp(const blkptr_t *bp, const char *prefix)
+{
+ char blkbuf[BP_SPRINTF_LEN];
+
+ sprintf_blkptr(blkbuf, bp);
+ (void) printf("%s%s\n", prefix, blkbuf);
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_create(zilog_t *zilog, int txtype, lr_create_t *lr)
+{
+ time_t crtime = lr->lr_crtime[0];
+ char *name, *link;
+ lr_attr_t *lrattr;
+
+ name = (char *)(lr + 1);
+
+ if (lr->lr_common.lrc_txtype == TX_CREATE_ATTR ||
+ lr->lr_common.lrc_txtype == TX_MKDIR_ATTR) {
+ lrattr = (lr_attr_t *)(lr + 1);
+ name += ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
+ }
+
+ if (txtype == TX_SYMLINK) {
+ link = name + strlen(name) + 1;
+ (void) printf("%s%s -> %s\n", prefix, name, link);
+ } else if (txtype != TX_MKXATTR) {
+ (void) printf("%s%s\n", prefix, name);
+ }
+
+ (void) printf("%s%s", prefix, ctime(&crtime));
+ (void) printf("%sdoid %llu, foid %llu, mode %llo\n", prefix,
+ (u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_foid,
+ (longlong_t)lr->lr_mode);
+ (void) printf("%suid %llu, gid %llu, gen %llu, rdev 0x%llx\n", prefix,
+ (u_longlong_t)lr->lr_uid, (u_longlong_t)lr->lr_gid,
+ (u_longlong_t)lr->lr_gen, (u_longlong_t)lr->lr_rdev);
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_remove(zilog_t *zilog, int txtype, lr_remove_t *lr)
+{
+ (void) printf("%sdoid %llu, name %s\n", prefix,
+ (u_longlong_t)lr->lr_doid, (char *)(lr + 1));
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_link(zilog_t *zilog, int txtype, lr_link_t *lr)
+{
+ (void) printf("%sdoid %llu, link_obj %llu, name %s\n", prefix,
+ (u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_link_obj,
+ (char *)(lr + 1));
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_rename(zilog_t *zilog, int txtype, lr_rename_t *lr)
+{
+ char *snm = (char *)(lr + 1);
+ char *tnm = snm + strlen(snm) + 1;
+
+ (void) printf("%ssdoid %llu, tdoid %llu\n", prefix,
+ (u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
+ (void) printf("%ssrc %s tgt %s\n", prefix, snm, tnm);
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
+{
+ char *data, *dlimit;
+ blkptr_t *bp = &lr->lr_blkptr;
+ zbookmark_t zb;
+ char buf[SPA_MAXBLOCKSIZE];
+ int verbose = MAX(dump_opt['d'], dump_opt['i']);
+ int error;
+
+ (void) printf("%sfoid %llu, offset %llx, length %llx\n", prefix,
+ (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_offset,
+ (u_longlong_t)lr->lr_length);
+
+ if (txtype == TX_WRITE2 || verbose < 5)
+ return;
+
+ if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
+ (void) printf("%shas blkptr, %s\n", prefix,
+ bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
+ "will claim" : "won't claim");
+ print_log_bp(bp, prefix);
+
+ if (BP_IS_HOLE(bp)) {
+ (void) printf("\t\t\tLSIZE 0x%llx\n",
+ (u_longlong_t)BP_GET_LSIZE(bp));
+ }
+ if (bp->blk_birth == 0) {
+ bzero(buf, sizeof (buf));
+ (void) printf("%s<hole>\n", prefix);
+ return;
+ }
+ if (bp->blk_birth < zilog->zl_header->zh_claim_txg) {
+ (void) printf("%s<block already committed>\n", prefix);
+ return;
+ }
+
+ SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os),
+ lr->lr_foid, ZB_ZIL_LEVEL,
+ lr->lr_offset / BP_GET_LSIZE(bp));
+
+ error = zio_wait(zio_read(NULL, zilog->zl_spa,
+ bp, buf, BP_GET_LSIZE(bp), NULL, NULL,
+ ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &zb));
+ if (error)
+ return;
+ data = buf;
+ } else {
+ data = (char *)(lr + 1);
+ }
+
+ dlimit = data + MIN(lr->lr_length,
+ (verbose < 6 ? 20 : SPA_MAXBLOCKSIZE));
+
+ (void) printf("%s", prefix);
+ while (data < dlimit) {
+ if (isprint(*data))
+ (void) printf("%c ", *data);
+ else
+ (void) printf("%2X", *data);
+ data++;
+ }
+ (void) printf("\n");
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_truncate(zilog_t *zilog, int txtype, lr_truncate_t *lr)
+{
+ (void) printf("%sfoid %llu, offset 0x%llx, length 0x%llx\n", prefix,
+ (u_longlong_t)lr->lr_foid, (longlong_t)lr->lr_offset,
+ (u_longlong_t)lr->lr_length);
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_setattr(zilog_t *zilog, int txtype, lr_setattr_t *lr)
+{
+ time_t atime = (time_t)lr->lr_atime[0];
+ time_t mtime = (time_t)lr->lr_mtime[0];
+
+ (void) printf("%sfoid %llu, mask 0x%llx\n", prefix,
+ (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_mask);
+
+ if (lr->lr_mask & AT_MODE) {
+ (void) printf("%sAT_MODE %llo\n", prefix,
+ (longlong_t)lr->lr_mode);
+ }
+
+ if (lr->lr_mask & AT_UID) {
+ (void) printf("%sAT_UID %llu\n", prefix,
+ (u_longlong_t)lr->lr_uid);
+ }
+
+ if (lr->lr_mask & AT_GID) {
+ (void) printf("%sAT_GID %llu\n", prefix,
+ (u_longlong_t)lr->lr_gid);
+ }
+
+ if (lr->lr_mask & AT_SIZE) {
+ (void) printf("%sAT_SIZE %llu\n", prefix,
+ (u_longlong_t)lr->lr_size);
+ }
+
+ if (lr->lr_mask & AT_ATIME) {
+ (void) printf("%sAT_ATIME %llu.%09llu %s", prefix,
+ (u_longlong_t)lr->lr_atime[0],
+ (u_longlong_t)lr->lr_atime[1],
+ ctime(&atime));
+ }
+
+ if (lr->lr_mask & AT_MTIME) {
+ (void) printf("%sAT_MTIME %llu.%09llu %s", prefix,
+ (u_longlong_t)lr->lr_mtime[0],
+ (u_longlong_t)lr->lr_mtime[1],
+ ctime(&mtime));
+ }
+}
+
+/* ARGSUSED */
+static void
+zil_prt_rec_acl(zilog_t *zilog, int txtype, lr_acl_t *lr)
+{
+ (void) printf("%sfoid %llu, aclcnt %llu\n", prefix,
+ (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_aclcnt);
+}
+
+typedef void (*zil_prt_rec_func_t)();
+typedef struct zil_rec_info {
+ zil_prt_rec_func_t zri_print;
+ char *zri_name;
+ uint64_t zri_count;
+} zil_rec_info_t;
+
+static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
+ { NULL, "Total " },
+ { zil_prt_rec_create, "TX_CREATE " },
+ { zil_prt_rec_create, "TX_MKDIR " },
+ { zil_prt_rec_create, "TX_MKXATTR " },
+ { zil_prt_rec_create, "TX_SYMLINK " },
+ { zil_prt_rec_remove, "TX_REMOVE " },
+ { zil_prt_rec_remove, "TX_RMDIR " },
+ { zil_prt_rec_link, "TX_LINK " },
+ { zil_prt_rec_rename, "TX_RENAME " },
+ { zil_prt_rec_write, "TX_WRITE " },
+ { zil_prt_rec_truncate, "TX_TRUNCATE " },
+ { zil_prt_rec_setattr, "TX_SETATTR " },
+ { zil_prt_rec_acl, "TX_ACL_V0 " },
+ { zil_prt_rec_acl, "TX_ACL_ACL " },
+ { zil_prt_rec_create, "TX_CREATE_ACL " },
+ { zil_prt_rec_create, "TX_CREATE_ATTR " },
+ { zil_prt_rec_create, "TX_CREATE_ACL_ATTR " },
+ { zil_prt_rec_create, "TX_MKDIR_ACL " },
+ { zil_prt_rec_create, "TX_MKDIR_ATTR " },
+ { zil_prt_rec_create, "TX_MKDIR_ACL_ATTR " },
+ { zil_prt_rec_write, "TX_WRITE2 " },
+};
+
+/* ARGSUSED */
+static int
+print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t claim_txg)
+{
+ int txtype;
+ int verbose = MAX(dump_opt['d'], dump_opt['i']);
+
+ /* reduce size of txtype to strip off TX_CI bit */
+ txtype = lr->lrc_txtype;
+
+ ASSERT(txtype != 0 && (uint_t)txtype < TX_MAX_TYPE);
+ ASSERT(lr->lrc_txg);
+
+ (void) printf("\t\t%s%s len %6llu, txg %llu, seq %llu\n",
+ (lr->lrc_txtype & TX_CI) ? "CI-" : "",
+ zil_rec_info[txtype].zri_name,
+ (u_longlong_t)lr->lrc_reclen,
+ (u_longlong_t)lr->lrc_txg,
+ (u_longlong_t)lr->lrc_seq);
+
+ if (txtype && verbose >= 3)
+ zil_rec_info[txtype].zri_print(zilog, txtype, lr);
+
+ zil_rec_info[txtype].zri_count++;
+ zil_rec_info[0].zri_count++;
+
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
+{
+ char blkbuf[BP_SPRINTF_LEN + 10];
+ int verbose = MAX(dump_opt['d'], dump_opt['i']);
+ char *claim;
+
+ if (verbose <= 3)
+ return (0);
+
+ if (verbose >= 5) {
+ (void) strcpy(blkbuf, ", ");
+ sprintf_blkptr(blkbuf + strlen(blkbuf), bp);
+ } else {
+ blkbuf[0] = '\0';
+ }
+
+ if (claim_txg != 0)
+ claim = "already claimed";
+ else if (bp->blk_birth >= spa_first_txg(zilog->zl_spa))
+ claim = "will claim";
+ else
+ claim = "won't claim";
+
+ (void) printf("\tBlock seqno %llu, %s%s\n",
+ (u_longlong_t)bp->blk_cksum.zc_word[ZIL_ZC_SEQ], claim, blkbuf);
+
+ return (0);
+}
+
+static void
+print_log_stats(int verbose)
+{
+ int i, w, p10;
+
+ if (verbose > 3)
+ (void) printf("\n");
+
+ if (zil_rec_info[0].zri_count == 0)
+ return;
+
+ for (w = 1, p10 = 10; zil_rec_info[0].zri_count >= p10; p10 *= 10)
+ w++;
+
+ for (i = 0; i < TX_MAX_TYPE; i++)
+ if (zil_rec_info[i].zri_count || verbose >= 3)
+ (void) printf("\t\t%s %*llu\n",
+ zil_rec_info[i].zri_name, w,
+ (u_longlong_t)zil_rec_info[i].zri_count);
+ (void) printf("\n");
+}
+
+/* ARGSUSED */
+void
+dump_intent_log(zilog_t *zilog)
+{
+ const zil_header_t *zh = zilog->zl_header;
+ int verbose = MAX(dump_opt['d'], dump_opt['i']);
+ int i;
+
+ if (zh->zh_log.blk_birth == 0 || verbose < 1)
+ return;
+
+ (void) printf("\n ZIL header: claim_txg %llu, "
+ "claim_blk_seq %llu, claim_lr_seq %llu",
+ (u_longlong_t)zh->zh_claim_txg,
+ (u_longlong_t)zh->zh_claim_blk_seq,
+ (u_longlong_t)zh->zh_claim_lr_seq);
+ (void) printf(" replay_seq %llu, flags 0x%llx\n",
+ (u_longlong_t)zh->zh_replay_seq, (u_longlong_t)zh->zh_flags);
+
+ for (i = 0; i < TX_MAX_TYPE; i++)
+ zil_rec_info[i].zri_count = 0;
+
+ if (verbose >= 2) {
+ (void) printf("\n");
+ (void) zil_parse(zilog, print_log_block, print_log_record, NULL,
+ zh->zh_claim_txg);
+ print_log_stats(verbose);
+ }
+}
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
new file mode 100644
index 0000000..a7a51c9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8
@@ -0,0 +1,3322 @@
+'\" te
+.\" Copyright (c) 2013, Martin Matuska <mm@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright (c) 2012 by Delphix. All rights reserved.
+.\" Copyright (c) 2012, Joyent, Inc. All rights reserved.
+.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
+.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
+.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
+.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 21, 2013
+.Dt ZFS 8
+.Os
+.Sh NAME
+.Nm zfs
+.Nd configures ZFS file systems
+.Sh SYNOPSIS
+.Nm
+.Op Fl \&?
+.Nm
+.Cm create
+.Op Fl pu
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... Ar filesystem
+.Nm
+.Cm create
+.Op Fl ps
+.Op Fl b Ar blocksize
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Fl V
+.Ar size volume
+.Nm
+.Cm destroy
+.Op Fl fnpRrv
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm destroy
+.Op Fl dnpRrv
+.Sm off
+.Ar snapshot
+.Op % Ns Ar snapname
+.Op , Ns ...
+.Sm on
+.Nm
+.Cm snapshot
+.Op Fl r
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar filesystem@snapname Ns | Ns Ar volume@snapname
+.Ar filesystem@snapname Ns | Ns Ar volume@snapname Ns ...
+.Nm
+.Cm rollback
+.Op Fl rRf
+.Ar snapshot
+.Nm
+.Cm clone
+.Op Fl p
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar snapshot filesystem Ns | Ns Ar volume
+.Nm
+.Cm promote
+.Ar clone-filesystem
+.Nm
+.Cm rename
+.Op Fl f
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Nm
+.Cm rename
+.Op Fl f
+.Fl p
+.Ar filesystem Ns | Ns Ar volume
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm rename
+.Fl r
+.Ar snapshot snapshot
+.Nm
+.Cm rename
+.Fl u
+.Op Fl p
+.Ar filesystem filesystem
+.Nm
+.Cm list
+.Op Fl r Ns | Ns Fl d Ar depth
+.Op Fl H
+.Op Fl o Ar property Ns Oo , Ns property Ns Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns type Ns Oc Ns ...
+.Oo Fl s Ar property Oc Ns ...
+.Oo Fl S Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Nm
+.Cm set
+.Ar property Ns = Ns Ar value
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Nm
+.Cm get
+.Op Fl r Ns | Ns Fl d Ar depth
+.Op Fl Hp
+.Op Fl o Ar all | field Ns Oo , Ns Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ar type Oc Ns ...
+.Op Fl s Ar source Ns Oo Ns , Ns Ar source Oc Ns ...
+.Ar all | property Ns Oo Ns , Ns Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Nm
+.Cm inherit
+.Op Fl rS
+.Ar property
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Nm
+.Cm upgrade
+.Op Fl v
+.Nm
+.Cm upgrade
+.Op Fl r
+.Op Fl V Ar version
+.Fl a | Ar filesystem
+.Nm
+.Cm userspace
+.Op Fl Hinp
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ns Ar type Oc Ns ...
+.Ar filesystem Ns | Ns Ar snapshot
+.Nm
+.Cm groupspace
+.Op Fl Hinp
+.Op Fl o Ar field Ns Oo , Ns field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo Ns , Ns Ar type Oc Ns ...
+.Ar filesystem Ns | Ns Ar snapshot
+.Nm
+.Cm mount
+.Nm
+.Cm mount
+.Op Fl vO
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+.Fl a | Ar filesystem
+.Nm
+.Cm unmount
+.Op Fl f
+.Fl a | Ar filesystem Ns | Ns Ar mountpoint
+.Nm
+.Cm share
+.Fl a | Ar filesystem
+.Nm
+.Cm unshare
+.Fl a | Ar filesystem Ns | Ns Ar mountpoint
+.Nm
+.Cm send
+.Op Fl DnPpRv
+.Op Fl i Ar snapshot | Fl I Ar snapshot
+.Ar snapshot
+.Nm
+.Cm receive
+.Op Fl vnFu
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Nm
+.Cm receive
+.Op Fl vnFu
+.Op Fl d | e
+.Ar filesystem
+.Nm
+.Cm allow
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm allow
+.Op Fl ldug
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Ar perm Ns | Ns Ar @setname Ns
+.Oo Ns , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm allow
+.Op Fl ld
+.Fl e Ns | Ns Cm everyone
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm allow
+.Fl c
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm allow
+.Fl s
+.Ar @setname
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm unallow
+.Op Fl rldug
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm unallow
+.Op Fl rld
+.Fl e Ns | Ns Cm everyone
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm unallow
+.Op Fl r
+.Fl c
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm unallow
+.Op Fl r
+.Fl s
+.Ar @setname
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Nm
+.Cm hold
+.Op Fl r
+.Ar tag snapshot Ns ...
+.Nm
+.Cm holds
+.Op Fl r
+.Ar snapshot Ns ...
+.Nm
+.Cm release
+.Op Fl r
+.Ar tag snapshot Ns ...
+.Nm
+.Cm diff
+.Op Fl FHt
+.Ar snapshot
+.Op Ar snapshot Ns | Ns Ar filesystem
+.Nm
+.Cm jail
+.Ar jailid Ns | Ns Ar jailname filesystem
+.Nm
+.Cm unjail
+.Ar jailid Ns | Ns Ar jailname filesystem
+.Sh DESCRIPTION
+The
+.Nm
+command configures
+.Tn ZFS
+datasets within a
+.Tn ZFS
+storage pool, as described in
+.Xr zpool 8 .
+A dataset is identified by a unique path within the
+.Tn ZFS
+namespace. For example:
+.Bd -ragged -offset 4n
+.No pool/ Ns Brq filesystem,volume,snapshot
+.Ed
+.Pp
+where the maximum length of a dataset name is
+.Dv MAXNAMELEN
+(256 bytes).
+.Pp
+A dataset can be one of the following:
+.Bl -hang -width 12n
+.It Sy file system
+A
+.Tn ZFS
+dataset of type
+.Em filesystem
+can be mounted within the standard system namespace and behaves like other file
+systems. While
+.Tn ZFS
+file systems are designed to be
+.Tn POSIX
+compliant, known issues exist that prevent compliance in some cases.
+Applications that depend on standards conformance might fail due to nonstandard
+behavior when checking file system free space.
+.It Sy volume
+A logical volume exported as a raw or block device. This type of dataset should
+only be used under special circumstances. File systems are typically used in
+most environments.
+.It Sy snapshot
+A read-only version of a file system or volume at a given point in time. It is
+specified as
+.Em filesystem@name
+or
+.Em volume@name .
+.El
+.Ss ZFS File System Hierarchy
+A
+.Tn ZFS
+storage pool is a logical collection of devices that provide space for
+datasets. A storage pool is also the root of the
+.Tn ZFS
+file system hierarchy.
+.Pp
+The root of the pool can be accessed as a file system, such as mounting and
+unmounting, taking snapshots, and setting properties. The physical storage
+characteristics, however, are managed by the
+.Xr zpool 8
+command.
+.Pp
+See
+.Xr zpool 8
+for more information on creating and administering pools.
+.Ss Snapshots
+A snapshot is a read-only copy of a file system or volume. Snapshots can be
+created extremely quickly, and initially consume no additional space within the
+pool. As data within the active dataset changes, the snapshot consumes more
+data than would otherwise be shared with the active dataset.
+.Pp
+Snapshots can have arbitrary names. Snapshots of volumes can be cloned or
+rolled back, but cannot be accessed independently.
+.Pp
+File system snapshots can be accessed under the
+.Pa \&.zfs/snapshot
+directory in the root of the file system. Snapshots are automatically mounted
+on demand and may be unmounted at regular intervals. The visibility of the
+.Pa \&.zfs
+directory can be controlled by the
+.Sy snapdir
+property.
+.Ss Clones
+A clone is a writable volume or file system whose initial contents are the same
+as another dataset. As with snapshots, creating a clone is nearly
+instantaneous, and initially consumes no additional space.
+.Pp
+Clones can only be created from a snapshot. When a snapshot is cloned, it
+creates an implicit dependency between the parent and child. Even though the
+clone is created somewhere else in the dataset hierarchy, the original snapshot
+cannot be destroyed as long as a clone exists. The
+.Sy origin
+property exposes this dependency, and the
+.Cm destroy
+command lists any such dependencies, if they exist.
+.Pp
+The clone parent-child dependency relationship can be reversed by using the
+.Cm promote
+subcommand. This causes the "origin" file system to become a clone of the
+specified file system, which makes it possible to destroy the file system that
+the clone was created from.
+.Ss Mount Points
+Creating a
+.Tn ZFS
+file system is a simple operation, so the number of file systems per system is
+likely to be numerous. To cope with this,
+.Tn ZFS
+automatically manages mounting and unmounting file systems without the need to
+edit the
+.Pa /etc/fstab
+file. All automatically managed file systems are mounted by
+.Tn ZFS
+at boot time.
+.Pp
+By default, file systems are mounted under
+.Pa /path ,
+where
+.Ar path
+is the name of the file system in the
+.Tn ZFS
+namespace. Directories are created and destroyed as needed.
+.Pp
+A file system can also have a mount point set in the
+.Sy mountpoint
+property. This directory is created as needed, and
+.Tn ZFS
+automatically mounts the file system when the
+.Qq Nm Cm mount Fl a
+command is invoked (without editing
+.Pa /etc/fstab ) .
+The
+.Sy mountpoint
+property can be inherited, so if
+.Em pool/home
+has a mount point of
+.Pa /home ,
+then
+.Em pool/home/user
+automatically inherits a mount point of
+.Pa /home/user .
+.Pp
+A file system
+.Sy mountpoint
+property of
+.Cm none
+prevents the file system from being mounted.
+.Pp
+If needed,
+.Tn ZFS
+file systems can also be managed with traditional tools
+.Pq Xr mount 8 , Xr umount 8 , Xr fstab 5 .
+If a file system's mount point is set to
+.Cm legacy ,
+.Tn ZFS
+makes no attempt to manage the file system, and the administrator is
+responsible for mounting and unmounting the file system.
+.Ss Jails
+.No A Tn ZFS
+dataset can be attached to a jail by using the
+.Qq Nm Cm jail
+subcommand. You cannot attach a dataset to one jail and the children of the
+same dataset to another jails. To allow management of the dataset from within
+a jail, the
+.Sy jailed
+property has to be set and the jail needs access to the
+.Pa /dev/zfs
+device. The
+.Sy quota
+property cannot be changed from within a jail. See
+.Xr jail 8
+for information on how to allow mounting
+.Tn ZFS
+datasets from within a jail.
+.Pp
+.No A Tn ZFS
+dataset can be detached from a jail using the
+.Qq Nm Cm unjail
+subcommand.
+.Pp
+After a dataset is attached to a jail and the jailed property is set, a jailed
+file system cannot be mounted outside the jail, since the jail administrator
+might have set the mount point to an unacceptable value.
+.Ss Deduplication
+Deduplication is the process for removing redundant data at the block-level,
+reducing the total amount of data stored. If a file system has the
+.Cm dedup
+property enabled, duplicate data blocks are removed synchronously. The result
+is that only unique data is stored and common components are shared among
+files.
+.Ss Native Properties
+Properties are divided into two types, native properties and user-defined (or
+"user") properties. Native properties either export internal statistics or
+control
+.Tn ZFS
+behavior. In addition, native properties are either editable or read-only. User
+properties have no effect on
+.Tn ZFS
+behavior, but you can use them to annotate datasets in a way that is meaningful
+in your environment. For more information about user properties, see the
+.Qq Sx User Properties
+section, below.
+.Pp
+Every dataset has a set of properties that export statistics about the dataset
+as well as control various behaviors. Properties are inherited from the parent
+unless overridden by the child. Some properties apply only to certain types of
+datasets (file systems, volumes, or snapshots).
+.Pp
+The values of numeric properties can be specified using human-readable suffixes
+(for example,
+.Sy k , KB , M , Gb ,
+and so forth, up to
+.Sy Z
+for zettabyte). The following are all valid (and equal) specifications:
+.Bd -ragged -offset 4n
+1536M, 1.5g, 1.50GB
+.Ed
+.Pp
+The values of non-numeric properties are case sensitive and must be lowercase,
+except for
+.Sy mountpoint , sharenfs , No and Sy sharesmb .
+.Pp
+The following native properties consist of read-only statistics about the
+dataset. These properties can be neither set, nor inherited. Native properties
+apply to all dataset types unless otherwise noted.
+.Bl -tag -width 2n
+.It Sy available
+The amount of space available to the dataset and all its children, assuming
+that there is no other activity in the pool. Because space is shared within a
+pool, availability can be limited by any number of factors, including physical
+pool size, quotas, reservations, or other datasets within the pool.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy avail .
+.It Sy compressratio
+For non-snapshots, the compression ratio achieved for the
+.Sy used
+space of this dataset, expressed as a multiplier. The
+.Sy used
+property includes descendant datasets, and, for clones, does not include
+the space shared with the origin snapshot. For snapshots, the
+.Sy compressratio
+is the same as the
+.Sy refcompressratio
+property. Compression can be turned on by running:
+.Qq Nm Cm set compression=on Ar dataset
+The default value is
+.Cm off .
+.It Sy creation
+The time this dataset was created.
+.It Sy clones
+For snapshots, this property is a comma-separated list of filesystems or
+volumes which are clones of this snapshot. The clones'
+.Sy origin
+property is this snapshot. If the
+.Sy clones
+property is not empty, then this snapshot can not be destroyed (even with the
+.Fl r
+or
+.Fl f
+options).
+.It Sy defer_destroy
+This property is
+.Cm on
+if the snapshot has been marked for deferred destroy by using the
+.Qq Nm Cm destroy -d
+command. Otherwise, the property is
+.Cm off .
+.It Sy logicalreferenced
+The amount of space that is
+.Qq logically
+accessible by this dataset.
+See the
+.Sy referenced
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+However, it does include space consumed by metadata.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lrefer .
+.It Sy logicalused
+The amount of space that is
+.Qq logically
+consumed by this dataset and all its descendents.
+See the
+.Sy used
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lused .
+.It Sy mounted
+For file systems, indicates whether the file system is currently mounted. This
+property can be either
+.Cm yes
+or
+.Cm no .
+.It Sy origin
+For cloned file systems or volumes, the snapshot from which the clone was
+created. See also the
+.Sy clones
+property.
+.It Sy referenced
+The amount of data that is accessible by this dataset, which may or may not be
+shared with other datasets in the pool. When a snapshot or clone is created, it
+initially references the same amount of space as the file system or snapshot it
+was created from, since its contents are identical.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy refer .
+.It Sy refcompressratio
+The compression ratio achieved for the
+.Sy referenced
+space of this dataset, expressed as a multiplier. See also the
+.Sy compressratio
+property.
+.It Sy type
+The type of dataset:
+.Sy filesystem , volume , No or Sy snapshot .
+.It Sy used
+The amount of space consumed by this dataset and all its descendents. This is
+the value that is checked against this dataset's quota and reservation. The
+space used does not include this dataset's reservation, but does take into
+account the reservations of any descendent datasets. The amount of space that a
+dataset consumes from its parent, as well as the amount of space that are freed
+if this dataset is recursively destroyed, is the greater of its space used and
+its reservation.
+.Pp
+When snapshots (see the
+.Qq Sx Snapshots
+section) are created, their space is
+initially shared between the snapshot and the file system, and possibly with
+previous snapshots. As the file system changes, space that was previously
+shared becomes unique to the snapshot, and counted in the snapshot's space
+used. Additionally, deleting snapshots can increase the amount of space unique
+to (and used by) other snapshots.
+.Pp
+The amount of space used, available, or referenced does not take into account
+pending changes. Pending changes are generally accounted for within a few
+seconds. Committing a change to a disk using
+.Xr fsync 2
+or
+.Sy O_SYNC
+does not necessarily guarantee that the space usage information is updated
+immediately.
+.It Sy usedby*
+The
+.Sy usedby*
+properties decompose the
+.Sy used
+properties into the various reasons that space is used. Specifically,
+.Sy used No =
+.Sy usedbysnapshots + usedbydataset + usedbychildren + usedbyrefreservation .
+These properties are only available for datasets created
+with
+.Tn ZFS
+pool version 13 pools and higher.
+.It Sy usedbysnapshots
+The amount of space consumed by snapshots of this dataset. In particular, it is
+the amount of space that would be freed if all of this dataset's snapshots were
+destroyed. Note that this is not simply the sum of the snapshots'
+.Sy used
+properties because space can be shared by multiple snapshots.
+.It Sy usedbydataset
+The amount of space used by this dataset itself, which would be freed if the
+dataset were destroyed (after first removing any
+.Sy refreservation
+and destroying any necessary snapshots or descendents).
+.It Sy usedbychildren
+The amount of space used by children of this dataset, which would be freed if
+all the dataset's children were destroyed.
+.It Sy usedbyrefreservation
+The amount of space used by a
+.Sy refreservation
+set on this dataset, which would be freed if the
+.Sy refreservation
+was removed.
+.It Sy userused@ Ns Ar user
+The amount of space consumed by the specified user in this dataset. Space is
+charged to the owner of each file, as displayed by
+.Qq Nm ls Fl l .
+The amount of space charged is displayed by
+.Qq Nm du
+and
+.Qq Nm ls Fl s .
+See the
+.Qq Nm Cm userspace
+subcommand for more information.
+.Pp
+Unprivileged users can access only their own space usage. The root user, or a
+user who has been granted the
+.Sy userused
+privilege with
+.Qq Nm Cm allow ,
+can access everyone's usage.
+.Pp
+The
+.Sy userused@ Ns ...
+properties are not displayed by
+.Qq Nm Cm get all .
+The user's name must be appended after the
+.Sy @
+symbol, using one of the following forms:
+.Bl -bullet -offset 2n
+.It
+POSIX name (for example,
+.Em joe )
+.It
+POSIX numeric ID (for example,
+.Em 1001 )
+.El
+.It Sy userrefs
+This property is set to the number of user holds on this snapshot. User holds
+are set by using the
+.Qq Nm Cm hold
+command.
+.It Sy groupused@ Ns Ar group
+The amount of space consumed by the specified group in this dataset. Space is
+charged to the group of each file, as displayed by
+.Nm ls Fl l .
+See the
+.Sy userused@ Ns Ar user
+property for more information.
+.Pp
+Unprivileged users can only access their own groups' space usage. The root
+user, or a user who has been granted the
+.Sy groupused
+privilege with
+.Qq Nm Cm allow ,
+can access all groups' usage.
+.It Sy volblocksize Ns = Ns Ar blocksize
+For volumes, specifies the block size of the volume. The
+.Ar blocksize
+cannot be changed once the volume has been written, so it should be set at
+volume creation time. The default
+.Ar blocksize
+for volumes is 8 Kbytes. Any
+power of 2 from 512 bytes to 128 Kbytes is valid.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy volblock .
+.It Sy written
+The amount of
+.Sy referenced
+space written to this dataset since the previous snapshot.
+.It Sy written@ Ns Ar snapshot
+The amount of
+.Sy referenced
+space written to this dataset since the specified snapshot. This is the space
+that is referenced by this dataset but was not referenced by the specified
+snapshot.
+.Pp
+The
+.Ar snapshot
+may be specified as a short snapshot name (just the part after the
+.Sy @ ) ,
+in which case it will be interpreted as a snapshot in the same filesystem as
+this dataset. The
+.Ar snapshot
+may be a full snapshot name
+.Pq Em filesystem@snapshot ,
+which for clones may be a snapshot in the origin's filesystem (or the origin of
+the origin's filesystem, etc).
+.El
+.Pp
+The following native properties can be used to change the behavior of a
+.Tn ZFS
+dataset.
+.Bl -tag -width 2n
+.It Xo
+.Sy aclinherit Ns = Ns Cm discard |
+.Cm noallow |
+.Cm restricted |
+.Cm passthrough |
+.Cm passthrough-x
+.Xc
+Controls how
+.Tn ACL
+entries are inherited when files and directories are created. A file system
+with an
+.Sy aclinherit
+property of
+.Cm discard
+does not inherit any
+.Tn ACL
+entries. A file system with an
+.Sy aclinherit
+property value of
+.Cm noallow
+only inherits inheritable
+.Tn ACL
+entries that specify "deny" permissions. The property value
+.Cm restricted
+(the default) removes the
+.Em write_acl
+and
+.Em write_owner
+permissions when the
+.Tn ACL
+entry is inherited. A file system with an
+.Sy aclinherit
+property value of
+.Cm passthrough
+inherits all inheritable
+.Tn ACL
+entries without any modifications made to the
+.Tn ACL
+entries when they are inherited. A file system with an
+.Sy aclinherit
+property value of
+.Cm passthrough-x
+has the same meaning as
+.Cm passthrough ,
+except that the
+.Em owner@ , group@ , No and Em everyone@ Tn ACE Ns s
+inherit the execute permission only if the file creation mode also requests the
+execute bit.
+.Pp
+When the property value is set to
+.Cm passthrough ,
+files are created with a mode determined by the inheritable
+.Tn ACE Ns s.
+If no inheritable
+.Tn ACE Ns s
+exist that affect the mode, then the mode is set in accordance to the requested
+mode from the application.
+.It Sy aclmode Ns = Ns Cm discard | groupmask | passthrough | restricted
+Controls how an
+.Tn ACL
+is modified during
+.Xr chmod 2 .
+A file system with an
+.Sy aclmode
+property of
+.Cm discard
+(the default) deletes all
+.Tn ACL
+entries that do not represent the mode of the file. An
+.Sy aclmode
+property of
+.Cm groupmask
+reduces permissions granted in all
+.Em ALLOW
+entries found in the
+.Tn ACL
+such that they are no greater than the group permissions specified by
+.Xr chmod 2 .
+A file system with an
+.Sy aclmode
+property of
+.Cm passthrough
+indicates that no changes are made to the
+.Tn ACL
+other than creating or updating the necessary
+.Tn ACL
+entries to represent the new mode of the file or directory.
+An
+.Sy aclmode
+property of
+.Cm restricted
+will cause the
+.Xr chmod 2
+operation to return an error when used on any file or directory which has
+a non-trivial
+.Tn ACL
+whose entries can not be represented by a mode.
+.Xr chmod 2
+is required to change the set user ID, set group ID, or sticky bits on a file
+or directory, as they do not have equivalent
+.Tn ACL
+entries.
+In order to use
+.Xr chmod 2
+on a file or directory with a non-trivial
+.Tn ACL
+when
+.Sy aclmode
+is set to
+.Cm restricted ,
+you must first remove all
+.Tn ACL
+entries which do not represent the current mode.
+.It Sy atime Ns = Ns Cm on | off
+Controls whether the access time for files is updated when they are read.
+Turning this property off avoids producing write traffic when reading files and
+can result in significant performance gains, though it might confuse mailers
+and other similar utilities. The default value is
+.Cm on .
+.It Sy canmount Ns = Ns Cm on | off | noauto
+If this property is set to
+.Cm off ,
+the file system cannot be mounted, and is ignored by
+.Qq Nm Cm mount Fl a .
+Setting this property to
+.Cm off
+is similar to setting the
+.Sy mountpoint
+property to
+.Cm none ,
+except that the dataset still has a normal
+.Sy mountpoint
+property, which can be inherited. Setting this property to
+.Cm off
+allows datasets to be used solely as a mechanism to inherit properties. One
+example of setting
+.Sy canmount Ns = Ns Cm off
+is to have two datasets with the same
+.Sy mountpoint ,
+so that the children of both datasets appear in the same directory, but might
+have different inherited characteristics.
+.Pp
+When the
+.Cm noauto
+value is set, a dataset can only be mounted and unmounted explicitly. The
+dataset is not mounted automatically when the dataset is created or imported,
+nor is it mounted by the
+.Qq Nm Cm mount Fl a
+command or unmounted by the
+.Qq Nm Cm umount Fl a
+command.
+.Pp
+This property is not inherited.
+.It Sy checksum Ns = Ns Cm on | off | fletcher2 | fletcher4 | sha256
+Controls the checksum used to verify data integrity. The default value is
+.Cm on ,
+which automatically selects an appropriate algorithm (currently,
+.Cm fletcher4 ,
+but this may change in future releases). The value
+.Cm off
+disables integrity checking on user data. Disabling checksums is
+.Em NOT
+a recommended practice.
+.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | zle | Cm lz4
+Controls the compression algorithm used for this dataset. The
+.Cm lzjb
+compression algorithm is optimized for performance while providing decent data
+compression. Setting compression to
+.Cm on
+uses the
+.Cm lzjb
+compression algorithm. The
+.Cm gzip
+compression algorithm uses the same compression as the
+.Xr gzip 1
+command. You can specify the
+.Cm gzip
+level by using the value
+.Cm gzip- Ns Ar N
+where
+.Ar N
+is an integer from 1 (fastest) to 9 (best compression ratio). Currently,
+.Cm gzip
+is equivalent to
+.Cm gzip-6
+(which is also the default for
+.Xr gzip 1 ) .
+The
+.Cm zle
+compression algorithm compresses runs of zeros.
+.Pp
+The
+.Sy lz4
+compression algorithm is a high-performance replacement
+for the
+.Sy lzjb
+algorithm. It features significantly faster
+compression and decompression, as well as a moderately higher
+compression ratio than
+.Sy lzjb ,
+but can only be used on pools with
+the
+.Sy lz4_compress
+feature set to
+.Sy enabled .
+See
+.Xr zpool-features 7
+for details on ZFS feature flags and the
+.Sy lz4_compress
+feature.
+.Pp
+This property can also be referred to by its shortened column name
+.Cm compress .
+Changing this property affects only newly-written data.
+.It Sy copies Ns = Ns Cm 1 | 2 | 3
+Controls the number of copies of data stored for this dataset. These copies are
+in addition to any redundancy provided by the pool, for example, mirroring or
+RAID-Z. The copies are stored on different disks, if possible. The space used
+by multiple copies is charged to the associated file and dataset, changing the
+.Sy used
+property and counting against quotas and reservations.
+.Pp
+Changing this property only affects newly-written data. Therefore, set this
+property at file system creation time by using the
+.Fl o Cm copies= Ns Ar N
+option.
+.It Sy dedup Ns = Ns Cm on | off | verify | sha256 Ns Op Cm ,verify
+Configures deduplication for a dataset. The default value is
+.Cm off .
+The default deduplication checksum is
+.Cm sha256
+(this may change in the future).
+When
+.Sy dedup
+is enabled, the checksum defined here overrides the
+.Sy checksum
+property. Setting the value to
+.Cm verify
+has the same effect as the setting
+.Cm sha256,verify .
+.Pp
+If set to
+.Cm verify ,
+.Tn ZFS
+will do a byte-to-byte comparsion in case of two blocks having the same
+signature to make sure the block contents are identical.
+.It Sy devices Ns = Ns Cm on | off
+The
+.Sy devices
+property is currently not supported on
+.Fx .
+.It Sy exec Ns = Ns Cm on | off
+Controls whether processes can be executed from within this file system. The
+default value is
+.Cm on .
+.It Sy mlslabel Ns = Ns Ar label | Cm none
+The
+.Sy mlslabel
+property is currently not supported on
+.Fx .
+.It Sy mountpoint Ns = Ns Ar path | Cm none | legacy
+Controls the mount point used for this file system. See the
+.Qq Sx Mount Points
+section for more information on how this property is used.
+.Pp
+When the
+.Sy mountpoint
+property is changed for a file system, the file system and any children that
+inherit the mount point are unmounted. If the new value is
+.Cm legacy ,
+then they remain unmounted. Otherwise, they are automatically remounted in the
+new location if the property was previously
+.Cm legacy
+or
+.Cm none ,
+or if they were mounted before the property was changed. In addition, any
+shared file systems are unshared and shared in the new location.
+.It Sy nbmand Ns = Ns Cm on | off
+The
+.Sy nbmand
+property is currently not supported on
+.Fx .
+.It Sy primarycache Ns = Ns Cm all | none | metadata
+Controls what is cached in the primary cache (ARC). If this property is set to
+.Cm all ,
+then both user data and metadata is cached. If this property is set to
+.Cm none ,
+then neither user data nor metadata is cached. If this property is set to
+.Cm metadata ,
+then only metadata is cached. The default value is
+.Cm all .
+.It Sy quota Ns = Ns Ar size | Cm none
+Limits the amount of space a dataset and its descendents can consume. This
+property enforces a hard limit on the amount of space used. This includes all
+space consumed by descendents, including file systems and snapshots. Setting a
+quota on a descendent of a dataset that already has a quota does not override
+the ancestor's quota, but rather imposes an additional limit.
+.Pp
+Quotas cannot be set on volumes, as the
+.Sy volsize
+property acts as an implicit quota.
+.It Sy userquota@ Ns Ar user Ns = Ns Ar size | Cm none
+Limits the amount of space consumed by the specified user.
+Similar to the
+.Sy refquota
+property, the
+.Sy userquota
+space calculation does not include space that is used by descendent datasets,
+such as snapshots and clones. User space consumption is identified by the
+.Sy userspace@ Ns Ar user
+property.
+.Pp
+Enforcement of user quotas may be delayed by several seconds. This delay means
+that a user might exceed their quota before the system notices that they are
+over quota and begins to refuse additional writes with the
+.Em EDQUOT
+error message. See the
+.Cm userspace
+subcommand for more information.
+.Pp
+Unprivileged users can only access their own groups' space usage. The root
+user, or a user who has been granted the
+.Sy userquota
+privilege with
+.Qq Nm Cm allow ,
+can get and set everyone's quota.
+.Pp
+This property is not available on volumes, on file systems before version 4, or
+on pools before version 15. The
+.Sy userquota@ Ns ...
+properties are not displayed by
+.Qq Nm Cm get all .
+The user's name must be appended after the
+.Sy @
+symbol, using one of the following forms:
+.Bl -bullet -offset 2n
+.It
+POSIX name (for example,
+.Em joe )
+.It
+POSIX numeric ID (for example,
+.Em 1001 )
+.El
+.It Sy groupquota@ Ns Ar group Ns = Ns Ar size | Cm none
+Limits the amount of space consumed by the specified group. Group space
+consumption is identified by the
+.Sy userquota@ Ns Ar user
+property.
+.Pp
+Unprivileged users can access only their own groups' space usage. The root
+user, or a user who has been granted the
+.Sy groupquota
+privilege with
+.Qq Nm Cm allow ,
+can get and set all groups' quotas.
+.It Sy readonly Ns = Ns Cm on | off
+Controls whether this dataset can be modified. The default value is
+.Cm off .
+.It Sy recordsize Ns = Ns Ar size
+Specifies a suggested block size for files in the file system. This property is
+designed solely for use with database workloads that access files in fixed-size
+records.
+.Tn ZFS
+automatically tunes block sizes according to internal algorithms optimized for
+typical access patterns.
+.Pp
+For databases that create very large files but access them in small random
+chunks, these algorithms may be suboptimal. Specifying a
+.Sy recordsize
+greater than or equal to the record size of the database can result in
+significant performance gains. Use of this property for general purpose file
+systems is strongly discouraged, and may adversely affect performance.
+.Pp
+The size specified must be a power of two greater than or equal to 512 and less
+than or equal to 128 Kbytes.
+.Pp
+Changing the file system's
+.Sy recordsize
+affects only files created afterward; existing files are unaffected.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy recsize .
+.It Sy refquota Ns = Ns Ar size | Cm none
+Limits the amount of space a dataset can consume. This property enforces a hard
+limit on the amount of space used. This hard limit does not include space used
+by descendents, including file systems and snapshots.
+.It Sy refreservation Ns = Ns Ar size | Cm none
+The minimum amount of space guaranteed to a dataset, not including its
+descendents. When the amount of space used is below this value, the dataset is
+treated as if it were taking up the amount of space specified by
+.Sy refreservation .
+The
+.Sy refreservation
+reservation is accounted for in the parent datasets' space used, and counts
+against the parent datasets' quotas and reservations.
+.Pp
+If
+.Sy refreservation
+is set, a snapshot is only allowed if there is enough free pool space outside
+of this reservation to accommodate the current number of "referenced" bytes in
+the dataset.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy refreserv .
+.It Sy reservation Ns = Ns Ar size | Cm none
+The minimum amount of space guaranteed to a dataset and its descendents. When
+the amount of space used is below this value, the dataset is treated as if it
+were taking up the amount of space specified by its reservation. Reservations
+are accounted for in the parent datasets' space used, and count against the
+parent datasets' quotas and reservations.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy reserv .
+.It Sy secondarycache Ns = Ns Cm all | none | metadata
+Controls what is cached in the secondary cache (L2ARC). If this property is set
+to
+.Cm all ,
+then both user data and metadata is cached. If this property is set to
+.Cm none ,
+then neither user data nor metadata is cached. If this property is set to
+.Cm metadata ,
+then only metadata is cached. The default value is
+.Cm all .
+.It Sy setuid Ns = Ns Cm on | off
+Controls whether the
+.No set- Ns Tn UID
+bit is respected for the file system. The default value is
+.Cm on .
+.It Sy sharesmb Ns = Ns Cm on | off | Ar opts
+The
+.Sy sharesmb
+property currently has no effect on
+.Fx .
+.It Sy sharenfs Ns = Ns Cm on | off | Ar opts
+Controls whether the file system is shared via
+.Tn NFS ,
+and what options are used. A file system with a
+.Sy sharenfs
+property of
+.Cm off
+is managed the traditional way via
+.Xr exports 5 .
+Otherwise, the file system is automatically shared and unshared with the
+.Qq Nm Cm share
+and
+.Qq Nm Cm unshare
+commands. If the property is set to
+.Cm on
+no
+.Tn NFS
+export options are used. Otherwise,
+.Tn NFS
+export options are equivalent to the contents of this property. The export
+options may be comma-separated. See
+.Xr exports 5
+for a list of valid options.
+.Pp
+When the
+.Sy sharenfs
+property is changed for a dataset, the
+.Xr mountd 8
+daemon is reloaded.
+.It Sy logbias Ns = Ns Cm latency | throughput
+Provide a hint to
+.Tn ZFS
+about handling of synchronous requests in this dataset.
+If
+.Sy logbias
+is set to
+.Cm latency
+(the default),
+.Tn ZFS
+will use pool log devices (if configured) to handle the requests at low
+latency. If
+.Sy logbias
+is set to
+.Cm throughput ,
+.Tn ZFS
+will not use configured pool log devices.
+.Tn ZFS
+will instead optimize synchronous operations for global pool throughput and
+efficient use of resources.
+.It Sy snapdir Ns = Ns Cm hidden | visible
+Controls whether the
+.Pa \&.zfs
+directory is hidden or visible in the root of the file system as discussed in
+the
+.Qq Sx Snapshots
+section. The default value is
+.Cm hidden .
+.It Sy sync Ns = Ns Cm standard | always | disabled
+Controls the behavior of synchronous requests (e.g.
+.Xr fsync 2 ,
+O_DSYNC). This property accepts the following values:
+.Bl -tag -offset 4n -width 8n
+.It Sy standard
+This is the POSIX specified behavior of ensuring all synchronous requests are
+written to stable storage and all devices are flushed to ensure data is not
+cached by device controllers (this is the default).
+.It Sy always
+All file system transactions are written and flushed before their system calls
+return. This has a large performance penalty.
+.It Sy disabled
+Disables synchronous requests. File system transactions are only committed to
+stable storage periodically. This option will give the highest performance.
+However, it is very dangerous as
+.Tn ZFS
+would be ignoring the synchronous transaction demands of applications such as
+databases or
+.Tn NFS .
+Administrators should only use this option when the risks are understood.
+.El
+.It Sy volsize Ns = Ns Ar size
+For volumes, specifies the logical size of the volume. By default, creating a
+volume establishes a reservation of equal size. For storage pools with a
+version number of 9 or higher, a
+.Sy refreservation
+is set instead. Any changes to
+.Sy volsize
+are reflected in an equivalent change to the reservation (or
+.Sy refreservation ) .
+The
+.Sy volsize
+can only be set to a multiple of
+.Cm volblocksize ,
+and cannot be zero.
+.Pp
+The reservation is kept equal to the volume's logical size to prevent
+unexpected behavior for consumers. Without the reservation, the volume could
+run out of space, resulting in undefined behavior or data corruption, depending
+on how the volume is used. These effects can also occur when the volume size is
+changed while it is in use (particularly when shrinking the size). Extreme care
+should be used when adjusting the volume size.
+.Pp
+Though not recommended, a "sparse volume" (also known as "thin provisioning")
+can be created by specifying the
+.Fl s
+option to the
+.Qq Nm Cm create Fl V
+command, or by changing the reservation after the volume has been created. A
+"sparse volume" is a volume where the reservation is less then the volume size.
+Consequently, writes to a sparse volume can fail with
+.Sy ENOSPC
+when the pool is low on space. For a sparse volume, changes to
+.Sy volsize
+are not reflected in the reservation.
+.It Sy vscan Ns = Ns Cm off | on
+The
+.Sy vscan
+property is currently not supported on
+.Fx .
+.It Sy xattr Ns = Ns Cm off | on
+The
+.Sy xattr
+property is currently not supported on
+.Fx .
+.It Sy jailed Ns = Ns Cm off | on
+Controls whether the dataset is managed from a jail. See the
+.Qq Sx Jails
+section for more information. The default value is
+.Cm off .
+.El
+.Pp
+The following three properties cannot be changed after the file system is
+created, and therefore, should be set when the file system is created. If the
+properties are not set with the
+.Qq Nm Cm create
+or
+.Nm zpool Cm create
+commands, these properties are inherited from the parent dataset. If the parent
+dataset lacks these properties due to having been created prior to these
+features being supported, the new file system will have the default values for
+these properties.
+.Bl -tag -width 4n
+.It Sy casesensitivity Ns = Ns Cm sensitive | insensitive | mixed
+The
+.Sy casesensitivity
+property is currently not supported on
+.Fx .
+.It Sy normalization Ns = Ns Cm none | formC | formD | formKC | formKD
+Indicates whether the file system should perform a
+.Sy unicode
+normalization of file names whenever two file names are compared, and which
+normalization algorithm should be used. File names are always stored
+unmodified, names are normalized as part of any comparison process. If this
+property is set to a legal value other than
+.Cm none ,
+and the
+.Sy utf8only
+property was left unspecified, the
+.Sy utf8only
+property is automatically set to
+.Cm on .
+The default value of the
+.Sy normalization
+property is
+.Cm none .
+This property cannot be changed after the file system is created.
+.It Sy utf8only Ns = Ns Cm on | off
+Indicates whether the file system should reject file names that include
+characters that are not present in the
+.Sy UTF-8
+character code set. If this property is explicitly set to
+.Cm off ,
+the normalization property must either not be explicitly set or be set to
+.Cm none .
+The default value for the
+.Sy utf8only
+property is
+.Cm off .
+This property cannot be changed after the file system is created.
+.El
+.Pp
+The
+.Sy casesensitivity , normalization , No and Sy utf8only
+properties are also new permissions that can be assigned to non-privileged
+users by using the
+.Tn ZFS
+delegated administration feature.
+.Ss Temporary Mount Point Properties
+When a file system is mounted, either through
+.Xr mount 8
+for legacy mounts or the
+.Qq Nm Cm mount
+command for normal file systems, its mount options are set according to its
+properties. The correlation between properties and mount options is as follows:
+.Bl -column -offset 4n "PROPERTY" "MOUNT OPTION"
+.It "PROPERTY MOUNT OPTION"
+.It "atime atime/noatime"
+.It "exec exec/noexec"
+.It "readonly ro/rw"
+.It "setuid suid/nosuid"
+.El
+.Pp
+In addition, these options can be set on a per-mount basis using the
+.Fl o
+option, without affecting the property that is stored on disk. The values
+specified on the command line override the values stored in the dataset. These
+properties are reported as "temporary" by the
+.Qq Nm Cm get
+command. If the properties are changed while the dataset is mounted, the new
+setting overrides any temporary settings.
+.Ss User Properties
+In addition to the standard native properties,
+.Tn ZFS
+supports arbitrary user properties. User properties have no effect on
+.Tn ZFS
+behavior, but applications or administrators can use them to annotate datasets
+(file systems, volumes, and snapshots).
+.Pp
+User property names must contain a colon
+.Pq Sy \&:
+character to distinguish them from native properties. They may contain
+lowercase letters, numbers, and the following punctuation characters: colon
+.Pq Sy \&: ,
+dash
+.Pq Sy \&- ,
+period
+.Pq Sy \&.
+and underscore
+.Pq Sy \&_ .
+The expected convention is that the property name is divided into two portions
+such as
+.Em module Ns Sy \&: Ns Em property ,
+but this namespace is not enforced by
+.Tn ZFS .
+User property names can be at most 256 characters, and cannot begin with a dash
+.Pq Sy \&- .
+.Pp
+When making programmatic use of user properties, it is strongly suggested to
+use a reversed
+.Tn DNS
+domain name for the
+.Ar module
+component of property names to reduce the chance that two
+independently-developed packages use the same property name for different
+purposes. Property names beginning with
+.Em com.sun
+are reserved for use by Sun Microsystems.
+.Pp
+The values of user properties are arbitrary strings, are always inherited, and
+are never validated. All of the commands that operate on properties
+.Po
+.Qq Nm Cm list ,
+.Qq Nm Cm get ,
+.Qq Nm Cm set
+and so forth
+.Pc
+can be used to manipulate both native properties and user properties. Use the
+.Qq Nm Cm inherit
+command to clear a user property. If the property is not defined in any parent
+dataset, it is removed entirely. Property values are limited to 1024
+characters.
+.Sh SUBCOMMANDS
+All subcommands that modify state are logged persistently to the pool in their
+original form.
+.Bl -tag -width 2n
+.It Xo
+.Nm
+.Op Fl \&?
+.Xc
+.Pp
+Displays a help message.
+.It Xo
+.Nm
+.Cm create
+.Op Fl pu
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar filesystem
+.Xc
+.Pp
+Creates a new
+.Tn ZFS
+file system. The file system is automatically mounted according to the
+.Sy mountpoint
+property inherited from the parent.
+.Bl -tag -width indent
+.It Fl p
+Creates all the non-existing parent datasets. Datasets created in this manner
+are automatically mounted according to the
+.Sy mountpoint
+property inherited from their parent. Any property specified on the command
+line using the
+.Fl o
+option is ignored. If the target filesystem already exists, the operation
+completes successfully.
+.It Fl u
+Newly created file system is not mounted.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property as if the command
+.Qq Nm Cm set Ar property Ns = Ns Ar value
+was invoked at the same time the dataset was created. Any editable
+.Tn ZFS
+property can also be set at creation time. Multiple
+.Fl o
+options can be specified. An error results if the same property is specified in
+multiple
+.Fl o
+options.
+.El
+.It Xo
+.Nm
+.Cm create
+.Op Fl ps
+.Op Fl b Ar blocksize
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Fl V
+.Ar size volume
+.Xc
+.Pp
+Creates a volume of the given size. The volume is exported as a block device in
+.Pa /dev/zvol/path ,
+where
+.Ar path
+is the name of the volume in the
+.Tn ZFS
+namespace. The size represents the logical size as exported by the device. By
+default, a reservation of equal size is created.
+.Pp
+.Ar size
+is automatically rounded up to the nearest 128 Kbytes to ensure that
+the volume has an integral number of blocks regardless of
+.Ar blocksize .
+.Bl -tag -width indent
+.It Fl p
+Creates all the non-existing parent datasets. Datasets created in this manner
+are automatically mounted according to the
+.Sy mountpoint
+property inherited from their parent. Any property specified on the command
+line using the
+.Fl o
+option is ignored. If the target filesystem already exists, the operation
+completes successfully.
+.It Fl s
+Creates a sparse volume with no reservation. See
+.Sy volsize
+in the
+.Qq Sx Native Properties
+section for more information about sparse volumes.
+.It Fl b Ar blocksize
+Equivalent to
+.Fl o Cm volblocksize Ns = Ns Ar blocksize .
+If this option is specified in conjunction with
+.Fl o Cm volblocksize ,
+the resulting behavior is undefined.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property as if the
+.Qq Nm Cm set Ar property Ns = Ns Ar value
+command was invoked at the same time the dataset was created. Any editable
+.Tn ZFS
+property can also be set at creation time. Multiple
+.Fl o
+options can be specified. An error results if the same property is specified in
+multiple
+.Fl o
+options.
+.El
+.It Xo
+.Nm
+.Cm destroy
+.Op Fl fnpRrv
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Destroys the given dataset. By default, the command unshares any file systems
+that are currently shared, unmounts any file systems that are currently
+mounted, and refuses to destroy a dataset that has active dependents (children
+or clones).
+.Bl -tag -width indent
+.It Fl r
+Recursively destroy all children.
+.It Fl R
+Recursively destroy all dependents, including cloned file systems outside the
+target hierarchy.
+.It Fl f
+Force an unmount of any file systems using the
+.Qq Nm Cm unmount Fl f
+command. This option has no effect on non-file systems or unmounted file
+systems.
+.It Fl n
+Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
+conjunction with the
+.Fl v
+or
+.Fl p
+flags to determine what data would be deleted.
+.It Fl p
+Print machine-parsable verbose information about the deleted data.
+.It Fl v
+Print verbose information about the deleted data.
+.El
+.Pp
+Extreme care should be taken when applying either the
+.Fl r
+or the
+.Fl R
+options, as they can destroy large portions of a pool and cause unexpected
+behavior for mounted file systems in use.
+.It Xo
+.Nm
+.Cm destroy
+.Op Fl dnpRrv
+.Sm off
+.Ar snapshot
+.Op % Ns Ar snapname
+.Op , Ns ...
+.Sm on
+.Xc
+.Pp
+The given snapshots are destroyed immediately if and only if the
+.Qq Nm Cm destroy
+command without the
+.Fl d
+option would have destroyed it. Such immediate destruction would occur, for
+example, if the snapshot had no clones and the user-initiated reference count
+were zero.
+.Pp
+If a snapshot does not qualify for immediate destruction, it is marked for
+deferred deletion. In this state, it exists as a usable, visible snapshot until
+both of the preconditions listed above are met, at which point it is destroyed.
+.Pp
+An inclusive range of snapshots may be specified by separating the
+first and last snapshots with a percent sign
+.Pq Sy % .
+The first and/or last snapshots may be left blank, in which case the
+filesystem's oldest or newest snapshot will be implied.
+.Pp
+Multiple snapshots
+(or ranges of snapshots) of the same filesystem or volume may be specified
+in a comma-separated list of snapshots.
+Only the snapshot's short name (the
+part after the
+.Sy @ )
+should be specified when using a range or comma-separated list to identify
+multiple snapshots.
+.Bl -tag -width indent
+.It Fl r
+Destroy (or mark for deferred deletion) all snapshots with this name in
+descendent file systems.
+.It Fl R
+Recursively destroy all clones of these snapshots, including the clones,
+snapshots, and children.
+If this flag is specified, the
+.Op fl d
+flag will have no effect.
+.It Fl n
+Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
+conjunction with the
+.Fl v
+or
+.Fl p
+flags to determine what data would be deleted.
+.It Fl p
+Print machine-parsable verbose information about the deleted data.
+.It Fl v
+Print verbose information about the deleted data.
+.It Fl d
+Defer snapshot deletion.
+.El
+.Pp
+Extreme care should be taken when applying either the
+.Fl r
+or the
+.Fl R
+options, as they can destroy large portions of a pool and cause unexpected
+behavior for mounted file systems in use.
+.It Xo
+.Nm
+.Cm snapshot
+.Op Fl r
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar filesystem@snapname Ns | Ns volume@snapname
+.Ar filesystem@snapname Ns | Ns volume@snapname Ns ...
+.Xc
+.Pp
+Creates snapshots with the given names. All previous modifications by
+successful system calls to the file system are part of the snapshots.
+Snapshots are taken atomically, so that all snapshots correspond to the same
+moment in time. See the
+.Qq Sx Snapshots
+section for details.
+.Bl -tag -width indent
+.It Fl r
+Recursively create snapshots of all descendent datasets
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property; see
+.Qq Nm Cm create
+for details.
+.El
+.It Xo
+.Nm
+.Cm rollback
+.Op Fl rRf
+.Ar snapshot
+.Xc
+.Pp
+Roll back the given dataset to a previous snapshot. When a dataset is rolled
+back, all data that has changed since the snapshot is discarded, and the
+dataset reverts to the state at the time of the snapshot. By default, the
+command refuses to roll back to a snapshot other than the most recent one. In
+order to do so, all intermediate snapshots must be destroyed by specifying the
+.Fl r
+option.
+.Bl -tag -width indent
+.It Fl r
+Recursively destroy any snapshots more recent than the one specified.
+.It Fl R
+Recursively destroy any more recent snapshots, as well as any clones of those
+snapshots.
+.It Fl f
+Used with the
+.Fl R
+option to force an unmount of any clone file systems that are to be destroyed.
+.El
+.It Xo
+.Nm
+.Cm clone
+.Op Fl p
+.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
+.Ar snapshot filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Creates a clone of the given snapshot. See the
+.Qq Sx Clones
+section for details. The target dataset can be located anywhere in the
+.Tn ZFS
+hierarchy, and is created as the same type as the original.
+.Bl -tag -width indent
+.It Fl p
+Creates all the non-existing parent datasets. Datasets created in this manner
+are automatically mounted according to the
+.Sy mountpoint
+property inherited from their parent. If the target filesystem or volume
+already exists, the operation completes successfully.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property; see
+.Qq Nm Cm create
+for details.
+.El
+.It Xo
+.Nm
+.Cm promote
+.Ar clone-filesystem
+.Xc
+.Pp
+Promotes a clone file system to no longer be dependent on its "origin"
+snapshot. This makes it possible to destroy the file system that the clone was
+created from. The clone parent-child dependency relationship is reversed, so
+that the origin file system becomes a clone of the specified file system.
+.Pp
+The snapshot that was cloned, and any snapshots previous to this snapshot, are
+now owned by the promoted clone. The space they use moves from the origin file
+system to the promoted clone, so enough space must be available to accommodate
+these snapshots. No new space is consumed by this operation, but the space
+accounting is adjusted. The promoted clone must not have any conflicting
+snapshot names of its own. The
+.Cm rename
+subcommand can be used to rename any conflicting snapshots.
+.It Xo
+.Nm
+.Cm rename
+.Op Fl f
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Xc
+.It Xo
+.Nm
+.Cm rename
+.Op Fl f
+.Fl p
+.Ar filesystem Ns | Ns Ar volume
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.It Xo
+.Nm
+.Cm rename
+.Fl u
+.Op Fl p
+.Ar filesystem filesystem
+.Xc
+.Pp
+Renames the given dataset. The new target can be located anywhere in the
+.Tn ZFS
+hierarchy, with the exception of snapshots. Snapshots can only be renamed
+within the parent file system or volume. When renaming a snapshot, the parent
+file system of the snapshot does not need to be specified as part of the second
+argument. Renamed file systems can inherit new mount points, in which case they
+are unmounted and remounted at the new mount point.
+.Bl -tag -width indent
+.It Fl p
+Creates all the nonexistent parent datasets. Datasets created in this manner
+are automatically mounted according to the
+.Sy mountpoint
+property inherited from their parent.
+.It Fl u
+Do not remount file systems during rename. If a file system's
+.Sy mountpoint
+property is set to
+.Cm legacy
+or
+.Cm none ,
+file system is not unmounted even if this option is not given.
+.It Fl f
+Force unmount any filesystems that need to be unmounted in the process.
+This flag has no effect if used together with the
+.Fl u
+flag.
+.El
+.It Xo
+.Nm
+.Cm rename
+.Fl r
+.Ar snapshot snapshot
+.Xc
+.Pp
+Recursively rename the snapshots of all descendent datasets. Snapshots are the
+only dataset that can be renamed recursively.
+.It Xo
+.Nm
+.Cm list
+.Op Fl r Ns | Ns Fl d Ar depth
+.Op Fl H
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Oo Fl s Ar property Oc Ns ...
+.Oo Fl S Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Xc
+.Pp
+Lists the property information for the given datasets in tabular form. If
+specified, you can list property information by the absolute pathname or the
+relative pathname. By default, all file systems and volumes are displayed.
+Snapshots are displayed if the
+.Sy listsnaps
+property is
+.Cm on
+(the default is
+.Cm off ) .
+The following fields are displayed,
+.Sy name , used , available , referenced , mountpoint .
+.Bl -tag -width indent
+.It Fl r
+Recursively display any children of the dataset on the command line.
+.It Fl d Ar depth
+Recursively display any children of the dataset, limiting the recursion to
+.Ar depth .
+A depth of
+.Sy 1
+will display only the dataset and its direct children.
+.It Fl H
+Used for scripting mode. Do not print headers and separate fields by a single
+tab instead of arbitrary white space.
+.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+A comma-separated list of properties to display. The property must be:
+.Bl -bullet -offset 2n
+.It
+One of the properties described in the
+.Qq Sx Native Properties
+section
+.It
+A user property
+.It
+The value
+.Cm name
+to display the dataset name
+.It
+The value
+.Cm space
+to display space usage properties on file systems and volumes. This is a
+shortcut for specifying
+.Fl o
+.Sy name,avail,used,usedsnap,usedds,usedrefreserv,usedchild
+.Fl t
+.Sy filesystem,volume
+syntax.
+.El
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+A comma-separated list of types to display, where
+.Ar type
+is one of
+.Sy filesystem , snapshot , volume , No or Sy all .
+For example, specifying
+.Fl t Cm snapshot
+displays only snapshots.
+.It Fl s Ar property
+A property for sorting the output by column in ascending order based on the
+value of the property. The property must be one of the properties described in
+the
+.Qq Sx Properties
+section, or the special value
+.Cm name
+to sort by the dataset name. Multiple properties can be specified at one time
+using multiple
+.Fl s
+property options. Multiple
+.Fl s
+options are evaluated from left to right in decreasing order of importance.
+.Pp
+The following is a list of sorting criteria:
+.Bl -bullet -offset 2n
+.It
+Numeric types sort in numeric order.
+.It
+String types sort in alphabetical order.
+.It
+Types inappropriate for a row sort that row to the literal bottom, regardless
+of the specified ordering.
+.It
+If no sorting options are specified the existing behavior of
+.Qq Nm Cm list
+is preserved.
+.El
+.It Fl S Ar property
+Same as the
+.Fl s
+option, but sorts by property in descending order.
+.El
+.It Xo
+.Nm
+.Cm set
+.Ar property Ns = Ns Ar value
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Xc
+.Pp
+Sets the property to the given value for each dataset. Only some properties can
+be edited. See the "Properties" section for more information on what properties
+can be set and acceptable values. Numeric values can be specified as exact
+values, or in a human-readable form with a suffix of
+.Sy B , K , M , G , T , P , E , Z
+(for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or
+zettabytes, respectively). User properties can be set on snapshots. For more
+information, see the
+.Qq Sx User Properties
+section.
+.It Xo
+.Nm
+.Cm get
+.Op Fl r Ns | Ns Fl d Ar depth
+.Op Fl Hp
+.Op Fl o Ar all | field Ns Oo , Ns Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Op Fl s Ar source Ns Oo , Ns Ar source Oc Ns ...
+.Ar all | property Ns Oo , Ns Ar property Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Xc
+.Pp
+Displays properties for the given datasets. If no datasets are specified, then
+the command displays properties for all datasets on the system. For each
+property, the following columns are displayed:
+.Pp
+.Bl -hang -width "property" -offset indent -compact
+.It name
+Dataset name
+.It property
+Property name
+.It value
+Property value
+.It source
+Property source. Can either be local, default, temporary, inherited, or none
+(\&-).
+.El
+.Pp
+All columns except the
+.Sy RECEIVED
+column are displayed by default. The columns to display can be specified
+by using the
+.Fl o
+option. This command takes a comma-separated list of properties as described in
+the
+.Qq Sx Native Properties
+and
+.Qq Sx User Properties
+sections.
+.Pp
+The special value
+.Cm all
+can be used to display all properties that apply to the given dataset's type
+(filesystem, volume, or snapshot).
+.Bl -tag -width indent
+.It Fl r
+Recursively display properties for any children.
+.It Fl d Ar depth
+Recursively display any children of the dataset, limiting the recursion to
+.Ar depth .
+A depth of
+.Sy 1
+will display only the dataset and its direct children.
+.It Fl H
+Display output in a form more easily parsed by scripts. Any headers are
+omitted, and fields are explicitly separated by a single tab instead of an
+arbitrary amount of space.
+.It Fl p
+Display numbers in parseable (exact) values.
+.It Fl o Cm all | Ar field Ns Oo , Ns Ar field Oc Ns ...
+A comma-separated list of columns to display. Supported values are
+.Sy name,property,value,received,source .
+Default values are
+.Sy name,property,value,source .
+The keyword
+.Cm all
+specifies all columns.
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+A comma-separated list of types to display, where
+.Ar type
+is one of
+.Sy filesystem , snapshot , volume , No or Sy all .
+For example, specifying
+.Fl t Cm snapshot
+displays only snapshots.
+.It Fl s Ar source Ns Oo , Ns Ar source Oc Ns ...
+A comma-separated list of sources to display. Those properties coming from a
+source other than those in this list are ignored. Each source must be one of
+the following:
+.Sy local,default,inherited,temporary,received,none .
+The default value is all sources.
+.El
+.It Xo
+.Nm
+.Cm inherit
+.Op Fl rS
+.Ar property
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Xc
+.Pp
+Clears the specified property, causing it to be inherited from an ancestor. If
+no ancestor has the property set, then the default value is used. See the
+.Qq Sx Properties
+section for a listing of default values, and details on which properties can be
+inherited.
+.Bl -tag -width indent
+.It Fl r
+Recursively inherit the given property for all children.
+.It Fl S
+For properties with a received value, revert to this value. This flag has no
+effect on properties that do not have a received value.
+.El
+.It Xo
+.Nm
+.Cm upgrade
+.Op Fl v
+.Xc
+.Pp
+Displays a list of file systems that are not the most recent version.
+.Bl -tag -width indent
+.It Fl v
+Displays
+.Tn ZFS
+filesystem versions supported by the current software. The current
+.Tn ZFS
+filesystem version and all previous supported versions are displayed, along
+with an explanation of the features provided with each version.
+.El
+.It Xo
+.Nm
+.Cm upgrade
+.Op Fl r
+.Op Fl V Ar version
+.Fl a | Ar filesystem
+.Xc
+.Pp
+Upgrades file systems to a new on-disk version. Once this is done, the file
+systems will no longer be accessible on systems running older versions of the
+software.
+.Qq Nm Cm send
+streams generated from new snapshots of these file systems cannot be accessed
+on systems running older versions of the software.
+.Pp
+In general, the file system version is independent of the pool version. See
+.Xr zpool 8
+for information on the
+.Nm zpool Cm upgrade
+command.
+.Pp
+In some cases, the file system version and the pool version are interrelated
+and the pool version must be upgraded before the file system version can be
+upgraded.
+.Bl -tag -width indent
+.It Fl r
+Upgrade the specified file system and all descendent file systems.
+.It Fl V Ar version
+Upgrade to the specified
+.Ar version .
+If the
+.Fl V
+flag is not specified, this command upgrades to the most recent version. This
+option can only be used to increase the version number, and only up to the most
+recent version supported by this software.
+.It Fl a
+Upgrade all file systems on all imported pools.
+.It Ar filesystem
+Upgrade the specified file system.
+.El
+.It Xo
+.Nm
+.Cm userspace
+.Op Fl Hinp
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Ar filesystem Ns | Ns Ar snapshot
+.Xc
+.Pp
+Displays space consumed by, and quotas on, each user in the specified
+filesystem or snapshot. This corresponds to the
+.Sy userused@ Ns Ar user
+and
+.Sy userquota@ Ns Ar user
+properties.
+.Bl -tag -width indent
+.It Fl n
+Print numeric ID instead of user/group name.
+.It Fl H
+Do not print headers, use tab-delimited output.
+.It Fl p
+Use exact (parsable) numeric output.
+.It Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+Display only the specified fields from the following set:
+.Sy type,name,used,quota .
+The default is to display all fields.
+.It Fl s Ar field
+Sort output by this field. The
+.Fl s
+and
+.Fl S
+flags may be specified multiple times to sort first by one field, then by
+another. The default is
+.Fl s Cm type Fl s Cm name .
+.It Fl S Ar field
+Sort by this field in reverse order. See
+.Fl s .
+.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+Print only the specified types from the following set:
+.Sy all,posixuser,smbuser,posixgroup,smbgroup .
+.Pp
+The default is
+.Fl t Cm posixuser,smbuser .
+.Pp
+The default can be changed to include group types.
+.It Fl i
+Translate SID to POSIX ID. This flag currently has no effect on
+.Fx .
+.El
+.It Xo
+.Nm
+.Cm groupspace
+.Op Fl Hinp
+.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ...
+.Oo Fl s Ar field Oc Ns ...
+.Oo Fl S Ar field Oc Ns ...
+.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
+.Ar filesystem Ns | Ns Ar snapshot
+.Xc
+.Pp
+Displays space consumed by, and quotas on, each group in the specified
+filesystem or snapshot. This subcommand is identical to
+.Qq Nm Cm userspace ,
+except that the default types to display are
+.Fl t Sy posixgroup,smbgroup .
+.It Xo
+.Nm
+.Cm mount
+.Xc
+.Pp
+Displays all
+.Tn ZFS
+file systems currently mounted.
+.Bl -tag -width indent
+.It Fl f
+.El
+.It Xo
+.Nm
+.Cm mount
+.Op Fl vO
+.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+.Fl a | Ar filesystem
+.Xc
+.Pp
+Mounts
+.Tn ZFS
+file systems.
+.Bl -tag -width indent
+.It Fl v
+Report mount progress.
+.It Fl O
+Perform an overlay mount. Overlay mounts are not supported on
+.Fx .
+.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
+An optional, comma-separated list of mount options to use temporarily for the
+duration of the mount. See the
+.Qq Sx Temporary Mount Point Properties
+section for details.
+.It Fl a
+Mount all available
+.Tn ZFS
+file systems.
+This command may be executed on
+.Fx
+system startup by
+.Pa /etc/rc.d/zfs .
+For more information, see variable
+.Va zfs_enable
+in
+.Xr rc.conf 5 .
+.It Ar filesystem
+Mount the specified filesystem.
+.El
+.It Xo
+.Nm
+.Cm unmount
+.Op Fl f
+.Fl a | Ar filesystem Ns | Ns Ar mountpoint
+.Xc
+.Pp
+Unmounts currently mounted
+.Tn ZFS
+file systems.
+.Bl -tag -width indent
+.It Fl f
+Forcefully unmount the file system, even if it is currently in use.
+.It Fl a
+Unmount all available
+.Tn ZFS
+file systems.
+.It Ar filesystem | mountpoint
+Unmount the specified filesystem. The command can also be given a path to a
+.Tn ZFS
+file system mount point on the system.
+.El
+.It Xo
+.Nm
+.Cm share
+.Fl a | Ar filesystem
+.Xc
+.Pp
+Shares
+.Tn ZFS
+file systems that have the
+.Sy sharenfs
+property set.
+.Bl -tag -width indent
+.It Fl a
+Share all
+.Tn ZFS
+file systems that have the
+.Sy sharenfs
+property set.
+This command may be executed on
+.Fx
+system startup by
+.Pa /etc/rc.d/zfs .
+For more information, see variable
+.Va zfs_enable
+in
+.Xr rc.conf 5 .
+.It Ar filesystem
+Share the specified filesystem according to the
+.Tn sharenfs
+property. File systems are shared when the
+.Tn sharenfs
+property is set.
+.El
+.It Xo
+.Nm
+.Cm unshare
+.Fl a | Ar filesystem Ns | Ns Ar mountpoint
+.Xc
+.Pp
+Unshares
+.Tn ZFS
+file systems that have the
+.Tn sharenfs
+property set.
+.Bl -tag -width indent
+.It Fl a
+Unshares
+.Tn ZFS
+file systems that have the
+.Sy sharenfs
+property set.
+This command may be executed on
+.Fx
+system shutdown by
+.Pa /etc/rc.d/zfs .
+For more information, see variable
+.Va zfs_enable
+in
+.Xr rc.conf 5 .
+.It Ar filesystem | mountpoint
+Unshare the specified filesystem. The command can also be given a path to a
+.Tn ZFS
+file system shared on the system.
+.El
+.It Xo
+.Nm
+.Cm send
+.Op Fl DnPpRv
+.Op Fl i Ar snapshot | Fl I Ar snapshot
+.Ar snapshot
+.Xc
+.Pp
+Creates a stream representation of the last
+.Ar snapshot
+argument (not part of
+.Fl i
+or
+.Fl I )
+which is written to standard output. The output can be redirected to
+a file or to a different system (for example, using
+.Xr ssh 1 ) .
+By default, a full stream is generated.
+.Bl -tag -width indent
+.It Fl i Ar snapshot
+Generate an incremental stream from the
+.Fl i Ar snapshot
+to the last
+.Ar snapshot .
+The incremental source (the
+.Fl i Ar snapshot )
+can be specified as the last component of the snapshot name (for example, the
+part after the
+.Sy @ ) ,
+and it is assumed to be from the same file system as the last
+.Ar snapshot .
+.Pp
+If the destination is a clone, the source may be the origin snapshot, which
+must be fully specified (for example,
+.Cm pool/fs@origin ,
+not just
+.Cm @origin ) .
+.It Fl I Ar snapshot
+Generate a stream package that sends all intermediary snapshots from the
+.Fl I Ar snapshot
+to the last
+.Ar snapshot .
+For example,
+.Ic -I @a fs@d
+is similar to
+.Ic -i @a fs@b; -i @b fs@c; -i @c fs@d .
+The incremental source snapshot may be specified as with the
+.Fl i
+option.
+.It Fl R
+Generate a replication stream package, which will replicate the specified
+filesystem, and all descendent file systems, up to the named snapshot. When
+received, all properties, snapshots, descendent file systems, and clones are
+preserved.
+.Pp
+If the
+.Fl i
+or
+.Fl I
+flags are used in conjunction with the
+.Fl R
+flag, an incremental replication stream is generated. The current values of
+properties, and current snapshot and file system names are set when the stream
+is received. If the
+.Fl F
+flag is specified when this stream is received, snapshots and file systems that
+do not exist on the sending side are destroyed.
+.It Fl D
+Generate a deduplicated stream. Blocks which would have been sent multiple
+times in the send stream will only be sent once. The receiving system must
+also support this feature to receive a deduplicated stream. This flag can
+be used regardless of the dataset's
+.Sy dedup
+property, but performance will be much better if the filesystem uses a
+dedup-capable checksum (eg.
+.Sy sha256 ) .
+.It Fl p
+Include the dataset's properties in the stream. This flag is implicit when
+.Fl R
+is specified. The receiving system must also support this feature.
+.It Fl n
+Do a dry-run ("No-op") send. Do not generate any actual send data. This is
+useful in conjunction with the
+.Fl v
+or
+.Fl P
+flags to determine what data will be sent.
+.It Fl P
+Print machine-parsable verbose information about the stream package generated.
+.It Fl v
+Print verbose information about the stream package generated.
+This information includes a per-second report of how much data has been sent.
+.El
+.Pp
+The format of the stream is committed. You will be able to receive your streams
+on future versions of
+.Tn ZFS .
+.It Xo
+.Nm
+.Cm receive
+.Op Fl vnFu
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
+.Xc
+.It Xo
+.Nm
+.Cm receive
+.Op Fl vnFu
+.Op Fl d | e
+.Ar filesystem
+.Xc
+.Pp
+Creates a snapshot whose contents are as specified in the stream provided on
+standard input. If a full stream is received, then a new file system is created
+as well. Streams are created using the
+.Qq Nm Cm send
+subcommand, which by default creates a full stream.
+.Qq Nm Cm recv
+can be used as an alias for
+.Qq Nm Cm receive .
+.Pp
+If an incremental stream is received, then the destination file system must
+already exist, and its most recent snapshot must match the incremental stream's
+source. For
+.Sy zvol Ns s,
+the destination device link is destroyed and recreated, which means the
+.Sy zvol
+cannot be accessed during the
+.Sy receive
+operation.
+.Pp
+When a snapshot replication package stream that is generated by using the
+.Qq Nm Cm send Fl R
+command is received, any snapshots that do not exist on the sending location
+are destroyed by using the
+.Qq Nm Cm destroy Fl d
+command.
+.Pp
+The name of the snapshot (and file system, if a full stream is received) that
+this subcommand creates depends on the argument type and the
+.Fl d
+or
+.Fl e
+option.
+.Pp
+If the argument is a snapshot name, the specified
+.Ar snapshot
+is created. If the argument is a file system or volume name, a snapshot with
+the same name as the sent snapshot is created within the specified
+.Ar filesystem
+or
+.Ar volume .
+If the
+.Fl d
+or
+.Fl e
+option is specified, the snapshot name is determined by appending the sent
+snapshot's name to the specified
+.Ar filesystem .
+If the
+.Fl d
+option is specified, all but the pool name of the sent snapshot path is
+appended (for example,
+.Sy b/c@1
+appended from sent snapshot
+.Sy a/b/c@1 ) ,
+and if the
+.Fl e
+option is specified, only the tail of the sent snapshot path is appended (for
+example,
+.Sy c@1
+appended from sent snapshot
+.Sy a/b/c@1 ) .
+In the case of
+.Fl d ,
+any file systems needed to replicate the path of the sent snapshot are created
+within the specified file system.
+.Bl -tag -width indent
+.It Fl d
+Use the full sent snapshot path without the first element (without pool name)
+to determine the name of the new snapshot as described in the paragraph above.
+.It Fl e
+Use only the last element of the sent snapshot path to determine the name of
+the new snapshot as described in the paragraph above.
+.It Fl u
+File system that is associated with the received stream is not mounted.
+.It Fl v
+Print verbose information about the stream and the time required to perform the
+receive operation.
+.It Fl n
+Do not actually receive the stream. This can be useful in conjunction with the
+.Fl v
+option to verify the name the receive operation would use.
+.It Fl F
+Force a rollback of the file system to the most recent snapshot before
+performing the receive operation. If receiving an incremental replication
+stream (for example, one generated by
+.Qq Nm Cm send Fl R Fi iI ) ,
+destroy snapshots and file systems that do not exist on the sending side.
+.El
+.It Xo
+.Nm
+.Cm allow
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Displays permissions that have been delegated on the specified filesystem or
+volume. See the other forms of
+.Qq Nm Cm allow
+for more information.
+.It Xo
+.Nm
+.Cm allow
+.Op Fl ldug
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Ar perm Ns | Ns Ar @setname Ns
+.Oo Ns , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.It Xo
+.Nm
+.Cm allow
+.Op Fl ld
+.Fl e Ns | Ns Cm everyone
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Delegates
+.Tn ZFS
+administration permission for the file systems to non-privileged users.
+.Bl -tag -width indent
+.It Xo
+.Op Fl ug
+.Ar user Ns | Ns Ar group Ns Oo , Ar user Ns | Ns Ar group Oc Ns ...
+.Xc
+Specifies to whom the permissions are delegated. Multiple entities can be
+specified as a comma-separated list. If neither of the
+.Fl ug
+options are specified, then the argument is interpreted preferentially as the
+keyword
+.Cm everyone ,
+then as a user name, and lastly as a group name. To specify
+a user or group named
+.Qq everyone ,
+use the
+.Fl u
+or
+.Fl g
+options. To specify a group with the same name as a user, use the
+.Fl g
+option.
+.It Op Fl e Ns | Ns Cm everyone
+Specifies that the permissions be delegated to
+.Qq everyone .
+.It Xo
+.Ar perm Ns | Ns Ar @setname Ns Oo , Ns Ar perm Ns | Ns Ar @setname Oc Ns ...
+.Xc
+The permissions to delegate. Multiple permissions
+may be specified as a comma-separated list. Permission names are the same as
+.Tn ZFS
+subcommand and property names. See the property list below. Property set names,
+which begin with an at sign
+.Pq Sy @ ,
+may be specified. See the
+.Fl s
+form below for details.
+.It Xo
+.Op Fl ld
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+Specifies where the permissions are delegated. If neither of the
+.Fl ld
+options are specified, or both are, then the permissions are allowed for the
+file system or volume, and all of its descendents. If only the
+.Fl l
+option is used, then is allowed "locally" only for the specified file system.
+If only the
+.Fl d
+option is used, then is allowed only for the descendent file systems.
+.El
+.Pp
+Permissions are generally the ability to use a
+.Tn ZFS
+subcommand or change a
+.Tn ZFS
+property. The following permissions are available:
+.Bl -column -offset 4n "secondarycache" "subcommand"
+.It NAME Ta TYPE Ta NOTES
+.It allow Ta subcommand Ta Must Xo
+also have the permission that is being allowed
+.Xc
+.It clone Ta subcommand Ta Must Xo
+also have the 'create' ability and 'mount' ability in the origin file system
+.Xc
+.It create Ta subcommand Ta Must also have the 'mount' ability
+.It destroy Ta subcommand Ta Must also have the 'mount' ability
+.It diff Ta subcommand Ta Allows lookup of paths within a dataset given an
+object number, and the ability to create snapshots necessary to 'zfs diff'
+.It hold Ta subcommand Ta Allows adding a user hold to a snapshot
+.It mount Ta subcommand Ta Allows mount/umount of Tn ZFS No datasets
+.It promote Ta subcommand Ta Must Xo
+also have the 'mount' and 'promote' ability in the origin file system
+.Xc
+.It receive Ta subcommand Ta Must also have the 'mount' and 'create' ability
+.It release Ta subcommand Ta Allows Xo
+releasing a user hold which might destroy the snapshot
+.Xc
+.It rename Ta subcommand Ta Must Xo
+also have the 'mount' and 'create' ability in the new parent
+.Xc
+.It rollback Ta subcommand Ta Must also have the 'mount' ability
+.It send Ta subcommand
+.It share Ta subcommand Ta Allows Xo
+sharing file systems over the
+.Tn NFS
+protocol
+.Xc
+.It snapshot Ta subcommand Ta Must also have the 'mount' ability
+.It groupquota Ta other Ta Allows accessing any groupquota@... property
+.It groupused Ta other Ta Allows reading any groupused@... property
+.It userprop Ta other Ta Allows changing any user property
+.It userquota Ta other Ta Allows accessing any userquota@... property
+.It userused Ta other Ta Allows reading any userused@... property
+.It aclinherit Ta property
+.It aclmode Ta property
+.It atime Ta property
+.It canmount Ta property
+.It casesensitivity Ta property
+.It checksum Ta property
+.It compression Ta property
+.It copies Ta property
+.It dedup Ta property
+.It devices Ta property
+.It exec Ta property
+.It logbias Ta property
+.It jailed Ta property
+.It mlslabel Ta property
+.It mountpoint Ta property
+.It nbmand Ta property
+.It normalization Ta property
+.It primarycache Ta property
+.It quota Ta property
+.It readonly Ta property
+.It recordsize Ta property
+.It refquota Ta property
+.It refreservation Ta property
+.It reservation Ta property
+.It secondarycache Ta property
+.It setuid Ta property
+.It sharenfs Ta property
+.It sharesmb Ta property
+.It snapdir Ta property
+.It sync Ta property
+.It utf8only Ta property
+.It version Ta property
+.It volblocksize Ta property
+.It volsize Ta property
+.It vscan Ta property
+.It xattr Ta property
+.El
+.It Xo
+.Nm
+.Cm allow
+.Fl c
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Sets "create time" permissions. These permissions are granted (locally) to the
+creator of any newly-created descendent file system.
+.It Xo
+.Nm
+.Cm allow
+.Fl s
+.Ar @setname
+.Ar perm Ns | Ns Ar @setname Ns Op Ns , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ...
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Defines or adds permissions to a permission set. The set can be used by other
+.Qq Nm Cm allow
+commands for the specified file system and its descendents. Sets are evaluated
+dynamically, so changes to a set are immediately reflected. Permission sets
+follow the same naming restrictions as ZFS file systems, but the name must
+begin with an "at sign"
+.Pq Sy @ ,
+and can be no more than 64 characters long.
+.It Xo
+.Nm
+.Cm unallow
+.Op Fl rldug
+.Ar user Ns | Ns Ar group Ns Oo Ns , Ns Ar user Ns | Ns Ar group Oc Ns ...
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.It Xo
+.Nm
+.Cm unallow
+.Op Fl rld
+.Fl e Ns | Ns Cm everyone
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.It Xo
+.Nm
+.Cm unallow
+.Op Fl r
+.Fl c
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Removes permissions that were granted with the
+.Qq Nm Cm allow
+command. No permissions are explicitly denied, so other permissions granted are
+still in effect. For example, if the permission is granted by an ancestor. If
+no permissions are specified, then all permissions for the specified
+.Ar user , group , No or everyone
+are removed. Specifying
+.Cm everyone
+.Po or using the Fl e
+option
+.Pc only removes the permissions that were granted to everyone ,
+not all permissions for every user and group. See the
+.Qq Nm Cm allow
+command for a description of the
+.Fl ldugec
+options.
+.Bl -tag -width indent
+.It Fl r
+Recursively remove the permissions from this file system and all descendents.
+.El
+.It Xo
+.Nm
+.Cm unallow
+.Op Fl r
+.Fl s
+.Ar @setname
+.Oo Ar perm Ns | Ns Ar @setname Ns Op , Ns Ar perm Ns | Ns Ar @setname Ns
+.Ns ... Oc
+.Ar filesystem Ns | Ns Ar volume
+.Xc
+.Pp
+Removes permissions from a permission set. If no permissions are specified,
+then all permissions are removed, thus removing the set entirely.
+.It Xo
+.Nm
+.Cm hold
+.Op Fl r
+.Ar tag snapshot Ns ...
+.Xc
+.Pp
+Adds a single reference, named with the
+.Ar tag
+argument, to the specified snapshot or snapshots. Each snapshot has its own tag
+namespace, and tags must be unique within that space.
+.Pp
+If a hold exists on a snapshot, attempts to destroy that snapshot by using the
+.Qq Nm Cm destroy
+command returns
+.Em EBUSY .
+.Bl -tag -width indent
+.It Fl r
+Specifies that a hold with the given tag is applied recursively to the
+snapshots of all descendent file systems.
+.El
+.It Xo
+.Nm
+.Cm holds
+.Op Fl r
+.Ar snapshot Ns ...
+.Xc
+.Pp
+Lists all existing user references for the given snapshot or snapshots.
+.Bl -tag -width indent
+.It Fl r
+Lists the holds that are set on the named descendent snapshots, in addition to
+listing the holds on the named snapshot.
+.El
+.It Xo
+.Nm
+.Cm release
+.Op Fl r
+.Ar tag snapshot Ns ...
+.Xc
+.Pp
+Removes a single reference, named with the
+.Ar tag
+argument, from the specified snapshot or snapshots. The tag must already exist
+for each snapshot.
+.Bl -tag -width indent
+.It Fl r
+Recursively releases a hold with the given tag on the snapshots of all
+descendent file systems.
+.El
+.It Xo
+.Nm
+.Cm diff
+.Op Fl FHt
+.Ar snapshot
+.Op Ar snapshot Ns | Ns Ar filesystem
+.Xc
+.Pp
+Display the difference between a snapshot of a given filesystem and another
+snapshot of that filesystem from a later time or the current contents of the
+filesystem. The first column is a character indicating the type of change,
+the other columns indicate pathname, new pathname
+.Pq in case of rename ,
+change in link count, and optionally file type and/or change time.
+.Pp
+The types of change are:
+.Bl -column -offset 2n indent
+.It \&- Ta path was removed
+.It \&+ Ta path was added
+.It \&M Ta path was modified
+.It \&R Ta path was renamed
+.El
+.Bl -tag -width indent
+.It Fl F
+Display an indication of the type of file, in a manner similar to the
+.Fl F
+option of
+.Xr ls 1 .
+.Bl -column -offset 2n indent
+.It \&B Ta block device
+.It \&C Ta character device
+.It \&F Ta regular file
+.It \&/ Ta directory
+.It \&@ Ta symbolic link
+.It \&= Ta socket
+.It \&> Ta door (not supported on Fx )
+.It \&| Ta named pipe (not supported on Fx )
+.It \&P Ta event port (not supported on Fx )
+.El
+.It Fl H
+Give more parseable tab-separated output, without header lines and without
+arrows.
+.It Fl t
+Display the path's inode change time as the first column of output.
+.El
+.It Xo
+.Nm
+.Cm jail
+.Ar jailid filesystem
+.Xc
+.Pp
+Attaches the specified
+.Ar filesystem
+to the jail identified by JID
+.Ar jailid .
+From now on this file system tree can be managed from within a jail if the
+.Sy jailed
+property has been set. To use this functionality, the jail needs the
+.Va allow.mount
+and
+.Va allow.mount.zfs
+parameters set to 1 and the
+.Va enforce_statfs
+parameter set to a value lower than 2.
+.Pp
+See
+.Xr jail 8
+for more information on managing jails and configuring the parameters above.
+.It Xo
+.Nm
+.Cm unjail
+.Ar jailid filesystem
+.Xc
+.Pp
+Detaches the specified
+.Ar filesystem
+from the jail identified by JID
+.Ar jailid .
+.El
+.Sh EXIT STATUS
+The following exit values are returned:
+.Bl -tag -offset 2n -width 2n
+.It 0
+Successful completion.
+.It 1
+An error occurred.
+.It 2
+Invalid command line options were specified.
+.El
+.Sh EXAMPLES
+.Bl -tag -width 0n
+.It Sy Example 1 No Creating a Tn ZFS No File System Hierarchy
+.Pp
+The following commands create a file system named
+.Em pool/home
+and a file system named
+.Em pool/home/bob .
+The mount point
+.Pa /home
+is set for the parent file system, and is automatically inherited by the child
+file system.
+.Bd -literal -offset 2n
+.Li # Ic zfs create pool/home
+.Li # Ic zfs set mountpoint=/home pool/home
+.Li # Ic zfs create pool/home/bob
+.Ed
+.It Sy Example 2 No Creating a Tn ZFS No Snapshot
+.Pp
+The following command creates a snapshot named
+.Sy yesterday .
+This snapshot is mounted on demand in the
+.Pa \&.zfs/snapshot
+directory at the root of the
+.Em pool/home/bob
+file system.
+.Bd -literal -offset 2n
+.Li # Ic zfs snapshot pool/home/bob@yesterday
+.Ed
+.It Sy Example 3 No Creating and Destroying Multiple Snapshots
+.Pp
+The following command creates snapshots named
+.Em yesterday
+of
+.Em pool/home
+and all of its descendent file systems. Each snapshot is mounted on demand in
+the
+.Pa \&.zfs/snapshot
+directory at the root of its file system. The second command destroys the newly
+created snapshots.
+.Bd -literal -offset 2n
+.Li # Ic zfs snapshot -r pool/home@yesterday
+.Li # Ic zfs destroy -r pool/home@yesterday
+.Ed
+.It Sy Example 4 No Disabling and Enabling File System Compression
+.Pp
+The following command disables the
+.Sy compression
+property for all file systems under
+.Em pool/home .
+The next command explicitly enables
+.Sy compression
+for
+.Em pool/home/anne .
+.Bd -literal -offset 2n
+.Li # Ic zfs set compression=off pool/home
+.Li # Ic zfs set compression=on pool/home/anne
+.Ed
+.It Sy Example 5 No Listing Tn ZFS No Datasets
+.Pp
+The following command lists all active file systems and volumes in the system.
+Snapshots are displayed if the
+.Sy listsnaps
+property is
+.Cm on .
+The default is
+.Cm off .
+See
+.Xr zpool 8
+for more information on pool properties.
+.Bd -literal -offset 2n
+.Li # Ic zfs list
+ NAME USED AVAIL REFER MOUNTPOINT
+ pool 450K 457G 18K /pool
+ pool/home 315K 457G 21K /home
+ pool/home/anne 18K 457G 18K /home/anne
+ pool/home/bob 276K 457G 276K /home/bob
+.Ed
+.It Sy Example 6 No Setting a Quota on a Tn ZFS No File System
+.Pp
+The following command sets a quota of 50 Gbytes for
+.Em pool/home/bob .
+.Bd -literal -offset 2n
+.Li # Ic zfs set quota=50G pool/home/bob
+.Ed
+.It Sy Example 7 No Listing Tn ZFS No Properties
+.Pp
+The following command lists all properties for
+.Em pool/home/bob .
+.Bd -literal -offset 2n
+.Li # Ic zfs get all pool/home/bob
+NAME PROPERTY VALUE SOURCE
+pool/home/bob type filesystem -
+pool/home/bob creation Tue Jul 21 15:53 2009 -
+pool/home/bob used 21K -
+pool/home/bob available 20.0G -
+pool/home/bob referenced 21K -
+pool/home/bob compressratio 1.00x -
+pool/home/bob mounted yes -
+pool/home/bob quota 20G local
+pool/home/bob reservation none default
+pool/home/bob recordsize 128K default
+pool/home/bob mountpoint /home/bob default
+pool/home/bob sharenfs off default
+pool/home/bob checksum on default
+pool/home/bob compression on local
+pool/home/bob atime on default
+pool/home/bob devices on default
+pool/home/bob exec on default
+pool/home/bob setuid on default
+pool/home/bob readonly off default
+pool/home/bob jailed off default
+pool/home/bob snapdir hidden default
+pool/home/bob aclmode discard default
+pool/home/bob aclinherit restricted default
+pool/home/bob canmount on default
+pool/home/bob xattr on default
+pool/home/bob copies 1 default
+pool/home/bob version 5 -
+pool/home/bob utf8only off -
+pool/home/bob normalization none -
+pool/home/bob casesensitivity sensitive -
+pool/home/bob vscan off default
+pool/home/bob nbmand off default
+pool/home/bob sharesmb off default
+pool/home/bob refquota none default
+pool/home/bob refreservation none default
+pool/home/bob primarycache all default
+pool/home/bob secondarycache all default
+pool/home/bob usedbysnapshots 0 -
+pool/home/bob usedbydataset 21K -
+pool/home/bob usedbychildren 0 -
+pool/home/bob usedbyrefreservation 0 -
+pool/home/bob logbias latency default
+pool/home/bob dedup off default
+pool/home/bob mlslabel -
+pool/home/bob sync standard default
+pool/home/bob refcompressratio 1.00x -
+.Ed
+.Pp
+The following command gets a single property value.
+.Bd -literal -offset 2n
+.Li # Ic zfs get -H -o value compression pool/home/bob
+on
+.Ed
+.Pp
+The following command lists all properties with local settings for
+.Em pool/home/bob .
+.Bd -literal -offset 2n
+.Li # Ic zfs get -s local -o name,property,value all pool/home/bob
+NAME PROPERTY VALUE
+pool/home/bob quota 20G
+pool/home/bob compression on
+.Ed
+.It Sy Example 8 No Rolling Back a Tn ZFS No File System
+.Pp
+The following command reverts the contents of
+.Em pool/home/anne
+to the snapshot named
+.Em yesterday ,
+deleting all intermediate snapshots.
+.Bd -literal -offset 2n
+.Li # Ic zfs rollback -r pool/home/anne@yesterday
+.Ed
+.It Sy Example 9 No Creating a Tn ZFS No Clone
+.Pp
+The following command creates a writable file system whose initial contents are
+the same as
+.Em pool/home/bob@yesterday .
+.Bd -literal -offset 2n
+.Li # Ic zfs clone pool/home/bob@yesterday pool/clone
+.Ed
+.It Sy Example 10 No Promoting a Tn ZFS No Clone
+.Pp
+The following commands illustrate how to test out changes to a file system, and
+then replace the original file system with the changed one, using clones, clone
+promotion, and renaming:
+.Bd -literal -offset 2n
+.Li # Ic zfs create pool/project/production
+.Ed
+.Pp
+Populate
+.Pa /pool/project/production
+with data and continue with the following commands:
+.Bd -literal -offset 2n
+.Li # Ic zfs snapshot pool/project/production@today
+.Li # Ic zfs clone pool/project/production@today pool/project/beta
+.Ed
+.Pp
+Now make changes to
+.Pa /pool/project/beta
+and continue with the following commands:
+.Bd -literal -offset 2n
+.Li # Ic zfs promote pool/project/beta
+.Li # Ic zfs rename pool/project/production pool/project/legacy
+.Li # Ic zfs rename pool/project/beta pool/project/production
+.Ed
+.Pp
+Once the legacy version is no longer needed, it can be destroyed.
+.Bd -literal -offset 2n
+.Li # Ic zfs destroy pool/project/legacy
+.Ed
+.It Sy Example 11 No Inheriting Tn ZFS No Properties
+.Pp
+The following command causes
+.Em pool/home/bob
+and
+.Em pool/home/anne
+to inherit the
+.Sy checksum
+property from their parent.
+.Bd -literal -offset 2n
+.Li # Ic zfs inherit checksum pool/home/bob pool/home/anne
+.Ed
+.It Sy Example 12 No Remotely Replicating Tn ZFS No Data
+.Pp
+The following commands send a full stream and then an incremental stream to a
+remote machine, restoring them into
+.Sy poolB/received/fs@a
+and
+.Sy poolB/received/fs@b ,
+respectively.
+.Sy poolB
+must contain the file system
+.Sy poolB/received ,
+and must not initially contain
+.Sy poolB/received/fs .
+.Bd -literal -offset 2n
+.Li # Ic zfs send pool/fs@a | ssh host zfs receive poolB/received/fs@a
+.Li # Ic zfs send -i a pool/fs@b | ssh host zfs receive poolB/received/fs
+.Ed
+.It Xo
+.Sy Example 13
+Using the
+.Qq zfs receive -d
+Option
+.Xc
+.Pp
+The following command sends a full stream of
+.Sy poolA/fsA/fsB@snap
+to a remote machine, receiving it into
+.Sy poolB/received/fsA/fsB@snap .
+The
+.Sy fsA/fsB@snap
+portion of the received snapshot's name is determined from the name of the sent
+snapshot.
+.Sy poolB
+must contain the file system
+.Sy poolB/received .
+If
+.Sy poolB/received/fsA
+does not exist, it is created as an empty file system.
+.Bd -literal -offset 2n
+.Li # Ic zfs send poolA/fsA/fsB@snap | ssh host zfs receive -d poolB/received
+.Ed
+.It Sy Example 14 No Setting User Properties
+.Pp
+The following example sets the user-defined
+.Sy com.example:department
+property for a dataset.
+.Bd -literal -offset 2n
+.Li # Ic zfs set com.example:department=12345 tank/accounting
+.Ed
+.It Sy Example 15 No Performing a Rolling Snapshot
+.Pp
+The following example shows how to maintain a history of snapshots with a
+consistent naming scheme. To keep a week's worth of snapshots, the user
+destroys the oldest snapshot, renames the remaining snapshots, and then creates
+a new snapshot, as follows:
+.Bd -literal -offset 2n
+.Li # Ic zfs destroy -r pool/users@7daysago
+.Li # Ic zfs rename -r pool/users@6daysago @7daysago
+.Li # Ic zfs rename -r pool/users@5daysago @6daysago
+.Li # Ic zfs rename -r pool/users@4daysago @5daysago
+.Li # Ic zfs rename -r pool/users@3daysago @4daysago
+.Li # Ic zfs rename -r pool/users@2daysago @3daysago
+.Li # Ic zfs rename -r pool/users@yesterday @2daysago
+.Li # Ic zfs rename -r pool/users@today @yesterday
+.Li # Ic zfs snapshot -r pool/users@today
+.Ed
+.It Xo
+.Sy Example 16
+Setting
+.Qq sharenfs
+Property Options on a ZFS File System
+.Xc
+.Pp
+The following command shows how to set
+.Sy sharenfs
+property options to enable root access for a specific network on the
+.Em tank/home
+file system. The contents of the
+.Sy sharenfs
+property are valid
+.Xr exports 5
+options.
+.Bd -literal -offset 2n
+.Li # Ic zfs set sharenfs="maproot=root,network 192.168.0.0/24" tank/home
+.Ed
+.Pp
+Another way to write this command with the same result is:
+.Bd -literal -offset 2n
+.Li # Ic set zfs sharenfs="-maproot=root -network 192.168.0.0/24" tank/home
+.Ed
+.It Xo
+.Sy Example 17
+Delegating
+.Tn ZFS
+Administration Permissions on a
+.Tn ZFS
+Dataset
+.Xc
+.Pp
+The following example shows how to set permissions so that user
+.Em cindys
+can create, destroy, mount, and take snapshots on
+.Em tank/cindys .
+The permissions on
+.Em tank/cindys
+are also displayed.
+.Bd -literal -offset 2n
+.Li # Ic zfs allow cindys create,destroy,mount,snapshot tank/cindys
+.Li # Ic zfs allow tank/cindys
+-------------------------------------------------------------
+Local+Descendent permissions on (tank/cindys)
+ user cindys create,destroy,mount,snapshot
+-------------------------------------------------------------
+.Ed
+.It Sy Example 18 No Delegating Create Time Permissions on a Tn ZFS No Dataset
+.Pp
+The following example shows how to grant anyone in the group
+.Em staff
+to create file systems in
+.Em tank/users .
+This syntax also allows staff members to destroy their own file systems, but
+not destroy anyone else's file system. The permissions on
+.Em tank/users
+are also displayed.
+.Bd -literal -offset 2n
+.Li # Ic zfs allow staff create,mount tank/users
+.Li # Ic zfs allow -c destroy tank/users
+.Li # Ic zfs allow tank/users
+-------------------------------------------------------------
+Create time permissions on (tank/users)
+ create,destroy
+Local+Descendent permissions on (tank/users)
+ group staff create,mount
+-------------------------------------------------------------
+.Ed
+.It Xo
+.Sy Example 19
+Defining and Granting a Permission Set on a
+.Tn ZFS
+Dataset
+.Xc
+.Pp
+The following example shows how to define and grant a permission set on the
+.Em tank/users
+file system. The permissions on
+.Em tank/users
+are also displayed.
+.Bd -literal -offset 2n
+.Li # Ic zfs allow -s @pset create,destroy,snapshot,mount tank/users
+.Li # Ic zfs allow staff @pset tank/users
+.Li # Ic zfs allow tank/users
+-------------------------------------------------------------
+Permission sets on (tank/users)
+ @pset create,destroy,mount,snapshot
+Create time permissions on (tank/users)
+ create,destroy
+Local+Descendent permissions on (tank/users)
+ group staff @pset,create,mount
+-------------------------------------------------------------
+.Ed
+.It Sy Example 20 No Delegating Property Permissions on a Tn ZFS No Dataset
+.Pp
+The following example shows to grant the ability to set quotas and reservations
+on the
+.Sy users/home
+file system. The permissions on
+.Sy users/home
+are also displayed.
+.Bd -literal -offset 2n
+.Li # Ic zfs allow cindys quota,reservation users/home
+.Li # Ic zfs allow cindys
+-------------------------------------------------------------
+Local+Descendent permissions on (users/home)
+ user cindys quota,reservation
+-------------------------------------------------------------
+.Li # Ic su - cindys
+.Li cindys% Ic zfs set quota=10G users/home/marks
+.Li cindys% Ic zfs get quota users/home/marks
+NAME PROPERTY VALUE SOURCE
+users/home/marks quota 10G local
+.Ed
+.It Sy Example 21 No Removing ZFS Delegated Permissions on a Tn ZFS No Dataset
+.Pp
+The following example shows how to remove the snapshot permission from the
+.Em staff
+group on the
+.Em tank/users
+file system. The permissions on
+.Em tank/users
+are also displayed.
+.Bd -literal -offset 2n
+.Li # Ic zfs unallow staff snapshot tank/users
+.Li # Ic zfs allow tank/users
+-------------------------------------------------------------
+Permission sets on (tank/users)
+ @pset create,destroy,mount,snapshot
+Create time permissions on (tank/users)
+ create,destroy
+Local+Descendent permissions on (tank/users)
+ group staff @pset,create,mount
+-------------------------------------------------------------
+.Ed
+.It Sy Example 22 Showing the differences between a snapshot and a ZFS Dataset
+.Pp
+The following example shows how to see what has changed between a prior
+snapshot of a ZFS Dataset and its current state. The
+.Fl F
+option is used to indicate type information for the files affected.
+.Bd -literal -offset 2n
+.Li # Ic zfs diff tank/test@before tank/test
+M / /tank/test/
+M F /tank/test/linked (+1)
+R F /tank/test/oldname -> /tank/test/newname
+- F /tank/test/deleted
++ F /tank/test/created
+M F /tank/test/modified
+.Ed
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr fsync 2 ,
+.Xr exports 5 ,
+.Xr fstab 5 ,
+.Xr rc.conf 5 ,
+.Xr jail 8 ,
+.Xr mount 8 ,
+.Xr umount 8 ,
+.Xr zpool 8
+.Sh AUTHORS
+This manual page is a
+.Xr mdoc 7
+reimplementation of the
+.Tn OpenSolaris
+manual page
+.Em zfs(1M) ,
+modified and customized for
+.Fx
+and licensed under the
+Common Development and Distribution License
+.Pq Tn CDDL .
+.Pp
+The
+.Xr mdoc 7
+implementation of this manual page was initially written by
+.An Martin Matuska Aq mm@FreeBSD.org .
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
new file mode 100644
index 0000000..62cd9d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
@@ -0,0 +1,490 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ */
+
+#include <libintl.h>
+#include <libuutil.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <libzfs.h>
+
+#include "zfs_util.h"
+#include "zfs_iter.h"
+
+/*
+ * This is a private interface used to gather up all the datasets specified on
+ * the command line so that we can iterate over them in order.
+ *
+ * First, we iterate over all filesystems, gathering them together into an
+ * AVL tree. We report errors for any explicitly specified datasets
+ * that we couldn't open.
+ *
+ * When finished, we have an AVL tree of ZFS handles. We go through and execute
+ * the provided callback for each one, passing whatever data the user supplied.
+ */
+
+typedef struct zfs_node {
+ zfs_handle_t *zn_handle;
+ uu_avl_node_t zn_avlnode;
+} zfs_node_t;
+
+typedef struct callback_data {
+ uu_avl_t *cb_avl;
+ int cb_flags;
+ zfs_type_t cb_types;
+ zfs_sort_column_t *cb_sortcol;
+ zprop_list_t **cb_proplist;
+ int cb_depth_limit;
+ int cb_depth;
+ uint8_t cb_props_table[ZFS_NUM_PROPS];
+} callback_data_t;
+
+uu_avl_pool_t *avl_pool;
+
+/*
+ * Include snaps if they were requested or if this a zfs list where types
+ * were not specified and the "listsnapshots" property is set on this pool.
+ */
+static int
+zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
+{
+ zpool_handle_t *zph;
+
+ if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
+ return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
+
+ zph = zfs_get_pool_handle(zhp);
+ return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
+}
+
+/*
+ * Called for each dataset. If the object is of an appropriate type,
+ * add it to the avl tree and recurse over any children as necessary.
+ */
+static int
+zfs_callback(zfs_handle_t *zhp, void *data)
+{
+ callback_data_t *cb = data;
+ int dontclose = 0;
+ int include_snaps = zfs_include_snapshots(zhp, cb);
+
+ if ((zfs_get_type(zhp) & cb->cb_types) ||
+ ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
+ uu_avl_index_t idx;
+ zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
+
+ node->zn_handle = zhp;
+ uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
+ if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
+ &idx) == NULL) {
+ if (cb->cb_proplist) {
+ if ((*cb->cb_proplist) &&
+ !(*cb->cb_proplist)->pl_all)
+ zfs_prune_proplist(zhp,
+ cb->cb_props_table);
+
+ if (zfs_expand_proplist(zhp, cb->cb_proplist,
+ (cb->cb_flags & ZFS_ITER_RECVD_PROPS))
+ != 0) {
+ free(node);
+ return (-1);
+ }
+ }
+ uu_avl_insert(cb->cb_avl, node, idx);
+ dontclose = 1;
+ } else {
+ free(node);
+ }
+ }
+
+ /*
+ * Recurse if necessary.
+ */
+ if (cb->cb_flags & ZFS_ITER_RECURSE &&
+ ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
+ cb->cb_depth < cb->cb_depth_limit)) {
+ cb->cb_depth++;
+ if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
+ (void) zfs_iter_filesystems(zhp, zfs_callback, data);
+ if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps) {
+ (void) zfs_iter_snapshots(zhp,
+ (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
+ data);
+ }
+ cb->cb_depth--;
+ }
+
+ if (!dontclose)
+ zfs_close(zhp);
+
+ return (0);
+}
+
+int
+zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
+ boolean_t reverse)
+{
+ zfs_sort_column_t *col;
+ zfs_prop_t prop;
+
+ if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
+ !zfs_prop_user(name))
+ return (-1);
+
+ col = safe_malloc(sizeof (zfs_sort_column_t));
+
+ col->sc_prop = prop;
+ col->sc_reverse = reverse;
+ if (prop == ZPROP_INVAL) {
+ col->sc_user_prop = safe_malloc(strlen(name) + 1);
+ (void) strcpy(col->sc_user_prop, name);
+ }
+
+ if (*sc == NULL) {
+ col->sc_last = col;
+ *sc = col;
+ } else {
+ (*sc)->sc_last->sc_next = col;
+ (*sc)->sc_last = col;
+ }
+
+ return (0);
+}
+
+void
+zfs_free_sort_columns(zfs_sort_column_t *sc)
+{
+ zfs_sort_column_t *col;
+
+ while (sc != NULL) {
+ col = sc->sc_next;
+ free(sc->sc_user_prop);
+ free(sc);
+ sc = col;
+ }
+}
+
+boolean_t
+zfs_sort_only_by_name(const zfs_sort_column_t *sc)
+{
+
+ return (sc != NULL && sc->sc_next == NULL &&
+ sc->sc_prop == ZFS_PROP_NAME);
+}
+
+/* ARGSUSED */
+static int
+zfs_compare(const void *larg, const void *rarg, void *unused)
+{
+ zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
+ zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
+ const char *lname = zfs_get_name(l);
+ const char *rname = zfs_get_name(r);
+ char *lat, *rat;
+ uint64_t lcreate, rcreate;
+ int ret;
+
+ lat = (char *)strchr(lname, '@');
+ rat = (char *)strchr(rname, '@');
+
+ if (lat != NULL)
+ *lat = '\0';
+ if (rat != NULL)
+ *rat = '\0';
+
+ ret = strcmp(lname, rname);
+ if (ret == 0) {
+ /*
+ * If we're comparing a dataset to one of its snapshots, we
+ * always make the full dataset first.
+ */
+ if (lat == NULL) {
+ ret = -1;
+ } else if (rat == NULL) {
+ ret = 1;
+ } else {
+ /*
+ * If we have two snapshots from the same dataset, then
+ * we want to sort them according to creation time. We
+ * use the hidden CREATETXG property to get an absolute
+ * ordering of snapshots.
+ */
+ lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
+ rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
+
+ /*
+ * Both lcreate and rcreate being 0 means we don't have
+ * properties and we should compare full name.
+ */
+ if (lcreate == 0 && rcreate == 0)
+ ret = strcmp(lat + 1, rat + 1);
+ else if (lcreate < rcreate)
+ ret = -1;
+ else if (lcreate > rcreate)
+ ret = 1;
+ }
+ }
+
+ if (lat != NULL)
+ *lat = '@';
+ if (rat != NULL)
+ *rat = '@';
+
+ return (ret);
+}
+
+/*
+ * Sort datasets by specified columns.
+ *
+ * o Numeric types sort in ascending order.
+ * o String types sort in alphabetical order.
+ * o Types inappropriate for a row sort that row to the literal
+ * bottom, regardless of the specified ordering.
+ *
+ * If no sort columns are specified, or two datasets compare equally
+ * across all specified columns, they are sorted alphabetically by name
+ * with snapshots grouped under their parents.
+ */
+static int
+zfs_sort(const void *larg, const void *rarg, void *data)
+{
+ zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
+ zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
+ zfs_sort_column_t *sc = (zfs_sort_column_t *)data;
+ zfs_sort_column_t *psc;
+
+ for (psc = sc; psc != NULL; psc = psc->sc_next) {
+ char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
+ char *lstr, *rstr;
+ uint64_t lnum, rnum;
+ boolean_t lvalid, rvalid;
+ int ret = 0;
+
+ /*
+ * We group the checks below the generic code. If 'lstr' and
+ * 'rstr' are non-NULL, then we do a string based comparison.
+ * Otherwise, we compare 'lnum' and 'rnum'.
+ */
+ lstr = rstr = NULL;
+ if (psc->sc_prop == ZPROP_INVAL) {
+ nvlist_t *luser, *ruser;
+ nvlist_t *lval, *rval;
+
+ luser = zfs_get_user_props(l);
+ ruser = zfs_get_user_props(r);
+
+ lvalid = (nvlist_lookup_nvlist(luser,
+ psc->sc_user_prop, &lval) == 0);
+ rvalid = (nvlist_lookup_nvlist(ruser,
+ psc->sc_user_prop, &rval) == 0);
+
+ if (lvalid)
+ verify(nvlist_lookup_string(lval,
+ ZPROP_VALUE, &lstr) == 0);
+ if (rvalid)
+ verify(nvlist_lookup_string(rval,
+ ZPROP_VALUE, &rstr) == 0);
+ } else if (psc->sc_prop == ZFS_PROP_NAME) {
+ lvalid = rvalid = B_TRUE;
+
+ (void) strlcpy(lbuf, zfs_get_name(l), sizeof(lbuf));
+ (void) strlcpy(rbuf, zfs_get_name(r), sizeof(rbuf));
+
+ lstr = lbuf;
+ rstr = rbuf;
+ } else if (zfs_prop_is_string(psc->sc_prop)) {
+ lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
+ sizeof (lbuf), NULL, NULL, 0, B_TRUE) == 0);
+ rvalid = (zfs_prop_get(r, psc->sc_prop, rbuf,
+ sizeof (rbuf), NULL, NULL, 0, B_TRUE) == 0);
+
+ lstr = lbuf;
+ rstr = rbuf;
+ } else {
+ lvalid = zfs_prop_valid_for_type(psc->sc_prop,
+ zfs_get_type(l));
+ rvalid = zfs_prop_valid_for_type(psc->sc_prop,
+ zfs_get_type(r));
+
+ if (lvalid)
+ (void) zfs_prop_get_numeric(l, psc->sc_prop,
+ &lnum, NULL, NULL, 0);
+ if (rvalid)
+ (void) zfs_prop_get_numeric(r, psc->sc_prop,
+ &rnum, NULL, NULL, 0);
+ }
+
+ if (!lvalid && !rvalid)
+ continue;
+ else if (!lvalid)
+ return (1);
+ else if (!rvalid)
+ return (-1);
+
+ if (lstr)
+ ret = strcmp(lstr, rstr);
+ else if (lnum < rnum)
+ ret = -1;
+ else if (lnum > rnum)
+ ret = 1;
+
+ if (ret != 0) {
+ if (psc->sc_reverse == B_TRUE)
+ ret = (ret < 0) ? 1 : -1;
+ return (ret);
+ }
+ }
+
+ return (zfs_compare(larg, rarg, NULL));
+}
+
+int
+zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
+ zfs_sort_column_t *sortcol, zprop_list_t **proplist, int limit,
+ zfs_iter_f callback, void *data)
+{
+ callback_data_t cb = {0};
+ int ret = 0;
+ zfs_node_t *node;
+ uu_avl_walk_t *walk;
+
+ avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
+ offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
+
+ if (avl_pool == NULL)
+ nomem();
+
+ cb.cb_sortcol = sortcol;
+ cb.cb_flags = flags;
+ cb.cb_proplist = proplist;
+ cb.cb_types = types;
+ cb.cb_depth_limit = limit;
+ /*
+ * If cb_proplist is provided then in the zfs_handles created we
+ * retain only those properties listed in cb_proplist and sortcol.
+ * The rest are pruned. So, the caller should make sure that no other
+ * properties other than those listed in cb_proplist/sortcol are
+ * accessed.
+ *
+ * If cb_proplist is NULL then we retain all the properties. We
+ * always retain the zoned property, which some other properties
+ * need (userquota & friends), and the createtxg property, which
+ * we need to sort snapshots.
+ */
+ if (cb.cb_proplist && *cb.cb_proplist) {
+ zprop_list_t *p = *cb.cb_proplist;
+
+ while (p) {
+ if (p->pl_prop >= ZFS_PROP_TYPE &&
+ p->pl_prop < ZFS_NUM_PROPS) {
+ cb.cb_props_table[p->pl_prop] = B_TRUE;
+ }
+ p = p->pl_next;
+ }
+
+ while (sortcol) {
+ if (sortcol->sc_prop >= ZFS_PROP_TYPE &&
+ sortcol->sc_prop < ZFS_NUM_PROPS) {
+ cb.cb_props_table[sortcol->sc_prop] = B_TRUE;
+ }
+ sortcol = sortcol->sc_next;
+ }
+
+ cb.cb_props_table[ZFS_PROP_ZONED] = B_TRUE;
+ cb.cb_props_table[ZFS_PROP_CREATETXG] = B_TRUE;
+ } else {
+ (void) memset(cb.cb_props_table, B_TRUE,
+ sizeof (cb.cb_props_table));
+ }
+
+ if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
+ nomem();
+
+ if (argc == 0) {
+ /*
+ * If given no arguments, iterate over all datasets.
+ */
+ cb.cb_flags |= ZFS_ITER_RECURSE;
+ ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
+ } else {
+ int i;
+ zfs_handle_t *zhp;
+ zfs_type_t argtype;
+
+ /*
+ * If we're recursive, then we always allow filesystems as
+ * arguments. If we also are interested in snapshots, then we
+ * can take volumes as well.
+ */
+ argtype = types;
+ if (flags & ZFS_ITER_RECURSE) {
+ argtype |= ZFS_TYPE_FILESYSTEM;
+ if (types & ZFS_TYPE_SNAPSHOT)
+ argtype |= ZFS_TYPE_VOLUME;
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
+ zhp = zfs_path_to_zhandle(g_zfs, argv[i],
+ argtype);
+ } else {
+ zhp = zfs_open(g_zfs, argv[i], argtype);
+ }
+ if (zhp != NULL)
+ ret |= zfs_callback(zhp, &cb);
+ else
+ ret = 1;
+ }
+ }
+
+ /*
+ * At this point we've got our AVL tree full of zfs handles, so iterate
+ * over each one and execute the real user callback.
+ */
+ for (node = uu_avl_first(cb.cb_avl); node != NULL;
+ node = uu_avl_next(cb.cb_avl, node))
+ ret |= callback(node->zn_handle, data);
+
+ /*
+ * Finally, clean up the AVL tree.
+ */
+ if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
+ nomem();
+
+ while ((node = uu_avl_walk_next(walk)) != NULL) {
+ uu_avl_remove(cb.cb_avl, node);
+ zfs_close(node->zn_handle);
+ free(node);
+ }
+
+ uu_avl_walk_end(walk);
+ uu_avl_destroy(cb.cb_avl);
+ uu_avl_pool_destroy(avl_pool);
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
new file mode 100644
index 0000000..a287374
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef ZFS_ITER_H
+#define ZFS_ITER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct zfs_sort_column {
+ struct zfs_sort_column *sc_next;
+ struct zfs_sort_column *sc_last;
+ zfs_prop_t sc_prop;
+ char *sc_user_prop;
+ boolean_t sc_reverse;
+} zfs_sort_column_t;
+
+#define ZFS_ITER_RECURSE (1 << 0)
+#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
+#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
+#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
+#define ZFS_ITER_RECVD_PROPS (1 << 4)
+#define ZFS_ITER_SIMPLE (1 << 5)
+
+int zfs_for_each(int, char **, int options, zfs_type_t,
+ zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
+int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
+void zfs_free_sort_columns(zfs_sort_column_t *);
+boolean_t zfs_sort_only_by_name(const zfs_sort_column_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZFS_ITER_H */
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
new file mode 100644
index 0000000..611740c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
@@ -0,0 +1,6758 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <libuutil.h>
+#include <libnvpair.h>
+#include <locale.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <zone.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <sys/list.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/fs/zfs.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <libzfs.h>
+#include <libzfs_core.h>
+#include <zfs_prop.h>
+#include <zfs_deleg.h>
+#include <libuutil.h>
+#ifdef sun
+#include <aclutils.h>
+#include <directory.h>
+#endif
+
+#include "zfs_iter.h"
+#include "zfs_util.h"
+#include "zfs_comutil.h"
+
+libzfs_handle_t *g_zfs;
+
+static FILE *mnttab_file;
+static char history_str[HIS_MAX_RECORD_LEN];
+static boolean_t log_history = B_TRUE;
+
+static int zfs_do_clone(int argc, char **argv);
+static int zfs_do_create(int argc, char **argv);
+static int zfs_do_destroy(int argc, char **argv);
+static int zfs_do_get(int argc, char **argv);
+static int zfs_do_inherit(int argc, char **argv);
+static int zfs_do_list(int argc, char **argv);
+static int zfs_do_mount(int argc, char **argv);
+static int zfs_do_rename(int argc, char **argv);
+static int zfs_do_rollback(int argc, char **argv);
+static int zfs_do_set(int argc, char **argv);
+static int zfs_do_upgrade(int argc, char **argv);
+static int zfs_do_snapshot(int argc, char **argv);
+static int zfs_do_unmount(int argc, char **argv);
+static int zfs_do_share(int argc, char **argv);
+static int zfs_do_unshare(int argc, char **argv);
+static int zfs_do_send(int argc, char **argv);
+static int zfs_do_receive(int argc, char **argv);
+static int zfs_do_promote(int argc, char **argv);
+static int zfs_do_userspace(int argc, char **argv);
+static int zfs_do_allow(int argc, char **argv);
+static int zfs_do_unallow(int argc, char **argv);
+static int zfs_do_hold(int argc, char **argv);
+static int zfs_do_holds(int argc, char **argv);
+static int zfs_do_release(int argc, char **argv);
+static int zfs_do_diff(int argc, char **argv);
+static int zfs_do_jail(int argc, char **argv);
+static int zfs_do_unjail(int argc, char **argv);
+
+/*
+ * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
+ */
+
+#ifdef DEBUG
+const char *
+_umem_debug_init(void)
+{
+ return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+ return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
+#endif
+
+typedef enum {
+ HELP_CLONE,
+ HELP_CREATE,
+ HELP_DESTROY,
+ HELP_GET,
+ HELP_INHERIT,
+ HELP_UPGRADE,
+ HELP_JAIL,
+ HELP_UNJAIL,
+ HELP_LIST,
+ HELP_MOUNT,
+ HELP_PROMOTE,
+ HELP_RECEIVE,
+ HELP_RENAME,
+ HELP_ROLLBACK,
+ HELP_SEND,
+ HELP_SET,
+ HELP_SHARE,
+ HELP_SNAPSHOT,
+ HELP_UNMOUNT,
+ HELP_UNSHARE,
+ HELP_ALLOW,
+ HELP_UNALLOW,
+ HELP_USERSPACE,
+ HELP_GROUPSPACE,
+ HELP_HOLD,
+ HELP_HOLDS,
+ HELP_RELEASE,
+ HELP_DIFF,
+} zfs_help_t;
+
+typedef struct zfs_command {
+ const char *name;
+ int (*func)(int argc, char **argv);
+ zfs_help_t usage;
+} zfs_command_t;
+
+/*
+ * Master command table. Each ZFS command has a name, associated function, and
+ * usage message. The usage messages need to be internationalized, so we have
+ * to have a function to return the usage message based on a command index.
+ *
+ * These commands are organized according to how they are displayed in the usage
+ * message. An empty command (one with a NULL name) indicates an empty line in
+ * the generic usage message.
+ */
+static zfs_command_t command_table[] = {
+ { "create", zfs_do_create, HELP_CREATE },
+ { "destroy", zfs_do_destroy, HELP_DESTROY },
+ { NULL },
+ { "snapshot", zfs_do_snapshot, HELP_SNAPSHOT },
+ { "rollback", zfs_do_rollback, HELP_ROLLBACK },
+ { "clone", zfs_do_clone, HELP_CLONE },
+ { "promote", zfs_do_promote, HELP_PROMOTE },
+ { "rename", zfs_do_rename, HELP_RENAME },
+ { NULL },
+ { "list", zfs_do_list, HELP_LIST },
+ { NULL },
+ { "set", zfs_do_set, HELP_SET },
+ { "get", zfs_do_get, HELP_GET },
+ { "inherit", zfs_do_inherit, HELP_INHERIT },
+ { "upgrade", zfs_do_upgrade, HELP_UPGRADE },
+ { "userspace", zfs_do_userspace, HELP_USERSPACE },
+ { "groupspace", zfs_do_userspace, HELP_GROUPSPACE },
+ { NULL },
+ { "mount", zfs_do_mount, HELP_MOUNT },
+ { "unmount", zfs_do_unmount, HELP_UNMOUNT },
+ { "share", zfs_do_share, HELP_SHARE },
+ { "unshare", zfs_do_unshare, HELP_UNSHARE },
+ { NULL },
+ { "send", zfs_do_send, HELP_SEND },
+ { "receive", zfs_do_receive, HELP_RECEIVE },
+ { NULL },
+ { "allow", zfs_do_allow, HELP_ALLOW },
+ { NULL },
+ { "unallow", zfs_do_unallow, HELP_UNALLOW },
+ { NULL },
+ { "hold", zfs_do_hold, HELP_HOLD },
+ { "holds", zfs_do_holds, HELP_HOLDS },
+ { "release", zfs_do_release, HELP_RELEASE },
+ { "diff", zfs_do_diff, HELP_DIFF },
+ { NULL },
+ { "jail", zfs_do_jail, HELP_JAIL },
+ { "unjail", zfs_do_unjail, HELP_UNJAIL },
+};
+
+#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
+
+zfs_command_t *current_command;
+
+static const char *
+get_usage(zfs_help_t idx)
+{
+ switch (idx) {
+ case HELP_CLONE:
+ return (gettext("\tclone [-p] [-o property=value] ... "
+ "<snapshot> <filesystem|volume>\n"));
+ case HELP_CREATE:
+ return (gettext("\tcreate [-pu] [-o property=value] ... "
+ "<filesystem>\n"
+ "\tcreate [-ps] [-b blocksize] [-o property=value] ... "
+ "-V <size> <volume>\n"));
+ case HELP_DESTROY:
+ return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n"
+ "\tdestroy [-dnpRrv] "
+ "<snapshot>[%<snapname>][,...]\n"));
+ case HELP_GET:
+ return (gettext("\tget [-rHp] [-d max] "
+ "[-o \"all\" | field[,...]] [-t type[,...]] "
+ "[-s source[,...]]\n"
+ "\t <\"all\" | property[,...]> "
+ "[filesystem|volume|snapshot] ...\n"));
+ case HELP_INHERIT:
+ return (gettext("\tinherit [-rS] <property> "
+ "<filesystem|volume|snapshot> ...\n"));
+ case HELP_UPGRADE:
+ return (gettext("\tupgrade [-v]\n"
+ "\tupgrade [-r] [-V version] <-a | filesystem ...>\n"));
+ case HELP_JAIL:
+ return (gettext("\tjail <jailid|jailname> <filesystem>\n"));
+ case HELP_UNJAIL:
+ return (gettext("\tunjail <jailid|jailname> <filesystem>\n"));
+ case HELP_LIST:
+ return (gettext("\tlist [-rH][-d max] "
+ "[-o property[,...]] [-t type[,...]] [-s property] ...\n"
+ "\t [-S property] ... "
+ "[filesystem|volume|snapshot] ...\n"));
+ case HELP_MOUNT:
+ return (gettext("\tmount\n"
+ "\tmount [-vO] [-o opts] <-a | filesystem>\n"));
+ case HELP_PROMOTE:
+ return (gettext("\tpromote <clone-filesystem>\n"));
+ case HELP_RECEIVE:
+ return (gettext("\treceive [-vnFu] <filesystem|volume|"
+ "snapshot>\n"
+ "\treceive [-vnFu] [-d | -e] <filesystem>\n"));
+ case HELP_RENAME:
+ return (gettext("\trename [-f] <filesystem|volume|snapshot> "
+ "<filesystem|volume|snapshot>\n"
+ "\trename [-f] -p <filesystem|volume> "
+ "<filesystem|volume>\n"
+ "\trename -r <snapshot> <snapshot>\n"
+ "\trename -u [-p] <filesystem> <filesystem>"));
+ case HELP_ROLLBACK:
+ return (gettext("\trollback [-rRf] <snapshot>\n"));
+ case HELP_SEND:
+ return (gettext("\tsend [-DnPpRv] "
+ "[-i snapshot | -I snapshot] <snapshot>\n"));
+ case HELP_SET:
+ return (gettext("\tset <property=value> "
+ "<filesystem|volume|snapshot> ...\n"));
+ case HELP_SHARE:
+ return (gettext("\tshare <-a | filesystem>\n"));
+ case HELP_SNAPSHOT:
+ return (gettext("\tsnapshot [-r] [-o property=value] ... "
+ "<filesystem@snapname|volume@snapname> ...\n"));
+ case HELP_UNMOUNT:
+ return (gettext("\tunmount [-f] "
+ "<-a | filesystem|mountpoint>\n"));
+ case HELP_UNSHARE:
+ return (gettext("\tunshare "
+ "<-a | filesystem|mountpoint>\n"));
+ case HELP_ALLOW:
+ return (gettext("\tallow <filesystem|volume>\n"
+ "\tallow [-ldug] "
+ "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
+ "\t <filesystem|volume>\n"
+ "\tallow [-ld] -e <perm|@setname>[,...] "
+ "<filesystem|volume>\n"
+ "\tallow -c <perm|@setname>[,...] <filesystem|volume>\n"
+ "\tallow -s @setname <perm|@setname>[,...] "
+ "<filesystem|volume>\n"));
+ case HELP_UNALLOW:
+ return (gettext("\tunallow [-rldug] "
+ "<\"everyone\"|user|group>[,...]\n"
+ "\t [<perm|@setname>[,...]] <filesystem|volume>\n"
+ "\tunallow [-rld] -e [<perm|@setname>[,...]] "
+ "<filesystem|volume>\n"
+ "\tunallow [-r] -c [<perm|@setname>[,...]] "
+ "<filesystem|volume>\n"
+ "\tunallow [-r] -s @setname [<perm|@setname>[,...]] "
+ "<filesystem|volume>\n"));
+ case HELP_USERSPACE:
+ return (gettext("\tuserspace [-Hinp] [-o field[,...]] "
+ "[-s field] ...\n\t[-S field] ... "
+ "[-t type[,...]] <filesystem|snapshot>\n"));
+ case HELP_GROUPSPACE:
+ return (gettext("\tgroupspace [-Hinp] [-o field[,...]] "
+ "[-s field] ...\n\t[-S field] ... "
+ "[-t type[,...]] <filesystem|snapshot>\n"));
+ case HELP_HOLD:
+ return (gettext("\thold [-r] <tag> <snapshot> ...\n"));
+ case HELP_HOLDS:
+ return (gettext("\tholds [-r] <snapshot> ...\n"));
+ case HELP_RELEASE:
+ return (gettext("\trelease [-r] <tag> <snapshot> ...\n"));
+ case HELP_DIFF:
+ return (gettext("\tdiff [-FHt] <snapshot> "
+ "[snapshot|filesystem]\n"));
+ }
+
+ abort();
+ /* NOTREACHED */
+}
+
+void
+nomem(void)
+{
+ (void) fprintf(stderr, gettext("internal error: out of memory\n"));
+ exit(1);
+}
+
+/*
+ * Utility function to guarantee malloc() success.
+ */
+
+void *
+safe_malloc(size_t size)
+{
+ void *data;
+
+ if ((data = calloc(1, size)) == NULL)
+ nomem();
+
+ return (data);
+}
+
+static char *
+safe_strdup(char *str)
+{
+ char *dupstr = strdup(str);
+
+ if (dupstr == NULL)
+ nomem();
+
+ return (dupstr);
+}
+
+/*
+ * Callback routine that will print out information for each of
+ * the properties.
+ */
+static int
+usage_prop_cb(int prop, void *cb)
+{
+ FILE *fp = cb;
+
+ (void) fprintf(fp, "\t%-15s ", zfs_prop_to_name(prop));
+
+ if (zfs_prop_readonly(prop))
+ (void) fprintf(fp, " NO ");
+ else
+ (void) fprintf(fp, "YES ");
+
+ if (zfs_prop_inheritable(prop))
+ (void) fprintf(fp, " YES ");
+ else
+ (void) fprintf(fp, " NO ");
+
+ if (zfs_prop_values(prop) == NULL)
+ (void) fprintf(fp, "-\n");
+ else
+ (void) fprintf(fp, "%s\n", zfs_prop_values(prop));
+
+ return (ZPROP_CONT);
+}
+
+/*
+ * Display usage message. If we're inside a command, display only the usage for
+ * that command. Otherwise, iterate over the entire command table and display
+ * a complete usage message.
+ */
+static void
+usage(boolean_t requested)
+{
+ int i;
+ boolean_t show_properties = B_FALSE;
+ FILE *fp = requested ? stdout : stderr;
+
+ if (current_command == NULL) {
+
+ (void) fprintf(fp, gettext("usage: zfs command args ...\n"));
+ (void) fprintf(fp,
+ gettext("where 'command' is one of the following:\n\n"));
+
+ for (i = 0; i < NCOMMAND; i++) {
+ if (command_table[i].name == NULL)
+ (void) fprintf(fp, "\n");
+ else
+ (void) fprintf(fp, "%s",
+ get_usage(command_table[i].usage));
+ }
+
+ (void) fprintf(fp, gettext("\nEach dataset is of the form: "
+ "pool/[dataset/]*dataset[@name]\n"));
+ } else {
+ (void) fprintf(fp, gettext("usage:\n"));
+ (void) fprintf(fp, "%s", get_usage(current_command->usage));
+ }
+
+ if (current_command != NULL &&
+ (strcmp(current_command->name, "set") == 0 ||
+ strcmp(current_command->name, "get") == 0 ||
+ strcmp(current_command->name, "inherit") == 0 ||
+ strcmp(current_command->name, "list") == 0))
+ show_properties = B_TRUE;
+
+ if (show_properties) {
+ (void) fprintf(fp,
+ gettext("\nThe following properties are supported:\n"));
+
+ (void) fprintf(fp, "\n\t%-14s %s %s %s\n\n",
+ "PROPERTY", "EDIT", "INHERIT", "VALUES");
+
+ /* Iterate over all properties */
+ (void) zprop_iter(usage_prop_cb, fp, B_FALSE, B_TRUE,
+ ZFS_TYPE_DATASET);
+
+ (void) fprintf(fp, "\t%-15s ", "userused@...");
+ (void) fprintf(fp, " NO NO <size>\n");
+ (void) fprintf(fp, "\t%-15s ", "groupused@...");
+ (void) fprintf(fp, " NO NO <size>\n");
+ (void) fprintf(fp, "\t%-15s ", "userquota@...");
+ (void) fprintf(fp, "YES NO <size> | none\n");
+ (void) fprintf(fp, "\t%-15s ", "groupquota@...");
+ (void) fprintf(fp, "YES NO <size> | none\n");
+ (void) fprintf(fp, "\t%-15s ", "written@<snap>");
+ (void) fprintf(fp, " NO NO <size>\n");
+
+ (void) fprintf(fp, gettext("\nSizes are specified in bytes "
+ "with standard units such as K, M, G, etc.\n"));
+ (void) fprintf(fp, gettext("\nUser-defined properties can "
+ "be specified by using a name containing a colon (:).\n"));
+ (void) fprintf(fp, gettext("\nThe {user|group}{used|quota}@ "
+ "properties must be appended with\n"
+ "a user or group specifier of one of these forms:\n"
+ " POSIX name (eg: \"matt\")\n"
+ " POSIX id (eg: \"126829\")\n"
+ " SMB name@domain (eg: \"matt@sun\")\n"
+ " SMB SID (eg: \"S-1-234-567-89\")\n"));
+ } else {
+ (void) fprintf(fp,
+ gettext("\nFor the property list, run: %s\n"),
+ "zfs set|get");
+ (void) fprintf(fp,
+ gettext("\nFor the delegated permission list, run: %s\n"),
+ "zfs allow|unallow");
+ }
+
+ /*
+ * See comments at end of main().
+ */
+ if (getenv("ZFS_ABORT") != NULL) {
+ (void) printf("dumping core by request\n");
+ abort();
+ }
+
+ exit(requested ? 0 : 2);
+}
+
+static int
+parseprop(nvlist_t *props)
+{
+ char *propname = optarg;
+ char *propval, *strval;
+
+ if ((propval = strchr(propname, '=')) == NULL) {
+ (void) fprintf(stderr, gettext("missing "
+ "'=' for -o option\n"));
+ return (-1);
+ }
+ *propval = '\0';
+ propval++;
+ if (nvlist_lookup_string(props, propname, &strval) == 0) {
+ (void) fprintf(stderr, gettext("property '%s' "
+ "specified multiple times\n"), propname);
+ return (-1);
+ }
+ if (nvlist_add_string(props, propname, propval) != 0)
+ nomem();
+ return (0);
+}
+
+static int
+parse_depth(char *opt, int *flags)
+{
+ char *tmp;
+ int depth;
+
+ depth = (int)strtol(opt, &tmp, 0);
+ if (*tmp) {
+ (void) fprintf(stderr,
+ gettext("%s is not an integer\n"), optarg);
+ usage(B_FALSE);
+ }
+ if (depth < 0) {
+ (void) fprintf(stderr,
+ gettext("Depth can not be negative.\n"));
+ usage(B_FALSE);
+ }
+ *flags |= (ZFS_ITER_DEPTH_LIMIT|ZFS_ITER_RECURSE);
+ return (depth);
+}
+
+#define PROGRESS_DELAY 2 /* seconds */
+
+static char *pt_reverse = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
+static time_t pt_begin;
+static char *pt_header = NULL;
+static boolean_t pt_shown;
+
+static void
+start_progress_timer(void)
+{
+ pt_begin = time(NULL) + PROGRESS_DELAY;
+ pt_shown = B_FALSE;
+}
+
+static void
+set_progress_header(char *header)
+{
+ assert(pt_header == NULL);
+ pt_header = safe_strdup(header);
+ if (pt_shown) {
+ (void) printf("%s: ", header);
+ (void) fflush(stdout);
+ }
+}
+
+static void
+update_progress(char *update)
+{
+ if (!pt_shown && time(NULL) > pt_begin) {
+ int len = strlen(update);
+
+ (void) printf("%s: %s%*.*s", pt_header, update, len, len,
+ pt_reverse);
+ (void) fflush(stdout);
+ pt_shown = B_TRUE;
+ } else if (pt_shown) {
+ int len = strlen(update);
+
+ (void) printf("%s%*.*s", update, len, len, pt_reverse);
+ (void) fflush(stdout);
+ }
+}
+
+static void
+finish_progress(char *done)
+{
+ if (pt_shown) {
+ (void) printf("%s\n", done);
+ (void) fflush(stdout);
+ }
+ free(pt_header);
+ pt_header = NULL;
+}
+/*
+ * zfs clone [-p] [-o prop=value] ... <snap> <fs | vol>
+ *
+ * Given an existing dataset, create a writable copy whose initial contents
+ * are the same as the source. The newly created dataset maintains a
+ * dependency on the original; the original cannot be destroyed so long as
+ * the clone exists.
+ *
+ * The '-p' flag creates all the non-existing ancestors of the target first.
+ */
+static int
+zfs_do_clone(int argc, char **argv)
+{
+ zfs_handle_t *zhp = NULL;
+ boolean_t parents = B_FALSE;
+ nvlist_t *props;
+ int ret = 0;
+ int c;
+
+ if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ /* check options */
+ while ((c = getopt(argc, argv, "o:p")) != -1) {
+ switch (c) {
+ case 'o':
+ if (parseprop(props))
+ return (1);
+ break;
+ case 'p':
+ parents = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ goto usage;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing source dataset "
+ "argument\n"));
+ goto usage;
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing target dataset "
+ "argument\n"));
+ goto usage;
+ }
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ goto usage;
+ }
+
+ /* open the source dataset */
+ if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_SNAPSHOT)) == NULL)
+ return (1);
+
+ if (parents && zfs_name_valid(argv[1], ZFS_TYPE_FILESYSTEM |
+ ZFS_TYPE_VOLUME)) {
+ /*
+ * Now create the ancestors of the target dataset. If the
+ * target already exists and '-p' option was used we should not
+ * complain.
+ */
+ if (zfs_dataset_exists(g_zfs, argv[1], ZFS_TYPE_FILESYSTEM |
+ ZFS_TYPE_VOLUME))
+ return (0);
+ if (zfs_create_ancestors(g_zfs, argv[1]) != 0)
+ return (1);
+ }
+
+ /* pass to libzfs */
+ ret = zfs_clone(zhp, argv[1], props);
+
+ /* create the mountpoint if necessary */
+ if (ret == 0) {
+ zfs_handle_t *clone;
+
+ clone = zfs_open(g_zfs, argv[1], ZFS_TYPE_DATASET);
+ if (clone != NULL) {
+ if (zfs_get_type(clone) != ZFS_TYPE_VOLUME)
+ if ((ret = zfs_mount(clone, NULL, 0)) == 0)
+ ret = zfs_share(clone);
+ zfs_close(clone);
+ }
+ }
+
+ zfs_close(zhp);
+ nvlist_free(props);
+
+ return (!!ret);
+
+usage:
+ if (zhp)
+ zfs_close(zhp);
+ nvlist_free(props);
+ usage(B_FALSE);
+ return (-1);
+}
+
+/*
+ * zfs create [-pu] [-o prop=value] ... fs
+ * zfs create [-ps] [-b blocksize] [-o prop=value] ... -V vol size
+ *
+ * Create a new dataset. This command can be used to create filesystems
+ * and volumes. Snapshot creation is handled by 'zfs snapshot'.
+ * For volumes, the user must specify a size to be used.
+ *
+ * The '-s' flag applies only to volumes, and indicates that we should not try
+ * to set the reservation for this volume. By default we set a reservation
+ * equal to the size for any volume. For pools with SPA_VERSION >=
+ * SPA_VERSION_REFRESERVATION, we set a refreservation instead.
+ *
+ * The '-p' flag creates all the non-existing ancestors of the target first.
+ *
+ * The '-u' flag prevents mounting of newly created file system.
+ */
+static int
+zfs_do_create(int argc, char **argv)
+{
+ zfs_type_t type = ZFS_TYPE_FILESYSTEM;
+ zfs_handle_t *zhp = NULL;
+ uint64_t volsize;
+ int c;
+ boolean_t noreserve = B_FALSE;
+ boolean_t bflag = B_FALSE;
+ boolean_t parents = B_FALSE;
+ boolean_t nomount = B_FALSE;
+ int ret = 1;
+ nvlist_t *props;
+ uint64_t intval;
+ int canmount = ZFS_CANMOUNT_OFF;
+
+ if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":V:b:so:pu")) != -1) {
+ switch (c) {
+ case 'V':
+ type = ZFS_TYPE_VOLUME;
+ if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
+ (void) fprintf(stderr, gettext("bad volume "
+ "size '%s': %s\n"), optarg,
+ libzfs_error_description(g_zfs));
+ goto error;
+ }
+
+ if (nvlist_add_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLSIZE), intval) != 0)
+ nomem();
+ volsize = intval;
+ break;
+ case 'p':
+ parents = B_TRUE;
+ break;
+ case 'b':
+ bflag = B_TRUE;
+ if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
+ (void) fprintf(stderr, gettext("bad volume "
+ "block size '%s': %s\n"), optarg,
+ libzfs_error_description(g_zfs));
+ goto error;
+ }
+
+ if (nvlist_add_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+ intval) != 0)
+ nomem();
+ break;
+ case 'o':
+ if (parseprop(props))
+ goto error;
+ break;
+ case 's':
+ noreserve = B_TRUE;
+ break;
+ case 'u':
+ nomount = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing size "
+ "argument\n"));
+ goto badusage;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ goto badusage;
+ }
+ }
+
+ if ((bflag || noreserve) && type != ZFS_TYPE_VOLUME) {
+ (void) fprintf(stderr, gettext("'-s' and '-b' can only be "
+ "used when creating a volume\n"));
+ goto badusage;
+ }
+ if (nomount && type != ZFS_TYPE_FILESYSTEM) {
+ (void) fprintf(stderr, gettext("'-u' can only be "
+ "used when creating a file system\n"));
+ goto badusage;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc == 0) {
+ (void) fprintf(stderr, gettext("missing %s argument\n"),
+ zfs_type_to_name(type));
+ goto badusage;
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ goto badusage;
+ }
+
+ if (type == ZFS_TYPE_VOLUME && !noreserve) {
+ zpool_handle_t *zpool_handle;
+ uint64_t spa_version;
+ char *p;
+ zfs_prop_t resv_prop;
+ char *strval;
+
+ if (p = strchr(argv[0], '/'))
+ *p = '\0';
+ zpool_handle = zpool_open(g_zfs, argv[0]);
+ if (p != NULL)
+ *p = '/';
+ if (zpool_handle == NULL)
+ goto error;
+ spa_version = zpool_get_prop_int(zpool_handle,
+ ZPOOL_PROP_VERSION, NULL);
+ zpool_close(zpool_handle);
+ if (spa_version >= SPA_VERSION_REFRESERVATION)
+ resv_prop = ZFS_PROP_REFRESERVATION;
+ else
+ resv_prop = ZFS_PROP_RESERVATION;
+ volsize = zvol_volsize_to_reservation(volsize, props);
+
+ if (nvlist_lookup_string(props, zfs_prop_to_name(resv_prop),
+ &strval) != 0) {
+ if (nvlist_add_uint64(props,
+ zfs_prop_to_name(resv_prop), volsize) != 0) {
+ nvlist_free(props);
+ nomem();
+ }
+ }
+ }
+
+ if (parents && zfs_name_valid(argv[0], type)) {
+ /*
+ * Now create the ancestors of target dataset. If the target
+ * already exists and '-p' option was used we should not
+ * complain.
+ */
+ if (zfs_dataset_exists(g_zfs, argv[0], type)) {
+ ret = 0;
+ goto error;
+ }
+ if (zfs_create_ancestors(g_zfs, argv[0]) != 0)
+ goto error;
+ }
+
+ /* pass to libzfs */
+ if (zfs_create(g_zfs, argv[0], type, props) != 0)
+ goto error;
+
+ if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
+ goto error;
+
+ ret = 0;
+ /*
+ * if the user doesn't want the dataset automatically mounted,
+ * then skip the mount/share step
+ */
+ if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type))
+ canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
+
+ /*
+ * Mount and/or share the new filesystem as appropriate. We provide a
+ * verbose error message to let the user know that their filesystem was
+ * in fact created, even if we failed to mount or share it.
+ */
+ if (!nomount && canmount == ZFS_CANMOUNT_ON) {
+ if (zfs_mount(zhp, NULL, 0) != 0) {
+ (void) fprintf(stderr, gettext("filesystem "
+ "successfully created, but not mounted\n"));
+ ret = 1;
+ } else if (zfs_share(zhp) != 0) {
+ (void) fprintf(stderr, gettext("filesystem "
+ "successfully created, but not shared\n"));
+ ret = 1;
+ }
+ }
+
+error:
+ if (zhp)
+ zfs_close(zhp);
+ nvlist_free(props);
+ return (ret);
+badusage:
+ nvlist_free(props);
+ usage(B_FALSE);
+ return (2);
+}
+
+/*
+ * zfs destroy [-rRf] <fs, vol>
+ * zfs destroy [-rRd] <snap>
+ *
+ * -r Recursively destroy all children
+ * -R Recursively destroy all dependents, including clones
+ * -f Force unmounting of any dependents
+ * -d If we can't destroy now, mark for deferred destruction
+ *
+ * Destroys the given dataset. By default, it will unmount any filesystems,
+ * and refuse to destroy a dataset that has any dependents. A dependent can
+ * either be a child, or a clone of a child.
+ */
+typedef struct destroy_cbdata {
+ boolean_t cb_first;
+ boolean_t cb_force;
+ boolean_t cb_recurse;
+ boolean_t cb_error;
+ boolean_t cb_doclones;
+ zfs_handle_t *cb_target;
+ boolean_t cb_defer_destroy;
+ boolean_t cb_verbose;
+ boolean_t cb_parsable;
+ boolean_t cb_dryrun;
+ nvlist_t *cb_nvl;
+ nvlist_t *cb_batchedsnaps;
+
+ /* first snap in contiguous run */
+ char *cb_firstsnap;
+ /* previous snap in contiguous run */
+ char *cb_prevsnap;
+ int64_t cb_snapused;
+ char *cb_snapspec;
+} destroy_cbdata_t;
+
+/*
+ * Check for any dependents based on the '-r' or '-R' flags.
+ */
+static int
+destroy_check_dependent(zfs_handle_t *zhp, void *data)
+{
+ destroy_cbdata_t *cbp = data;
+ const char *tname = zfs_get_name(cbp->cb_target);
+ const char *name = zfs_get_name(zhp);
+
+ if (strncmp(tname, name, strlen(tname)) == 0 &&
+ (name[strlen(tname)] == '/' || name[strlen(tname)] == '@')) {
+ /*
+ * This is a direct descendant, not a clone somewhere else in
+ * the hierarchy.
+ */
+ if (cbp->cb_recurse)
+ goto out;
+
+ if (cbp->cb_first) {
+ (void) fprintf(stderr, gettext("cannot destroy '%s': "
+ "%s has children\n"),
+ zfs_get_name(cbp->cb_target),
+ zfs_type_to_name(zfs_get_type(cbp->cb_target)));
+ (void) fprintf(stderr, gettext("use '-r' to destroy "
+ "the following datasets:\n"));
+ cbp->cb_first = B_FALSE;
+ cbp->cb_error = B_TRUE;
+ }
+
+ (void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
+ } else {
+ /*
+ * This is a clone. We only want to report this if the '-r'
+ * wasn't specified, or the target is a snapshot.
+ */
+ if (!cbp->cb_recurse &&
+ zfs_get_type(cbp->cb_target) != ZFS_TYPE_SNAPSHOT)
+ goto out;
+
+ if (cbp->cb_first) {
+ (void) fprintf(stderr, gettext("cannot destroy '%s': "
+ "%s has dependent clones\n"),
+ zfs_get_name(cbp->cb_target),
+ zfs_type_to_name(zfs_get_type(cbp->cb_target)));
+ (void) fprintf(stderr, gettext("use '-R' to destroy "
+ "the following datasets:\n"));
+ cbp->cb_first = B_FALSE;
+ cbp->cb_error = B_TRUE;
+ cbp->cb_dryrun = B_TRUE;
+ }
+
+ (void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
+ }
+
+out:
+ zfs_close(zhp);
+ return (0);
+}
+
+static int
+destroy_callback(zfs_handle_t *zhp, void *data)
+{
+ destroy_cbdata_t *cb = data;
+ const char *name = zfs_get_name(zhp);
+
+ if (cb->cb_verbose) {
+ if (cb->cb_parsable) {
+ (void) printf("destroy\t%s\n", name);
+ } else if (cb->cb_dryrun) {
+ (void) printf(gettext("would destroy %s\n"),
+ name);
+ } else {
+ (void) printf(gettext("will destroy %s\n"),
+ name);
+ }
+ }
+
+ /*
+ * Ignore pools (which we've already flagged as an error before getting
+ * here).
+ */
+ if (strchr(zfs_get_name(zhp), '/') == NULL &&
+ zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
+ zfs_close(zhp);
+ return (0);
+ }
+ if (cb->cb_dryrun) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ /*
+ * We batch up all contiguous snapshots (even of different
+ * filesystems) and destroy them with one ioctl. We can't
+ * simply do all snap deletions and then all fs deletions,
+ * because we must delete a clone before its origin.
+ */
+ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
+ fnvlist_add_boolean(cb->cb_batchedsnaps, name);
+ } else {
+ int error = zfs_destroy_snaps_nvl(g_zfs,
+ cb->cb_batchedsnaps, B_FALSE);
+ fnvlist_free(cb->cb_batchedsnaps);
+ cb->cb_batchedsnaps = fnvlist_alloc();
+
+ if (error != 0 ||
+ zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
+ zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
+ zfs_close(zhp);
+ return (-1);
+ }
+ }
+
+ zfs_close(zhp);
+ return (0);
+}
+
+static int
+destroy_print_cb(zfs_handle_t *zhp, void *arg)
+{
+ destroy_cbdata_t *cb = arg;
+ const char *name = zfs_get_name(zhp);
+ int err = 0;
+
+ if (nvlist_exists(cb->cb_nvl, name)) {
+ if (cb->cb_firstsnap == NULL)
+ cb->cb_firstsnap = strdup(name);
+ if (cb->cb_prevsnap != NULL)
+ free(cb->cb_prevsnap);
+ /* this snap continues the current range */
+ cb->cb_prevsnap = strdup(name);
+ if (cb->cb_firstsnap == NULL || cb->cb_prevsnap == NULL)
+ nomem();
+ if (cb->cb_verbose) {
+ if (cb->cb_parsable) {
+ (void) printf("destroy\t%s\n", name);
+ } else if (cb->cb_dryrun) {
+ (void) printf(gettext("would destroy %s\n"),
+ name);
+ } else {
+ (void) printf(gettext("will destroy %s\n"),
+ name);
+ }
+ }
+ } else if (cb->cb_firstsnap != NULL) {
+ /* end of this range */
+ uint64_t used = 0;
+ err = lzc_snaprange_space(cb->cb_firstsnap,
+ cb->cb_prevsnap, &used);
+ cb->cb_snapused += used;
+ free(cb->cb_firstsnap);
+ cb->cb_firstsnap = NULL;
+ free(cb->cb_prevsnap);
+ cb->cb_prevsnap = NULL;
+ }
+ zfs_close(zhp);
+ return (err);
+}
+
+static int
+destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_cbdata_t *cb)
+{
+ int err = 0;
+ assert(cb->cb_firstsnap == NULL);
+ assert(cb->cb_prevsnap == NULL);
+ err = zfs_iter_snapshots_sorted(fs_zhp, destroy_print_cb, cb);
+ if (cb->cb_firstsnap != NULL) {
+ uint64_t used = 0;
+ if (err == 0) {
+ err = lzc_snaprange_space(cb->cb_firstsnap,
+ cb->cb_prevsnap, &used);
+ }
+ cb->cb_snapused += used;
+ free(cb->cb_firstsnap);
+ cb->cb_firstsnap = NULL;
+ free(cb->cb_prevsnap);
+ cb->cb_prevsnap = NULL;
+ }
+ return (err);
+}
+
+static int
+snapshot_to_nvl_cb(zfs_handle_t *zhp, void *arg)
+{
+ destroy_cbdata_t *cb = arg;
+ int err = 0;
+
+ /* Check for clones. */
+ if (!cb->cb_doclones && !cb->cb_defer_destroy) {
+ cb->cb_target = zhp;
+ cb->cb_first = B_TRUE;
+ err = zfs_iter_dependents(zhp, B_TRUE,
+ destroy_check_dependent, cb);
+ }
+
+ if (err == 0) {
+ if (nvlist_add_boolean(cb->cb_nvl, zfs_get_name(zhp)))
+ nomem();
+ }
+ zfs_close(zhp);
+ return (err);
+}
+
+static int
+gather_snapshots(zfs_handle_t *zhp, void *arg)
+{
+ destroy_cbdata_t *cb = arg;
+ int err = 0;
+
+ err = zfs_iter_snapspec(zhp, cb->cb_snapspec, snapshot_to_nvl_cb, cb);
+ if (err == ENOENT)
+ err = 0;
+ if (err != 0)
+ goto out;
+
+ if (cb->cb_verbose) {
+ err = destroy_print_snapshots(zhp, cb);
+ if (err != 0)
+ goto out;
+ }
+
+ if (cb->cb_recurse)
+ err = zfs_iter_filesystems(zhp, gather_snapshots, cb);
+
+out:
+ zfs_close(zhp);
+ return (err);
+}
+
+static int
+destroy_clones(destroy_cbdata_t *cb)
+{
+ nvpair_t *pair;
+ for (pair = nvlist_next_nvpair(cb->cb_nvl, NULL);
+ pair != NULL;
+ pair = nvlist_next_nvpair(cb->cb_nvl, pair)) {
+ zfs_handle_t *zhp = zfs_open(g_zfs, nvpair_name(pair),
+ ZFS_TYPE_SNAPSHOT);
+ if (zhp != NULL) {
+ boolean_t defer = cb->cb_defer_destroy;
+ int err = 0;
+
+ /*
+ * We can't defer destroy non-snapshots, so set it to
+ * false while destroying the clones.
+ */
+ cb->cb_defer_destroy = B_FALSE;
+ err = zfs_iter_dependents(zhp, B_FALSE,
+ destroy_callback, cb);
+ cb->cb_defer_destroy = defer;
+ zfs_close(zhp);
+ if (err != 0)
+ return (err);
+ }
+ }
+ return (0);
+}
+
+static int
+zfs_do_destroy(int argc, char **argv)
+{
+ destroy_cbdata_t cb = { 0 };
+ int rv = 0;
+ int err = 0;
+ int c;
+ zfs_handle_t *zhp = NULL;
+ char *at;
+ zfs_type_t type = ZFS_TYPE_DATASET;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "vpndfrR")) != -1) {
+ switch (c) {
+ case 'v':
+ cb.cb_verbose = B_TRUE;
+ break;
+ case 'p':
+ cb.cb_verbose = B_TRUE;
+ cb.cb_parsable = B_TRUE;
+ break;
+ case 'n':
+ cb.cb_dryrun = B_TRUE;
+ break;
+ case 'd':
+ cb.cb_defer_destroy = B_TRUE;
+ type = ZFS_TYPE_SNAPSHOT;
+ break;
+ case 'f':
+ cb.cb_force = B_TRUE;
+ break;
+ case 'r':
+ cb.cb_recurse = B_TRUE;
+ break;
+ case 'R':
+ cb.cb_recurse = B_TRUE;
+ cb.cb_doclones = B_TRUE;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc == 0) {
+ (void) fprintf(stderr, gettext("missing dataset argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ at = strchr(argv[0], '@');
+ if (at != NULL) {
+
+ /* Build the list of snaps to destroy in cb_nvl. */
+ cb.cb_nvl = fnvlist_alloc();
+
+ *at = '\0';
+ zhp = zfs_open(g_zfs, argv[0],
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ return (1);
+
+ cb.cb_snapspec = at + 1;
+ if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
+ cb.cb_error) {
+ rv = 1;
+ goto out;
+ }
+
+ if (nvlist_empty(cb.cb_nvl)) {
+ (void) fprintf(stderr, gettext("could not find any "
+ "snapshots to destroy; check snapshot names.\n"));
+ rv = 1;
+ goto out;
+ }
+
+ if (cb.cb_verbose) {
+ char buf[16];
+ zfs_nicenum(cb.cb_snapused, buf, sizeof (buf));
+ if (cb.cb_parsable) {
+ (void) printf("reclaim\t%llu\n",
+ cb.cb_snapused);
+ } else if (cb.cb_dryrun) {
+ (void) printf(gettext("would reclaim %s\n"),
+ buf);
+ } else {
+ (void) printf(gettext("will reclaim %s\n"),
+ buf);
+ }
+ }
+
+ if (!cb.cb_dryrun) {
+ if (cb.cb_doclones) {
+ cb.cb_batchedsnaps = fnvlist_alloc();
+ err = destroy_clones(&cb);
+ if (err == 0) {
+ err = zfs_destroy_snaps_nvl(g_zfs,
+ cb.cb_batchedsnaps, B_FALSE);
+ }
+ if (err != 0) {
+ rv = 1;
+ goto out;
+ }
+ }
+ if (err == 0) {
+ err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl,
+ cb.cb_defer_destroy);
+ }
+ }
+
+ if (err != 0)
+ rv = 1;
+ } else {
+ /* Open the given dataset */
+ if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
+ return (1);
+
+ cb.cb_target = zhp;
+
+ /*
+ * Perform an explicit check for pools before going any further.
+ */
+ if (!cb.cb_recurse && strchr(zfs_get_name(zhp), '/') == NULL &&
+ zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
+ (void) fprintf(stderr, gettext("cannot destroy '%s': "
+ "operation does not apply to pools\n"),
+ zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use 'zfs destroy -r "
+ "%s' to destroy all datasets in the pool\n"),
+ zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use 'zpool destroy %s' "
+ "to destroy the pool itself\n"), zfs_get_name(zhp));
+ rv = 1;
+ goto out;
+ }
+
+ /*
+ * Check for any dependents and/or clones.
+ */
+ cb.cb_first = B_TRUE;
+ if (!cb.cb_doclones &&
+ zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
+ &cb) != 0) {
+ rv = 1;
+ goto out;
+ }
+
+ if (cb.cb_error) {
+ rv = 1;
+ goto out;
+ }
+
+ cb.cb_batchedsnaps = fnvlist_alloc();
+ if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
+ &cb) != 0) {
+ rv = 1;
+ goto out;
+ }
+
+ /*
+ * Do the real thing. The callback will close the
+ * handle regardless of whether it succeeds or not.
+ */
+ err = destroy_callback(zhp, &cb);
+ zhp = NULL;
+ if (err == 0) {
+ err = zfs_destroy_snaps_nvl(g_zfs,
+ cb.cb_batchedsnaps, cb.cb_defer_destroy);
+ }
+ if (err != 0)
+ rv = 1;
+ }
+
+out:
+ fnvlist_free(cb.cb_batchedsnaps);
+ fnvlist_free(cb.cb_nvl);
+ if (zhp != NULL)
+ zfs_close(zhp);
+ return (rv);
+}
+
+static boolean_t
+is_recvd_column(zprop_get_cbdata_t *cbp)
+{
+ int i;
+ zfs_get_column_t col;
+
+ for (i = 0; i < ZFS_GET_NCOLS &&
+ (col = cbp->cb_columns[i]) != GET_COL_NONE; i++)
+ if (col == GET_COL_RECVD)
+ return (B_TRUE);
+ return (B_FALSE);
+}
+
+/*
+ * zfs get [-rHp] [-o all | field[,field]...] [-s source[,source]...]
+ * < all | property[,property]... > < fs | snap | vol > ...
+ *
+ * -r recurse over any child datasets
+ * -H scripted mode. Headers are stripped, and fields are separated
+ * by tabs instead of spaces.
+ * -o Set of fields to display. One of "name,property,value,
+ * received,source". Default is "name,property,value,source".
+ * "all" is an alias for all five.
+ * -s Set of sources to allow. One of
+ * "local,default,inherited,received,temporary,none". Default is
+ * all six.
+ * -p Display values in parsable (literal) format.
+ *
+ * Prints properties for the given datasets. The user can control which
+ * columns to display as well as which property types to allow.
+ */
+
+/*
+ * Invoked to display the properties for a single dataset.
+ */
+static int
+get_callback(zfs_handle_t *zhp, void *data)
+{
+ char buf[ZFS_MAXPROPLEN];
+ char rbuf[ZFS_MAXPROPLEN];
+ zprop_source_t sourcetype;
+ char source[ZFS_MAXNAMELEN];
+ zprop_get_cbdata_t *cbp = data;
+ nvlist_t *user_props = zfs_get_user_props(zhp);
+ zprop_list_t *pl = cbp->cb_proplist;
+ nvlist_t *propval;
+ char *strval;
+ char *sourceval;
+ boolean_t received = is_recvd_column(cbp);
+
+ for (; pl != NULL; pl = pl->pl_next) {
+ char *recvdval = NULL;
+ /*
+ * Skip the special fake placeholder. This will also skip over
+ * the name property when 'all' is specified.
+ */
+ if (pl->pl_prop == ZFS_PROP_NAME &&
+ pl == cbp->cb_proplist)
+ continue;
+
+ if (pl->pl_prop != ZPROP_INVAL) {
+ if (zfs_prop_get(zhp, pl->pl_prop, buf,
+ sizeof (buf), &sourcetype, source,
+ sizeof (source),
+ cbp->cb_literal) != 0) {
+ if (pl->pl_all)
+ continue;
+ if (!zfs_prop_valid_for_type(pl->pl_prop,
+ ZFS_TYPE_DATASET)) {
+ (void) fprintf(stderr,
+ gettext("No such property '%s'\n"),
+ zfs_prop_to_name(pl->pl_prop));
+ continue;
+ }
+ sourcetype = ZPROP_SRC_NONE;
+ (void) strlcpy(buf, "-", sizeof (buf));
+ }
+
+ if (received && (zfs_prop_get_recvd(zhp,
+ zfs_prop_to_name(pl->pl_prop), rbuf, sizeof (rbuf),
+ cbp->cb_literal) == 0))
+ recvdval = rbuf;
+
+ zprop_print_one_property(zfs_get_name(zhp), cbp,
+ zfs_prop_to_name(pl->pl_prop),
+ buf, sourcetype, source, recvdval);
+ } else if (zfs_prop_userquota(pl->pl_user_prop)) {
+ sourcetype = ZPROP_SRC_LOCAL;
+
+ if (zfs_prop_get_userquota(zhp, pl->pl_user_prop,
+ buf, sizeof (buf), cbp->cb_literal) != 0) {
+ sourcetype = ZPROP_SRC_NONE;
+ (void) strlcpy(buf, "-", sizeof (buf));
+ }
+
+ zprop_print_one_property(zfs_get_name(zhp), cbp,
+ pl->pl_user_prop, buf, sourcetype, source, NULL);
+ } else if (zfs_prop_written(pl->pl_user_prop)) {
+ sourcetype = ZPROP_SRC_LOCAL;
+
+ if (zfs_prop_get_written(zhp, pl->pl_user_prop,
+ buf, sizeof (buf), cbp->cb_literal) != 0) {
+ sourcetype = ZPROP_SRC_NONE;
+ (void) strlcpy(buf, "-", sizeof (buf));
+ }
+
+ zprop_print_one_property(zfs_get_name(zhp), cbp,
+ pl->pl_user_prop, buf, sourcetype, source, NULL);
+ } else {
+ if (nvlist_lookup_nvlist(user_props,
+ pl->pl_user_prop, &propval) != 0) {
+ if (pl->pl_all)
+ continue;
+ sourcetype = ZPROP_SRC_NONE;
+ strval = "-";
+ } else {
+ verify(nvlist_lookup_string(propval,
+ ZPROP_VALUE, &strval) == 0);
+ verify(nvlist_lookup_string(propval,
+ ZPROP_SOURCE, &sourceval) == 0);
+
+ if (strcmp(sourceval,
+ zfs_get_name(zhp)) == 0) {
+ sourcetype = ZPROP_SRC_LOCAL;
+ } else if (strcmp(sourceval,
+ ZPROP_SOURCE_VAL_RECVD) == 0) {
+ sourcetype = ZPROP_SRC_RECEIVED;
+ } else {
+ sourcetype = ZPROP_SRC_INHERITED;
+ (void) strlcpy(source,
+ sourceval, sizeof (source));
+ }
+ }
+
+ if (received && (zfs_prop_get_recvd(zhp,
+ pl->pl_user_prop, rbuf, sizeof (rbuf),
+ cbp->cb_literal) == 0))
+ recvdval = rbuf;
+
+ zprop_print_one_property(zfs_get_name(zhp), cbp,
+ pl->pl_user_prop, strval, sourcetype,
+ source, recvdval);
+ }
+ }
+
+ return (0);
+}
+
+static int
+zfs_do_get(int argc, char **argv)
+{
+ zprop_get_cbdata_t cb = { 0 };
+ int i, c, flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
+ int types = ZFS_TYPE_DATASET;
+ char *value, *fields;
+ int ret = 0;
+ int limit = 0;
+ zprop_list_t fake_name = { 0 };
+
+ /*
+ * Set up default columns and sources.
+ */
+ cb.cb_sources = ZPROP_SRC_ALL;
+ cb.cb_columns[0] = GET_COL_NAME;
+ cb.cb_columns[1] = GET_COL_PROPERTY;
+ cb.cb_columns[2] = GET_COL_VALUE;
+ cb.cb_columns[3] = GET_COL_SOURCE;
+ cb.cb_type = ZFS_TYPE_DATASET;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":d:o:s:rt:Hp")) != -1) {
+ switch (c) {
+ case 'p':
+ cb.cb_literal = B_TRUE;
+ break;
+ case 'd':
+ limit = parse_depth(optarg, &flags);
+ break;
+ case 'r':
+ flags |= ZFS_ITER_RECURSE;
+ break;
+ case 'H':
+ cb.cb_scripted = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case 'o':
+ /*
+ * Process the set of columns to display. We zero out
+ * the structure to give us a blank slate.
+ */
+ bzero(&cb.cb_columns, sizeof (cb.cb_columns));
+ i = 0;
+ while (*optarg != '\0') {
+ static char *col_subopts[] =
+ { "name", "property", "value", "received",
+ "source", "all", NULL };
+
+ if (i == ZFS_GET_NCOLS) {
+ (void) fprintf(stderr, gettext("too "
+ "many fields given to -o "
+ "option\n"));
+ usage(B_FALSE);
+ }
+
+ switch (getsubopt(&optarg, col_subopts,
+ &value)) {
+ case 0:
+ cb.cb_columns[i++] = GET_COL_NAME;
+ break;
+ case 1:
+ cb.cb_columns[i++] = GET_COL_PROPERTY;
+ break;
+ case 2:
+ cb.cb_columns[i++] = GET_COL_VALUE;
+ break;
+ case 3:
+ cb.cb_columns[i++] = GET_COL_RECVD;
+ flags |= ZFS_ITER_RECVD_PROPS;
+ break;
+ case 4:
+ cb.cb_columns[i++] = GET_COL_SOURCE;
+ break;
+ case 5:
+ if (i > 0) {
+ (void) fprintf(stderr,
+ gettext("\"all\" conflicts "
+ "with specific fields "
+ "given to -o option\n"));
+ usage(B_FALSE);
+ }
+ cb.cb_columns[0] = GET_COL_NAME;
+ cb.cb_columns[1] = GET_COL_PROPERTY;
+ cb.cb_columns[2] = GET_COL_VALUE;
+ cb.cb_columns[3] = GET_COL_RECVD;
+ cb.cb_columns[4] = GET_COL_SOURCE;
+ flags |= ZFS_ITER_RECVD_PROPS;
+ i = ZFS_GET_NCOLS;
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("invalid column name "
+ "'%s'\n"), value);
+ usage(B_FALSE);
+ }
+ }
+ break;
+
+ case 's':
+ cb.cb_sources = 0;
+ while (*optarg != '\0') {
+ static char *source_subopts[] = {
+ "local", "default", "inherited",
+ "received", "temporary", "none",
+ NULL };
+
+ switch (getsubopt(&optarg, source_subopts,
+ &value)) {
+ case 0:
+ cb.cb_sources |= ZPROP_SRC_LOCAL;
+ break;
+ case 1:
+ cb.cb_sources |= ZPROP_SRC_DEFAULT;
+ break;
+ case 2:
+ cb.cb_sources |= ZPROP_SRC_INHERITED;
+ break;
+ case 3:
+ cb.cb_sources |= ZPROP_SRC_RECEIVED;
+ break;
+ case 4:
+ cb.cb_sources |= ZPROP_SRC_TEMPORARY;
+ break;
+ case 5:
+ cb.cb_sources |= ZPROP_SRC_NONE;
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("invalid source "
+ "'%s'\n"), value);
+ usage(B_FALSE);
+ }
+ }
+ break;
+
+ case 't':
+ types = 0;
+ flags &= ~ZFS_ITER_PROP_LISTSNAPS;
+ while (*optarg != '\0') {
+ static char *type_subopts[] = { "filesystem",
+ "volume", "snapshot", "all", NULL };
+
+ switch (getsubopt(&optarg, type_subopts,
+ &value)) {
+ case 0:
+ types |= ZFS_TYPE_FILESYSTEM;
+ break;
+ case 1:
+ types |= ZFS_TYPE_VOLUME;
+ break;
+ case 2:
+ types |= ZFS_TYPE_SNAPSHOT;
+ break;
+ case 3:
+ types = ZFS_TYPE_DATASET;
+ break;
+
+ default:
+ (void) fprintf(stderr,
+ gettext("invalid type '%s'\n"),
+ value);
+ usage(B_FALSE);
+ }
+ }
+ break;
+
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing property "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+
+ fields = argv[0];
+
+ if (zprop_get_list(g_zfs, fields, &cb.cb_proplist, ZFS_TYPE_DATASET)
+ != 0)
+ usage(B_FALSE);
+
+ argc--;
+ argv++;
+
+ /*
+ * As part of zfs_expand_proplist(), we keep track of the maximum column
+ * width for each property. For the 'NAME' (and 'SOURCE') columns, we
+ * need to know the maximum name length. However, the user likely did
+ * not specify 'name' as one of the properties to fetch, so we need to
+ * make sure we always include at least this property for
+ * print_get_headers() to work properly.
+ */
+ if (cb.cb_proplist != NULL) {
+ fake_name.pl_prop = ZFS_PROP_NAME;
+ fake_name.pl_width = strlen(gettext("NAME"));
+ fake_name.pl_next = cb.cb_proplist;
+ cb.cb_proplist = &fake_name;
+ }
+
+ cb.cb_first = B_TRUE;
+
+ /* run for each object */
+ ret = zfs_for_each(argc, argv, flags, types, NULL,
+ &cb.cb_proplist, limit, get_callback, &cb);
+
+ if (cb.cb_proplist == &fake_name)
+ zprop_free_list(fake_name.pl_next);
+ else
+ zprop_free_list(cb.cb_proplist);
+
+ return (ret);
+}
+
+/*
+ * inherit [-rS] <property> <fs|vol> ...
+ *
+ * -r Recurse over all children
+ * -S Revert to received value, if any
+ *
+ * For each dataset specified on the command line, inherit the given property
+ * from its parent. Inheriting a property at the pool level will cause it to
+ * use the default value. The '-r' flag will recurse over all children, and is
+ * useful for setting a property on a hierarchy-wide basis, regardless of any
+ * local modifications for each dataset.
+ */
+
+typedef struct inherit_cbdata {
+ const char *cb_propname;
+ boolean_t cb_received;
+} inherit_cbdata_t;
+
+static int
+inherit_recurse_cb(zfs_handle_t *zhp, void *data)
+{
+ inherit_cbdata_t *cb = data;
+ zfs_prop_t prop = zfs_name_to_prop(cb->cb_propname);
+
+ /*
+ * If we're doing it recursively, then ignore properties that
+ * are not valid for this type of dataset.
+ */
+ if (prop != ZPROP_INVAL &&
+ !zfs_prop_valid_for_type(prop, zfs_get_type(zhp)))
+ return (0);
+
+ return (zfs_prop_inherit(zhp, cb->cb_propname, cb->cb_received) != 0);
+}
+
+static int
+inherit_cb(zfs_handle_t *zhp, void *data)
+{
+ inherit_cbdata_t *cb = data;
+
+ return (zfs_prop_inherit(zhp, cb->cb_propname, cb->cb_received) != 0);
+}
+
+static int
+zfs_do_inherit(int argc, char **argv)
+{
+ int c;
+ zfs_prop_t prop;
+ inherit_cbdata_t cb = { 0 };
+ char *propname;
+ int ret = 0;
+ int flags = 0;
+ boolean_t received = B_FALSE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "rS")) != -1) {
+ switch (c) {
+ case 'r':
+ flags |= ZFS_ITER_RECURSE;
+ break;
+ case 'S':
+ received = B_TRUE;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing property argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing dataset argument\n"));
+ usage(B_FALSE);
+ }
+
+ propname = argv[0];
+ argc--;
+ argv++;
+
+ if ((prop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
+ if (zfs_prop_readonly(prop)) {
+ (void) fprintf(stderr, gettext(
+ "%s property is read-only\n"),
+ propname);
+ return (1);
+ }
+ if (!zfs_prop_inheritable(prop) && !received) {
+ (void) fprintf(stderr, gettext("'%s' property cannot "
+ "be inherited\n"), propname);
+ if (prop == ZFS_PROP_QUOTA ||
+ prop == ZFS_PROP_RESERVATION ||
+ prop == ZFS_PROP_REFQUOTA ||
+ prop == ZFS_PROP_REFRESERVATION)
+ (void) fprintf(stderr, gettext("use 'zfs set "
+ "%s=none' to clear\n"), propname);
+ return (1);
+ }
+ if (received && (prop == ZFS_PROP_VOLSIZE ||
+ prop == ZFS_PROP_VERSION)) {
+ (void) fprintf(stderr, gettext("'%s' property cannot "
+ "be reverted to a received value\n"), propname);
+ return (1);
+ }
+ } else if (!zfs_prop_user(propname)) {
+ (void) fprintf(stderr, gettext("invalid property '%s'\n"),
+ propname);
+ usage(B_FALSE);
+ }
+
+ cb.cb_propname = propname;
+ cb.cb_received = received;
+
+ if (flags & ZFS_ITER_RECURSE) {
+ ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
+ NULL, NULL, 0, inherit_recurse_cb, &cb);
+ } else {
+ ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_DATASET,
+ NULL, NULL, 0, inherit_cb, &cb);
+ }
+
+ return (ret);
+}
+
+typedef struct upgrade_cbdata {
+ uint64_t cb_numupgraded;
+ uint64_t cb_numsamegraded;
+ uint64_t cb_numfailed;
+ uint64_t cb_version;
+ boolean_t cb_newer;
+ boolean_t cb_foundone;
+ char cb_lastfs[ZFS_MAXNAMELEN];
+} upgrade_cbdata_t;
+
+static int
+same_pool(zfs_handle_t *zhp, const char *name)
+{
+ int len1 = strcspn(name, "/@");
+ const char *zhname = zfs_get_name(zhp);
+ int len2 = strcspn(zhname, "/@");
+
+ if (len1 != len2)
+ return (B_FALSE);
+ return (strncmp(name, zhname, len1) == 0);
+}
+
+static int
+upgrade_list_callback(zfs_handle_t *zhp, void *data)
+{
+ upgrade_cbdata_t *cb = data;
+ int version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+
+ /* list if it's old/new */
+ if ((!cb->cb_newer && version < ZPL_VERSION) ||
+ (cb->cb_newer && version > ZPL_VERSION)) {
+ char *str;
+ if (cb->cb_newer) {
+ str = gettext("The following filesystems are "
+ "formatted using a newer software version and\n"
+ "cannot be accessed on the current system.\n\n");
+ } else {
+ str = gettext("The following filesystems are "
+ "out of date, and can be upgraded. After being\n"
+ "upgraded, these filesystems (and any 'zfs send' "
+ "streams generated from\n"
+ "subsequent snapshots) will no longer be "
+ "accessible by older software versions.\n\n");
+ }
+
+ if (!cb->cb_foundone) {
+ (void) puts(str);
+ (void) printf(gettext("VER FILESYSTEM\n"));
+ (void) printf(gettext("--- ------------\n"));
+ cb->cb_foundone = B_TRUE;
+ }
+
+ (void) printf("%2u %s\n", version, zfs_get_name(zhp));
+ }
+
+ return (0);
+}
+
+static int
+upgrade_set_callback(zfs_handle_t *zhp, void *data)
+{
+ upgrade_cbdata_t *cb = data;
+ int version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ int needed_spa_version;
+ int spa_version;
+
+ if (zfs_spa_version(zhp, &spa_version) < 0)
+ return (-1);
+
+ needed_spa_version = zfs_spa_version_map(cb->cb_version);
+
+ if (needed_spa_version < 0)
+ return (-1);
+
+ if (spa_version < needed_spa_version) {
+ /* can't upgrade */
+ (void) printf(gettext("%s: can not be "
+ "upgraded; the pool version needs to first "
+ "be upgraded\nto version %d\n\n"),
+ zfs_get_name(zhp), needed_spa_version);
+ cb->cb_numfailed++;
+ return (0);
+ }
+
+ /* upgrade */
+ if (version < cb->cb_version) {
+ char verstr[16];
+ (void) snprintf(verstr, sizeof (verstr),
+ "%llu", cb->cb_version);
+ if (cb->cb_lastfs[0] && !same_pool(zhp, cb->cb_lastfs)) {
+ /*
+ * If they did "zfs upgrade -a", then we could
+ * be doing ioctls to different pools. We need
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
+ */
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
+ }
+ if (zfs_prop_set(zhp, "version", verstr) == 0)
+ cb->cb_numupgraded++;
+ else
+ cb->cb_numfailed++;
+ (void) strcpy(cb->cb_lastfs, zfs_get_name(zhp));
+ } else if (version > cb->cb_version) {
+ /* can't downgrade */
+ (void) printf(gettext("%s: can not be downgraded; "
+ "it is already at version %u\n"),
+ zfs_get_name(zhp), version);
+ cb->cb_numfailed++;
+ } else {
+ cb->cb_numsamegraded++;
+ }
+ return (0);
+}
+
+/*
+ * zfs upgrade
+ * zfs upgrade -v
+ * zfs upgrade [-r] [-V <version>] <-a | filesystem>
+ */
+static int
+zfs_do_upgrade(int argc, char **argv)
+{
+ boolean_t all = B_FALSE;
+ boolean_t showversions = B_FALSE;
+ int ret = 0;
+ upgrade_cbdata_t cb = { 0 };
+ char c;
+ int flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "rvV:a")) != -1) {
+ switch (c) {
+ case 'r':
+ flags |= ZFS_ITER_RECURSE;
+ break;
+ case 'v':
+ showversions = B_TRUE;
+ break;
+ case 'V':
+ if (zfs_prop_string_to_index(ZFS_PROP_VERSION,
+ optarg, &cb.cb_version) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid version %s\n"), optarg);
+ usage(B_FALSE);
+ }
+ break;
+ case 'a':
+ all = B_TRUE;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if ((!all && !argc) && ((flags & ZFS_ITER_RECURSE) | cb.cb_version))
+ usage(B_FALSE);
+ if (showversions && (flags & ZFS_ITER_RECURSE || all ||
+ cb.cb_version || argc))
+ usage(B_FALSE);
+ if ((all || argc) && (showversions))
+ usage(B_FALSE);
+ if (all && argc)
+ usage(B_FALSE);
+
+ if (showversions) {
+ /* Show info on available versions. */
+ (void) printf(gettext("The following filesystem versions are "
+ "supported:\n\n"));
+ (void) printf(gettext("VER DESCRIPTION\n"));
+ (void) printf("--- -----------------------------------------"
+ "---------------\n");
+ (void) printf(gettext(" 1 Initial ZFS filesystem version\n"));
+ (void) printf(gettext(" 2 Enhanced directory entries\n"));
+ (void) printf(gettext(" 3 Case insensitive and filesystem "
+ "user identifier (FUID)\n"));
+ (void) printf(gettext(" 4 userquota, groupquota "
+ "properties\n"));
+ (void) printf(gettext(" 5 System attributes\n"));
+ (void) printf(gettext("\nFor more information on a particular "
+ "version, including supported releases,\n"));
+ (void) printf("see the ZFS Administration Guide.\n\n");
+ ret = 0;
+ } else if (argc || all) {
+ /* Upgrade filesystems */
+ if (cb.cb_version == 0)
+ cb.cb_version = ZPL_VERSION;
+ ret = zfs_for_each(argc, argv, flags, ZFS_TYPE_FILESYSTEM,
+ NULL, NULL, 0, upgrade_set_callback, &cb);
+ (void) printf(gettext("%llu filesystems upgraded\n"),
+ cb.cb_numupgraded);
+ if (cb.cb_numsamegraded) {
+ (void) printf(gettext("%llu filesystems already at "
+ "this version\n"),
+ cb.cb_numsamegraded);
+ }
+ if (cb.cb_numfailed != 0)
+ ret = 1;
+ } else {
+ /* List old-version filesytems */
+ boolean_t found;
+ (void) printf(gettext("This system is currently running "
+ "ZFS filesystem version %llu.\n\n"), ZPL_VERSION);
+
+ flags |= ZFS_ITER_RECURSE;
+ ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
+ NULL, NULL, 0, upgrade_list_callback, &cb);
+
+ found = cb.cb_foundone;
+ cb.cb_foundone = B_FALSE;
+ cb.cb_newer = B_TRUE;
+
+ ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
+ NULL, NULL, 0, upgrade_list_callback, &cb);
+
+ if (!cb.cb_foundone && !found) {
+ (void) printf(gettext("All filesystems are "
+ "formatted with the current version.\n"));
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * zfs userspace [-Hinp] [-o field[,...]] [-s field [-s field]...]
+ * [-S field [-S field]...] [-t type[,...]] filesystem | snapshot
+ * zfs groupspace [-Hinp] [-o field[,...]] [-s field [-s field]...]
+ * [-S field [-S field]...] [-t type[,...]] filesystem | snapshot
+ *
+ * -H Scripted mode; elide headers and separate columns by tabs.
+ * -i Translate SID to POSIX ID.
+ * -n Print numeric ID instead of user/group name.
+ * -o Control which fields to display.
+ * -p Use exact (parseable) numeric output.
+ * -s Specify sort columns, descending order.
+ * -S Specify sort columns, ascending order.
+ * -t Control which object types to display.
+ *
+ * Displays space consumed by, and quotas on, each user in the specified
+ * filesystem or snapshot.
+ */
+
+/* us_field_types, us_field_hdr and us_field_names should be kept in sync */
+enum us_field_types {
+ USFIELD_TYPE,
+ USFIELD_NAME,
+ USFIELD_USED,
+ USFIELD_QUOTA
+};
+static char *us_field_hdr[] = { "TYPE", "NAME", "USED", "QUOTA" };
+static char *us_field_names[] = { "type", "name", "used", "quota" };
+#define USFIELD_LAST (sizeof (us_field_names) / sizeof (char *))
+
+#define USTYPE_PSX_GRP (1 << 0)
+#define USTYPE_PSX_USR (1 << 1)
+#define USTYPE_SMB_GRP (1 << 2)
+#define USTYPE_SMB_USR (1 << 3)
+#define USTYPE_ALL \
+ (USTYPE_PSX_GRP | USTYPE_PSX_USR | USTYPE_SMB_GRP | USTYPE_SMB_USR)
+
+static int us_type_bits[] = {
+ USTYPE_PSX_GRP,
+ USTYPE_PSX_USR,
+ USTYPE_SMB_GRP,
+ USTYPE_SMB_USR,
+ USTYPE_ALL
+};
+static char *us_type_names[] = { "posixgroup", "posxiuser", "smbgroup",
+ "smbuser", "all" };
+
+typedef struct us_node {
+ nvlist_t *usn_nvl;
+ uu_avl_node_t usn_avlnode;
+ uu_list_node_t usn_listnode;
+} us_node_t;
+
+typedef struct us_cbdata {
+ nvlist_t **cb_nvlp;
+ uu_avl_pool_t *cb_avl_pool;
+ uu_avl_t *cb_avl;
+ boolean_t cb_numname;
+ boolean_t cb_nicenum;
+ boolean_t cb_sid2posix;
+ zfs_userquota_prop_t cb_prop;
+ zfs_sort_column_t *cb_sortcol;
+ size_t cb_width[USFIELD_LAST];
+} us_cbdata_t;
+
+static boolean_t us_populated = B_FALSE;
+
+typedef struct {
+ zfs_sort_column_t *si_sortcol;
+ boolean_t si_numname;
+} us_sort_info_t;
+
+static int
+us_field_index(char *field)
+{
+ int i;
+
+ for (i = 0; i < USFIELD_LAST; i++) {
+ if (strcmp(field, us_field_names[i]) == 0)
+ return (i);
+ }
+
+ return (-1);
+}
+
+static int
+us_compare(const void *larg, const void *rarg, void *unused)
+{
+ const us_node_t *l = larg;
+ const us_node_t *r = rarg;
+ us_sort_info_t *si = (us_sort_info_t *)unused;
+ zfs_sort_column_t *sortcol = si->si_sortcol;
+ boolean_t numname = si->si_numname;
+ nvlist_t *lnvl = l->usn_nvl;
+ nvlist_t *rnvl = r->usn_nvl;
+ int rc = 0;
+ boolean_t lvb, rvb;
+
+ for (; sortcol != NULL; sortcol = sortcol->sc_next) {
+ char *lvstr = "";
+ char *rvstr = "";
+ uint32_t lv32 = 0;
+ uint32_t rv32 = 0;
+ uint64_t lv64 = 0;
+ uint64_t rv64 = 0;
+ zfs_prop_t prop = sortcol->sc_prop;
+ const char *propname = NULL;
+ boolean_t reverse = sortcol->sc_reverse;
+
+ switch (prop) {
+ case ZFS_PROP_TYPE:
+ propname = "type";
+ (void) nvlist_lookup_uint32(lnvl, propname, &lv32);
+ (void) nvlist_lookup_uint32(rnvl, propname, &rv32);
+ if (rv32 != lv32)
+ rc = (rv32 < lv32) ? 1 : -1;
+ break;
+ case ZFS_PROP_NAME:
+ propname = "name";
+ if (numname) {
+ (void) nvlist_lookup_uint64(lnvl, propname,
+ &lv64);
+ (void) nvlist_lookup_uint64(rnvl, propname,
+ &rv64);
+ if (rv64 != lv64)
+ rc = (rv64 < lv64) ? 1 : -1;
+ } else {
+ (void) nvlist_lookup_string(lnvl, propname,
+ &lvstr);
+ (void) nvlist_lookup_string(rnvl, propname,
+ &rvstr);
+ rc = strcmp(lvstr, rvstr);
+ }
+ break;
+ case ZFS_PROP_USED:
+ case ZFS_PROP_QUOTA:
+ if (!us_populated)
+ break;
+ if (prop == ZFS_PROP_USED)
+ propname = "used";
+ else
+ propname = "quota";
+ (void) nvlist_lookup_uint64(lnvl, propname, &lv64);
+ (void) nvlist_lookup_uint64(rnvl, propname, &rv64);
+ if (rv64 != lv64)
+ rc = (rv64 < lv64) ? 1 : -1;
+ break;
+ }
+
+ if (rc != 0) {
+ if (rc < 0)
+ return (reverse ? 1 : -1);
+ else
+ return (reverse ? -1 : 1);
+ }
+ }
+
+ /*
+ * If entries still seem to be the same, check if they are of the same
+ * type (smbentity is added only if we are doing SID to POSIX ID
+ * translation where we can have duplicate type/name combinations).
+ */
+ if (nvlist_lookup_boolean_value(lnvl, "smbentity", &lvb) == 0 &&
+ nvlist_lookup_boolean_value(rnvl, "smbentity", &rvb) == 0 &&
+ lvb != rvb)
+ return (lvb < rvb ? -1 : 1);
+
+ return (0);
+}
+
+static inline const char *
+us_type2str(unsigned field_type)
+{
+ switch (field_type) {
+ case USTYPE_PSX_USR:
+ return ("POSIX User");
+ case USTYPE_PSX_GRP:
+ return ("POSIX Group");
+ case USTYPE_SMB_USR:
+ return ("SMB User");
+ case USTYPE_SMB_GRP:
+ return ("SMB Group");
+ default:
+ return ("Undefined");
+ }
+}
+
+static int
+userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
+{
+ us_cbdata_t *cb = (us_cbdata_t *)arg;
+ zfs_userquota_prop_t prop = cb->cb_prop;
+ char *name = NULL;
+ char *propname;
+ char sizebuf[32];
+ us_node_t *node;
+ uu_avl_pool_t *avl_pool = cb->cb_avl_pool;
+ uu_avl_t *avl = cb->cb_avl;
+ uu_avl_index_t idx;
+ nvlist_t *props;
+ us_node_t *n;
+ zfs_sort_column_t *sortcol = cb->cb_sortcol;
+ unsigned type;
+ const char *typestr;
+ size_t namelen;
+ size_t typelen;
+ size_t sizelen;
+ int typeidx, nameidx, sizeidx;
+ us_sort_info_t sortinfo = { sortcol, cb->cb_numname };
+ boolean_t smbentity = B_FALSE;
+
+ if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+ node = safe_malloc(sizeof (us_node_t));
+ uu_avl_node_init(node, &node->usn_avlnode, avl_pool);
+ node->usn_nvl = props;
+
+ if (domain != NULL && domain[0] != '\0') {
+ /* SMB */
+ char sid[ZFS_MAXNAMELEN + 32];
+ uid_t id;
+ uint64_t classes;
+#ifdef sun
+ int err;
+ directory_error_t e;
+#endif
+
+ smbentity = B_TRUE;
+
+ (void) snprintf(sid, sizeof (sid), "%s-%u", domain, rid);
+
+ if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) {
+ type = USTYPE_SMB_GRP;
+#ifdef sun
+ err = sid_to_id(sid, B_FALSE, &id);
+#endif
+ } else {
+ type = USTYPE_SMB_USR;
+#ifdef sun
+ err = sid_to_id(sid, B_TRUE, &id);
+#endif
+ }
+
+#ifdef sun
+ if (err == 0) {
+ rid = id;
+ if (!cb->cb_sid2posix) {
+ e = directory_name_from_sid(NULL, sid, &name,
+ &classes);
+ if (e != NULL)
+ directory_error_free(e);
+ if (name == NULL)
+ name = sid;
+ }
+ }
+#endif
+ }
+
+ if (cb->cb_sid2posix || domain == NULL || domain[0] == '\0') {
+ /* POSIX or -i */
+ if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) {
+ type = USTYPE_PSX_GRP;
+ if (!cb->cb_numname) {
+ struct group *g;
+
+ if ((g = getgrgid(rid)) != NULL)
+ name = g->gr_name;
+ }
+ } else {
+ type = USTYPE_PSX_USR;
+ if (!cb->cb_numname) {
+ struct passwd *p;
+
+ if ((p = getpwuid(rid)) != NULL)
+ name = p->pw_name;
+ }
+ }
+ }
+
+ /*
+ * Make sure that the type/name combination is unique when doing
+ * SID to POSIX ID translation (hence changing the type from SMB to
+ * POSIX).
+ */
+ if (cb->cb_sid2posix &&
+ nvlist_add_boolean_value(props, "smbentity", smbentity) != 0)
+ nomem();
+
+ /* Calculate/update width of TYPE field */
+ typestr = us_type2str(type);
+ typelen = strlen(gettext(typestr));
+ typeidx = us_field_index("type");
+ if (typelen > cb->cb_width[typeidx])
+ cb->cb_width[typeidx] = typelen;
+ if (nvlist_add_uint32(props, "type", type) != 0)
+ nomem();
+
+ /* Calculate/update width of NAME field */
+ if ((cb->cb_numname && cb->cb_sid2posix) || name == NULL) {
+ if (nvlist_add_uint64(props, "name", rid) != 0)
+ nomem();
+ namelen = snprintf(NULL, 0, "%u", rid);
+ } else {
+ if (nvlist_add_string(props, "name", name) != 0)
+ nomem();
+ namelen = strlen(name);
+ }
+ nameidx = us_field_index("name");
+ if (namelen > cb->cb_width[nameidx])
+ cb->cb_width[nameidx] = namelen;
+
+ /*
+ * Check if this type/name combination is in the list and update it;
+ * otherwise add new node to the list.
+ */
+ if ((n = uu_avl_find(avl, node, &sortinfo, &idx)) == NULL) {
+ uu_avl_insert(avl, node, idx);
+ } else {
+ nvlist_free(props);
+ free(node);
+ node = n;
+ props = node->usn_nvl;
+ }
+
+ /* Calculate/update width of USED/QUOTA fields */
+ if (cb->cb_nicenum)
+ zfs_nicenum(space, sizebuf, sizeof (sizebuf));
+ else
+ (void) snprintf(sizebuf, sizeof (sizebuf), "%llu", space);
+ sizelen = strlen(sizebuf);
+ if (prop == ZFS_PROP_USERUSED || prop == ZFS_PROP_GROUPUSED) {
+ propname = "used";
+ if (!nvlist_exists(props, "quota"))
+ (void) nvlist_add_uint64(props, "quota", 0);
+ } else {
+ propname = "quota";
+ if (!nvlist_exists(props, "used"))
+ (void) nvlist_add_uint64(props, "used", 0);
+ }
+ sizeidx = us_field_index(propname);
+ if (sizelen > cb->cb_width[sizeidx])
+ cb->cb_width[sizeidx] = sizelen;
+
+ if (nvlist_add_uint64(props, propname, space) != 0)
+ nomem();
+
+ return (0);
+}
+
+static void
+print_us_node(boolean_t scripted, boolean_t parsable, int *fields, int types,
+ size_t *width, us_node_t *node)
+{
+ nvlist_t *nvl = node->usn_nvl;
+ char valstr[ZFS_MAXNAMELEN];
+ boolean_t first = B_TRUE;
+ int cfield = 0;
+ int field;
+ uint32_t ustype;
+
+ /* Check type */
+ (void) nvlist_lookup_uint32(nvl, "type", &ustype);
+ if (!(ustype & types))
+ return;
+
+ while ((field = fields[cfield]) != USFIELD_LAST) {
+ nvpair_t *nvp = NULL;
+ data_type_t type;
+ uint32_t val32;
+ uint64_t val64;
+ char *strval = NULL;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ if (strcmp(nvpair_name(nvp),
+ us_field_names[field]) == 0)
+ break;
+ }
+
+ type = nvpair_type(nvp);
+ switch (type) {
+ case DATA_TYPE_UINT32:
+ (void) nvpair_value_uint32(nvp, &val32);
+ break;
+ case DATA_TYPE_UINT64:
+ (void) nvpair_value_uint64(nvp, &val64);
+ break;
+ case DATA_TYPE_STRING:
+ (void) nvpair_value_string(nvp, &strval);
+ break;
+ default:
+ (void) fprintf(stderr, "invalid data type\n");
+ }
+
+ switch (field) {
+ case USFIELD_TYPE:
+ strval = (char *)us_type2str(val32);
+ break;
+ case USFIELD_NAME:
+ if (type == DATA_TYPE_UINT64) {
+ (void) sprintf(valstr, "%llu", val64);
+ strval = valstr;
+ }
+ break;
+ case USFIELD_USED:
+ case USFIELD_QUOTA:
+ if (type == DATA_TYPE_UINT64) {
+ if (parsable) {
+ (void) sprintf(valstr, "%llu", val64);
+ } else {
+ zfs_nicenum(val64, valstr,
+ sizeof (valstr));
+ }
+ if (field == USFIELD_QUOTA &&
+ strcmp(valstr, "0") == 0)
+ strval = "none";
+ else
+ strval = valstr;
+ }
+ break;
+ }
+
+ if (!first) {
+ if (scripted)
+ (void) printf("\t");
+ else
+ (void) printf(" ");
+ }
+ if (scripted)
+ (void) printf("%s", strval);
+ else if (field == USFIELD_TYPE || field == USFIELD_NAME)
+ (void) printf("%-*s", width[field], strval);
+ else
+ (void) printf("%*s", width[field], strval);
+
+ first = B_FALSE;
+ cfield++;
+ }
+
+ (void) printf("\n");
+}
+
+static void
+print_us(boolean_t scripted, boolean_t parsable, int *fields, int types,
+ size_t *width, boolean_t rmnode, uu_avl_t *avl)
+{
+ us_node_t *node;
+ const char *col;
+ int cfield = 0;
+ int field;
+
+ if (!scripted) {
+ boolean_t first = B_TRUE;
+
+ while ((field = fields[cfield]) != USFIELD_LAST) {
+ col = gettext(us_field_hdr[field]);
+ if (field == USFIELD_TYPE || field == USFIELD_NAME) {
+ (void) printf(first ? "%-*s" : " %-*s",
+ width[field], col);
+ } else {
+ (void) printf(first ? "%*s" : " %*s",
+ width[field], col);
+ }
+ first = B_FALSE;
+ cfield++;
+ }
+ (void) printf("\n");
+ }
+
+ for (node = uu_avl_first(avl); node; node = uu_avl_next(avl, node)) {
+ print_us_node(scripted, parsable, fields, types, width, node);
+ if (rmnode)
+ nvlist_free(node->usn_nvl);
+ }
+}
+
+static int
+zfs_do_userspace(int argc, char **argv)
+{
+ zfs_handle_t *zhp;
+ zfs_userquota_prop_t p;
+
+ uu_avl_pool_t *avl_pool;
+ uu_avl_t *avl_tree;
+ uu_avl_walk_t *walk;
+ char *delim;
+ char deffields[] = "type,name,used,quota";
+ char *ofield = NULL;
+ char *tfield = NULL;
+ int cfield = 0;
+ int fields[256];
+ int i;
+ boolean_t scripted = B_FALSE;
+ boolean_t prtnum = B_FALSE;
+ boolean_t parsable = B_FALSE;
+ boolean_t sid2posix = B_FALSE;
+ int ret = 0;
+ int c;
+ zfs_sort_column_t *sortcol = NULL;
+ int types = USTYPE_PSX_USR | USTYPE_SMB_USR;
+ us_cbdata_t cb;
+ us_node_t *node;
+ us_node_t *rmnode;
+ uu_list_pool_t *listpool;
+ uu_list_t *list;
+ uu_avl_index_t idx = 0;
+ uu_list_index_t idx2 = 0;
+
+ if (argc < 2)
+ usage(B_FALSE);
+
+ if (strcmp(argv[0], "groupspace") == 0)
+ /* Toggle default group types */
+ types = USTYPE_PSX_GRP | USTYPE_SMB_GRP;
+
+ while ((c = getopt(argc, argv, "nHpo:s:S:t:i")) != -1) {
+ switch (c) {
+ case 'n':
+ prtnum = B_TRUE;
+ break;
+ case 'H':
+ scripted = B_TRUE;
+ break;
+ case 'p':
+ parsable = B_TRUE;
+ break;
+ case 'o':
+ ofield = optarg;
+ break;
+ case 's':
+ case 'S':
+ if (zfs_add_sort_column(&sortcol, optarg,
+ c == 's' ? B_FALSE : B_TRUE) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid field '%s'\n"), optarg);
+ usage(B_FALSE);
+ }
+ break;
+ case 't':
+ tfield = optarg;
+ break;
+ case 'i':
+ sid2posix = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing dataset name\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ /* Use default output fields if not specified using -o */
+ if (ofield == NULL)
+ ofield = deffields;
+ do {
+ if ((delim = strchr(ofield, ',')) != NULL)
+ *delim = '\0';
+ if ((fields[cfield++] = us_field_index(ofield)) == -1) {
+ (void) fprintf(stderr, gettext("invalid type '%s' "
+ "for -o option\n"), ofield);
+ return (-1);
+ }
+ if (delim != NULL)
+ ofield = delim + 1;
+ } while (delim != NULL);
+ fields[cfield] = USFIELD_LAST;
+
+ /* Override output types (-t option) */
+ if (tfield != NULL) {
+ types = 0;
+
+ do {
+ boolean_t found = B_FALSE;
+
+ if ((delim = strchr(tfield, ',')) != NULL)
+ *delim = '\0';
+ for (i = 0; i < sizeof (us_type_bits) / sizeof (int);
+ i++) {
+ if (strcmp(tfield, us_type_names[i]) == 0) {
+ found = B_TRUE;
+ types |= us_type_bits[i];
+ break;
+ }
+ }
+ if (!found) {
+ (void) fprintf(stderr, gettext("invalid type "
+ "'%s' for -t option\n"), tfield);
+ return (-1);
+ }
+ if (delim != NULL)
+ tfield = delim + 1;
+ } while (delim != NULL);
+ }
+
+ if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
+ return (1);
+
+ if ((avl_pool = uu_avl_pool_create("us_avl_pool", sizeof (us_node_t),
+ offsetof(us_node_t, usn_avlnode), us_compare, UU_DEFAULT)) == NULL)
+ nomem();
+ if ((avl_tree = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
+ nomem();
+
+ /* Always add default sorting columns */
+ (void) zfs_add_sort_column(&sortcol, "type", B_FALSE);
+ (void) zfs_add_sort_column(&sortcol, "name", B_FALSE);
+
+ cb.cb_sortcol = sortcol;
+ cb.cb_numname = prtnum;
+ cb.cb_nicenum = !parsable;
+ cb.cb_avl_pool = avl_pool;
+ cb.cb_avl = avl_tree;
+ cb.cb_sid2posix = sid2posix;
+
+ for (i = 0; i < USFIELD_LAST; i++)
+ cb.cb_width[i] = strlen(gettext(us_field_hdr[i]));
+
+ for (p = 0; p < ZFS_NUM_USERQUOTA_PROPS; p++) {
+ if (((p == ZFS_PROP_USERUSED || p == ZFS_PROP_USERQUOTA) &&
+ !(types & (USTYPE_PSX_USR | USTYPE_SMB_USR))) ||
+ ((p == ZFS_PROP_GROUPUSED || p == ZFS_PROP_GROUPQUOTA) &&
+ !(types & (USTYPE_PSX_GRP | USTYPE_SMB_GRP))))
+ continue;
+ cb.cb_prop = p;
+ if ((ret = zfs_userspace(zhp, p, userspace_cb, &cb)) != 0)
+ return (ret);
+ }
+
+ /* Sort the list */
+ if ((node = uu_avl_first(avl_tree)) == NULL)
+ return (0);
+
+ us_populated = B_TRUE;
+
+ listpool = uu_list_pool_create("tmplist", sizeof (us_node_t),
+ offsetof(us_node_t, usn_listnode), NULL, UU_DEFAULT);
+ list = uu_list_create(listpool, NULL, UU_DEFAULT);
+ uu_list_node_init(node, &node->usn_listnode, listpool);
+
+ while (node != NULL) {
+ rmnode = node;
+ node = uu_avl_next(avl_tree, node);
+ uu_avl_remove(avl_tree, rmnode);
+ if (uu_list_find(list, rmnode, NULL, &idx2) == NULL)
+ uu_list_insert(list, rmnode, idx2);
+ }
+
+ for (node = uu_list_first(list); node != NULL;
+ node = uu_list_next(list, node)) {
+ us_sort_info_t sortinfo = { sortcol, cb.cb_numname };
+
+ if (uu_avl_find(avl_tree, node, &sortinfo, &idx) == NULL)
+ uu_avl_insert(avl_tree, node, idx);
+ }
+
+ uu_list_destroy(list);
+ uu_list_pool_destroy(listpool);
+
+ /* Print and free node nvlist memory */
+ print_us(scripted, parsable, fields, types, cb.cb_width, B_TRUE,
+ cb.cb_avl);
+
+ zfs_free_sort_columns(sortcol);
+
+ /* Clean up the AVL tree */
+ if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
+ nomem();
+
+ while ((node = uu_avl_walk_next(walk)) != NULL) {
+ uu_avl_remove(cb.cb_avl, node);
+ free(node);
+ }
+
+ uu_avl_walk_end(walk);
+ uu_avl_destroy(avl_tree);
+ uu_avl_pool_destroy(avl_pool);
+
+ return (ret);
+}
+
+/*
+ * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...]
+ * [-s property [-s property]...] [-S property [-S property]...]
+ * <dataset> ...
+ *
+ * -r Recurse over all children
+ * -d Limit recursion by depth.
+ * -H Scripted mode; elide headers and separate columns by tabs
+ * -o Control which fields to display.
+ * -t Control which object types to display.
+ * -s Specify sort columns, descending order.
+ * -S Specify sort columns, ascending order.
+ *
+ * When given no arguments, lists all filesystems in the system.
+ * Otherwise, list the specified datasets, optionally recursing down them if
+ * '-r' is specified.
+ */
+typedef struct list_cbdata {
+ boolean_t cb_first;
+ boolean_t cb_scripted;
+ zprop_list_t *cb_proplist;
+} list_cbdata_t;
+
+/*
+ * Given a list of columns to display, output appropriate headers for each one.
+ */
+static void
+print_header(zprop_list_t *pl)
+{
+ char headerbuf[ZFS_MAXPROPLEN];
+ const char *header;
+ int i;
+ boolean_t first = B_TRUE;
+ boolean_t right_justify;
+
+ for (; pl != NULL; pl = pl->pl_next) {
+ if (!first) {
+ (void) printf(" ");
+ } else {
+ first = B_FALSE;
+ }
+
+ right_justify = B_FALSE;
+ if (pl->pl_prop != ZPROP_INVAL) {
+ header = zfs_prop_column_name(pl->pl_prop);
+ right_justify = zfs_prop_align_right(pl->pl_prop);
+ } else {
+ for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
+ headerbuf[i] = toupper(pl->pl_user_prop[i]);
+ headerbuf[i] = '\0';
+ header = headerbuf;
+ }
+
+ if (pl->pl_next == NULL && !right_justify)
+ (void) printf("%s", header);
+ else if (right_justify)
+ (void) printf("%*s", pl->pl_width, header);
+ else
+ (void) printf("%-*s", pl->pl_width, header);
+ }
+
+ (void) printf("\n");
+}
+
+/*
+ * Given a dataset and a list of fields, print out all the properties according
+ * to the described layout.
+ */
+static void
+print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted)
+{
+ boolean_t first = B_TRUE;
+ char property[ZFS_MAXPROPLEN];
+ nvlist_t *userprops = zfs_get_user_props(zhp);
+ nvlist_t *propval;
+ char *propstr;
+ boolean_t right_justify;
+ int width;
+
+ for (; pl != NULL; pl = pl->pl_next) {
+ if (!first) {
+ if (scripted)
+ (void) printf("\t");
+ else
+ (void) printf(" ");
+ } else {
+ first = B_FALSE;
+ }
+
+ if (pl->pl_prop == ZFS_PROP_NAME) {
+ (void) strlcpy(property, zfs_get_name(zhp),
+ sizeof(property));
+ propstr = property;
+ right_justify = zfs_prop_align_right(pl->pl_prop);
+ } else if (pl->pl_prop != ZPROP_INVAL) {
+ if (zfs_prop_get(zhp, pl->pl_prop, property,
+ sizeof (property), NULL, NULL, 0, B_FALSE) != 0)
+ propstr = "-";
+ else
+ propstr = property;
+
+ right_justify = zfs_prop_align_right(pl->pl_prop);
+ } else if (zfs_prop_userquota(pl->pl_user_prop)) {
+ if (zfs_prop_get_userquota(zhp, pl->pl_user_prop,
+ property, sizeof (property), B_FALSE) != 0)
+ propstr = "-";
+ else
+ propstr = property;
+ right_justify = B_TRUE;
+ } else if (zfs_prop_written(pl->pl_user_prop)) {
+ if (zfs_prop_get_written(zhp, pl->pl_user_prop,
+ property, sizeof (property), B_FALSE) != 0)
+ propstr = "-";
+ else
+ propstr = property;
+ right_justify = B_TRUE;
+ } else {
+ if (nvlist_lookup_nvlist(userprops,
+ pl->pl_user_prop, &propval) != 0)
+ propstr = "-";
+ else
+ verify(nvlist_lookup_string(propval,
+ ZPROP_VALUE, &propstr) == 0);
+ right_justify = B_FALSE;
+ }
+
+ width = pl->pl_width;
+
+ /*
+ * If this is being called in scripted mode, or if this is the
+ * last column and it is left-justified, don't include a width
+ * format specifier.
+ */
+ if (scripted || (pl->pl_next == NULL && !right_justify))
+ (void) printf("%s", propstr);
+ else if (right_justify)
+ (void) printf("%*s", width, propstr);
+ else
+ (void) printf("%-*s", width, propstr);
+ }
+
+ (void) printf("\n");
+}
+
+/*
+ * Generic callback function to list a dataset or snapshot.
+ */
+static int
+list_callback(zfs_handle_t *zhp, void *data)
+{
+ list_cbdata_t *cbp = data;
+
+ if (cbp->cb_first) {
+ if (!cbp->cb_scripted)
+ print_header(cbp->cb_proplist);
+ cbp->cb_first = B_FALSE;
+ }
+
+ print_dataset(zhp, cbp->cb_proplist, cbp->cb_scripted);
+
+ return (0);
+}
+
+static int
+zfs_do_list(int argc, char **argv)
+{
+ int c;
+ boolean_t scripted = B_FALSE;
+ static char default_fields[] =
+ "name,used,available,referenced,mountpoint";
+ int types = ZFS_TYPE_DATASET;
+ boolean_t types_specified = B_FALSE;
+ char *fields = NULL;
+ list_cbdata_t cb = { 0 };
+ char *value;
+ int limit = 0;
+ int ret = 0;
+ zfs_sort_column_t *sortcol = NULL;
+ int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":d:o:rt:Hs:S:")) != -1) {
+ switch (c) {
+ case 'o':
+ fields = optarg;
+ break;
+ case 'd':
+ limit = parse_depth(optarg, &flags);
+ break;
+ case 'r':
+ flags |= ZFS_ITER_RECURSE;
+ break;
+ case 'H':
+ scripted = B_TRUE;
+ break;
+ case 's':
+ if (zfs_add_sort_column(&sortcol, optarg,
+ B_FALSE) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid property '%s'\n"), optarg);
+ usage(B_FALSE);
+ }
+ break;
+ case 'S':
+ if (zfs_add_sort_column(&sortcol, optarg,
+ B_TRUE) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid property '%s'\n"), optarg);
+ usage(B_FALSE);
+ }
+ break;
+ case 't':
+ types = 0;
+ types_specified = B_TRUE;
+ flags &= ~ZFS_ITER_PROP_LISTSNAPS;
+ while (*optarg != '\0') {
+ static char *type_subopts[] = { "filesystem",
+ "volume", "snapshot", "all", NULL };
+
+ switch (getsubopt(&optarg, type_subopts,
+ &value)) {
+ case 0:
+ types |= ZFS_TYPE_FILESYSTEM;
+ break;
+ case 1:
+ types |= ZFS_TYPE_VOLUME;
+ break;
+ case 2:
+ types |= ZFS_TYPE_SNAPSHOT;
+ break;
+ case 3:
+ types = ZFS_TYPE_DATASET;
+ break;
+
+ default:
+ (void) fprintf(stderr,
+ gettext("invalid type '%s'\n"),
+ value);
+ usage(B_FALSE);
+ }
+ }
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (fields == NULL)
+ fields = default_fields;
+
+ /*
+ * If we are only going to list snapshot names and sort by name,
+ * then we can use faster version.
+ */
+ if (strcmp(fields, "name") == 0 && zfs_sort_only_by_name(sortcol))
+ flags |= ZFS_ITER_SIMPLE;
+
+ /*
+ * If "-o space" and no types were specified, don't display snapshots.
+ */
+ if (strcmp(fields, "space") == 0 && types_specified == B_FALSE)
+ types &= ~ZFS_TYPE_SNAPSHOT;
+
+ /*
+ * If the user specifies '-o all', the zprop_get_list() doesn't
+ * normally include the name of the dataset. For 'zfs list', we always
+ * want this property to be first.
+ */
+ if (zprop_get_list(g_zfs, fields, &cb.cb_proplist, ZFS_TYPE_DATASET)
+ != 0)
+ usage(B_FALSE);
+
+ cb.cb_scripted = scripted;
+ cb.cb_first = B_TRUE;
+
+ ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
+ limit, list_callback, &cb);
+
+ zprop_free_list(cb.cb_proplist);
+ zfs_free_sort_columns(sortcol);
+
+ if (ret == 0 && cb.cb_first && !cb.cb_scripted)
+ (void) printf(gettext("no datasets available\n"));
+
+ return (ret);
+}
+
+/*
+ * zfs rename [-f] <fs | snap | vol> <fs | snap | vol>
+ * zfs rename [-f] -p <fs | vol> <fs | vol>
+ * zfs rename -r <snap> <snap>
+ * zfs rename -u [-p] <fs> <fs>
+ *
+ * Renames the given dataset to another of the same type.
+ *
+ * The '-p' flag creates all the non-existing ancestors of the target first.
+ */
+/* ARGSUSED */
+static int
+zfs_do_rename(int argc, char **argv)
+{
+ zfs_handle_t *zhp;
+ renameflags_t flags = { 0 };
+ int c;
+ int ret = 0;
+ int types;
+ boolean_t parents = B_FALSE;
+ char *snapshot = NULL;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "fpru")) != -1) {
+ switch (c) {
+ case 'p':
+ parents = B_TRUE;
+ break;
+ case 'r':
+ flags.recurse = B_TRUE;
+ break;
+ case 'u':
+ flags.nounmount = B_TRUE;
+ break;
+ case 'f':
+ flags.forceunmount = B_TRUE;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing source dataset "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing target dataset "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if (flags.recurse && parents) {
+ (void) fprintf(stderr, gettext("-p and -r options are mutually "
+ "exclusive\n"));
+ usage(B_FALSE);
+ }
+
+ if (flags.recurse && strchr(argv[0], '@') == 0) {
+ (void) fprintf(stderr, gettext("source dataset for recursive "
+ "rename must be a snapshot\n"));
+ usage(B_FALSE);
+ }
+
+ if (flags.nounmount && parents) {
+ (void) fprintf(stderr, gettext("-u and -p options are mutually "
+ "exclusive\n"));
+ usage(B_FALSE);
+ }
+
+ if (flags.nounmount)
+ types = ZFS_TYPE_FILESYSTEM;
+ else if (parents)
+ types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+ else
+ types = ZFS_TYPE_DATASET;
+
+ if (flags.recurse) {
+ /*
+ * When we do recursive rename we are fine when the given
+ * snapshot for the given dataset doesn't exist - it can
+ * still exists below.
+ */
+
+ snapshot = strchr(argv[0], '@');
+ assert(snapshot != NULL);
+ *snapshot = '\0';
+ snapshot++;
+ }
+
+ if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL)
+ return (1);
+
+ /* If we were asked and the name looks good, try to create ancestors. */
+ if (parents && zfs_name_valid(argv[1], zfs_get_type(zhp)) &&
+ zfs_create_ancestors(g_zfs, argv[1]) != 0) {
+ zfs_close(zhp);
+ return (1);
+ }
+
+ ret = (zfs_rename(zhp, snapshot, argv[1], flags) != 0);
+
+ zfs_close(zhp);
+ return (ret);
+}
+
+/*
+ * zfs promote <fs>
+ *
+ * Promotes the given clone fs to be the parent
+ */
+/* ARGSUSED */
+static int
+zfs_do_promote(int argc, char **argv)
+{
+ zfs_handle_t *zhp;
+ int ret = 0;
+
+ /* check options */
+ if (argc > 1 && argv[1][0] == '-') {
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ argv[1][1]);
+ usage(B_FALSE);
+ }
+
+ /* check number of arguments */
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing clone filesystem"
+ " argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ zhp = zfs_open(g_zfs, argv[1], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ return (1);
+
+ ret = (zfs_promote(zhp) != 0);
+
+
+ zfs_close(zhp);
+ return (ret);
+}
+
+/*
+ * zfs rollback [-rRf] <snapshot>
+ *
+ * -r Delete any intervening snapshots before doing rollback
+ * -R Delete any snapshots and their clones
+ * -f ignored for backwards compatability
+ *
+ * Given a filesystem, rollback to a specific snapshot, discarding any changes
+ * since then and making it the active dataset. If more recent snapshots exist,
+ * the command will complain unless the '-r' flag is given.
+ */
+typedef struct rollback_cbdata {
+ uint64_t cb_create;
+ boolean_t cb_first;
+ int cb_doclones;
+ char *cb_target;
+ int cb_error;
+ boolean_t cb_recurse;
+ boolean_t cb_dependent;
+} rollback_cbdata_t;
+
+/*
+ * Report any snapshots more recent than the one specified. Used when '-r' is
+ * not specified. We reuse this same callback for the snapshot dependents - if
+ * 'cb_dependent' is set, then this is a dependent and we should report it
+ * without checking the transaction group.
+ */
+static int
+rollback_check(zfs_handle_t *zhp, void *data)
+{
+ rollback_cbdata_t *cbp = data;
+
+ if (cbp->cb_doclones) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (!cbp->cb_dependent) {
+ if (strcmp(zfs_get_name(zhp), cbp->cb_target) != 0 &&
+ zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
+ zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
+ cbp->cb_create) {
+
+ if (cbp->cb_first && !cbp->cb_recurse) {
+ (void) fprintf(stderr, gettext("cannot "
+ "rollback to '%s': more recent snapshots "
+ "exist\n"),
+ cbp->cb_target);
+ (void) fprintf(stderr, gettext("use '-r' to "
+ "force deletion of the following "
+ "snapshots:\n"));
+ cbp->cb_first = 0;
+ cbp->cb_error = 1;
+ }
+
+ if (cbp->cb_recurse) {
+ cbp->cb_dependent = B_TRUE;
+ if (zfs_iter_dependents(zhp, B_TRUE,
+ rollback_check, cbp) != 0) {
+ zfs_close(zhp);
+ return (-1);
+ }
+ cbp->cb_dependent = B_FALSE;
+ } else {
+ (void) fprintf(stderr, "%s\n",
+ zfs_get_name(zhp));
+ }
+ }
+ } else {
+ if (cbp->cb_first && cbp->cb_recurse) {
+ (void) fprintf(stderr, gettext("cannot rollback to "
+ "'%s': clones of previous snapshots exist\n"),
+ cbp->cb_target);
+ (void) fprintf(stderr, gettext("use '-R' to "
+ "force deletion of the following clones and "
+ "dependents:\n"));
+ cbp->cb_first = 0;
+ cbp->cb_error = 1;
+ }
+
+ (void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
+ }
+
+ zfs_close(zhp);
+ return (0);
+}
+
+static int
+zfs_do_rollback(int argc, char **argv)
+{
+ int ret = 0;
+ int c;
+ boolean_t force = B_FALSE;
+ rollback_cbdata_t cb = { 0 };
+ zfs_handle_t *zhp, *snap;
+ char parentname[ZFS_MAXNAMELEN];
+ char *delim;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "rRf")) != -1) {
+ switch (c) {
+ case 'r':
+ cb.cb_recurse = 1;
+ break;
+ case 'R':
+ cb.cb_recurse = 1;
+ cb.cb_doclones = 1;
+ break;
+ case 'f':
+ force = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing dataset argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ /* open the snapshot */
+ if ((snap = zfs_open(g_zfs, argv[0], ZFS_TYPE_SNAPSHOT)) == NULL)
+ return (1);
+
+ /* open the parent dataset */
+ (void) strlcpy(parentname, argv[0], sizeof (parentname));
+ verify((delim = strrchr(parentname, '@')) != NULL);
+ *delim = '\0';
+ if ((zhp = zfs_open(g_zfs, parentname, ZFS_TYPE_DATASET)) == NULL) {
+ zfs_close(snap);
+ return (1);
+ }
+
+ /*
+ * Check for more recent snapshots and/or clones based on the presence
+ * of '-r' and '-R'.
+ */
+ cb.cb_target = argv[0];
+ cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
+ cb.cb_first = B_TRUE;
+ cb.cb_error = 0;
+ if ((ret = zfs_iter_children(zhp, rollback_check, &cb)) != 0)
+ goto out;
+
+ if ((ret = cb.cb_error) != 0)
+ goto out;
+
+ /*
+ * Rollback parent to the given snapshot.
+ */
+ ret = zfs_rollback(zhp, snap, force);
+
+out:
+ zfs_close(snap);
+ zfs_close(zhp);
+
+ if (ret == 0)
+ return (0);
+ else
+ return (1);
+}
+
+/*
+ * zfs set property=value { fs | snap | vol } ...
+ *
+ * Sets the given property for all datasets specified on the command line.
+ */
+typedef struct set_cbdata {
+ char *cb_propname;
+ char *cb_value;
+} set_cbdata_t;
+
+static int
+set_callback(zfs_handle_t *zhp, void *data)
+{
+ set_cbdata_t *cbp = data;
+
+ if (zfs_prop_set(zhp, cbp->cb_propname, cbp->cb_value) != 0) {
+ switch (libzfs_errno(g_zfs)) {
+ case EZFS_MOUNTFAILED:
+ (void) fprintf(stderr, gettext("property may be set "
+ "but unable to remount filesystem\n"));
+ break;
+ case EZFS_SHARENFSFAILED:
+ (void) fprintf(stderr, gettext("property may be set "
+ "but unable to reshare filesystem\n"));
+ break;
+ }
+ return (1);
+ }
+ return (0);
+}
+
+static int
+zfs_do_set(int argc, char **argv)
+{
+ set_cbdata_t cb;
+ int ret = 0;
+
+ /* check for options */
+ if (argc > 1 && argv[1][0] == '-') {
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ argv[1][1]);
+ usage(B_FALSE);
+ }
+
+ /* check number of arguments */
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing property=value "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 3) {
+ (void) fprintf(stderr, gettext("missing dataset name\n"));
+ usage(B_FALSE);
+ }
+
+ /* validate property=value argument */
+ cb.cb_propname = argv[1];
+ if (((cb.cb_value = strchr(cb.cb_propname, '=')) == NULL) ||
+ (cb.cb_value[1] == '\0')) {
+ (void) fprintf(stderr, gettext("missing value in "
+ "property=value argument\n"));
+ usage(B_FALSE);
+ }
+
+ *cb.cb_value = '\0';
+ cb.cb_value++;
+
+ if (*cb.cb_propname == '\0') {
+ (void) fprintf(stderr,
+ gettext("missing property in property=value argument\n"));
+ usage(B_FALSE);
+ }
+
+ ret = zfs_for_each(argc - 2, argv + 2, 0,
+ ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, &cb);
+
+ return (ret);
+}
+
+typedef struct snap_cbdata {
+ nvlist_t *sd_nvl;
+ boolean_t sd_recursive;
+ const char *sd_snapname;
+} snap_cbdata_t;
+
+static int
+zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
+{
+ snap_cbdata_t *sd = arg;
+ char *name;
+ int rv = 0;
+ int error;
+
+ error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+ if (error == -1)
+ nomem();
+ fnvlist_add_boolean(sd->sd_nvl, name);
+ free(name);
+
+ if (sd->sd_recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ zfs_close(zhp);
+ return (rv);
+}
+
+/*
+ * zfs snapshot [-r] [-o prop=value] ... <fs@snap>
+ *
+ * Creates a snapshot with the given name. While functionally equivalent to
+ * 'zfs create', it is a separate command to differentiate intent.
+ */
+static int
+zfs_do_snapshot(int argc, char **argv)
+{
+ int ret = 0;
+ char c;
+ nvlist_t *props;
+ snap_cbdata_t sd = { 0 };
+ boolean_t multiple_snaps = B_FALSE;
+
+ if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+ if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ /* check options */
+ while ((c = getopt(argc, argv, "ro:")) != -1) {
+ switch (c) {
+ case 'o':
+ if (parseprop(props))
+ return (1);
+ break;
+ case 'r':
+ sd.sd_recursive = B_TRUE;
+ multiple_snaps = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ goto usage;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing snapshot argument\n"));
+ goto usage;
+ }
+
+ if (argc > 1)
+ multiple_snaps = B_TRUE;
+ for (; argc > 0; argc--, argv++) {
+ char *atp;
+ zfs_handle_t *zhp;
+
+ atp = strchr(argv[0], '@');
+ if (atp == NULL)
+ goto usage;
+ *atp = '\0';
+ sd.sd_snapname = atp + 1;
+ zhp = zfs_open(g_zfs, argv[0],
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ goto usage;
+ if (zfs_snapshot_cb(zhp, &sd) != 0)
+ goto usage;
+ }
+
+ ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
+ nvlist_free(sd.sd_nvl);
+ nvlist_free(props);
+ if (ret != 0 && multiple_snaps)
+ (void) fprintf(stderr, gettext("no snapshots were created\n"));
+ return (ret != 0);
+
+usage:
+ nvlist_free(sd.sd_nvl);
+ nvlist_free(props);
+ usage(B_FALSE);
+ return (-1);
+}
+
+/*
+ * Send a backup stream to stdout.
+ */
+static int
+zfs_do_send(int argc, char **argv)
+{
+ char *fromname = NULL;
+ char *toname = NULL;
+ char *cp;
+ zfs_handle_t *zhp;
+ sendflags_t flags = { 0 };
+ int c, err;
+ nvlist_t *dbgnv = NULL;
+ boolean_t extraverbose = B_FALSE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":i:I:RDpvnP")) != -1) {
+ switch (c) {
+ case 'i':
+ if (fromname)
+ usage(B_FALSE);
+ fromname = optarg;
+ break;
+ case 'I':
+ if (fromname)
+ usage(B_FALSE);
+ fromname = optarg;
+ flags.doall = B_TRUE;
+ break;
+ case 'R':
+ flags.replicate = B_TRUE;
+ break;
+ case 'p':
+ flags.props = B_TRUE;
+ break;
+ case 'P':
+ flags.parsable = B_TRUE;
+ flags.verbose = B_TRUE;
+ break;
+ case 'v':
+ if (flags.verbose)
+ extraverbose = B_TRUE;
+ flags.verbose = B_TRUE;
+ flags.progress = B_TRUE;
+ break;
+ case 'D':
+ flags.dedup = B_TRUE;
+ break;
+ case 'n':
+ flags.dryrun = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing snapshot argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if (!flags.dryrun && isatty(STDOUT_FILENO)) {
+ (void) fprintf(stderr,
+ gettext("Error: Stream can not be written to a terminal.\n"
+ "You must redirect standard output.\n"));
+ return (1);
+ }
+
+ cp = strchr(argv[0], '@');
+ if (cp == NULL) {
+ (void) fprintf(stderr,
+ gettext("argument must be a snapshot\n"));
+ usage(B_FALSE);
+ }
+ *cp = '\0';
+ toname = cp + 1;
+ zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ return (1);
+
+ /*
+ * If they specified the full path to the snapshot, chop off
+ * everything except the short name of the snapshot, but special
+ * case if they specify the origin.
+ */
+ if (fromname && (cp = strchr(fromname, '@')) != NULL) {
+ char origin[ZFS_MAXNAMELEN];
+ zprop_source_t src;
+
+ (void) zfs_prop_get(zhp, ZFS_PROP_ORIGIN,
+ origin, sizeof (origin), &src, NULL, 0, B_FALSE);
+
+ if (strcmp(origin, fromname) == 0) {
+ fromname = NULL;
+ flags.fromorigin = B_TRUE;
+ } else {
+ *cp = '\0';
+ if (cp != fromname && strcmp(argv[0], fromname)) {
+ (void) fprintf(stderr,
+ gettext("incremental source must be "
+ "in same filesystem\n"));
+ usage(B_FALSE);
+ }
+ fromname = cp + 1;
+ if (strchr(fromname, '@') || strchr(fromname, '/')) {
+ (void) fprintf(stderr,
+ gettext("invalid incremental source\n"));
+ usage(B_FALSE);
+ }
+ }
+ }
+
+ if (flags.replicate && fromname == NULL)
+ flags.doall = B_TRUE;
+
+ err = zfs_send(zhp, fromname, toname, &flags, STDOUT_FILENO, NULL, 0,
+ extraverbose ? &dbgnv : NULL);
+
+ if (extraverbose && dbgnv != NULL) {
+ /*
+ * dump_nvlist prints to stdout, but that's been
+ * redirected to a file. Make it print to stderr
+ * instead.
+ */
+ (void) dup2(STDERR_FILENO, STDOUT_FILENO);
+ dump_nvlist(dbgnv, 0);
+ nvlist_free(dbgnv);
+ }
+ zfs_close(zhp);
+
+ return (err != 0);
+}
+
+/*
+ * zfs receive [-vnFu] [-d | -e] <fs@snap>
+ *
+ * Restore a backup stream from stdin.
+ */
+static int
+zfs_do_receive(int argc, char **argv)
+{
+ int c, err;
+ recvflags_t flags = { 0 };
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":denuvF")) != -1) {
+ switch (c) {
+ case 'd':
+ flags.isprefix = B_TRUE;
+ break;
+ case 'e':
+ flags.isprefix = B_TRUE;
+ flags.istail = B_TRUE;
+ break;
+ case 'n':
+ flags.dryrun = B_TRUE;
+ break;
+ case 'u':
+ flags.nomount = B_TRUE;
+ break;
+ case 'v':
+ flags.verbose = B_TRUE;
+ break;
+ case 'F':
+ flags.force = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing snapshot argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if (isatty(STDIN_FILENO)) {
+ (void) fprintf(stderr,
+ gettext("Error: Backup stream can not be read "
+ "from a terminal.\n"
+ "You must redirect standard input.\n"));
+ return (1);
+ }
+
+ err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
+
+ return (err != 0);
+}
+
+/*
+ * allow/unallow stuff
+ */
+/* copied from zfs/sys/dsl_deleg.h */
+#define ZFS_DELEG_PERM_CREATE "create"
+#define ZFS_DELEG_PERM_DESTROY "destroy"
+#define ZFS_DELEG_PERM_SNAPSHOT "snapshot"
+#define ZFS_DELEG_PERM_ROLLBACK "rollback"
+#define ZFS_DELEG_PERM_CLONE "clone"
+#define ZFS_DELEG_PERM_PROMOTE "promote"
+#define ZFS_DELEG_PERM_RENAME "rename"
+#define ZFS_DELEG_PERM_MOUNT "mount"
+#define ZFS_DELEG_PERM_SHARE "share"
+#define ZFS_DELEG_PERM_SEND "send"
+#define ZFS_DELEG_PERM_RECEIVE "receive"
+#define ZFS_DELEG_PERM_ALLOW "allow"
+#define ZFS_DELEG_PERM_USERPROP "userprop"
+#define ZFS_DELEG_PERM_VSCAN "vscan" /* ??? */
+#define ZFS_DELEG_PERM_USERQUOTA "userquota"
+#define ZFS_DELEG_PERM_GROUPQUOTA "groupquota"
+#define ZFS_DELEG_PERM_USERUSED "userused"
+#define ZFS_DELEG_PERM_GROUPUSED "groupused"
+#define ZFS_DELEG_PERM_HOLD "hold"
+#define ZFS_DELEG_PERM_RELEASE "release"
+#define ZFS_DELEG_PERM_DIFF "diff"
+
+#define ZFS_NUM_DELEG_NOTES ZFS_DELEG_NOTE_NONE
+
+static zfs_deleg_perm_tab_t zfs_deleg_perm_tbl[] = {
+ { ZFS_DELEG_PERM_ALLOW, ZFS_DELEG_NOTE_ALLOW },
+ { ZFS_DELEG_PERM_CLONE, ZFS_DELEG_NOTE_CLONE },
+ { ZFS_DELEG_PERM_CREATE, ZFS_DELEG_NOTE_CREATE },
+ { ZFS_DELEG_PERM_DESTROY, ZFS_DELEG_NOTE_DESTROY },
+ { ZFS_DELEG_PERM_DIFF, ZFS_DELEG_NOTE_DIFF},
+ { ZFS_DELEG_PERM_HOLD, ZFS_DELEG_NOTE_HOLD },
+ { ZFS_DELEG_PERM_MOUNT, ZFS_DELEG_NOTE_MOUNT },
+ { ZFS_DELEG_PERM_PROMOTE, ZFS_DELEG_NOTE_PROMOTE },
+ { ZFS_DELEG_PERM_RECEIVE, ZFS_DELEG_NOTE_RECEIVE },
+ { ZFS_DELEG_PERM_RELEASE, ZFS_DELEG_NOTE_RELEASE },
+ { ZFS_DELEG_PERM_RENAME, ZFS_DELEG_NOTE_RENAME },
+ { ZFS_DELEG_PERM_ROLLBACK, ZFS_DELEG_NOTE_ROLLBACK },
+ { ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND },
+ { ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE },
+ { ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT },
+
+ { ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA },
+ { ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED },
+ { ZFS_DELEG_PERM_USERPROP, ZFS_DELEG_NOTE_USERPROP },
+ { ZFS_DELEG_PERM_USERQUOTA, ZFS_DELEG_NOTE_USERQUOTA },
+ { ZFS_DELEG_PERM_USERUSED, ZFS_DELEG_NOTE_USERUSED },
+ { NULL, ZFS_DELEG_NOTE_NONE }
+};
+
+/* permission structure */
+typedef struct deleg_perm {
+ zfs_deleg_who_type_t dp_who_type;
+ const char *dp_name;
+ boolean_t dp_local;
+ boolean_t dp_descend;
+} deleg_perm_t;
+
+/* */
+typedef struct deleg_perm_node {
+ deleg_perm_t dpn_perm;
+
+ uu_avl_node_t dpn_avl_node;
+} deleg_perm_node_t;
+
+typedef struct fs_perm fs_perm_t;
+
+/* permissions set */
+typedef struct who_perm {
+ zfs_deleg_who_type_t who_type;
+ const char *who_name; /* id */
+ char who_ug_name[256]; /* user/group name */
+ fs_perm_t *who_fsperm; /* uplink */
+
+ uu_avl_t *who_deleg_perm_avl; /* permissions */
+} who_perm_t;
+
+/* */
+typedef struct who_perm_node {
+ who_perm_t who_perm;
+ uu_avl_node_t who_avl_node;
+} who_perm_node_t;
+
+typedef struct fs_perm_set fs_perm_set_t;
+/* fs permissions */
+struct fs_perm {
+ const char *fsp_name;
+
+ uu_avl_t *fsp_sc_avl; /* sets,create */
+ uu_avl_t *fsp_uge_avl; /* user,group,everyone */
+
+ fs_perm_set_t *fsp_set; /* uplink */
+};
+
+/* */
+typedef struct fs_perm_node {
+ fs_perm_t fspn_fsperm;
+ uu_avl_t *fspn_avl;
+
+ uu_list_node_t fspn_list_node;
+} fs_perm_node_t;
+
+/* top level structure */
+struct fs_perm_set {
+ uu_list_pool_t *fsps_list_pool;
+ uu_list_t *fsps_list; /* list of fs_perms */
+
+ uu_avl_pool_t *fsps_named_set_avl_pool;
+ uu_avl_pool_t *fsps_who_perm_avl_pool;
+ uu_avl_pool_t *fsps_deleg_perm_avl_pool;
+};
+
+static inline const char *
+deleg_perm_type(zfs_deleg_note_t note)
+{
+ /* subcommands */
+ switch (note) {
+ /* SUBCOMMANDS */
+ /* OTHER */
+ case ZFS_DELEG_NOTE_GROUPQUOTA:
+ case ZFS_DELEG_NOTE_GROUPUSED:
+ case ZFS_DELEG_NOTE_USERPROP:
+ case ZFS_DELEG_NOTE_USERQUOTA:
+ case ZFS_DELEG_NOTE_USERUSED:
+ /* other */
+ return (gettext("other"));
+ default:
+ return (gettext("subcommand"));
+ }
+}
+
+static int inline
+who_type2weight(zfs_deleg_who_type_t who_type)
+{
+ int res;
+ switch (who_type) {
+ case ZFS_DELEG_NAMED_SET_SETS:
+ case ZFS_DELEG_NAMED_SET:
+ res = 0;
+ break;
+ case ZFS_DELEG_CREATE_SETS:
+ case ZFS_DELEG_CREATE:
+ res = 1;
+ break;
+ case ZFS_DELEG_USER_SETS:
+ case ZFS_DELEG_USER:
+ res = 2;
+ break;
+ case ZFS_DELEG_GROUP_SETS:
+ case ZFS_DELEG_GROUP:
+ res = 3;
+ break;
+ case ZFS_DELEG_EVERYONE_SETS:
+ case ZFS_DELEG_EVERYONE:
+ res = 4;
+ break;
+ default:
+ res = -1;
+ }
+
+ return (res);
+}
+
+/* ARGSUSED */
+static int
+who_perm_compare(const void *larg, const void *rarg, void *unused)
+{
+ const who_perm_node_t *l = larg;
+ const who_perm_node_t *r = rarg;
+ zfs_deleg_who_type_t ltype = l->who_perm.who_type;
+ zfs_deleg_who_type_t rtype = r->who_perm.who_type;
+ int lweight = who_type2weight(ltype);
+ int rweight = who_type2weight(rtype);
+ int res = lweight - rweight;
+ if (res == 0)
+ res = strncmp(l->who_perm.who_name, r->who_perm.who_name,
+ ZFS_MAX_DELEG_NAME-1);
+
+ if (res == 0)
+ return (0);
+ if (res > 0)
+ return (1);
+ else
+ return (-1);
+}
+
+/* ARGSUSED */
+static int
+deleg_perm_compare(const void *larg, const void *rarg, void *unused)
+{
+ const deleg_perm_node_t *l = larg;
+ const deleg_perm_node_t *r = rarg;
+ int res = strncmp(l->dpn_perm.dp_name, r->dpn_perm.dp_name,
+ ZFS_MAX_DELEG_NAME-1);
+
+ if (res == 0)
+ return (0);
+
+ if (res > 0)
+ return (1);
+ else
+ return (-1);
+}
+
+static inline void
+fs_perm_set_init(fs_perm_set_t *fspset)
+{
+ bzero(fspset, sizeof (fs_perm_set_t));
+
+ if ((fspset->fsps_list_pool = uu_list_pool_create("fsps_list_pool",
+ sizeof (fs_perm_node_t), offsetof(fs_perm_node_t, fspn_list_node),
+ NULL, UU_DEFAULT)) == NULL)
+ nomem();
+ if ((fspset->fsps_list = uu_list_create(fspset->fsps_list_pool, NULL,
+ UU_DEFAULT)) == NULL)
+ nomem();
+
+ if ((fspset->fsps_named_set_avl_pool = uu_avl_pool_create(
+ "named_set_avl_pool", sizeof (who_perm_node_t), offsetof(
+ who_perm_node_t, who_avl_node), who_perm_compare,
+ UU_DEFAULT)) == NULL)
+ nomem();
+
+ if ((fspset->fsps_who_perm_avl_pool = uu_avl_pool_create(
+ "who_perm_avl_pool", sizeof (who_perm_node_t), offsetof(
+ who_perm_node_t, who_avl_node), who_perm_compare,
+ UU_DEFAULT)) == NULL)
+ nomem();
+
+ if ((fspset->fsps_deleg_perm_avl_pool = uu_avl_pool_create(
+ "deleg_perm_avl_pool", sizeof (deleg_perm_node_t), offsetof(
+ deleg_perm_node_t, dpn_avl_node), deleg_perm_compare, UU_DEFAULT))
+ == NULL)
+ nomem();
+}
+
+static inline void fs_perm_fini(fs_perm_t *);
+static inline void who_perm_fini(who_perm_t *);
+
+static inline void
+fs_perm_set_fini(fs_perm_set_t *fspset)
+{
+ fs_perm_node_t *node = uu_list_first(fspset->fsps_list);
+
+ while (node != NULL) {
+ fs_perm_node_t *next_node =
+ uu_list_next(fspset->fsps_list, node);
+ fs_perm_t *fsperm = &node->fspn_fsperm;
+ fs_perm_fini(fsperm);
+ uu_list_remove(fspset->fsps_list, node);
+ free(node);
+ node = next_node;
+ }
+
+ uu_avl_pool_destroy(fspset->fsps_named_set_avl_pool);
+ uu_avl_pool_destroy(fspset->fsps_who_perm_avl_pool);
+ uu_avl_pool_destroy(fspset->fsps_deleg_perm_avl_pool);
+}
+
+static inline void
+deleg_perm_init(deleg_perm_t *deleg_perm, zfs_deleg_who_type_t type,
+ const char *name)
+{
+ deleg_perm->dp_who_type = type;
+ deleg_perm->dp_name = name;
+}
+
+static inline void
+who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
+ zfs_deleg_who_type_t type, const char *name)
+{
+ uu_avl_pool_t *pool;
+ pool = fsperm->fsp_set->fsps_deleg_perm_avl_pool;
+
+ bzero(who_perm, sizeof (who_perm_t));
+
+ if ((who_perm->who_deleg_perm_avl = uu_avl_create(pool, NULL,
+ UU_DEFAULT)) == NULL)
+ nomem();
+
+ who_perm->who_type = type;
+ who_perm->who_name = name;
+ who_perm->who_fsperm = fsperm;
+}
+
+static inline void
+who_perm_fini(who_perm_t *who_perm)
+{
+ deleg_perm_node_t *node = uu_avl_first(who_perm->who_deleg_perm_avl);
+
+ while (node != NULL) {
+ deleg_perm_node_t *next_node =
+ uu_avl_next(who_perm->who_deleg_perm_avl, node);
+
+ uu_avl_remove(who_perm->who_deleg_perm_avl, node);
+ free(node);
+ node = next_node;
+ }
+
+ uu_avl_destroy(who_perm->who_deleg_perm_avl);
+}
+
+static inline void
+fs_perm_init(fs_perm_t *fsperm, fs_perm_set_t *fspset, const char *fsname)
+{
+ uu_avl_pool_t *nset_pool = fspset->fsps_named_set_avl_pool;
+ uu_avl_pool_t *who_pool = fspset->fsps_who_perm_avl_pool;
+
+ bzero(fsperm, sizeof (fs_perm_t));
+
+ if ((fsperm->fsp_sc_avl = uu_avl_create(nset_pool, NULL, UU_DEFAULT))
+ == NULL)
+ nomem();
+
+ if ((fsperm->fsp_uge_avl = uu_avl_create(who_pool, NULL, UU_DEFAULT))
+ == NULL)
+ nomem();
+
+ fsperm->fsp_set = fspset;
+ fsperm->fsp_name = fsname;
+}
+
+static inline void
+fs_perm_fini(fs_perm_t *fsperm)
+{
+ who_perm_node_t *node = uu_avl_first(fsperm->fsp_sc_avl);
+ while (node != NULL) {
+ who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_sc_avl,
+ node);
+ who_perm_t *who_perm = &node->who_perm;
+ who_perm_fini(who_perm);
+ uu_avl_remove(fsperm->fsp_sc_avl, node);
+ free(node);
+ node = next_node;
+ }
+
+ node = uu_avl_first(fsperm->fsp_uge_avl);
+ while (node != NULL) {
+ who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_uge_avl,
+ node);
+ who_perm_t *who_perm = &node->who_perm;
+ who_perm_fini(who_perm);
+ uu_avl_remove(fsperm->fsp_uge_avl, node);
+ free(node);
+ node = next_node;
+ }
+
+ uu_avl_destroy(fsperm->fsp_sc_avl);
+ uu_avl_destroy(fsperm->fsp_uge_avl);
+}
+
+static void inline
+set_deleg_perm_node(uu_avl_t *avl, deleg_perm_node_t *node,
+ zfs_deleg_who_type_t who_type, const char *name, char locality)
+{
+ uu_avl_index_t idx = 0;
+
+ deleg_perm_node_t *found_node = NULL;
+ deleg_perm_t *deleg_perm = &node->dpn_perm;
+
+ deleg_perm_init(deleg_perm, who_type, name);
+
+ if ((found_node = uu_avl_find(avl, node, NULL, &idx))
+ == NULL)
+ uu_avl_insert(avl, node, idx);
+ else {
+ node = found_node;
+ deleg_perm = &node->dpn_perm;
+ }
+
+
+ switch (locality) {
+ case ZFS_DELEG_LOCAL:
+ deleg_perm->dp_local = B_TRUE;
+ break;
+ case ZFS_DELEG_DESCENDENT:
+ deleg_perm->dp_descend = B_TRUE;
+ break;
+ case ZFS_DELEG_NA:
+ break;
+ default:
+ assert(B_FALSE); /* invalid locality */
+ }
+}
+
+static inline int
+parse_who_perm(who_perm_t *who_perm, nvlist_t *nvl, char locality)
+{
+ nvpair_t *nvp = NULL;
+ fs_perm_set_t *fspset = who_perm->who_fsperm->fsp_set;
+ uu_avl_t *avl = who_perm->who_deleg_perm_avl;
+ zfs_deleg_who_type_t who_type = who_perm->who_type;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ const char *name = nvpair_name(nvp);
+ data_type_t type = nvpair_type(nvp);
+ uu_avl_pool_t *avl_pool = fspset->fsps_deleg_perm_avl_pool;
+ deleg_perm_node_t *node =
+ safe_malloc(sizeof (deleg_perm_node_t));
+
+ assert(type == DATA_TYPE_BOOLEAN);
+
+ uu_avl_node_init(node, &node->dpn_avl_node, avl_pool);
+ set_deleg_perm_node(avl, node, who_type, name, locality);
+ }
+
+ return (0);
+}
+
+static inline int
+parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
+{
+ nvpair_t *nvp = NULL;
+ fs_perm_set_t *fspset = fsperm->fsp_set;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ nvlist_t *nvl2 = NULL;
+ const char *name = nvpair_name(nvp);
+ uu_avl_t *avl = NULL;
+ uu_avl_pool_t *avl_pool;
+ zfs_deleg_who_type_t perm_type = name[0];
+ char perm_locality = name[1];
+ const char *perm_name = name + 3;
+ boolean_t is_set = B_TRUE;
+ who_perm_t *who_perm = NULL;
+
+ assert('$' == name[2]);
+
+ if (nvpair_value_nvlist(nvp, &nvl2) != 0)
+ return (-1);
+
+ switch (perm_type) {
+ case ZFS_DELEG_CREATE:
+ case ZFS_DELEG_CREATE_SETS:
+ case ZFS_DELEG_NAMED_SET:
+ case ZFS_DELEG_NAMED_SET_SETS:
+ avl_pool = fspset->fsps_named_set_avl_pool;
+ avl = fsperm->fsp_sc_avl;
+ break;
+ case ZFS_DELEG_USER:
+ case ZFS_DELEG_USER_SETS:
+ case ZFS_DELEG_GROUP:
+ case ZFS_DELEG_GROUP_SETS:
+ case ZFS_DELEG_EVERYONE:
+ case ZFS_DELEG_EVERYONE_SETS:
+ avl_pool = fspset->fsps_who_perm_avl_pool;
+ avl = fsperm->fsp_uge_avl;
+ break;
+ }
+
+ if (is_set) {
+ who_perm_node_t *found_node = NULL;
+ who_perm_node_t *node = safe_malloc(
+ sizeof (who_perm_node_t));
+ who_perm = &node->who_perm;
+ uu_avl_index_t idx = 0;
+
+ uu_avl_node_init(node, &node->who_avl_node, avl_pool);
+ who_perm_init(who_perm, fsperm, perm_type, perm_name);
+
+ if ((found_node = uu_avl_find(avl, node, NULL, &idx))
+ == NULL) {
+ if (avl == fsperm->fsp_uge_avl) {
+ uid_t rid = 0;
+ struct passwd *p = NULL;
+ struct group *g = NULL;
+ const char *nice_name = NULL;
+
+ switch (perm_type) {
+ case ZFS_DELEG_USER_SETS:
+ case ZFS_DELEG_USER:
+ rid = atoi(perm_name);
+ p = getpwuid(rid);
+ if (p)
+ nice_name = p->pw_name;
+ break;
+ case ZFS_DELEG_GROUP_SETS:
+ case ZFS_DELEG_GROUP:
+ rid = atoi(perm_name);
+ g = getgrgid(rid);
+ if (g)
+ nice_name = g->gr_name;
+ break;
+ }
+
+ if (nice_name != NULL)
+ (void) strlcpy(
+ node->who_perm.who_ug_name,
+ nice_name, 256);
+ }
+
+ uu_avl_insert(avl, node, idx);
+ } else {
+ node = found_node;
+ who_perm = &node->who_perm;
+ }
+ }
+
+ (void) parse_who_perm(who_perm, nvl2, perm_locality);
+ }
+
+ return (0);
+}
+
+static inline int
+parse_fs_perm_set(fs_perm_set_t *fspset, nvlist_t *nvl)
+{
+ nvpair_t *nvp = NULL;
+ uu_avl_index_t idx = 0;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ nvlist_t *nvl2 = NULL;
+ const char *fsname = nvpair_name(nvp);
+ data_type_t type = nvpair_type(nvp);
+ fs_perm_t *fsperm = NULL;
+ fs_perm_node_t *node = safe_malloc(sizeof (fs_perm_node_t));
+ if (node == NULL)
+ nomem();
+
+ fsperm = &node->fspn_fsperm;
+
+ assert(DATA_TYPE_NVLIST == type);
+
+ uu_list_node_init(node, &node->fspn_list_node,
+ fspset->fsps_list_pool);
+
+ idx = uu_list_numnodes(fspset->fsps_list);
+ fs_perm_init(fsperm, fspset, fsname);
+
+ if (nvpair_value_nvlist(nvp, &nvl2) != 0)
+ return (-1);
+
+ (void) parse_fs_perm(fsperm, nvl2);
+
+ uu_list_insert(fspset->fsps_list, node, idx);
+ }
+
+ return (0);
+}
+
+static inline const char *
+deleg_perm_comment(zfs_deleg_note_t note)
+{
+ const char *str = "";
+
+ /* subcommands */
+ switch (note) {
+ /* SUBCOMMANDS */
+ case ZFS_DELEG_NOTE_ALLOW:
+ str = gettext("Must also have the permission that is being"
+ "\n\t\t\t\tallowed");
+ break;
+ case ZFS_DELEG_NOTE_CLONE:
+ str = gettext("Must also have the 'create' ability and 'mount'"
+ "\n\t\t\t\tability in the origin file system");
+ break;
+ case ZFS_DELEG_NOTE_CREATE:
+ str = gettext("Must also have the 'mount' ability");
+ break;
+ case ZFS_DELEG_NOTE_DESTROY:
+ str = gettext("Must also have the 'mount' ability");
+ break;
+ case ZFS_DELEG_NOTE_DIFF:
+ str = gettext("Allows lookup of paths within a dataset;"
+ "\n\t\t\t\tgiven an object number. Ordinary users need this"
+ "\n\t\t\t\tin order to use zfs diff");
+ break;
+ case ZFS_DELEG_NOTE_HOLD:
+ str = gettext("Allows adding a user hold to a snapshot");
+ break;
+ case ZFS_DELEG_NOTE_MOUNT:
+ str = gettext("Allows mount/umount of ZFS datasets");
+ break;
+ case ZFS_DELEG_NOTE_PROMOTE:
+ str = gettext("Must also have the 'mount'\n\t\t\t\tand"
+ " 'promote' ability in the origin file system");
+ break;
+ case ZFS_DELEG_NOTE_RECEIVE:
+ str = gettext("Must also have the 'mount' and 'create'"
+ " ability");
+ break;
+ case ZFS_DELEG_NOTE_RELEASE:
+ str = gettext("Allows releasing a user hold which\n\t\t\t\t"
+ "might destroy the snapshot");
+ break;
+ case ZFS_DELEG_NOTE_RENAME:
+ str = gettext("Must also have the 'mount' and 'create'"
+ "\n\t\t\t\tability in the new parent");
+ break;
+ case ZFS_DELEG_NOTE_ROLLBACK:
+ str = gettext("");
+ break;
+ case ZFS_DELEG_NOTE_SEND:
+ str = gettext("");
+ break;
+ case ZFS_DELEG_NOTE_SHARE:
+ str = gettext("Allows sharing file systems over NFS or SMB"
+ "\n\t\t\t\tprotocols");
+ break;
+ case ZFS_DELEG_NOTE_SNAPSHOT:
+ str = gettext("");
+ break;
+/*
+ * case ZFS_DELEG_NOTE_VSCAN:
+ * str = gettext("");
+ * break;
+ */
+ /* OTHER */
+ case ZFS_DELEG_NOTE_GROUPQUOTA:
+ str = gettext("Allows accessing any groupquota@... property");
+ break;
+ case ZFS_DELEG_NOTE_GROUPUSED:
+ str = gettext("Allows reading any groupused@... property");
+ break;
+ case ZFS_DELEG_NOTE_USERPROP:
+ str = gettext("Allows changing any user property");
+ break;
+ case ZFS_DELEG_NOTE_USERQUOTA:
+ str = gettext("Allows accessing any userquota@... property");
+ break;
+ case ZFS_DELEG_NOTE_USERUSED:
+ str = gettext("Allows reading any userused@... property");
+ break;
+ /* other */
+ default:
+ str = "";
+ }
+
+ return (str);
+}
+
+struct allow_opts {
+ boolean_t local;
+ boolean_t descend;
+ boolean_t user;
+ boolean_t group;
+ boolean_t everyone;
+ boolean_t create;
+ boolean_t set;
+ boolean_t recursive; /* unallow only */
+ boolean_t prt_usage;
+
+ boolean_t prt_perms;
+ char *who;
+ char *perms;
+ const char *dataset;
+};
+
+static inline int
+prop_cmp(const void *a, const void *b)
+{
+ const char *str1 = *(const char **)a;
+ const char *str2 = *(const char **)b;
+ return (strcmp(str1, str2));
+}
+
+static void
+allow_usage(boolean_t un, boolean_t requested, const char *msg)
+{
+ const char *opt_desc[] = {
+ "-h", gettext("show this help message and exit"),
+ "-l", gettext("set permission locally"),
+ "-d", gettext("set permission for descents"),
+ "-u", gettext("set permission for user"),
+ "-g", gettext("set permission for group"),
+ "-e", gettext("set permission for everyone"),
+ "-c", gettext("set create time permission"),
+ "-s", gettext("define permission set"),
+ /* unallow only */
+ "-r", gettext("remove permissions recursively"),
+ };
+ size_t unallow_size = sizeof (opt_desc) / sizeof (char *);
+ size_t allow_size = unallow_size - 2;
+ const char *props[ZFS_NUM_PROPS];
+ int i;
+ size_t count = 0;
+ FILE *fp = requested ? stdout : stderr;
+ zprop_desc_t *pdtbl = zfs_prop_get_table();
+ const char *fmt = gettext("%-16s %-14s\t%s\n");
+
+ (void) fprintf(fp, gettext("Usage: %s\n"), get_usage(un ? HELP_UNALLOW :
+ HELP_ALLOW));
+ (void) fprintf(fp, gettext("Options:\n"));
+ for (i = 0; i < (un ? unallow_size : allow_size); i++) {
+ const char *opt = opt_desc[i++];
+ const char *optdsc = opt_desc[i];
+ (void) fprintf(fp, gettext(" %-10s %s\n"), opt, optdsc);
+ }
+
+ (void) fprintf(fp, gettext("\nThe following permissions are "
+ "supported:\n\n"));
+ (void) fprintf(fp, fmt, gettext("NAME"), gettext("TYPE"),
+ gettext("NOTES"));
+ for (i = 0; i < ZFS_NUM_DELEG_NOTES; i++) {
+ const char *perm_name = zfs_deleg_perm_tbl[i].z_perm;
+ zfs_deleg_note_t perm_note = zfs_deleg_perm_tbl[i].z_note;
+ const char *perm_type = deleg_perm_type(perm_note);
+ const char *perm_comment = deleg_perm_comment(perm_note);
+ (void) fprintf(fp, fmt, perm_name, perm_type, perm_comment);
+ }
+
+ for (i = 0; i < ZFS_NUM_PROPS; i++) {
+ zprop_desc_t *pd = &pdtbl[i];
+ if (pd->pd_visible != B_TRUE)
+ continue;
+
+ if (pd->pd_attr == PROP_READONLY)
+ continue;
+
+ props[count++] = pd->pd_name;
+ }
+ props[count] = NULL;
+
+ qsort(props, count, sizeof (char *), prop_cmp);
+
+ for (i = 0; i < count; i++)
+ (void) fprintf(fp, fmt, props[i], gettext("property"), "");
+
+ if (msg != NULL)
+ (void) fprintf(fp, gettext("\nzfs: error: %s"), msg);
+
+ exit(requested ? 0 : 2);
+}
+
+static inline const char *
+munge_args(int argc, char **argv, boolean_t un, size_t expected_argc,
+ char **permsp)
+{
+ if (un && argc == expected_argc - 1)
+ *permsp = NULL;
+ else if (argc == expected_argc)
+ *permsp = argv[argc - 2];
+ else
+ allow_usage(un, B_FALSE,
+ gettext("wrong number of parameters\n"));
+
+ return (argv[argc - 1]);
+}
+
+static void
+parse_allow_args(int argc, char **argv, boolean_t un, struct allow_opts *opts)
+{
+ int uge_sum = opts->user + opts->group + opts->everyone;
+ int csuge_sum = opts->create + opts->set + uge_sum;
+ int ldcsuge_sum = csuge_sum + opts->local + opts->descend;
+ int all_sum = un ? ldcsuge_sum + opts->recursive : ldcsuge_sum;
+
+ if (uge_sum > 1)
+ allow_usage(un, B_FALSE,
+ gettext("-u, -g, and -e are mutually exclusive\n"));
+
+ if (opts->prt_usage)
+ if (argc == 0 && all_sum == 0)
+ allow_usage(un, B_TRUE, NULL);
+ else
+ usage(B_FALSE);
+
+ if (opts->set) {
+ if (csuge_sum > 1)
+ allow_usage(un, B_FALSE,
+ gettext("invalid options combined with -s\n"));
+
+ opts->dataset = munge_args(argc, argv, un, 3, &opts->perms);
+ if (argv[0][0] != '@')
+ allow_usage(un, B_FALSE,
+ gettext("invalid set name: missing '@' prefix\n"));
+ opts->who = argv[0];
+ } else if (opts->create) {
+ if (ldcsuge_sum > 1)
+ allow_usage(un, B_FALSE,
+ gettext("invalid options combined with -c\n"));
+ opts->dataset = munge_args(argc, argv, un, 2, &opts->perms);
+ } else if (opts->everyone) {
+ if (csuge_sum > 1)
+ allow_usage(un, B_FALSE,
+ gettext("invalid options combined with -e\n"));
+ opts->dataset = munge_args(argc, argv, un, 2, &opts->perms);
+ } else if (uge_sum == 0 && argc > 0 && strcmp(argv[0], "everyone")
+ == 0) {
+ opts->everyone = B_TRUE;
+ argc--;
+ argv++;
+ opts->dataset = munge_args(argc, argv, un, 2, &opts->perms);
+ } else if (argc == 1 && !un) {
+ opts->prt_perms = B_TRUE;
+ opts->dataset = argv[argc-1];
+ } else {
+ opts->dataset = munge_args(argc, argv, un, 3, &opts->perms);
+ opts->who = argv[0];
+ }
+
+ if (!opts->local && !opts->descend) {
+ opts->local = B_TRUE;
+ opts->descend = B_TRUE;
+ }
+}
+
+static void
+store_allow_perm(zfs_deleg_who_type_t type, boolean_t local, boolean_t descend,
+ const char *who, char *perms, nvlist_t *top_nvl)
+{
+ int i;
+ char ld[2] = { '\0', '\0' };
+ char who_buf[ZFS_MAXNAMELEN+32];
+ char base_type;
+ char set_type;
+ nvlist_t *base_nvl = NULL;
+ nvlist_t *set_nvl = NULL;
+ nvlist_t *nvl;
+
+ if (nvlist_alloc(&base_nvl, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+ if (nvlist_alloc(&set_nvl, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ switch (type) {
+ case ZFS_DELEG_NAMED_SET_SETS:
+ case ZFS_DELEG_NAMED_SET:
+ set_type = ZFS_DELEG_NAMED_SET_SETS;
+ base_type = ZFS_DELEG_NAMED_SET;
+ ld[0] = ZFS_DELEG_NA;
+ break;
+ case ZFS_DELEG_CREATE_SETS:
+ case ZFS_DELEG_CREATE:
+ set_type = ZFS_DELEG_CREATE_SETS;
+ base_type = ZFS_DELEG_CREATE;
+ ld[0] = ZFS_DELEG_NA;
+ break;
+ case ZFS_DELEG_USER_SETS:
+ case ZFS_DELEG_USER:
+ set_type = ZFS_DELEG_USER_SETS;
+ base_type = ZFS_DELEG_USER;
+ if (local)
+ ld[0] = ZFS_DELEG_LOCAL;
+ if (descend)
+ ld[1] = ZFS_DELEG_DESCENDENT;
+ break;
+ case ZFS_DELEG_GROUP_SETS:
+ case ZFS_DELEG_GROUP:
+ set_type = ZFS_DELEG_GROUP_SETS;
+ base_type = ZFS_DELEG_GROUP;
+ if (local)
+ ld[0] = ZFS_DELEG_LOCAL;
+ if (descend)
+ ld[1] = ZFS_DELEG_DESCENDENT;
+ break;
+ case ZFS_DELEG_EVERYONE_SETS:
+ case ZFS_DELEG_EVERYONE:
+ set_type = ZFS_DELEG_EVERYONE_SETS;
+ base_type = ZFS_DELEG_EVERYONE;
+ if (local)
+ ld[0] = ZFS_DELEG_LOCAL;
+ if (descend)
+ ld[1] = ZFS_DELEG_DESCENDENT;
+ }
+
+ if (perms != NULL) {
+ char *curr = perms;
+ char *end = curr + strlen(perms);
+
+ while (curr < end) {
+ char *delim = strchr(curr, ',');
+ if (delim == NULL)
+ delim = end;
+ else
+ *delim = '\0';
+
+ if (curr[0] == '@')
+ nvl = set_nvl;
+ else
+ nvl = base_nvl;
+
+ (void) nvlist_add_boolean(nvl, curr);
+ if (delim != end)
+ *delim = ',';
+ curr = delim + 1;
+ }
+
+ for (i = 0; i < 2; i++) {
+ char locality = ld[i];
+ if (locality == 0)
+ continue;
+
+ if (!nvlist_empty(base_nvl)) {
+ if (who != NULL)
+ (void) snprintf(who_buf,
+ sizeof (who_buf), "%c%c$%s",
+ base_type, locality, who);
+ else
+ (void) snprintf(who_buf,
+ sizeof (who_buf), "%c%c$",
+ base_type, locality);
+
+ (void) nvlist_add_nvlist(top_nvl, who_buf,
+ base_nvl);
+ }
+
+
+ if (!nvlist_empty(set_nvl)) {
+ if (who != NULL)
+ (void) snprintf(who_buf,
+ sizeof (who_buf), "%c%c$%s",
+ set_type, locality, who);
+ else
+ (void) snprintf(who_buf,
+ sizeof (who_buf), "%c%c$",
+ set_type, locality);
+
+ (void) nvlist_add_nvlist(top_nvl, who_buf,
+ set_nvl);
+ }
+ }
+ } else {
+ for (i = 0; i < 2; i++) {
+ char locality = ld[i];
+ if (locality == 0)
+ continue;
+
+ if (who != NULL)
+ (void) snprintf(who_buf, sizeof (who_buf),
+ "%c%c$%s", base_type, locality, who);
+ else
+ (void) snprintf(who_buf, sizeof (who_buf),
+ "%c%c$", base_type, locality);
+ (void) nvlist_add_boolean(top_nvl, who_buf);
+
+ if (who != NULL)
+ (void) snprintf(who_buf, sizeof (who_buf),
+ "%c%c$%s", set_type, locality, who);
+ else
+ (void) snprintf(who_buf, sizeof (who_buf),
+ "%c%c$", set_type, locality);
+ (void) nvlist_add_boolean(top_nvl, who_buf);
+ }
+ }
+}
+
+static int
+construct_fsacl_list(boolean_t un, struct allow_opts *opts, nvlist_t **nvlp)
+{
+ if (nvlist_alloc(nvlp, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ if (opts->set) {
+ store_allow_perm(ZFS_DELEG_NAMED_SET, opts->local,
+ opts->descend, opts->who, opts->perms, *nvlp);
+ } else if (opts->create) {
+ store_allow_perm(ZFS_DELEG_CREATE, opts->local,
+ opts->descend, NULL, opts->perms, *nvlp);
+ } else if (opts->everyone) {
+ store_allow_perm(ZFS_DELEG_EVERYONE, opts->local,
+ opts->descend, NULL, opts->perms, *nvlp);
+ } else {
+ char *curr = opts->who;
+ char *end = curr + strlen(curr);
+
+ while (curr < end) {
+ const char *who;
+ zfs_deleg_who_type_t who_type;
+ char *endch;
+ char *delim = strchr(curr, ',');
+ char errbuf[256];
+ char id[64];
+ struct passwd *p = NULL;
+ struct group *g = NULL;
+
+ uid_t rid;
+ if (delim == NULL)
+ delim = end;
+ else
+ *delim = '\0';
+
+ rid = (uid_t)strtol(curr, &endch, 0);
+ if (opts->user) {
+ who_type = ZFS_DELEG_USER;
+ if (*endch != '\0')
+ p = getpwnam(curr);
+ else
+ p = getpwuid(rid);
+
+ if (p != NULL)
+ rid = p->pw_uid;
+ else {
+ (void) snprintf(errbuf, 256, gettext(
+ "invalid user %s"), curr);
+ allow_usage(un, B_TRUE, errbuf);
+ }
+ } else if (opts->group) {
+ who_type = ZFS_DELEG_GROUP;
+ if (*endch != '\0')
+ g = getgrnam(curr);
+ else
+ g = getgrgid(rid);
+
+ if (g != NULL)
+ rid = g->gr_gid;
+ else {
+ (void) snprintf(errbuf, 256, gettext(
+ "invalid group %s"), curr);
+ allow_usage(un, B_TRUE, errbuf);
+ }
+ } else {
+ if (*endch != '\0') {
+ p = getpwnam(curr);
+ } else {
+ p = getpwuid(rid);
+ }
+
+ if (p == NULL)
+ if (*endch != '\0') {
+ g = getgrnam(curr);
+ } else {
+ g = getgrgid(rid);
+ }
+
+ if (p != NULL) {
+ who_type = ZFS_DELEG_USER;
+ rid = p->pw_uid;
+ } else if (g != NULL) {
+ who_type = ZFS_DELEG_GROUP;
+ rid = g->gr_gid;
+ } else {
+ (void) snprintf(errbuf, 256, gettext(
+ "invalid user/group %s"), curr);
+ allow_usage(un, B_TRUE, errbuf);
+ }
+ }
+
+ (void) sprintf(id, "%u", rid);
+ who = id;
+
+ store_allow_perm(who_type, opts->local,
+ opts->descend, who, opts->perms, *nvlp);
+ curr = delim + 1;
+ }
+ }
+
+ return (0);
+}
+
+static void
+print_set_creat_perms(uu_avl_t *who_avl)
+{
+ const char *sc_title[] = {
+ gettext("Permission sets:\n"),
+ gettext("Create time permissions:\n"),
+ NULL
+ };
+ const char **title_ptr = sc_title;
+ who_perm_node_t *who_node = NULL;
+ int prev_weight = -1;
+
+ for (who_node = uu_avl_first(who_avl); who_node != NULL;
+ who_node = uu_avl_next(who_avl, who_node)) {
+ uu_avl_t *avl = who_node->who_perm.who_deleg_perm_avl;
+ zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
+ const char *who_name = who_node->who_perm.who_name;
+ int weight = who_type2weight(who_type);
+ boolean_t first = B_TRUE;
+ deleg_perm_node_t *deleg_node;
+
+ if (prev_weight != weight) {
+ (void) printf(*title_ptr++);
+ prev_weight = weight;
+ }
+
+ if (who_name == NULL || strnlen(who_name, 1) == 0)
+ (void) printf("\t");
+ else
+ (void) printf("\t%s ", who_name);
+
+ for (deleg_node = uu_avl_first(avl); deleg_node != NULL;
+ deleg_node = uu_avl_next(avl, deleg_node)) {
+ if (first) {
+ (void) printf("%s",
+ deleg_node->dpn_perm.dp_name);
+ first = B_FALSE;
+ } else
+ (void) printf(",%s",
+ deleg_node->dpn_perm.dp_name);
+ }
+
+ (void) printf("\n");
+ }
+}
+
+static void inline
+print_uge_deleg_perms(uu_avl_t *who_avl, boolean_t local, boolean_t descend,
+ const char *title)
+{
+ who_perm_node_t *who_node = NULL;
+ boolean_t prt_title = B_TRUE;
+ uu_avl_walk_t *walk;
+
+ if ((walk = uu_avl_walk_start(who_avl, UU_WALK_ROBUST)) == NULL)
+ nomem();
+
+ while ((who_node = uu_avl_walk_next(walk)) != NULL) {
+ const char *who_name = who_node->who_perm.who_name;
+ const char *nice_who_name = who_node->who_perm.who_ug_name;
+ uu_avl_t *avl = who_node->who_perm.who_deleg_perm_avl;
+ zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
+ char delim = ' ';
+ deleg_perm_node_t *deleg_node;
+ boolean_t prt_who = B_TRUE;
+
+ for (deleg_node = uu_avl_first(avl);
+ deleg_node != NULL;
+ deleg_node = uu_avl_next(avl, deleg_node)) {
+ if (local != deleg_node->dpn_perm.dp_local ||
+ descend != deleg_node->dpn_perm.dp_descend)
+ continue;
+
+ if (prt_who) {
+ const char *who = NULL;
+ if (prt_title) {
+ prt_title = B_FALSE;
+ (void) printf(title);
+ }
+
+ switch (who_type) {
+ case ZFS_DELEG_USER_SETS:
+ case ZFS_DELEG_USER:
+ who = gettext("user");
+ if (nice_who_name)
+ who_name = nice_who_name;
+ break;
+ case ZFS_DELEG_GROUP_SETS:
+ case ZFS_DELEG_GROUP:
+ who = gettext("group");
+ if (nice_who_name)
+ who_name = nice_who_name;
+ break;
+ case ZFS_DELEG_EVERYONE_SETS:
+ case ZFS_DELEG_EVERYONE:
+ who = gettext("everyone");
+ who_name = NULL;
+ }
+
+ prt_who = B_FALSE;
+ if (who_name == NULL)
+ (void) printf("\t%s", who);
+ else
+ (void) printf("\t%s %s", who, who_name);
+ }
+
+ (void) printf("%c%s", delim,
+ deleg_node->dpn_perm.dp_name);
+ delim = ',';
+ }
+
+ if (!prt_who)
+ (void) printf("\n");
+ }
+
+ uu_avl_walk_end(walk);
+}
+
+static void
+print_fs_perms(fs_perm_set_t *fspset)
+{
+ fs_perm_node_t *node = NULL;
+ char buf[ZFS_MAXNAMELEN+32];
+ const char *dsname = buf;
+
+ for (node = uu_list_first(fspset->fsps_list); node != NULL;
+ node = uu_list_next(fspset->fsps_list, node)) {
+ uu_avl_t *sc_avl = node->fspn_fsperm.fsp_sc_avl;
+ uu_avl_t *uge_avl = node->fspn_fsperm.fsp_uge_avl;
+ int left = 0;
+
+ (void) snprintf(buf, ZFS_MAXNAMELEN+32,
+ gettext("---- Permissions on %s "),
+ node->fspn_fsperm.fsp_name);
+ (void) printf(dsname);
+ left = 70 - strlen(buf);
+ while (left-- > 0)
+ (void) printf("-");
+ (void) printf("\n");
+
+ print_set_creat_perms(sc_avl);
+ print_uge_deleg_perms(uge_avl, B_TRUE, B_FALSE,
+ gettext("Local permissions:\n"));
+ print_uge_deleg_perms(uge_avl, B_FALSE, B_TRUE,
+ gettext("Descendent permissions:\n"));
+ print_uge_deleg_perms(uge_avl, B_TRUE, B_TRUE,
+ gettext("Local+Descendent permissions:\n"));
+ }
+}
+
+static fs_perm_set_t fs_perm_set = { NULL, NULL, NULL, NULL };
+
+struct deleg_perms {
+ boolean_t un;
+ nvlist_t *nvl;
+};
+
+static int
+set_deleg_perms(zfs_handle_t *zhp, void *data)
+{
+ struct deleg_perms *perms = (struct deleg_perms *)data;
+ zfs_type_t zfs_type = zfs_get_type(zhp);
+
+ if (zfs_type != ZFS_TYPE_FILESYSTEM && zfs_type != ZFS_TYPE_VOLUME)
+ return (0);
+
+ return (zfs_set_fsacl(zhp, perms->un, perms->nvl));
+}
+
+static int
+zfs_do_allow_unallow_impl(int argc, char **argv, boolean_t un)
+{
+ zfs_handle_t *zhp;
+ nvlist_t *perm_nvl = NULL;
+ nvlist_t *update_perm_nvl = NULL;
+ int error = 1;
+ int c;
+ struct allow_opts opts = { 0 };
+
+ const char *optstr = un ? "ldugecsrh" : "ldugecsh";
+
+ /* check opts */
+ while ((c = getopt(argc, argv, optstr)) != -1) {
+ switch (c) {
+ case 'l':
+ opts.local = B_TRUE;
+ break;
+ case 'd':
+ opts.descend = B_TRUE;
+ break;
+ case 'u':
+ opts.user = B_TRUE;
+ break;
+ case 'g':
+ opts.group = B_TRUE;
+ break;
+ case 'e':
+ opts.everyone = B_TRUE;
+ break;
+ case 's':
+ opts.set = B_TRUE;
+ break;
+ case 'c':
+ opts.create = B_TRUE;
+ break;
+ case 'r':
+ opts.recursive = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case 'h':
+ opts.prt_usage = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check arguments */
+ parse_allow_args(argc, argv, un, &opts);
+
+ /* try to open the dataset */
+ if ((zhp = zfs_open(g_zfs, opts.dataset, ZFS_TYPE_FILESYSTEM |
+ ZFS_TYPE_VOLUME)) == NULL) {
+ (void) fprintf(stderr, "Failed to open dataset: %s\n",
+ opts.dataset);
+ return (-1);
+ }
+
+ if (zfs_get_fsacl(zhp, &perm_nvl) != 0)
+ goto cleanup2;
+
+ fs_perm_set_init(&fs_perm_set);
+ if (parse_fs_perm_set(&fs_perm_set, perm_nvl) != 0) {
+ (void) fprintf(stderr, "Failed to parse fsacl permissions\n");
+ goto cleanup1;
+ }
+
+ if (opts.prt_perms)
+ print_fs_perms(&fs_perm_set);
+ else {
+ (void) construct_fsacl_list(un, &opts, &update_perm_nvl);
+ if (zfs_set_fsacl(zhp, un, update_perm_nvl) != 0)
+ goto cleanup0;
+
+ if (un && opts.recursive) {
+ struct deleg_perms data = { un, update_perm_nvl };
+ if (zfs_iter_filesystems(zhp, set_deleg_perms,
+ &data) != 0)
+ goto cleanup0;
+ }
+ }
+
+ error = 0;
+
+cleanup0:
+ nvlist_free(perm_nvl);
+ if (update_perm_nvl != NULL)
+ nvlist_free(update_perm_nvl);
+cleanup1:
+ fs_perm_set_fini(&fs_perm_set);
+cleanup2:
+ zfs_close(zhp);
+
+ return (error);
+}
+
+static int
+zfs_do_allow(int argc, char **argv)
+{
+ return (zfs_do_allow_unallow_impl(argc, argv, B_FALSE));
+}
+
+static int
+zfs_do_unallow(int argc, char **argv)
+{
+ return (zfs_do_allow_unallow_impl(argc, argv, B_TRUE));
+}
+
+static int
+zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
+{
+ int errors = 0;
+ int i;
+ const char *tag;
+ boolean_t recursive = B_FALSE;
+ const char *opts = holding ? "rt" : "r";
+ int c;
+
+ /* check options */
+ while ((c = getopt(argc, argv, opts)) != -1) {
+ switch (c) {
+ case 'r':
+ recursive = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 2)
+ usage(B_FALSE);
+
+ tag = argv[0];
+ --argc;
+ ++argv;
+
+ if (holding && tag[0] == '.') {
+ /* tags starting with '.' are reserved for libzfs */
+ (void) fprintf(stderr, gettext("tag may not start with '.'\n"));
+ usage(B_FALSE);
+ }
+
+ for (i = 0; i < argc; ++i) {
+ zfs_handle_t *zhp;
+ char parent[ZFS_MAXNAMELEN];
+ const char *delim;
+ char *path = argv[i];
+
+ delim = strchr(path, '@');
+ if (delim == NULL) {
+ (void) fprintf(stderr,
+ gettext("'%s' is not a snapshot\n"), path);
+ ++errors;
+ continue;
+ }
+ (void) strncpy(parent, path, delim - path);
+ parent[delim - path] = '\0';
+
+ zhp = zfs_open(g_zfs, parent,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL) {
+ ++errors;
+ continue;
+ }
+ if (holding) {
+ if (zfs_hold(zhp, delim+1, tag, recursive,
+ B_FALSE, -1) != 0)
+ ++errors;
+ } else {
+ if (zfs_release(zhp, delim+1, tag, recursive) != 0)
+ ++errors;
+ }
+ zfs_close(zhp);
+ }
+
+ return (errors != 0);
+}
+
+/*
+ * zfs hold [-r] [-t] <tag> <snap> ...
+ *
+ * -r Recursively hold
+ *
+ * Apply a user-hold with the given tag to the list of snapshots.
+ */
+static int
+zfs_do_hold(int argc, char **argv)
+{
+ return (zfs_do_hold_rele_impl(argc, argv, B_TRUE));
+}
+
+/*
+ * zfs release [-r] <tag> <snap> ...
+ *
+ * -r Recursively release
+ *
+ * Release a user-hold with the given tag from the list of snapshots.
+ */
+static int
+zfs_do_release(int argc, char **argv)
+{
+ return (zfs_do_hold_rele_impl(argc, argv, B_FALSE));
+}
+
+typedef struct holds_cbdata {
+ boolean_t cb_recursive;
+ const char *cb_snapname;
+ nvlist_t **cb_nvlp;
+ size_t cb_max_namelen;
+ size_t cb_max_taglen;
+} holds_cbdata_t;
+
+#define STRFTIME_FMT_STR "%a %b %e %k:%M %Y"
+#define DATETIME_BUF_LEN (32)
+/*
+ *
+ */
+static void
+print_holds(boolean_t scripted, size_t nwidth, size_t tagwidth, nvlist_t *nvl)
+{
+ int i;
+ nvpair_t *nvp = NULL;
+ char *hdr_cols[] = { "NAME", "TAG", "TIMESTAMP" };
+ const char *col;
+
+ if (!scripted) {
+ for (i = 0; i < 3; i++) {
+ col = gettext(hdr_cols[i]);
+ if (i < 2)
+ (void) printf("%-*s ", i ? tagwidth : nwidth,
+ col);
+ else
+ (void) printf("%s\n", col);
+ }
+ }
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ char *zname = nvpair_name(nvp);
+ nvlist_t *nvl2;
+ nvpair_t *nvp2 = NULL;
+ (void) nvpair_value_nvlist(nvp, &nvl2);
+ while ((nvp2 = nvlist_next_nvpair(nvl2, nvp2)) != NULL) {
+ char tsbuf[DATETIME_BUF_LEN];
+ char *tagname = nvpair_name(nvp2);
+ uint64_t val = 0;
+ time_t time;
+ struct tm t;
+ char sep = scripted ? '\t' : ' ';
+ size_t sepnum = scripted ? 1 : 2;
+
+ (void) nvpair_value_uint64(nvp2, &val);
+ time = (time_t)val;
+ (void) localtime_r(&time, &t);
+ (void) strftime(tsbuf, DATETIME_BUF_LEN,
+ gettext(STRFTIME_FMT_STR), &t);
+
+ (void) printf("%-*s%*c%-*s%*c%s\n", nwidth, zname,
+ sepnum, sep, tagwidth, tagname, sepnum, sep, tsbuf);
+ }
+ }
+}
+
+/*
+ * Generic callback function to list a dataset or snapshot.
+ */
+static int
+holds_callback(zfs_handle_t *zhp, void *data)
+{
+ holds_cbdata_t *cbp = data;
+ nvlist_t *top_nvl = *cbp->cb_nvlp;
+ nvlist_t *nvl = NULL;
+ nvpair_t *nvp = NULL;
+ const char *zname = zfs_get_name(zhp);
+ size_t znamelen = strnlen(zname, ZFS_MAXNAMELEN);
+
+ if (cbp->cb_recursive) {
+ const char *snapname;
+ char *delim = strchr(zname, '@');
+ if (delim == NULL)
+ return (0);
+
+ snapname = delim + 1;
+ if (strcmp(cbp->cb_snapname, snapname))
+ return (0);
+ }
+
+ if (zfs_get_holds(zhp, &nvl) != 0)
+ return (-1);
+
+ if (znamelen > cbp->cb_max_namelen)
+ cbp->cb_max_namelen = znamelen;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ const char *tag = nvpair_name(nvp);
+ size_t taglen = strnlen(tag, MAXNAMELEN);
+ if (taglen > cbp->cb_max_taglen)
+ cbp->cb_max_taglen = taglen;
+ }
+
+ return (nvlist_add_nvlist(top_nvl, zname, nvl));
+}
+
+/*
+ * zfs holds [-r] <snap> ...
+ *
+ * -r Recursively hold
+ */
+static int
+zfs_do_holds(int argc, char **argv)
+{
+ int errors = 0;
+ int c;
+ int i;
+ boolean_t scripted = B_FALSE;
+ boolean_t recursive = B_FALSE;
+ const char *opts = "rH";
+ nvlist_t *nvl;
+
+ int types = ZFS_TYPE_SNAPSHOT;
+ holds_cbdata_t cb = { 0 };
+
+ int limit = 0;
+ int ret = 0;
+ int flags = 0;
+
+ /* check options */
+ while ((c = getopt(argc, argv, opts)) != -1) {
+ switch (c) {
+ case 'r':
+ recursive = B_TRUE;
+ break;
+ case 'H':
+ scripted = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ if (recursive) {
+ types |= ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+ flags |= ZFS_ITER_RECURSE;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (argc < 1)
+ usage(B_FALSE);
+
+ if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
+ nomem();
+
+ for (i = 0; i < argc; ++i) {
+ char *snapshot = argv[i];
+ const char *delim;
+ const char *snapname;
+
+ delim = strchr(snapshot, '@');
+ if (delim == NULL) {
+ (void) fprintf(stderr,
+ gettext("'%s' is not a snapshot\n"), snapshot);
+ ++errors;
+ continue;
+ }
+ snapname = delim + 1;
+ if (recursive)
+ snapshot[delim - snapshot] = '\0';
+
+ cb.cb_recursive = recursive;
+ cb.cb_snapname = snapname;
+ cb.cb_nvlp = &nvl;
+
+ /*
+ * 1. collect holds data, set format options
+ */
+ ret = zfs_for_each(argc, argv, flags, types, NULL, NULL, limit,
+ holds_callback, &cb);
+ if (ret != 0)
+ ++errors;
+ }
+
+ /*
+ * 2. print holds data
+ */
+ print_holds(scripted, cb.cb_max_namelen, cb.cb_max_taglen, nvl);
+
+ if (nvlist_empty(nvl))
+ (void) printf(gettext("no datasets available\n"));
+
+ nvlist_free(nvl);
+
+ return (0 != errors);
+}
+
+#define CHECK_SPINNER 30
+#define SPINNER_TIME 3 /* seconds */
+#define MOUNT_TIME 5 /* seconds */
+
+static int
+get_one_dataset(zfs_handle_t *zhp, void *data)
+{
+ static char *spin[] = { "-", "\\", "|", "/" };
+ static int spinval = 0;
+ static int spincheck = 0;
+ static time_t last_spin_time = (time_t)0;
+ get_all_cb_t *cbp = data;
+ zfs_type_t type = zfs_get_type(zhp);
+
+ if (cbp->cb_verbose) {
+ if (--spincheck < 0) {
+ time_t now = time(NULL);
+ if (last_spin_time + SPINNER_TIME < now) {
+ update_progress(spin[spinval++ % 4]);
+ last_spin_time = now;
+ }
+ spincheck = CHECK_SPINNER;
+ }
+ }
+
+ /*
+ * Interate over any nested datasets.
+ */
+ if (zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) {
+ zfs_close(zhp);
+ return (1);
+ }
+
+ /*
+ * Skip any datasets whose type does not match.
+ */
+ if ((type & ZFS_TYPE_FILESYSTEM) == 0) {
+ zfs_close(zhp);
+ return (0);
+ }
+ libzfs_add_handle(cbp, zhp);
+ assert(cbp->cb_used <= cbp->cb_alloc);
+
+ return (0);
+}
+
+static void
+get_all_datasets(zfs_handle_t ***dslist, size_t *count, boolean_t verbose)
+{
+ get_all_cb_t cb = { 0 };
+ cb.cb_verbose = verbose;
+ cb.cb_getone = get_one_dataset;
+
+ if (verbose)
+ set_progress_header(gettext("Reading ZFS config"));
+ (void) zfs_iter_root(g_zfs, get_one_dataset, &cb);
+
+ *dslist = cb.cb_handles;
+ *count = cb.cb_used;
+
+ if (verbose)
+ finish_progress(gettext("done."));
+}
+
+/*
+ * Generic callback for sharing or mounting filesystems. Because the code is so
+ * similar, we have a common function with an extra parameter to determine which
+ * mode we are using.
+ */
+#define OP_SHARE 0x1
+#define OP_MOUNT 0x2
+
+/*
+ * Share or mount a dataset.
+ */
+static int
+share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
+ boolean_t explicit, const char *options)
+{
+ char mountpoint[ZFS_MAXPROPLEN];
+ char shareopts[ZFS_MAXPROPLEN];
+ char smbshareopts[ZFS_MAXPROPLEN];
+ const char *cmdname = op == OP_SHARE ? "share" : "mount";
+ struct mnttab mnt;
+ uint64_t zoned, canmount;
+ boolean_t shared_nfs, shared_smb;
+
+ assert(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM);
+
+ /*
+ * Check to make sure we can mount/share this dataset. If we
+ * are in the global zone and the filesystem is exported to a
+ * local zone, or if we are in a local zone and the
+ * filesystem is not exported, then it is an error.
+ */
+ zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
+
+ if (zoned && getzoneid() == GLOBAL_ZONEID) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot %s '%s': "
+ "dataset is exported to a local zone\n"), cmdname,
+ zfs_get_name(zhp));
+ return (1);
+
+ } else if (!zoned && getzoneid() != GLOBAL_ZONEID) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot %s '%s': "
+ "permission denied\n"), cmdname,
+ zfs_get_name(zhp));
+ return (1);
+ }
+
+ /*
+ * Ignore any filesystems which don't apply to us. This
+ * includes those with a legacy mountpoint, or those with
+ * legacy share options.
+ */
+ verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
+ sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
+ sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
+ sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
+
+ if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
+ strcmp(smbshareopts, "off") == 0) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot share '%s': "
+ "legacy share\n"), zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use share(1M) to "
+ "share this filesystem, or set "
+ "sharenfs property on\n"));
+ return (1);
+ }
+
+ /*
+ * We cannot share or mount legacy filesystems. If the
+ * shareopts is non-legacy but the mountpoint is legacy, we
+ * treat it as a legacy share.
+ */
+ if (strcmp(mountpoint, "legacy") == 0) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot %s '%s': "
+ "legacy mountpoint\n"), cmdname, zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use %s(1M) to "
+ "%s this filesystem\n"), cmdname, cmdname);
+ return (1);
+ }
+
+ if (strcmp(mountpoint, "none") == 0) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot %s '%s': no "
+ "mountpoint set\n"), cmdname, zfs_get_name(zhp));
+ return (1);
+ }
+
+ /*
+ * canmount explicit outcome
+ * on no pass through
+ * on yes pass through
+ * off no return 0
+ * off yes display error, return 1
+ * noauto no return 0
+ * noauto yes pass through
+ */
+ canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
+ if (canmount == ZFS_CANMOUNT_OFF) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot %s '%s': "
+ "'canmount' property is set to 'off'\n"), cmdname,
+ zfs_get_name(zhp));
+ return (1);
+ } else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) {
+ return (0);
+ }
+
+ /*
+ * At this point, we have verified that the mountpoint and/or
+ * shareopts are appropriate for auto management. If the
+ * filesystem is already mounted or shared, return (failing
+ * for explicit requests); otherwise mount or share the
+ * filesystem.
+ */
+ switch (op) {
+ case OP_SHARE:
+
+ shared_nfs = zfs_is_shared_nfs(zhp, NULL);
+ shared_smb = zfs_is_shared_smb(zhp, NULL);
+
+ if (shared_nfs && shared_smb ||
+ (shared_nfs && strcmp(shareopts, "on") == 0 &&
+ strcmp(smbshareopts, "off") == 0) ||
+ (shared_smb && strcmp(smbshareopts, "on") == 0 &&
+ strcmp(shareopts, "off") == 0)) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot share "
+ "'%s': filesystem already shared\n"),
+ zfs_get_name(zhp));
+ return (1);
+ }
+
+ if (!zfs_is_mounted(zhp, NULL) &&
+ zfs_mount(zhp, NULL, 0) != 0)
+ return (1);
+
+ if (protocol == NULL) {
+ if (zfs_shareall(zhp) != 0)
+ return (1);
+ } else if (strcmp(protocol, "nfs") == 0) {
+ if (zfs_share_nfs(zhp))
+ return (1);
+ } else if (strcmp(protocol, "smb") == 0) {
+ if (zfs_share_smb(zhp))
+ return (1);
+ } else {
+ (void) fprintf(stderr, gettext("cannot share "
+ "'%s': invalid share type '%s' "
+ "specified\n"),
+ zfs_get_name(zhp), protocol);
+ return (1);
+ }
+
+ break;
+
+ case OP_MOUNT:
+ if (options == NULL)
+ mnt.mnt_mntopts = "";
+ else
+ mnt.mnt_mntopts = (char *)options;
+
+ if (!hasmntopt(&mnt, MNTOPT_REMOUNT) &&
+ zfs_is_mounted(zhp, NULL)) {
+ if (!explicit)
+ return (0);
+
+ (void) fprintf(stderr, gettext("cannot mount "
+ "'%s': filesystem already mounted\n"),
+ zfs_get_name(zhp));
+ return (1);
+ }
+
+ if (zfs_mount(zhp, options, flags) != 0)
+ return (1);
+ break;
+ }
+
+ return (0);
+}
+
+/*
+ * Reports progress in the form "(current/total)". Not thread-safe.
+ */
+static void
+report_mount_progress(int current, int total)
+{
+ static time_t last_progress_time = 0;
+ time_t now = time(NULL);
+ char info[32];
+
+ /* report 1..n instead of 0..n-1 */
+ ++current;
+
+ /* display header if we're here for the first time */
+ if (current == 1) {
+ set_progress_header(gettext("Mounting ZFS filesystems"));
+ } else if (current != total && last_progress_time + MOUNT_TIME >= now) {
+ /* too soon to report again */
+ return;
+ }
+
+ last_progress_time = now;
+
+ (void) sprintf(info, "(%d/%d)", current, total);
+
+ if (current == total)
+ finish_progress(info);
+ else
+ update_progress(info);
+}
+
+static void
+append_options(char *mntopts, char *newopts)
+{
+ int len = strlen(mntopts);
+
+ /* original length plus new string to append plus 1 for the comma */
+ if (len + 1 + strlen(newopts) >= MNT_LINE_MAX) {
+ (void) fprintf(stderr, gettext("the opts argument for "
+ "'%c' option is too long (more than %d chars)\n"),
+ "-o", MNT_LINE_MAX);
+ usage(B_FALSE);
+ }
+
+ if (*mntopts)
+ mntopts[len++] = ',';
+
+ (void) strcpy(&mntopts[len], newopts);
+}
+
+static int
+share_mount(int op, int argc, char **argv)
+{
+ int do_all = 0;
+ boolean_t verbose = B_FALSE;
+ int c, ret = 0;
+ char *options = NULL;
+ int flags = 0;
+
+ /* check options */
+ while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:O" : "a"))
+ != -1) {
+ switch (c) {
+ case 'a':
+ do_all = 1;
+ break;
+ case 'v':
+ verbose = B_TRUE;
+ break;
+ case 'o':
+ if (*optarg == '\0') {
+ (void) fprintf(stderr, gettext("empty mount "
+ "options (-o) specified\n"));
+ usage(B_FALSE);
+ }
+
+ if (options == NULL)
+ options = safe_malloc(MNT_LINE_MAX + 1);
+
+ /* option validation is done later */
+ append_options(options, optarg);
+ break;
+
+ case 'O':
+ warnx("no overlay mounts support on FreeBSD, ignoring");
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check number of arguments */
+ if (do_all) {
+ zfs_handle_t **dslist = NULL;
+ size_t i, count = 0;
+ char *protocol = NULL;
+
+ if (op == OP_SHARE && argc > 0) {
+ if (strcmp(argv[0], "nfs") != 0 &&
+ strcmp(argv[0], "smb") != 0) {
+ (void) fprintf(stderr, gettext("share type "
+ "must be 'nfs' or 'smb'\n"));
+ usage(B_FALSE);
+ }
+ protocol = argv[0];
+ argc--;
+ argv++;
+ }
+
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ start_progress_timer();
+ get_all_datasets(&dslist, &count, verbose);
+
+ if (count == 0)
+ return (0);
+
+ qsort(dslist, count, sizeof (void *), libzfs_dataset_cmp);
+
+ for (i = 0; i < count; i++) {
+ if (verbose)
+ report_mount_progress(i, count);
+
+ if (share_mount_one(dslist[i], op, flags, protocol,
+ B_FALSE, options) != 0)
+ ret = 1;
+ zfs_close(dslist[i]);
+ }
+
+ free(dslist);
+ } else if (argc == 0) {
+ struct mnttab entry;
+
+ if ((op == OP_SHARE) || (options != NULL)) {
+ (void) fprintf(stderr, gettext("missing filesystem "
+ "argument (specify -a for all)\n"));
+ usage(B_FALSE);
+ }
+
+ /*
+ * When mount is given no arguments, go through /etc/mnttab and
+ * display any active ZFS mounts. We hide any snapshots, since
+ * they are controlled automatically.
+ */
+ rewind(mnttab_file);
+ while (getmntent(mnttab_file, &entry) == 0) {
+ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 ||
+ strchr(entry.mnt_special, '@') != NULL)
+ continue;
+
+ (void) printf("%-30s %s\n", entry.mnt_special,
+ entry.mnt_mountp);
+ }
+
+ } else {
+ zfs_handle_t *zhp;
+
+ if (argc > 1) {
+ (void) fprintf(stderr,
+ gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if ((zhp = zfs_open(g_zfs, argv[0],
+ ZFS_TYPE_FILESYSTEM)) == NULL) {
+ ret = 1;
+ } else {
+ ret = share_mount_one(zhp, op, flags, NULL, B_TRUE,
+ options);
+ zfs_close(zhp);
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * zfs mount -a [nfs]
+ * zfs mount filesystem
+ *
+ * Mount all filesystems, or mount the given filesystem.
+ */
+static int
+zfs_do_mount(int argc, char **argv)
+{
+ return (share_mount(OP_MOUNT, argc, argv));
+}
+
+/*
+ * zfs share -a [nfs | smb]
+ * zfs share filesystem
+ *
+ * Share all filesystems, or share the given filesystem.
+ */
+static int
+zfs_do_share(int argc, char **argv)
+{
+ return (share_mount(OP_SHARE, argc, argv));
+}
+
+typedef struct unshare_unmount_node {
+ zfs_handle_t *un_zhp;
+ char *un_mountp;
+ uu_avl_node_t un_avlnode;
+} unshare_unmount_node_t;
+
+/* ARGSUSED */
+static int
+unshare_unmount_compare(const void *larg, const void *rarg, void *unused)
+{
+ const unshare_unmount_node_t *l = larg;
+ const unshare_unmount_node_t *r = rarg;
+
+ return (strcmp(l->un_mountp, r->un_mountp));
+}
+
+/*
+ * Convenience routine used by zfs_do_umount() and manual_unmount(). Given an
+ * absolute path, find the entry /etc/mnttab, verify that its a ZFS filesystem,
+ * and unmount it appropriately.
+ */
+static int
+unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
+{
+ zfs_handle_t *zhp;
+ int ret = 0;
+ struct stat64 statbuf;
+ struct extmnttab entry;
+ const char *cmdname = (op == OP_SHARE) ? "unshare" : "unmount";
+ ino_t path_inode;
+
+ /*
+ * Search for the path in /etc/mnttab. Rather than looking for the
+ * specific path, which can be fooled by non-standard paths (i.e. ".."
+ * or "//"), we stat() the path and search for the corresponding
+ * (major,minor) device pair.
+ */
+ if (stat64(path, &statbuf) != 0) {
+ (void) fprintf(stderr, gettext("cannot %s '%s': %s\n"),
+ cmdname, path, strerror(errno));
+ return (1);
+ }
+ path_inode = statbuf.st_ino;
+
+ /*
+ * Search for the given (major,minor) pair in the mount table.
+ */
+#ifdef sun
+ rewind(mnttab_file);
+ while ((ret = getextmntent(mnttab_file, &entry, 0)) == 0) {
+ if (entry.mnt_major == major(statbuf.st_dev) &&
+ entry.mnt_minor == minor(statbuf.st_dev))
+ break;
+ }
+#else
+ {
+ struct statfs sfs;
+
+ if (statfs(path, &sfs) != 0) {
+ (void) fprintf(stderr, "%s: %s\n", path,
+ strerror(errno));
+ ret = -1;
+ }
+ statfs2mnttab(&sfs, &entry);
+ }
+#endif
+ if (ret != 0) {
+ if (op == OP_SHARE) {
+ (void) fprintf(stderr, gettext("cannot %s '%s': not "
+ "currently mounted\n"), cmdname, path);
+ return (1);
+ }
+ (void) fprintf(stderr, gettext("warning: %s not in mnttab\n"),
+ path);
+ if ((ret = umount2(path, flags)) != 0)
+ (void) fprintf(stderr, gettext("%s: %s\n"), path,
+ strerror(errno));
+ return (ret != 0);
+ }
+
+ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) {
+ (void) fprintf(stderr, gettext("cannot %s '%s': not a ZFS "
+ "filesystem\n"), cmdname, path);
+ return (1);
+ }
+
+ if ((zhp = zfs_open(g_zfs, entry.mnt_special,
+ ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (1);
+
+ ret = 1;
+ if (stat64(entry.mnt_mountp, &statbuf) != 0) {
+ (void) fprintf(stderr, gettext("cannot %s '%s': %s\n"),
+ cmdname, path, strerror(errno));
+ goto out;
+ } else if (statbuf.st_ino != path_inode) {
+ (void) fprintf(stderr, gettext("cannot "
+ "%s '%s': not a mountpoint\n"), cmdname, path);
+ goto out;
+ }
+
+ if (op == OP_SHARE) {
+ char nfs_mnt_prop[ZFS_MAXPROPLEN];
+ char smbshare_prop[ZFS_MAXPROPLEN];
+
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, nfs_mnt_prop,
+ sizeof (nfs_mnt_prop), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshare_prop,
+ sizeof (smbshare_prop), NULL, NULL, 0, B_FALSE) == 0);
+
+ if (strcmp(nfs_mnt_prop, "off") == 0 &&
+ strcmp(smbshare_prop, "off") == 0) {
+ (void) fprintf(stderr, gettext("cannot unshare "
+ "'%s': legacy share\n"), path);
+ (void) fprintf(stderr, gettext("use "
+ "unshare(1M) to unshare this filesystem\n"));
+ } else if (!zfs_is_shared(zhp)) {
+ (void) fprintf(stderr, gettext("cannot unshare '%s': "
+ "not currently shared\n"), path);
+ } else {
+ ret = zfs_unshareall_bypath(zhp, path);
+ }
+ } else {
+ char mtpt_prop[ZFS_MAXPROPLEN];
+
+ verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mtpt_prop,
+ sizeof (mtpt_prop), NULL, NULL, 0, B_FALSE) == 0);
+
+ if (is_manual) {
+ ret = zfs_unmount(zhp, NULL, flags);
+ } else if (strcmp(mtpt_prop, "legacy") == 0) {
+ (void) fprintf(stderr, gettext("cannot unmount "
+ "'%s': legacy mountpoint\n"),
+ zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use umount(1M) "
+ "to unmount this filesystem\n"));
+ } else {
+ ret = zfs_unmountall(zhp, flags);
+ }
+ }
+
+out:
+ zfs_close(zhp);
+
+ return (ret != 0);
+}
+
+/*
+ * Generic callback for unsharing or unmounting a filesystem.
+ */
+static int
+unshare_unmount(int op, int argc, char **argv)
+{
+ int do_all = 0;
+ int flags = 0;
+ int ret = 0;
+ int c;
+ zfs_handle_t *zhp;
+ char nfs_mnt_prop[ZFS_MAXPROPLEN];
+ char sharesmb[ZFS_MAXPROPLEN];
+
+ /* check options */
+ while ((c = getopt(argc, argv, op == OP_SHARE ? "a" : "af")) != -1) {
+ switch (c) {
+ case 'a':
+ do_all = 1;
+ break;
+ case 'f':
+ flags = MS_FORCE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (do_all) {
+ /*
+ * We could make use of zfs_for_each() to walk all datasets in
+ * the system, but this would be very inefficient, especially
+ * since we would have to linearly search /etc/mnttab for each
+ * one. Instead, do one pass through /etc/mnttab looking for
+ * zfs entries and call zfs_unmount() for each one.
+ *
+ * Things get a little tricky if the administrator has created
+ * mountpoints beneath other ZFS filesystems. In this case, we
+ * have to unmount the deepest filesystems first. To accomplish
+ * this, we place all the mountpoints in an AVL tree sorted by
+ * the special type (dataset name), and walk the result in
+ * reverse to make sure to get any snapshots first.
+ */
+ struct mnttab entry;
+ uu_avl_pool_t *pool;
+ uu_avl_t *tree;
+ unshare_unmount_node_t *node;
+ uu_avl_index_t idx;
+ uu_avl_walk_t *walk;
+
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if (((pool = uu_avl_pool_create("unmount_pool",
+ sizeof (unshare_unmount_node_t),
+ offsetof(unshare_unmount_node_t, un_avlnode),
+ unshare_unmount_compare, UU_DEFAULT)) == NULL) ||
+ ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL))
+ nomem();
+
+ rewind(mnttab_file);
+ while (getmntent(mnttab_file, &entry) == 0) {
+
+ /* ignore non-ZFS entries */
+ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
+ continue;
+
+ /* ignore snapshots */
+ if (strchr(entry.mnt_special, '@') != NULL)
+ continue;
+
+ if ((zhp = zfs_open(g_zfs, entry.mnt_special,
+ ZFS_TYPE_FILESYSTEM)) == NULL) {
+ ret = 1;
+ continue;
+ }
+
+ switch (op) {
+ case OP_SHARE:
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
+ nfs_mnt_prop,
+ sizeof (nfs_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfs_mnt_prop, "off") != 0)
+ break;
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
+ nfs_mnt_prop,
+ sizeof (nfs_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfs_mnt_prop, "off") == 0)
+ continue;
+ break;
+ case OP_MOUNT:
+ /* Ignore legacy mounts */
+ verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
+ nfs_mnt_prop,
+ sizeof (nfs_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfs_mnt_prop, "legacy") == 0)
+ continue;
+ /* Ignore canmount=noauto mounts */
+ if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
+ ZFS_CANMOUNT_NOAUTO)
+ continue;
+ default:
+ break;
+ }
+
+ node = safe_malloc(sizeof (unshare_unmount_node_t));
+ node->un_zhp = zhp;
+ node->un_mountp = safe_strdup(entry.mnt_mountp);
+
+ uu_avl_node_init(node, &node->un_avlnode, pool);
+
+ if (uu_avl_find(tree, node, NULL, &idx) == NULL) {
+ uu_avl_insert(tree, node, idx);
+ } else {
+ zfs_close(node->un_zhp);
+ free(node->un_mountp);
+ free(node);
+ }
+ }
+
+ /*
+ * Walk the AVL tree in reverse, unmounting each filesystem and
+ * removing it from the AVL tree in the process.
+ */
+ if ((walk = uu_avl_walk_start(tree,
+ UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
+ nomem();
+
+ while ((node = uu_avl_walk_next(walk)) != NULL) {
+ uu_avl_remove(tree, node);
+
+ switch (op) {
+ case OP_SHARE:
+ if (zfs_unshareall_bypath(node->un_zhp,
+ node->un_mountp) != 0)
+ ret = 1;
+ break;
+
+ case OP_MOUNT:
+ if (zfs_unmount(node->un_zhp,
+ node->un_mountp, flags) != 0)
+ ret = 1;
+ break;
+ }
+
+ zfs_close(node->un_zhp);
+ free(node->un_mountp);
+ free(node);
+ }
+
+ uu_avl_walk_end(walk);
+ uu_avl_destroy(tree);
+ uu_avl_pool_destroy(pool);
+
+ } else {
+ if (argc != 1) {
+ if (argc == 0)
+ (void) fprintf(stderr,
+ gettext("missing filesystem argument\n"));
+ else
+ (void) fprintf(stderr,
+ gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ /*
+ * We have an argument, but it may be a full path or a ZFS
+ * filesystem. Pass full paths off to unmount_path() (shared by
+ * manual_unmount), otherwise open the filesystem and pass to
+ * zfs_unmount().
+ */
+ if (argv[0][0] == '/')
+ return (unshare_unmount_path(op, argv[0],
+ flags, B_FALSE));
+
+ if ((zhp = zfs_open(g_zfs, argv[0],
+ ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (1);
+
+ verify(zfs_prop_get(zhp, op == OP_SHARE ?
+ ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT,
+ nfs_mnt_prop, sizeof (nfs_mnt_prop), NULL,
+ NULL, 0, B_FALSE) == 0);
+
+ switch (op) {
+ case OP_SHARE:
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
+ nfs_mnt_prop,
+ sizeof (nfs_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
+ sharesmb, sizeof (sharesmb), NULL, NULL,
+ 0, B_FALSE) == 0);
+
+ if (strcmp(nfs_mnt_prop, "off") == 0 &&
+ strcmp(sharesmb, "off") == 0) {
+ (void) fprintf(stderr, gettext("cannot "
+ "unshare '%s': legacy share\n"),
+ zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use "
+ "unshare(1M) to unshare this "
+ "filesystem\n"));
+ ret = 1;
+ } else if (!zfs_is_shared(zhp)) {
+ (void) fprintf(stderr, gettext("cannot "
+ "unshare '%s': not currently "
+ "shared\n"), zfs_get_name(zhp));
+ ret = 1;
+ } else if (zfs_unshareall(zhp) != 0) {
+ ret = 1;
+ }
+ break;
+
+ case OP_MOUNT:
+ if (strcmp(nfs_mnt_prop, "legacy") == 0) {
+ (void) fprintf(stderr, gettext("cannot "
+ "unmount '%s': legacy "
+ "mountpoint\n"), zfs_get_name(zhp));
+ (void) fprintf(stderr, gettext("use "
+ "umount(1M) to unmount this "
+ "filesystem\n"));
+ ret = 1;
+ } else if (!zfs_is_mounted(zhp, NULL)) {
+ (void) fprintf(stderr, gettext("cannot "
+ "unmount '%s': not currently "
+ "mounted\n"),
+ zfs_get_name(zhp));
+ ret = 1;
+ } else if (zfs_unmountall(zhp, flags) != 0) {
+ ret = 1;
+ }
+ break;
+ }
+
+ zfs_close(zhp);
+ }
+
+ return (ret);
+}
+
+/*
+ * zfs unmount -a
+ * zfs unmount filesystem
+ *
+ * Unmount all filesystems, or a specific ZFS filesystem.
+ */
+static int
+zfs_do_unmount(int argc, char **argv)
+{
+ return (unshare_unmount(OP_MOUNT, argc, argv));
+}
+
+/*
+ * zfs unshare -a
+ * zfs unshare filesystem
+ *
+ * Unshare all filesystems, or a specific ZFS filesystem.
+ */
+static int
+zfs_do_unshare(int argc, char **argv)
+{
+ return (unshare_unmount(OP_SHARE, argc, argv));
+}
+
+/*
+ * Attach/detach the given dataset to/from the given jail
+ */
+/* ARGSUSED */
+static int
+do_jail(int argc, char **argv, int attach)
+{
+ zfs_handle_t *zhp;
+ int jailid, ret;
+
+ /* check number of arguments */
+ if (argc < 3) {
+ (void) fprintf(stderr, gettext("missing argument(s)\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 3) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ jailid = jail_getid(argv[1]);
+ if (jailid < 0) {
+ (void) fprintf(stderr, gettext("invalid jail id or name\n"));
+ usage(B_FALSE);
+ }
+
+ zhp = zfs_open(g_zfs, argv[2], ZFS_TYPE_FILESYSTEM);
+ if (zhp == NULL)
+ return (1);
+
+ ret = (zfs_jail(zhp, jailid, attach) != 0);
+
+ zfs_close(zhp);
+ return (ret);
+}
+
+/*
+ * zfs jail jailid filesystem
+ *
+ * Attach the given dataset to the given jail
+ */
+/* ARGSUSED */
+static int
+zfs_do_jail(int argc, char **argv)
+{
+
+ return (do_jail(argc, argv, 1));
+}
+
+/*
+ * zfs unjail jailid filesystem
+ *
+ * Detach the given dataset from the given jail
+ */
+/* ARGSUSED */
+static int
+zfs_do_unjail(int argc, char **argv)
+{
+
+ return (do_jail(argc, argv, 0));
+}
+
+/*
+ * Called when invoked as /etc/fs/zfs/mount. Do the mount if the mountpoint is
+ * 'legacy'. Otherwise, complain that use should be using 'zfs mount'.
+ */
+static int
+manual_mount(int argc, char **argv)
+{
+ zfs_handle_t *zhp;
+ char mountpoint[ZFS_MAXPROPLEN];
+ char mntopts[MNT_LINE_MAX] = { '\0' };
+ int ret = 0;
+ int c;
+ int flags = 0;
+ char *dataset, *path;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":mo:O")) != -1) {
+ switch (c) {
+ case 'o':
+ (void) strlcpy(mntopts, optarg, sizeof (mntopts));
+ break;
+ case 'O':
+ flags |= MS_OVERLAY;
+ break;
+ case 'm':
+ flags |= MS_NOMNTTAB;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ (void) fprintf(stderr, gettext("usage: mount [-o opts] "
+ "<path>\n"));
+ return (2);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check that we only have two arguments */
+ if (argc != 2) {
+ if (argc == 0)
+ (void) fprintf(stderr, gettext("missing dataset "
+ "argument\n"));
+ else if (argc == 1)
+ (void) fprintf(stderr,
+ gettext("missing mountpoint argument\n"));
+ else
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ (void) fprintf(stderr, "usage: mount <dataset> <mountpoint>\n");
+ return (2);
+ }
+
+ dataset = argv[0];
+ path = argv[1];
+
+ /* try to open the dataset */
+ if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (1);
+
+ (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
+ sizeof (mountpoint), NULL, NULL, 0, B_FALSE);
+
+ /* check for legacy mountpoint and complain appropriately */
+ ret = 0;
+ if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) {
+ if (zmount(dataset, path, flags, MNTTYPE_ZFS,
+ NULL, 0, mntopts, sizeof (mntopts)) != 0) {
+ (void) fprintf(stderr, gettext("mount failed: %s\n"),
+ strerror(errno));
+ ret = 1;
+ }
+ } else {
+ (void) fprintf(stderr, gettext("filesystem '%s' cannot be "
+ "mounted using 'mount -F zfs'\n"), dataset);
+ (void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' "
+ "instead.\n"), path);
+ (void) fprintf(stderr, gettext("If you must use 'mount -F zfs' "
+ "or /etc/vfstab, use 'zfs set mountpoint=legacy'.\n"));
+ (void) fprintf(stderr, gettext("See zfs(1M) for more "
+ "information.\n"));
+ ret = 1;
+ }
+
+ return (ret);
+}
+
+/*
+ * Called when invoked as /etc/fs/zfs/umount. Unlike a manual mount, we allow
+ * unmounts of non-legacy filesystems, as this is the dominant administrative
+ * interface.
+ */
+static int
+manual_unmount(int argc, char **argv)
+{
+ int flags = 0;
+ int c;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ flags = MS_FORCE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ (void) fprintf(stderr, gettext("usage: unmount [-f] "
+ "<path>\n"));
+ return (2);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check arguments */
+ if (argc != 1) {
+ if (argc == 0)
+ (void) fprintf(stderr, gettext("missing path "
+ "argument\n"));
+ else
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ (void) fprintf(stderr, gettext("usage: unmount [-f] <path>\n"));
+ return (2);
+ }
+
+ return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE));
+}
+
+static int
+find_command_idx(char *command, int *idx)
+{
+ int i;
+
+ for (i = 0; i < NCOMMAND; i++) {
+ if (command_table[i].name == NULL)
+ continue;
+
+ if (strcmp(command, command_table[i].name) == 0) {
+ *idx = i;
+ return (0);
+ }
+ }
+ return (1);
+}
+
+static int
+zfs_do_diff(int argc, char **argv)
+{
+ zfs_handle_t *zhp;
+ int flags = 0;
+ char *tosnap = NULL;
+ char *fromsnap = NULL;
+ char *atp, *copy;
+ int err = 0;
+ int c;
+
+ while ((c = getopt(argc, argv, "FHt")) != -1) {
+ switch (c) {
+ case 'F':
+ flags |= ZFS_DIFF_CLASSIFY;
+ break;
+ case 'H':
+ flags |= ZFS_DIFF_PARSEABLE;
+ break;
+ case 't':
+ flags |= ZFS_DIFF_TIMESTAMP;
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("invalid option '%c'\n"), optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr,
+ gettext("must provide at least one snapshot name\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ fromsnap = argv[0];
+ tosnap = (argc == 2) ? argv[1] : NULL;
+
+ copy = NULL;
+ if (*fromsnap != '@')
+ copy = strdup(fromsnap);
+ else if (tosnap)
+ copy = strdup(tosnap);
+ if (copy == NULL)
+ usage(B_FALSE);
+
+ if (atp = strchr(copy, '@'))
+ *atp = '\0';
+
+ if ((zhp = zfs_open(g_zfs, copy, ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (1);
+
+ free(copy);
+
+ /*
+ * Ignore SIGPIPE so that the library can give us
+ * information on any failure
+ */
+ (void) sigignore(SIGPIPE);
+
+ err = zfs_show_diffs(zhp, STDOUT_FILENO, fromsnap, tosnap, flags);
+
+ zfs_close(zhp);
+
+ return (err != 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+ int i;
+ char *progname;
+ char *cmdname;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ opterr = 0;
+
+ if ((g_zfs = libzfs_init()) == NULL) {
+ (void) fprintf(stderr, gettext("internal error: failed to "
+ "initialize ZFS library\n"));
+ return (1);
+ }
+
+ zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
+
+ libzfs_print_on_error(g_zfs, B_TRUE);
+
+ if ((mnttab_file = fopen(MNTTAB, "r")) == NULL) {
+ (void) fprintf(stderr, gettext("internal error: unable to "
+ "open %s\n"), MNTTAB);
+ return (1);
+ }
+
+ /*
+ * This command also doubles as the /etc/fs mount and unmount program.
+ * Determine if we should take this behavior based on argv[0].
+ */
+ progname = basename(argv[0]);
+ if (strcmp(progname, "mount") == 0) {
+ ret = manual_mount(argc, argv);
+ } else if (strcmp(progname, "umount") == 0) {
+ ret = manual_unmount(argc, argv);
+ } else {
+ /*
+ * Make sure the user has specified some command.
+ */
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing command\n"));
+ usage(B_FALSE);
+ }
+
+ cmdname = argv[1];
+
+ /*
+ * The 'umount' command is an alias for 'unmount'
+ */
+ if (strcmp(cmdname, "umount") == 0)
+ cmdname = "unmount";
+
+ /*
+ * The 'recv' command is an alias for 'receive'
+ */
+ if (strcmp(cmdname, "recv") == 0)
+ cmdname = "receive";
+
+ /*
+ * Special case '-?'
+ */
+ if (strcmp(cmdname, "-?") == 0)
+ usage(B_TRUE);
+
+ /*
+ * Run the appropriate command.
+ */
+ libzfs_mnttab_cache(g_zfs, B_TRUE);
+ if (find_command_idx(cmdname, &i) == 0) {
+ current_command = &command_table[i];
+ ret = command_table[i].func(argc - 1, argv + 1);
+ } else if (strchr(cmdname, '=') != NULL) {
+ verify(find_command_idx("set", &i) == 0);
+ current_command = &command_table[i];
+ ret = command_table[i].func(argc, argv);
+ } else {
+ (void) fprintf(stderr, gettext("unrecognized "
+ "command '%s'\n"), cmdname);
+ usage(B_FALSE);
+ }
+ libzfs_mnttab_cache(g_zfs, B_FALSE);
+ }
+
+ (void) fclose(mnttab_file);
+
+ if (ret == 0 && log_history)
+ (void) zpool_log_history(g_zfs, history_str);
+
+ libzfs_fini(g_zfs);
+
+ /*
+ * The 'ZFS_ABORT' environment variable causes us to dump core on exit
+ * for the purposes of running ::findleaks.
+ */
+ if (getenv("ZFS_ABORT") != NULL) {
+ (void) printf("dumping core by request\n");
+ abort();
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_util.h b/cddl/contrib/opensolaris/cmd/zfs/zfs_util.h
new file mode 100644
index 0000000..3ddff9e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_util.h
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _ZFS_UTIL_H
+#define _ZFS_UTIL_H
+
+#include <libzfs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void * safe_malloc(size_t size);
+void nomem(void);
+libzfs_handle_t *g_zfs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZFS_UTIL_H */
diff --git a/cddl/contrib/opensolaris/cmd/zhack/zhack.c b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
new file mode 100644
index 0000000..d80b3a0
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zhack/zhack.c
@@ -0,0 +1,541 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * zhack is a debugging tool that can write changes to ZFS pool using libzpool
+ * for testing purposes. Altering pools with zhack is unsupported and may
+ * result in corrupted pools.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu.h>
+#include <sys/zap.h>
+#include <sys/zfs_znode.h>
+#include <sys/dsl_synctask.h>
+#include <sys/vdev.h>
+#include <sys/fs/zfs.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_pool.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/zfeature.h>
+#include <sys/dmu_tx.h>
+#undef ZFS_MAXNAMELEN
+#undef verify
+#include <libzfs.h>
+
+extern boolean_t zfeature_checks_disable;
+
+const char cmdname[] = "zhack";
+libzfs_handle_t *g_zfs;
+static importargs_t g_importargs;
+static char *g_pool;
+static boolean_t g_readonly;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "Usage: %s [-c cachefile] [-d dir] <subcommand> <args> ...\n"
+ "where <subcommand> <args> is one of the following:\n"
+ "\n", cmdname);
+
+ (void) fprintf(stderr,
+ " feature stat <pool>\n"
+ " print information about enabled features\n"
+ " feature enable [-d desc] <pool> <feature>\n"
+ " add a new enabled feature to the pool\n"
+ " -d <desc> sets the feature's description\n"
+ " feature ref [-md] <pool> <feature>\n"
+ " change the refcount on the given feature\n"
+ " -d decrease instead of increase the refcount\n"
+ " -m add the feature to the label if increasing refcount\n"
+ "\n"
+ " <feature> : should be a feature guid\n");
+ exit(1);
+}
+
+
+static void
+fatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void) fprintf(stderr, "%s: ", cmdname);
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void) fprintf(stderr, "\n");
+
+ exit(1);
+}
+
+/* ARGSUSED */
+static int
+space_delta_cb(dmu_object_type_t bonustype, void *data,
+ uint64_t *userp, uint64_t *groupp)
+{
+ /*
+ * Is it a valid type of object to track?
+ */
+ if (bonustype != DMU_OT_ZNODE && bonustype != DMU_OT_SA)
+ return (ENOENT);
+ (void) fprintf(stderr, "modifying object that needs user accounting");
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Target is the dataset whose pool we want to open.
+ */
+static void
+import_pool(const char *target, boolean_t readonly)
+{
+ nvlist_t *config;
+ nvlist_t *pools;
+ int error;
+ char *sepp;
+ spa_t *spa;
+ nvpair_t *elem;
+ nvlist_t *props;
+ const char *name;
+
+ kernel_init(readonly ? FREAD : (FREAD | FWRITE));
+ g_zfs = libzfs_init();
+ ASSERT(g_zfs != NULL);
+
+ dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb);
+
+ g_readonly = readonly;
+
+ /*
+ * If we only want readonly access, it's OK if we find
+ * a potentially-active (ie, imported into the kernel) pool from the
+ * default cachefile.
+ */
+ if (readonly && spa_open(target, &spa, FTAG) == 0) {
+ spa_close(spa, FTAG);
+ return;
+ }
+
+ g_importargs.unique = B_TRUE;
+ g_importargs.can_be_active = readonly;
+ g_pool = strdup(target);
+ if ((sepp = strpbrk(g_pool, "/@")) != NULL)
+ *sepp = '\0';
+ g_importargs.poolname = g_pool;
+ pools = zpool_search_import(g_zfs, &g_importargs);
+
+ if (pools == NULL || nvlist_next_nvpair(pools, NULL) == NULL) {
+ if (!g_importargs.can_be_active) {
+ g_importargs.can_be_active = B_TRUE;
+ if (zpool_search_import(g_zfs, &g_importargs) != NULL ||
+ spa_open(target, &spa, FTAG) == 0) {
+ fatal("cannot import '%s': pool is active; run "
+ "\"zpool export %s\" first\n",
+ g_pool, g_pool);
+ }
+ }
+
+ fatal("cannot import '%s': no such pool available\n", g_pool);
+ }
+
+ elem = nvlist_next_nvpair(pools, NULL);
+ name = nvpair_name(elem);
+ verify(nvpair_value_nvlist(elem, &config) == 0);
+
+ props = NULL;
+ if (readonly) {
+ verify(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
+ verify(nvlist_add_uint64(props,
+ zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0);
+ }
+
+ zfeature_checks_disable = B_TRUE;
+ error = spa_import(name, config, props, ZFS_IMPORT_NORMAL);
+ zfeature_checks_disable = B_FALSE;
+ if (error == EEXIST)
+ error = 0;
+
+ if (error)
+ fatal("can't import '%s': %s", name, strerror(error));
+}
+
+static void
+zhack_spa_open(const char *target, boolean_t readonly, void *tag, spa_t **spa)
+{
+ int err;
+
+ import_pool(target, readonly);
+
+ zfeature_checks_disable = B_TRUE;
+ err = spa_open(target, spa, tag);
+ zfeature_checks_disable = B_FALSE;
+
+ if (err != 0)
+ fatal("cannot open '%s': %s", target, strerror(err));
+ if (spa_version(*spa) < SPA_VERSION_FEATURES) {
+ fatal("'%s' has version %d, features not enabled", target,
+ (int)spa_version(*spa));
+ }
+}
+
+static void
+dump_obj(objset_t *os, uint64_t obj, const char *name)
+{
+ zap_cursor_t zc;
+ zap_attribute_t za;
+
+ (void) printf("%s_obj:\n", name);
+
+ for (zap_cursor_init(&zc, os, obj);
+ zap_cursor_retrieve(&zc, &za) == 0;
+ zap_cursor_advance(&zc)) {
+ if (za.za_integer_length == 8) {
+ ASSERT(za.za_num_integers == 1);
+ (void) printf("\t%s = %llu\n",
+ za.za_name, (u_longlong_t)za.za_first_integer);
+ } else {
+ ASSERT(za.za_integer_length == 1);
+ char val[1024];
+ VERIFY(zap_lookup(os, obj, za.za_name,
+ 1, sizeof (val), val) == 0);
+ (void) printf("\t%s = %s\n", za.za_name, val);
+ }
+ }
+ zap_cursor_fini(&zc);
+}
+
+static void
+dump_mos(spa_t *spa)
+{
+ nvlist_t *nv = spa->spa_label_features;
+
+ (void) printf("label config:\n");
+ for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
+ pair != NULL;
+ pair = nvlist_next_nvpair(nv, pair)) {
+ (void) printf("\t%s\n", nvpair_name(pair));
+ }
+}
+
+static void
+zhack_do_feature_stat(int argc, char **argv)
+{
+ spa_t *spa;
+ objset_t *os;
+ char *target;
+
+ argc--;
+ argv++;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, "error: missing pool name\n");
+ usage();
+ }
+ target = argv[0];
+
+ zhack_spa_open(target, B_TRUE, FTAG, &spa);
+ os = spa->spa_meta_objset;
+
+ dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
+ dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
+ dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
+ dump_mos(spa);
+
+ spa_close(spa, FTAG);
+}
+
+static void
+feature_enable_sync(void *arg, dmu_tx_t *tx)
+{
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
+
+ spa_feature_enable(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack enable feature", tx,
+ "name=%s can_readonly=%u",
+ feature->fi_guid, feature->fi_can_readonly);
+}
+
+static void
+zhack_do_feature_enable(int argc, char **argv)
+{
+ char c;
+ char *desc, *target;
+ spa_t *spa;
+ objset_t *mos;
+ zfeature_info_t feature;
+ zfeature_info_t *nodeps[] = { NULL };
+
+ /*
+ * Features are not added to the pool's label until their refcounts
+ * are incremented, so fi_mos can just be left as false for now.
+ */
+ desc = NULL;
+ feature.fi_uname = "zhack";
+ feature.fi_mos = B_FALSE;
+ feature.fi_can_readonly = B_FALSE;
+ feature.fi_depends = nodeps;
+
+ optind = 1;
+ while ((c = getopt(argc, argv, "rmd:")) != -1) {
+ switch (c) {
+ case 'r':
+ feature.fi_can_readonly = B_TRUE;
+ break;
+ case 'd':
+ desc = strdup(optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (desc == NULL)
+ desc = strdup("zhack injected");
+ feature.fi_desc = desc;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 2) {
+ (void) fprintf(stderr, "error: missing feature or pool name\n");
+ usage();
+ }
+ target = argv[0];
+ feature.fi_guid = argv[1];
+
+ if (!zfeature_is_valid_guid(feature.fi_guid))
+ fatal("invalid feature guid: %s", feature.fi_guid);
+
+ zhack_spa_open(target, B_FALSE, FTAG, &spa);
+ mos = spa->spa_meta_objset;
+
+ if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
+ fatal("'%s' is a real feature, will not enable");
+ if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
+ fatal("feature already enabled: %s", feature.fi_guid);
+
+ VERIFY0(dsl_sync_task(spa_name(spa), NULL,
+ feature_enable_sync, &feature, 5));
+
+ spa_close(spa, FTAG);
+
+ free(desc);
+}
+
+static void
+feature_incr_sync(void *arg, dmu_tx_t *tx)
+{
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
+
+ spa_feature_incr(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack feature incr", tx,
+ "name=%s", feature->fi_guid);
+}
+
+static void
+feature_decr_sync(void *arg, dmu_tx_t *tx)
+{
+ spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+ zfeature_info_t *feature = arg;
+
+ spa_feature_decr(spa, feature, tx);
+ spa_history_log_internal(spa, "zhack feature decr", tx,
+ "name=%s", feature->fi_guid);
+}
+
+static void
+zhack_do_feature_ref(int argc, char **argv)
+{
+ char c;
+ char *target;
+ boolean_t decr = B_FALSE;
+ spa_t *spa;
+ objset_t *mos;
+ zfeature_info_t feature;
+ zfeature_info_t *nodeps[] = { NULL };
+
+ /*
+ * fi_desc does not matter here because it was written to disk
+ * when the feature was enabled, but we need to properly set the
+ * feature for read or write based on the information we read off
+ * disk later.
+ */
+ feature.fi_uname = "zhack";
+ feature.fi_mos = B_FALSE;
+ feature.fi_desc = NULL;
+ feature.fi_depends = nodeps;
+
+ optind = 1;
+ while ((c = getopt(argc, argv, "md")) != -1) {
+ switch (c) {
+ case 'm':
+ feature.fi_mos = B_TRUE;
+ break;
+ case 'd':
+ decr = B_TRUE;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 2) {
+ (void) fprintf(stderr, "error: missing feature or pool name\n");
+ usage();
+ }
+ target = argv[0];
+ feature.fi_guid = argv[1];
+
+ if (!zfeature_is_valid_guid(feature.fi_guid))
+ fatal("invalid feature guid: %s", feature.fi_guid);
+
+ zhack_spa_open(target, B_FALSE, FTAG, &spa);
+ mos = spa->spa_meta_objset;
+
+ if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
+ fatal("'%s' is a real feature, will not change refcount");
+
+ if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
+ feature.fi_guid)) {
+ feature.fi_can_readonly = B_FALSE;
+ } else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
+ feature.fi_guid)) {
+ feature.fi_can_readonly = B_TRUE;
+ } else {
+ fatal("feature is not enabled: %s", feature.fi_guid);
+ }
+
+ if (decr && !spa_feature_is_active(spa, &feature))
+ fatal("feature refcount already 0: %s", feature.fi_guid);
+
+ VERIFY0(dsl_sync_task(spa_name(spa), NULL,
+ decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
+
+ spa_close(spa, FTAG);
+}
+
+static int
+zhack_do_feature(int argc, char **argv)
+{
+ char *subcommand;
+
+ argc--;
+ argv++;
+ if (argc == 0) {
+ (void) fprintf(stderr,
+ "error: no feature operation specified\n");
+ usage();
+ }
+
+ subcommand = argv[0];
+ if (strcmp(subcommand, "stat") == 0) {
+ zhack_do_feature_stat(argc, argv);
+ } else if (strcmp(subcommand, "enable") == 0) {
+ zhack_do_feature_enable(argc, argv);
+ } else if (strcmp(subcommand, "ref") == 0) {
+ zhack_do_feature_ref(argc, argv);
+ } else {
+ (void) fprintf(stderr, "error: unknown subcommand: %s\n",
+ subcommand);
+ usage();
+ }
+
+ return (0);
+}
+
+#define MAX_NUM_PATHS 1024
+
+int
+main(int argc, char **argv)
+{
+ extern void zfs_prop_init(void);
+
+ char *path[MAX_NUM_PATHS];
+ const char *subcommand;
+ int rv = 0;
+ char c;
+
+ g_importargs.path = path;
+
+ dprintf_setup(&argc, argv);
+ zfs_prop_init();
+
+ while ((c = getopt(argc, argv, "c:d:")) != -1) {
+ switch (c) {
+ case 'c':
+ g_importargs.cachefile = optarg;
+ break;
+ case 'd':
+ assert(g_importargs.paths < MAX_NUM_PATHS);
+ g_importargs.path[g_importargs.paths++] = optarg;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ optind = 1;
+
+ if (argc == 0) {
+ (void) fprintf(stderr, "error: no command specified\n");
+ usage();
+ }
+
+ subcommand = argv[0];
+
+ if (strcmp(subcommand, "feature") == 0) {
+ rv = zhack_do_feature(argc, argv);
+ } else {
+ (void) fprintf(stderr, "error: unknown subcommand: %s\n",
+ subcommand);
+ usage();
+ }
+
+ if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_TRUE) != 0) {
+ fatal("pool export failed; "
+ "changes may not be committed to disk\n");
+ }
+
+ libzfs_fini(g_zfs);
+ kernel_fini();
+
+ return (rv);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zinject/translate.c b/cddl/contrib/opensolaris/cmd/zinject/translate.c
new file mode 100644
index 0000000..af25d3c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zinject/translate.c
@@ -0,0 +1,492 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <libzfs.h>
+
+#include <sys/zfs_context.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/file.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
+#include <sys/dnode.h>
+#include <sys/vdev_impl.h>
+
+#include "zinject.h"
+
+extern void kernel_init(int);
+extern void kernel_fini(void);
+
+static int debug;
+
+static void
+ziprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!debug)
+ return;
+
+ va_start(ap, fmt);
+ (void) vprintf(fmt, ap);
+ va_end(ap);
+}
+
+static void
+compress_slashes(const char *src, char *dest)
+{
+ while (*src != '\0') {
+ *dest = *src++;
+ while (*dest == '/' && *src == '/')
+ ++src;
+ ++dest;
+ }
+ *dest = '\0';
+}
+
+/*
+ * Given a full path to a file, translate into a dataset name and a relative
+ * path within the dataset. 'dataset' must be at least MAXNAMELEN characters,
+ * and 'relpath' must be at least MAXPATHLEN characters. We also pass a stat64
+ * buffer, which we need later to get the object ID.
+ */
+static int
+parse_pathname(const char *inpath, char *dataset, char *relpath,
+ struct stat64 *statbuf)
+{
+ struct statfs sfs;
+ const char *rel;
+ char fullpath[MAXPATHLEN];
+
+ compress_slashes(inpath, fullpath);
+
+ if (fullpath[0] != '/') {
+ (void) fprintf(stderr, "invalid object '%s': must be full "
+ "path\n", fullpath);
+ usage();
+ return (-1);
+ }
+
+ if (strlen(fullpath) >= MAXPATHLEN) {
+ (void) fprintf(stderr, "invalid object; pathname too long\n");
+ return (-1);
+ }
+
+ if (stat64(fullpath, statbuf) != 0) {
+ (void) fprintf(stderr, "cannot open '%s': %s\n",
+ fullpath, strerror(errno));
+ return (-1);
+ }
+
+ if (statfs(fullpath, &sfs) == -1) {
+ (void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
+ fullpath, strerror(errno));
+ return (-1);
+ }
+
+ if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
+ (void) fprintf(stderr, "invalid path '%s': not a ZFS "
+ "filesystem\n", fullpath);
+ return (-1);
+ }
+
+ if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
+ (void) fprintf(stderr, "invalid path '%s': mountpoint "
+ "doesn't match path\n", fullpath);
+ return (-1);
+ }
+
+ (void) strcpy(dataset, sfs.f_mntfromname);
+
+ rel = fullpath + strlen(sfs.f_mntonname);
+ if (rel[0] == '/')
+ rel++;
+ (void) strcpy(relpath, rel);
+
+ return (0);
+}
+
+/*
+ * Convert from a (dataset, path) pair into a (objset, object) pair. Note that
+ * we grab the object number from the inode number, since looking this up via
+ * libzpool is a real pain.
+ */
+/* ARGSUSED */
+static int
+object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
+ zinject_record_t *record)
+{
+ objset_t *os;
+ int err;
+
+ /*
+ * Before doing any libzpool operations, call sync() to ensure that the
+ * on-disk state is consistent with the in-core state.
+ */
+ sync();
+
+ err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, FTAG, &os);
+ if (err != 0) {
+ (void) fprintf(stderr, "cannot open dataset '%s': %s\n",
+ dataset, strerror(err));
+ return (-1);
+ }
+
+ record->zi_objset = dmu_objset_id(os);
+ record->zi_object = statbuf->st_ino;
+
+ dmu_objset_disown(os, FTAG);
+
+ return (0);
+}
+
+/*
+ * Calculate the real range based on the type, level, and range given.
+ */
+static int
+calculate_range(const char *dataset, err_type_t type, int level, char *range,
+ zinject_record_t *record)
+{
+ objset_t *os = NULL;
+ dnode_t *dn = NULL;
+ int err;
+ int ret = -1;
+
+ /*
+ * Determine the numeric range from the string.
+ */
+ if (range == NULL) {
+ /*
+ * If range is unspecified, set the range to [0,-1], which
+ * indicates that the whole object should be treated as an
+ * error.
+ */
+ record->zi_start = 0;
+ record->zi_end = -1ULL;
+ } else {
+ char *end;
+
+ /* XXX add support for suffixes */
+ record->zi_start = strtoull(range, &end, 10);
+
+
+ if (*end == '\0')
+ record->zi_end = record->zi_start + 1;
+ else if (*end == ',')
+ record->zi_end = strtoull(end + 1, &end, 10);
+
+ if (*end != '\0') {
+ (void) fprintf(stderr, "invalid range '%s': must be "
+ "a numeric range of the form 'start[,end]'\n",
+ range);
+ goto out;
+ }
+ }
+
+ switch (type) {
+ case TYPE_DATA:
+ break;
+
+ case TYPE_DNODE:
+ /*
+ * If this is a request to inject faults into the dnode, then we
+ * must translate the current (objset,object) pair into an
+ * offset within the metadnode for the objset. Specifying any
+ * kind of range with type 'dnode' is illegal.
+ */
+ if (range != NULL) {
+ (void) fprintf(stderr, "range cannot be specified when "
+ "type is 'dnode'\n");
+ goto out;
+ }
+
+ record->zi_start = record->zi_object * sizeof (dnode_phys_t);
+ record->zi_end = record->zi_start + sizeof (dnode_phys_t);
+ record->zi_object = 0;
+ break;
+ }
+
+ /*
+ * Get the dnode associated with object, so we can calculate the block
+ * size.
+ */
+ if ((err = dmu_objset_own(dataset, DMU_OST_ANY,
+ B_TRUE, FTAG, &os)) != 0) {
+ (void) fprintf(stderr, "cannot open dataset '%s': %s\n",
+ dataset, strerror(err));
+ goto out;
+ }
+
+ if (record->zi_object == 0) {
+ dn = DMU_META_DNODE(os);
+ } else {
+ err = dnode_hold(os, record->zi_object, FTAG, &dn);
+ if (err != 0) {
+ (void) fprintf(stderr, "failed to hold dnode "
+ "for object %llu\n",
+ (u_longlong_t)record->zi_object);
+ goto out;
+ }
+ }
+
+
+ ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
+ ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
+
+ /*
+ * Translate range into block IDs.
+ */
+ if (record->zi_start != 0 || record->zi_end != -1ULL) {
+ record->zi_start >>= dn->dn_datablkshift;
+ record->zi_end >>= dn->dn_datablkshift;
+ }
+
+ /*
+ * Check level, and then translate level 0 blkids into ranges
+ * appropriate for level of indirection.
+ */
+ record->zi_level = level;
+ if (level > 0) {
+ ziprintf("level 0 blkid range: [%llu, %llu]\n",
+ record->zi_start, record->zi_end);
+
+ if (level >= dn->dn_nlevels) {
+ (void) fprintf(stderr, "level %d exceeds max level "
+ "of object (%d)\n", level, dn->dn_nlevels - 1);
+ goto out;
+ }
+
+ if (record->zi_start != 0 || record->zi_end != 0) {
+ int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
+
+ for (; level > 0; level--) {
+ record->zi_start >>= shift;
+ record->zi_end >>= shift;
+ }
+ }
+ }
+
+ ret = 0;
+out:
+ if (dn) {
+ if (dn != DMU_META_DNODE(os))
+ dnode_rele(dn, FTAG);
+ }
+ if (os)
+ dmu_objset_disown(os, FTAG);
+
+ return (ret);
+}
+
+int
+translate_record(err_type_t type, const char *object, const char *range,
+ int level, zinject_record_t *record, char *poolname, char *dataset)
+{
+ char path[MAXPATHLEN];
+ char *slash;
+ struct stat64 statbuf;
+ int ret = -1;
+
+ kernel_init(FREAD);
+
+ debug = (getenv("ZINJECT_DEBUG") != NULL);
+
+ ziprintf("translating: %s\n", object);
+
+ if (MOS_TYPE(type)) {
+ /*
+ * MOS objects are treated specially.
+ */
+ switch (type) {
+ case TYPE_MOS:
+ record->zi_type = 0;
+ break;
+ case TYPE_MOSDIR:
+ record->zi_type = DMU_OT_OBJECT_DIRECTORY;
+ break;
+ case TYPE_METASLAB:
+ record->zi_type = DMU_OT_OBJECT_ARRAY;
+ break;
+ case TYPE_CONFIG:
+ record->zi_type = DMU_OT_PACKED_NVLIST;
+ break;
+ case TYPE_BPOBJ:
+ record->zi_type = DMU_OT_BPOBJ;
+ break;
+ case TYPE_SPACEMAP:
+ record->zi_type = DMU_OT_SPACE_MAP;
+ break;
+ case TYPE_ERRLOG:
+ record->zi_type = DMU_OT_ERROR_LOG;
+ break;
+ }
+
+ dataset[0] = '\0';
+ (void) strcpy(poolname, object);
+ return (0);
+ }
+
+ /*
+ * Convert a full path into a (dataset, file) pair.
+ */
+ if (parse_pathname(object, dataset, path, &statbuf) != 0)
+ goto err;
+
+ ziprintf(" dataset: %s\n", dataset);
+ ziprintf(" path: %s\n", path);
+
+ /*
+ * Convert (dataset, file) into (objset, object)
+ */
+ if (object_from_path(dataset, path, &statbuf, record) != 0)
+ goto err;
+
+ ziprintf("raw objset: %llu\n", record->zi_objset);
+ ziprintf("raw object: %llu\n", record->zi_object);
+
+ /*
+ * For the given object, calculate the real (type, level, range)
+ */
+ if (calculate_range(dataset, type, level, (char *)range, record) != 0)
+ goto err;
+
+ ziprintf(" objset: %llu\n", record->zi_objset);
+ ziprintf(" object: %llu\n", record->zi_object);
+ if (record->zi_start == 0 &&
+ record->zi_end == -1ULL)
+ ziprintf(" range: all\n");
+ else
+ ziprintf(" range: [%llu, %llu]\n", record->zi_start,
+ record->zi_end);
+
+ /*
+ * Copy the pool name
+ */
+ (void) strcpy(poolname, dataset);
+ if ((slash = strchr(poolname, '/')) != NULL)
+ *slash = '\0';
+
+ ret = 0;
+
+err:
+ kernel_fini();
+ return (ret);
+}
+
+int
+translate_raw(const char *str, zinject_record_t *record)
+{
+ /*
+ * A raw bookmark of the form objset:object:level:blkid, where each
+ * number is a hexidecimal value.
+ */
+ if (sscanf(str, "%llx:%llx:%x:%llx", (u_longlong_t *)&record->zi_objset,
+ (u_longlong_t *)&record->zi_object, &record->zi_level,
+ (u_longlong_t *)&record->zi_start) != 4) {
+ (void) fprintf(stderr, "bad raw spec '%s': must be of the form "
+ "'objset:object:level:blkid'\n", str);
+ return (-1);
+ }
+
+ record->zi_end = record->zi_start;
+
+ return (0);
+}
+
+int
+translate_device(const char *pool, const char *device, err_type_t label_type,
+ zinject_record_t *record)
+{
+ char *end;
+ zpool_handle_t *zhp;
+ nvlist_t *tgt;
+ boolean_t isspare, iscache;
+
+ /*
+ * Given a device name or GUID, create an appropriate injection record
+ * with zi_guid set.
+ */
+ if ((zhp = zpool_open(g_zfs, pool)) == NULL)
+ return (-1);
+
+ record->zi_guid = strtoull(device, &end, 16);
+ if (record->zi_guid == 0 || *end != '\0') {
+ tgt = zpool_find_vdev(zhp, device, &isspare, &iscache, NULL);
+
+ if (tgt == NULL) {
+ (void) fprintf(stderr, "cannot find device '%s' in "
+ "pool '%s'\n", device, pool);
+ return (-1);
+ }
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
+ &record->zi_guid) == 0);
+ }
+
+ /*
+ * Device faults can take on three different forms:
+ * 1). delayed or hanging I/O
+ * 2). zfs label faults
+ * 3). generic disk faults
+ */
+ if (record->zi_timer != 0) {
+ record->zi_cmd = ZINJECT_DELAY_IO;
+ } else if (label_type != TYPE_INVAL) {
+ record->zi_cmd = ZINJECT_LABEL_FAULT;
+ } else {
+ record->zi_cmd = ZINJECT_DEVICE_FAULT;
+ }
+
+ switch (label_type) {
+ case TYPE_LABEL_UBERBLOCK:
+ record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]);
+ record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1;
+ break;
+ case TYPE_LABEL_NVLIST:
+ record->zi_start = offsetof(vdev_label_t, vl_vdev_phys);
+ record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1;
+ break;
+ case TYPE_LABEL_PAD1:
+ record->zi_start = offsetof(vdev_label_t, vl_pad1);
+ record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1;
+ break;
+ case TYPE_LABEL_PAD2:
+ record->zi_start = offsetof(vdev_label_t, vl_pad2);
+ record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1;
+ break;
+ }
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zinject/zinject.c b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
new file mode 100644
index 0000000..994d687
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zinject/zinject.c
@@ -0,0 +1,987 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * ZFS Fault Injector
+ *
+ * This userland component takes a set of options and uses libzpool to translate
+ * from a user-visible object type and name to an internal representation.
+ * There are two basic types of faults: device faults and data faults.
+ *
+ *
+ * DEVICE FAULTS
+ *
+ * Errors can be injected into a particular vdev using the '-d' option. This
+ * option takes a path or vdev GUID to uniquely identify the device within a
+ * pool. There are two types of errors that can be injected, EIO and ENXIO,
+ * that can be controlled through the '-e' option. The default is ENXIO. For
+ * EIO failures, any attempt to read data from the device will return EIO, but
+ * subsequent attempt to reopen the device will succeed. For ENXIO failures,
+ * any attempt to read from the device will return EIO, but any attempt to
+ * reopen the device will also return ENXIO.
+ * For label faults, the -L option must be specified. This allows faults
+ * to be injected into either the nvlist, uberblock, pad1, or pad2 region
+ * of all the labels for the specified device.
+ *
+ * This form of the command looks like:
+ *
+ * zinject -d device [-e errno] [-L <uber | nvlist | pad1 | pad2>] pool
+ *
+ *
+ * DATA FAULTS
+ *
+ * We begin with a tuple of the form:
+ *
+ * <type,level,range,object>
+ *
+ * type A string describing the type of data to target. Each type
+ * implicitly describes how to interpret 'object'. Currently,
+ * the following values are supported:
+ *
+ * data User data for a file
+ * dnode Dnode for a file or directory
+ *
+ * The following MOS objects are special. Instead of injecting
+ * errors on a particular object or blkid, we inject errors across
+ * all objects of the given type.
+ *
+ * mos Any data in the MOS
+ * mosdir object directory
+ * config pool configuration
+ * bpobj blkptr list
+ * spacemap spacemap
+ * metaslab metaslab
+ * errlog persistent error log
+ *
+ * level Object level. Defaults to '0', not applicable to all types. If
+ * a range is given, this corresponds to the indirect block
+ * corresponding to the specific range.
+ *
+ * range A numerical range [start,end) within the object. Defaults to
+ * the full size of the file.
+ *
+ * object A string describing the logical location of the object. For
+ * files and directories (currently the only supported types),
+ * this is the path of the object on disk.
+ *
+ * This is translated, via libzpool, into the following internal representation:
+ *
+ * <type,objset,object,level,range>
+ *
+ * These types should be self-explanatory. This tuple is then passed to the
+ * kernel via a special ioctl() to initiate fault injection for the given
+ * object. Note that 'type' is not strictly necessary for fault injection, but
+ * is used when translating existing faults into a human-readable string.
+ *
+ *
+ * The command itself takes one of the forms:
+ *
+ * zinject
+ * zinject <-a | -u pool>
+ * zinject -c <id|all>
+ * zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
+ * [-r range] <object>
+ * zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
+ *
+ * With no arguments, the command prints all currently registered injection
+ * handlers, with their numeric identifiers.
+ *
+ * The '-c' option will clear the given handler, or all handlers if 'all' is
+ * specified.
+ *
+ * The '-e' option takes a string describing the errno to simulate. This must
+ * be either 'io' or 'checksum'. In most cases this will result in the same
+ * behavior, but RAID-Z will produce a different set of ereports for this
+ * situation.
+ *
+ * The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
+ * specified, then the ARC cache is flushed appropriately. If '-u' is
+ * specified, then the underlying SPA is unloaded. Either of these flags can be
+ * specified independently of any other handlers. The '-m' flag automatically
+ * does an unmount and remount of the underlying dataset to aid in flushing the
+ * cache.
+ *
+ * The '-f' flag controls the frequency of errors injected, expressed as a
+ * integer percentage between 1 and 100. The default is 100.
+ *
+ * The this form is responsible for actually injecting the handler into the
+ * framework. It takes the arguments described above, translates them to the
+ * internal tuple using libzpool, and then issues an ioctl() to register the
+ * handler.
+ *
+ * The final form can target a specific bookmark, regardless of whether a
+ * human-readable interface has been designed. It allows developers to specify
+ * a particular block by number.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <sys/fs/zfs.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <libzfs.h>
+
+#undef verify /* both libzfs.h and zfs_context.h want to define this */
+
+#include "zinject.h"
+
+libzfs_handle_t *g_zfs;
+int zfs_fd;
+
+#ifndef ECKSUM
+#define ECKSUM EBADE
+#endif
+
+static const char *errtable[TYPE_INVAL] = {
+ "data",
+ "dnode",
+ "mos",
+ "mosdir",
+ "metaslab",
+ "config",
+ "bpobj",
+ "spacemap",
+ "errlog",
+ "uber",
+ "nvlist",
+ "pad1",
+ "pad2"
+};
+
+static err_type_t
+name_to_type(const char *arg)
+{
+ int i;
+ for (i = 0; i < TYPE_INVAL; i++)
+ if (strcmp(errtable[i], arg) == 0)
+ return (i);
+
+ return (TYPE_INVAL);
+}
+
+static const char *
+type_to_name(uint64_t type)
+{
+ switch (type) {
+ case DMU_OT_OBJECT_DIRECTORY:
+ return ("mosdir");
+ case DMU_OT_OBJECT_ARRAY:
+ return ("metaslab");
+ case DMU_OT_PACKED_NVLIST:
+ return ("config");
+ case DMU_OT_BPOBJ:
+ return ("bpobj");
+ case DMU_OT_SPACE_MAP:
+ return ("spacemap");
+ case DMU_OT_ERROR_LOG:
+ return ("errlog");
+ default:
+ return ("-");
+ }
+}
+
+
+/*
+ * Print usage message.
+ */
+void
+usage(void)
+{
+ (void) printf(
+ "usage:\n"
+ "\n"
+ "\tzinject\n"
+ "\n"
+ "\t\tList all active injection records.\n"
+ "\n"
+ "\tzinject -c <id|all>\n"
+ "\n"
+ "\t\tClear the particular record (if given a numeric ID), or\n"
+ "\t\tall records if 'all' is specificed.\n"
+ "\n"
+ "\tzinject -p <function name> pool\n"
+ "\t\tInject a panic fault at the specified function. Only \n"
+ "\t\tfunctions which call spa_vdev_config_exit(), or \n"
+ "\t\tspa_vdev_exit() will trigger a panic.\n"
+ "\n"
+ "\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n"
+ "\t [-T <read|write|free|claim|all> pool\n"
+ "\t\tInject a fault into a particular device or the device's\n"
+ "\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
+ "\t\t'pad1', or 'pad2'.\n"
+ "\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n"
+ "\n"
+ "\tzinject -d device -A <degrade|fault> pool\n"
+ "\t\tPerform a specific action on a particular device\n"
+ "\n"
+ "\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
+ "\t\tCause the pool to stop writing blocks yet not\n"
+ "\t\treport errors for a duration. Simulates buggy hardware\n"
+ "\t\tthat fails to honor cache flush requests.\n"
+ "\t\tDefault duration is 30 seconds. The machine is panicked\n"
+ "\t\tat the end of the duration.\n"
+ "\n"
+ "\tzinject -b objset:object:level:blkid pool\n"
+ "\n"
+ "\t\tInject an error into pool 'pool' with the numeric bookmark\n"
+ "\t\tspecified by the remaining tuple. Each number is in\n"
+ "\t\thexidecimal, and only one block can be specified.\n"
+ "\n"
+ "\tzinject [-q] <-t type> [-e errno] [-l level] [-r range]\n"
+ "\t [-a] [-m] [-u] [-f freq] <object>\n"
+ "\n"
+ "\t\tInject an error into the object specified by the '-t' option\n"
+ "\t\tand the object descriptor. The 'object' parameter is\n"
+ "\t\tinterperted depending on the '-t' option.\n"
+ "\n"
+ "\t\t-q\tQuiet mode. Only print out the handler number added.\n"
+ "\t\t-e\tInject a specific error. Must be either 'io' or\n"
+ "\t\t\t'checksum'. Default is 'io'.\n"
+ "\t\t-l\tInject error at a particular block level. Default is "
+ "0.\n"
+ "\t\t-m\tAutomatically remount underlying filesystem.\n"
+ "\t\t-r\tInject error over a particular logical range of an\n"
+ "\t\t\tobject. Will be translated to the appropriate blkid\n"
+ "\t\t\trange according to the object's properties.\n"
+ "\t\t-a\tFlush the ARC cache. Can be specified without any\n"
+ "\t\t\tassociated object.\n"
+ "\t\t-u\tUnload the associated pool. Can be specified with only\n"
+ "\t\t\ta pool object.\n"
+ "\t\t-f\tOnly inject errors a fraction of the time. Expressed as\n"
+ "\t\t\ta percentage between 1 and 100.\n"
+ "\n"
+ "\t-t data\t\tInject an error into the plain file contents of a\n"
+ "\t\t\tfile. The object must be specified as a complete path\n"
+ "\t\t\tto a file on a ZFS filesystem.\n"
+ "\n"
+ "\t-t dnode\tInject an error into the metadnode in the block\n"
+ "\t\t\tcorresponding to the dnode for a file or directory. The\n"
+ "\t\t\t'-r' option is incompatible with this mode. The object\n"
+ "\t\t\tis specified as a complete path to a file or directory\n"
+ "\t\t\ton a ZFS filesystem.\n"
+ "\n"
+ "\t-t <mos>\tInject errors into the MOS for objects of the given\n"
+ "\t\t\ttype. Valid types are: mos, mosdir, config, bpobj,\n"
+ "\t\t\tspacemap, metaslab, errlog. The only valid <object> is\n"
+ "\t\t\tthe poolname.\n");
+}
+
+static int
+iter_handlers(int (*func)(int, const char *, zinject_record_t *, void *),
+ void *data)
+{
+ zfs_cmd_t zc = { 0 };
+ int ret;
+
+ while (ioctl(zfs_fd, ZFS_IOC_INJECT_LIST_NEXT, &zc) == 0)
+ if ((ret = func((int)zc.zc_guid, zc.zc_name,
+ &zc.zc_inject_record, data)) != 0)
+ return (ret);
+
+ if (errno != ENOENT) {
+ (void) fprintf(stderr, "Unable to list handlers: %s\n",
+ strerror(errno));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+print_data_handler(int id, const char *pool, zinject_record_t *record,
+ void *data)
+{
+ int *count = data;
+
+ if (record->zi_guid != 0 || record->zi_func[0] != '\0')
+ return (0);
+
+ if (*count == 0) {
+ (void) printf("%3s %-15s %-6s %-6s %-8s %3s %-15s\n",
+ "ID", "POOL", "OBJSET", "OBJECT", "TYPE", "LVL", "RANGE");
+ (void) printf("--- --------------- ------ "
+ "------ -------- --- ---------------\n");
+ }
+
+ *count += 1;
+
+ (void) printf("%3d %-15s %-6llu %-6llu %-8s %3d ", id, pool,
+ (u_longlong_t)record->zi_objset, (u_longlong_t)record->zi_object,
+ type_to_name(record->zi_type), record->zi_level);
+
+ if (record->zi_start == 0 &&
+ record->zi_end == -1ULL)
+ (void) printf("all\n");
+ else
+ (void) printf("[%llu, %llu]\n", (u_longlong_t)record->zi_start,
+ (u_longlong_t)record->zi_end);
+
+ return (0);
+}
+
+static int
+print_device_handler(int id, const char *pool, zinject_record_t *record,
+ void *data)
+{
+ int *count = data;
+
+ if (record->zi_guid == 0 || record->zi_func[0] != '\0')
+ return (0);
+
+ if (*count == 0) {
+ (void) printf("%3s %-15s %s\n", "ID", "POOL", "GUID");
+ (void) printf("--- --------------- ----------------\n");
+ }
+
+ *count += 1;
+
+ (void) printf("%3d %-15s %llx\n", id, pool,
+ (u_longlong_t)record->zi_guid);
+
+ return (0);
+}
+
+static int
+print_panic_handler(int id, const char *pool, zinject_record_t *record,
+ void *data)
+{
+ int *count = data;
+
+ if (record->zi_func[0] == '\0')
+ return (0);
+
+ if (*count == 0) {
+ (void) printf("%3s %-15s %s\n", "ID", "POOL", "FUNCTION");
+ (void) printf("--- --------------- ----------------\n");
+ }
+
+ *count += 1;
+
+ (void) printf("%3d %-15s %s\n", id, pool, record->zi_func);
+
+ return (0);
+}
+
+/*
+ * Print all registered error handlers. Returns the number of handlers
+ * registered.
+ */
+static int
+print_all_handlers(void)
+{
+ int count = 0, total = 0;
+
+ (void) iter_handlers(print_device_handler, &count);
+ if (count > 0) {
+ total += count;
+ (void) printf("\n");
+ count = 0;
+ }
+
+ (void) iter_handlers(print_data_handler, &count);
+ if (count > 0) {
+ total += count;
+ (void) printf("\n");
+ count = 0;
+ }
+
+ (void) iter_handlers(print_panic_handler, &count);
+
+ return (count + total);
+}
+
+/* ARGSUSED */
+static int
+cancel_one_handler(int id, const char *pool, zinject_record_t *record,
+ void *data)
+{
+ zfs_cmd_t zc = { 0 };
+
+ zc.zc_guid = (uint64_t)id;
+
+ if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
+ (void) fprintf(stderr, "failed to remove handler %d: %s\n",
+ id, strerror(errno));
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Remove all fault injection handlers.
+ */
+static int
+cancel_all_handlers(void)
+{
+ int ret = iter_handlers(cancel_one_handler, NULL);
+
+ if (ret == 0)
+ (void) printf("removed all registered handlers\n");
+
+ return (ret);
+}
+
+/*
+ * Remove a specific fault injection handler.
+ */
+static int
+cancel_handler(int id)
+{
+ zfs_cmd_t zc = { 0 };
+
+ zc.zc_guid = (uint64_t)id;
+
+ if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
+ (void) fprintf(stderr, "failed to remove handler %d: %s\n",
+ id, strerror(errno));
+ return (1);
+ }
+
+ (void) printf("removed handler %d\n", id);
+
+ return (0);
+}
+
+/*
+ * Register a new fault injection handler.
+ */
+static int
+register_handler(const char *pool, int flags, zinject_record_t *record,
+ int quiet)
+{
+ zfs_cmd_t zc = { 0 };
+
+ (void) strcpy(zc.zc_name, pool);
+ zc.zc_inject_record = *record;
+ zc.zc_guid = flags;
+
+ if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
+ (void) fprintf(stderr, "failed to add handler: %s\n",
+ strerror(errno));
+ return (1);
+ }
+
+ if (flags & ZINJECT_NULL)
+ return (0);
+
+ if (quiet) {
+ (void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
+ } else {
+ (void) printf("Added handler %llu with the following "
+ "properties:\n", (u_longlong_t)zc.zc_guid);
+ (void) printf(" pool: %s\n", pool);
+ if (record->zi_guid) {
+ (void) printf(" vdev: %llx\n",
+ (u_longlong_t)record->zi_guid);
+ } else if (record->zi_func[0] != '\0') {
+ (void) printf(" panic function: %s\n",
+ record->zi_func);
+ } else if (record->zi_duration > 0) {
+ (void) printf(" time: %lld seconds\n",
+ (u_longlong_t)record->zi_duration);
+ } else if (record->zi_duration < 0) {
+ (void) printf(" txgs: %lld \n",
+ (u_longlong_t)-record->zi_duration);
+ } else {
+ (void) printf("objset: %llu\n",
+ (u_longlong_t)record->zi_objset);
+ (void) printf("object: %llu\n",
+ (u_longlong_t)record->zi_object);
+ (void) printf(" type: %llu\n",
+ (u_longlong_t)record->zi_type);
+ (void) printf(" level: %d\n", record->zi_level);
+ if (record->zi_start == 0 &&
+ record->zi_end == -1ULL)
+ (void) printf(" range: all\n");
+ else
+ (void) printf(" range: [%llu, %llu)\n",
+ (u_longlong_t)record->zi_start,
+ (u_longlong_t)record->zi_end);
+ }
+ }
+
+ return (0);
+}
+
+int
+perform_action(const char *pool, zinject_record_t *record, int cmd)
+{
+ zfs_cmd_t zc = { 0 };
+
+ ASSERT(cmd == VDEV_STATE_DEGRADED || cmd == VDEV_STATE_FAULTED);
+ (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
+ zc.zc_guid = record->zi_guid;
+ zc.zc_cookie = cmd;
+
+ if (ioctl(zfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
+ return (0);
+
+ return (1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ char *range = NULL;
+ char *cancel = NULL;
+ char *end;
+ char *raw = NULL;
+ char *device = NULL;
+ int level = 0;
+ int quiet = 0;
+ int error = 0;
+ int domount = 0;
+ int io_type = ZIO_TYPES;
+ int action = VDEV_STATE_UNKNOWN;
+ err_type_t type = TYPE_INVAL;
+ err_type_t label = TYPE_INVAL;
+ zinject_record_t record = { 0 };
+ char pool[MAXNAMELEN];
+ char dataset[MAXNAMELEN];
+ zfs_handle_t *zhp;
+ int nowrites = 0;
+ int dur_txg = 0;
+ int dur_secs = 0;
+ int ret;
+ int flags = 0;
+
+ if ((g_zfs = libzfs_init()) == NULL) {
+ (void) fprintf(stderr, "internal error: failed to "
+ "initialize ZFS library\n");
+ return (1);
+ }
+
+ libzfs_print_on_error(g_zfs, B_TRUE);
+
+ if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
+ (void) fprintf(stderr, "failed to open ZFS device\n");
+ return (1);
+ }
+
+ if (argc == 1) {
+ /*
+ * No arguments. Print the available handlers. If there are no
+ * available handlers, direct the user to '-h' for help
+ * information.
+ */
+ if (print_all_handlers() == 0) {
+ (void) printf("No handlers registered.\n");
+ (void) printf("Run 'zinject -h' for usage "
+ "information.\n");
+ }
+
+ return (0);
+ }
+
+ while ((c = getopt(argc, argv,
+ ":aA:b:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
+ switch (c) {
+ case 'a':
+ flags |= ZINJECT_FLUSH_ARC;
+ break;
+ case 'A':
+ if (strcasecmp(optarg, "degrade") == 0) {
+ action = VDEV_STATE_DEGRADED;
+ } else if (strcasecmp(optarg, "fault") == 0) {
+ action = VDEV_STATE_FAULTED;
+ } else {
+ (void) fprintf(stderr, "invalid action '%s': "
+ "must be 'degrade' or 'fault'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'b':
+ raw = optarg;
+ break;
+ case 'c':
+ cancel = optarg;
+ break;
+ case 'd':
+ device = optarg;
+ break;
+ case 'D':
+ record.zi_timer = strtoull(optarg, &end, 10);
+ if (errno != 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid i/o delay "
+ "value: '%s'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'e':
+ if (strcasecmp(optarg, "io") == 0) {
+ error = EIO;
+ } else if (strcasecmp(optarg, "checksum") == 0) {
+ error = ECKSUM;
+ } else if (strcasecmp(optarg, "nxio") == 0) {
+ error = ENXIO;
+ } else if (strcasecmp(optarg, "dtl") == 0) {
+ error = ECHILD;
+ } else {
+ (void) fprintf(stderr, "invalid error type "
+ "'%s': must be 'io', 'checksum' or "
+ "'nxio'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'f':
+ record.zi_freq = atoi(optarg);
+ if (record.zi_freq < 1 || record.zi_freq > 100) {
+ (void) fprintf(stderr, "frequency range must "
+ "be in the range (0, 100]\n");
+ return (1);
+ }
+ break;
+ case 'F':
+ record.zi_failfast = B_TRUE;
+ break;
+ case 'g':
+ dur_txg = 1;
+ record.zi_duration = (int)strtol(optarg, &end, 10);
+ if (record.zi_duration <= 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid duration '%s': "
+ "must be a positive integer\n", optarg);
+ usage();
+ return (1);
+ }
+ /* store duration of txgs as its negative */
+ record.zi_duration *= -1;
+ break;
+ case 'h':
+ usage();
+ return (0);
+ case 'I':
+ /* default duration, if one hasn't yet been defined */
+ nowrites = 1;
+ if (dur_secs == 0 && dur_txg == 0)
+ record.zi_duration = 30;
+ break;
+ case 'l':
+ level = (int)strtol(optarg, &end, 10);
+ if (*end != '\0') {
+ (void) fprintf(stderr, "invalid level '%s': "
+ "must be an integer\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'm':
+ domount = 1;
+ break;
+ case 'p':
+ (void) strlcpy(record.zi_func, optarg,
+ sizeof (record.zi_func));
+ record.zi_cmd = ZINJECT_PANIC;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'r':
+ range = optarg;
+ break;
+ case 's':
+ dur_secs = 1;
+ record.zi_duration = (int)strtol(optarg, &end, 10);
+ if (record.zi_duration <= 0 || *end != '\0') {
+ (void) fprintf(stderr, "invalid duration '%s': "
+ "must be a positive integer\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'T':
+ if (strcasecmp(optarg, "read") == 0) {
+ io_type = ZIO_TYPE_READ;
+ } else if (strcasecmp(optarg, "write") == 0) {
+ io_type = ZIO_TYPE_WRITE;
+ } else if (strcasecmp(optarg, "free") == 0) {
+ io_type = ZIO_TYPE_FREE;
+ } else if (strcasecmp(optarg, "claim") == 0) {
+ io_type = ZIO_TYPE_CLAIM;
+ } else if (strcasecmp(optarg, "all") == 0) {
+ io_type = ZIO_TYPES;
+ } else {
+ (void) fprintf(stderr, "invalid I/O type "
+ "'%s': must be 'read', 'write', 'free', "
+ "'claim' or 'all'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 't':
+ if ((type = name_to_type(optarg)) == TYPE_INVAL &&
+ !MOS_TYPE(type)) {
+ (void) fprintf(stderr, "invalid type '%s'\n",
+ optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case 'u':
+ flags |= ZINJECT_UNLOAD_SPA;
+ break;
+ case 'L':
+ if ((label = name_to_type(optarg)) == TYPE_INVAL &&
+ !LABEL_TYPE(type)) {
+ (void) fprintf(stderr, "invalid label type "
+ "'%s'\n", optarg);
+ usage();
+ return (1);
+ }
+ break;
+ case ':':
+ (void) fprintf(stderr, "option -%c requires an "
+ "operand\n", optopt);
+ usage();
+ return (1);
+ case '?':
+ (void) fprintf(stderr, "invalid option '%c'\n",
+ optopt);
+ usage();
+ return (2);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (record.zi_duration != 0)
+ record.zi_cmd = ZINJECT_IGNORED_WRITES;
+
+ if (cancel != NULL) {
+ /*
+ * '-c' is invalid with any other options.
+ */
+ if (raw != NULL || range != NULL || type != TYPE_INVAL ||
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
+ (void) fprintf(stderr, "cancel (-c) incompatible with "
+ "any other options\n");
+ usage();
+ return (2);
+ }
+ if (argc != 0) {
+ (void) fprintf(stderr, "extraneous argument to '-c'\n");
+ usage();
+ return (2);
+ }
+
+ if (strcmp(cancel, "all") == 0) {
+ return (cancel_all_handlers());
+ } else {
+ int id = (int)strtol(cancel, &end, 10);
+ if (*end != '\0') {
+ (void) fprintf(stderr, "invalid handle id '%s':"
+ " must be an integer or 'all'\n", cancel);
+ usage();
+ return (1);
+ }
+ return (cancel_handler(id));
+ }
+ }
+
+ if (device != NULL) {
+ /*
+ * Device (-d) injection uses a completely different mechanism
+ * for doing injection, so handle it separately here.
+ */
+ if (raw != NULL || range != NULL || type != TYPE_INVAL ||
+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
+ (void) fprintf(stderr, "device (-d) incompatible with "
+ "data error injection\n");
+ usage();
+ return (2);
+ }
+
+ if (argc != 1) {
+ (void) fprintf(stderr, "device (-d) injection requires "
+ "a single pool name\n");
+ usage();
+ return (2);
+ }
+
+ (void) strcpy(pool, argv[0]);
+ dataset[0] = '\0';
+
+ if (error == ECKSUM) {
+ (void) fprintf(stderr, "device error type must be "
+ "'io' or 'nxio'\n");
+ return (1);
+ }
+
+ record.zi_iotype = io_type;
+ if (translate_device(pool, device, label, &record) != 0)
+ return (1);
+ if (!error)
+ error = ENXIO;
+
+ if (action != VDEV_STATE_UNKNOWN)
+ return (perform_action(pool, &record, action));
+
+ } else if (raw != NULL) {
+ if (range != NULL || type != TYPE_INVAL || level != 0 ||
+ record.zi_cmd != ZINJECT_UNINITIALIZED) {
+ (void) fprintf(stderr, "raw (-b) format with "
+ "any other options\n");
+ usage();
+ return (2);
+ }
+
+ if (argc != 1) {
+ (void) fprintf(stderr, "raw (-b) format expects a "
+ "single pool name\n");
+ usage();
+ return (2);
+ }
+
+ (void) strcpy(pool, argv[0]);
+ dataset[0] = '\0';
+
+ if (error == ENXIO) {
+ (void) fprintf(stderr, "data error type must be "
+ "'checksum' or 'io'\n");
+ return (1);
+ }
+
+ record.zi_cmd = ZINJECT_DATA_FAULT;
+ if (translate_raw(raw, &record) != 0)
+ return (1);
+ if (!error)
+ error = EIO;
+ } else if (record.zi_cmd == ZINJECT_PANIC) {
+ if (raw != NULL || range != NULL || type != TYPE_INVAL ||
+ level != 0 || device != NULL) {
+ (void) fprintf(stderr, "panic (-p) incompatible with "
+ "other options\n");
+ usage();
+ return (2);
+ }
+
+ if (argc < 1 || argc > 2) {
+ (void) fprintf(stderr, "panic (-p) injection requires "
+ "a single pool name and an optional id\n");
+ usage();
+ return (2);
+ }
+
+ (void) strcpy(pool, argv[0]);
+ if (argv[1] != NULL)
+ record.zi_type = atoi(argv[1]);
+ dataset[0] = '\0';
+ } else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
+ if (nowrites == 0) {
+ (void) fprintf(stderr, "-s or -g meaningless "
+ "without -I (ignore writes)\n");
+ usage();
+ return (2);
+ } else if (dur_secs && dur_txg) {
+ (void) fprintf(stderr, "choose a duration either "
+ "in seconds (-s) or a number of txgs (-g) "
+ "but not both\n");
+ usage();
+ return (2);
+ } else if (argc != 1) {
+ (void) fprintf(stderr, "ignore writes (-I) "
+ "injection requires a single pool name\n");
+ usage();
+ return (2);
+ }
+
+ (void) strcpy(pool, argv[0]);
+ dataset[0] = '\0';
+ } else if (type == TYPE_INVAL) {
+ if (flags == 0) {
+ (void) fprintf(stderr, "at least one of '-b', '-d', "
+ "'-t', '-a', '-p', '-I' or '-u' "
+ "must be specified\n");
+ usage();
+ return (2);
+ }
+
+ if (argc == 1 && (flags & ZINJECT_UNLOAD_SPA)) {
+ (void) strcpy(pool, argv[0]);
+ dataset[0] = '\0';
+ } else if (argc != 0) {
+ (void) fprintf(stderr, "extraneous argument for "
+ "'-f'\n");
+ usage();
+ return (2);
+ }
+
+ flags |= ZINJECT_NULL;
+ } else {
+ if (argc != 1) {
+ (void) fprintf(stderr, "missing object\n");
+ usage();
+ return (2);
+ }
+
+ if (error == ENXIO) {
+ (void) fprintf(stderr, "data error type must be "
+ "'checksum' or 'io'\n");
+ return (1);
+ }
+
+ record.zi_cmd = ZINJECT_DATA_FAULT;
+ if (translate_record(type, argv[0], range, level, &record, pool,
+ dataset) != 0)
+ return (1);
+ if (!error)
+ error = EIO;
+ }
+
+ /*
+ * If this is pool-wide metadata, unmount everything. The ioctl() will
+ * unload the pool, so that we trigger spa-wide reopen of metadata next
+ * time we access the pool.
+ */
+ if (dataset[0] != '\0' && domount) {
+ if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
+ return (1);
+
+ if (zfs_unmount(zhp, NULL, 0) != 0)
+ return (1);
+ }
+
+ record.zi_error = error;
+
+ ret = register_handler(pool, flags, &record, quiet);
+
+ if (dataset[0] != '\0' && domount)
+ ret = (zfs_mount(zhp, NULL, 0) != 0);
+
+ libzfs_fini(g_zfs);
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zinject/zinject.h b/cddl/contrib/opensolaris/cmd/zinject/zinject.h
new file mode 100644
index 0000000..46fdcad
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zinject/zinject.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _ZINJECT_H
+#define _ZINJECT_H
+
+#include <sys/zfs_ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ TYPE_DATA, /* plain file contents */
+ TYPE_DNODE, /* metadnode contents */
+ TYPE_MOS, /* all MOS data */
+ TYPE_MOSDIR, /* MOS object directory */
+ TYPE_METASLAB, /* metaslab objects */
+ TYPE_CONFIG, /* MOS config */
+ TYPE_BPOBJ, /* block pointer list */
+ TYPE_SPACEMAP, /* space map objects */
+ TYPE_ERRLOG, /* persistent error log */
+ TYPE_LABEL_UBERBLOCK, /* label specific uberblock */
+ TYPE_LABEL_NVLIST, /* label specific nvlist */
+ TYPE_LABEL_PAD1, /* label specific 8K pad1 area */
+ TYPE_LABEL_PAD2, /* label specific 8K pad2 area */
+ TYPE_INVAL
+} err_type_t;
+
+#define MOS_TYPE(t) \
+ ((t) >= TYPE_MOS && (t) < TYPE_LABEL_UBERBLOCK)
+
+#define LABEL_TYPE(t) \
+ ((t) >= TYPE_LABEL_UBERBLOCK && (t) < TYPE_INVAL)
+
+int translate_record(err_type_t type, const char *object, const char *range,
+ int level, zinject_record_t *record, char *poolname, char *dataset);
+int translate_raw(const char *raw, zinject_record_t *record);
+int translate_device(const char *pool, const char *device,
+ err_type_t label_type, zinject_record_t *record);
+void usage(void);
+
+extern libzfs_handle_t *g_zfs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZINJECT_H */
diff --git a/cddl/contrib/opensolaris/cmd/zlook/zlook.c b/cddl/contrib/opensolaris/cmd/zlook/zlook.c
new file mode 100644
index 0000000..29a6559
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zlook/zlook.c
@@ -0,0 +1,411 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This is a test program that uses ioctls to the ZFS Unit Test driver
+ * to perform readdirs or lookups using flags not normally available
+ * to user-land programs. This allows testing of the flags'
+ * behavior outside of a complicated consumer, such as the SMB driver.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/dirent.h>
+#include <sys/attr.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+
+#define _KERNEL
+
+#include <sys/fs/zut.h>
+#include <sys/extdirent.h>
+
+#undef _KERNEL
+
+#define MAXBUF (64 * 1024)
+#define BIGBUF 4096
+#define LILBUF (sizeof (dirent_t))
+
+#define DIRENT_NAMELEN(reclen) \
+ ((reclen) - (offsetof(dirent_t, d_name[0])))
+
+static void
+usage(char *pnam)
+{
+ (void) fprintf(stderr, "Usage:\n %s -l [-is] dir-to-look-in "
+ "file-in-dir [xfile-on-file]\n", pnam);
+ (void) fprintf(stderr, " %s -i [-ls] dir-to-look-in "
+ "file-in-dir [xfile-on-file]\n", pnam);
+ (void) fprintf(stderr, " %s -s [-il] dir-to-look-in "
+ "file-in-dir [xfile-on-file]\n", pnam);
+ (void) fprintf(stderr, "\t Perform a lookup\n");
+ (void) fprintf(stderr, "\t -l == lookup\n");
+ (void) fprintf(stderr, "\t -i == request FIGNORECASE\n");
+ (void) fprintf(stderr, "\t -s == request stat(2) and xvattr info\n");
+ (void) fprintf(stderr, " %s -r [-ea] [-b buffer-size-in-bytes] "
+ "dir-to-look-in [file-in-dir]\n", pnam);
+ (void) fprintf(stderr, " %s -e [-ra] [-b buffer-size-in-bytes] "
+ "dir-to-look-in [file-in-dir]\n", pnam);
+ (void) fprintf(stderr, " %s -a [-re] [-b buffer-size-in-bytes] "
+ "dir-to-look-in [file-in-dir]\n", pnam);
+ (void) fprintf(stderr, "\t Perform a readdir\n");
+ (void) fprintf(stderr, "\t -r == readdir\n");
+ (void) fprintf(stderr, "\t -e == request extended entries\n");
+ (void) fprintf(stderr, "\t -a == request access filtering\n");
+ (void) fprintf(stderr, "\t -b == buffer size (default 4K)\n");
+ (void) fprintf(stderr, " %s -A path\n", pnam);
+ (void) fprintf(stderr, "\t Look up _PC_ACCESS_FILTERING "
+ "for path with pathconf(2)\n");
+ (void) fprintf(stderr, " %s -E path\n", pnam);
+ (void) fprintf(stderr, "\t Look up _PC_SATTR_EXISTS "
+ "for path with pathconf(2)\n");
+ (void) fprintf(stderr, " %s -S path\n", pnam);
+ (void) fprintf(stderr, "\t Look up _PC_SATTR_EXISTS "
+ "for path with pathconf(2)\n");
+ exit(EINVAL);
+}
+
+static void
+print_extd_entries(zut_readdir_t *r)
+{
+ struct edirent *eodp;
+ char *bufstart;
+
+ eodp = (edirent_t *)(uintptr_t)r->zr_buf;
+ bufstart = (char *)eodp;
+ while ((char *)eodp < bufstart + r->zr_bytes) {
+ char *blanks = " ";
+ int i = 0;
+ while (i < EDIRENT_NAMELEN(eodp->ed_reclen)) {
+ if (!eodp->ed_name[i])
+ break;
+ (void) printf("%c", eodp->ed_name[i++]);
+ }
+ if (i < 16)
+ (void) printf("%.*s", 16 - i, blanks);
+ (void) printf("\t%x\n", eodp->ed_eflags);
+ eodp = (edirent_t *)((intptr_t)eodp + eodp->ed_reclen);
+ }
+}
+
+static void
+print_entries(zut_readdir_t *r)
+{
+ dirent64_t *dp;
+ char *bufstart;
+
+ dp = (dirent64_t *)(intptr_t)r->zr_buf;
+ bufstart = (char *)dp;
+ while ((char *)dp < bufstart + r->zr_bytes) {
+ int i = 0;
+ while (i < DIRENT_NAMELEN(dp->d_reclen)) {
+ if (!dp->d_name[i])
+ break;
+ (void) printf("%c", dp->d_name[i++]);
+ }
+ (void) printf("\n");
+ dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen);
+ }
+}
+
+static void
+print_stats(struct stat64 *sb)
+{
+ char timebuf[512];
+
+ (void) printf("st_mode\t\t\t%04lo\n", (unsigned long)sb->st_mode);
+ (void) printf("st_ino\t\t\t%llu\n", (unsigned long long)sb->st_ino);
+ (void) printf("st_nlink\t\t%lu\n", (unsigned long)sb->st_nlink);
+ (void) printf("st_uid\t\t\t%d\n", sb->st_uid);
+ (void) printf("st_gid\t\t\t%d\n", sb->st_gid);
+ (void) printf("st_size\t\t\t%lld\n", (long long)sb->st_size);
+ (void) printf("st_blksize\t\t%ld\n", (long)sb->st_blksize);
+ (void) printf("st_blocks\t\t%lld\n", (long long)sb->st_blocks);
+
+ timebuf[0] = 0;
+ if (ctime_r(&sb->st_atime, timebuf, 512)) {
+ (void) printf("st_atime\t\t");
+ (void) printf("%s", timebuf);
+ }
+ timebuf[0] = 0;
+ if (ctime_r(&sb->st_mtime, timebuf, 512)) {
+ (void) printf("st_mtime\t\t");
+ (void) printf("%s", timebuf);
+ }
+ timebuf[0] = 0;
+ if (ctime_r(&sb->st_ctime, timebuf, 512)) {
+ (void) printf("st_ctime\t\t");
+ (void) printf("%s", timebuf);
+ }
+}
+
+static void
+print_xvs(uint64_t xvs)
+{
+ uint_t bits;
+ int idx = 0;
+
+ if (xvs == 0)
+ return;
+
+ (void) printf("-------------------\n");
+ (void) printf("Attribute bit(s) set:\n");
+ (void) printf("-------------------\n");
+
+ bits = xvs & ((1 << F_ATTR_ALL) - 1);
+ while (bits) {
+ uint_t rest = bits >> 1;
+ if (bits & 1) {
+ (void) printf("%s", attr_to_name((f_attr_t)idx));
+ if (rest)
+ (void) printf(", ");
+ }
+ idx++;
+ bits = rest;
+ }
+ (void) printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ zut_lookup_t lk = {0};
+ zut_readdir_t rd = {0};
+ boolean_t checking = B_FALSE;
+ boolean_t looking = B_FALSE;
+ boolean_t reading = B_FALSE;
+ boolean_t bflag = B_FALSE;
+ long rddir_bufsize = BIGBUF;
+ int error = 0;
+ int check;
+ int fd;
+ int c;
+
+ while ((c = getopt(argc, argv, "lisaerb:ASE")) != -1) {
+ switch (c) {
+ case 'l':
+ looking = B_TRUE;
+ break;
+ case 'i':
+ lk.zl_reqflags |= ZUT_IGNORECASE;
+ looking = B_TRUE;
+ break;
+ case 's':
+ lk.zl_reqflags |= ZUT_GETSTAT;
+ looking = B_TRUE;
+ break;
+ case 'a':
+ rd.zr_reqflags |= ZUT_ACCFILTER;
+ reading = B_TRUE;
+ break;
+ case 'e':
+ rd.zr_reqflags |= ZUT_EXTRDDIR;
+ reading = B_TRUE;
+ break;
+ case 'r':
+ reading = B_TRUE;
+ break;
+ case 'b':
+ reading = B_TRUE;
+ bflag = B_TRUE;
+ rddir_bufsize = strtol(optarg, NULL, 0);
+ break;
+ case 'A':
+ checking = B_TRUE;
+ check = _PC_ACCESS_FILTERING;
+ break;
+ case 'S':
+ checking = B_TRUE;
+ check = _PC_SATTR_ENABLED;
+ break;
+ case 'E':
+ checking = B_TRUE;
+ check = _PC_SATTR_EXISTS;
+ break;
+ case '?':
+ default:
+ usage(argv[0]); /* no return */
+ }
+ }
+
+ if ((checking && looking) || (checking && reading) ||
+ (looking && reading) || (!reading && bflag) ||
+ (!checking && !reading && !looking))
+ usage(argv[0]); /* no return */
+
+ if (rddir_bufsize < LILBUF || rddir_bufsize > MAXBUF) {
+ (void) fprintf(stderr, "Sorry, buffer size "
+ "must be >= %d and less than or equal to %d bytes.\n",
+ (int)LILBUF, MAXBUF);
+ exit(EINVAL);
+ }
+
+ if (checking) {
+ char pathbuf[MAXPATHLEN];
+ long result;
+
+ if (argc - optind < 1)
+ usage(argv[0]); /* no return */
+ (void) strlcpy(pathbuf, argv[optind], MAXPATHLEN);
+ result = pathconf(pathbuf, check);
+ (void) printf("pathconf(2) check for %s\n", pathbuf);
+ switch (check) {
+ case _PC_SATTR_ENABLED:
+ (void) printf("System attributes ");
+ if (result != 0)
+ (void) printf("Enabled\n");
+ else
+ (void) printf("Not enabled\n");
+ break;
+ case _PC_SATTR_EXISTS:
+ (void) printf("System attributes ");
+ if (result != 0)
+ (void) printf("Exist\n");
+ else
+ (void) printf("Do not exist\n");
+ break;
+ case _PC_ACCESS_FILTERING:
+ (void) printf("Access filtering ");
+ if (result != 0)
+ (void) printf("Available\n");
+ else
+ (void) printf("Not available\n");
+ break;
+ }
+ return (result);
+ }
+
+ if ((fd = open(ZUT_DEV, O_RDONLY)) < 0) {
+ perror(ZUT_DEV);
+ return (ENXIO);
+ }
+
+ if (reading) {
+ char *buf;
+
+ if (argc - optind < 1)
+ usage(argv[0]); /* no return */
+
+ (void) strlcpy(rd.zr_dir, argv[optind], MAXPATHLEN);
+ if (argc - optind > 1) {
+ (void) strlcpy(rd.zr_file, argv[optind + 1],
+ MAXNAMELEN);
+ rd.zr_reqflags |= ZUT_XATTR;
+ }
+
+ if ((buf = malloc(rddir_bufsize)) == NULL) {
+ error = errno;
+ perror("malloc");
+ (void) close(fd);
+ return (error);
+ }
+
+ rd.zr_buf = (uint64_t)(uintptr_t)buf;
+ rd.zr_buflen = rddir_bufsize;
+
+ while (!rd.zr_eof) {
+ int ierr;
+
+ if ((ierr = ioctl(fd, ZUT_IOC_READDIR, &rd)) != 0) {
+ (void) fprintf(stderr,
+ "IOCTL error: %s (%d)\n",
+ strerror(ierr), ierr);
+ free(buf);
+ (void) close(fd);
+ return (ierr);
+ }
+ if (rd.zr_retcode) {
+ (void) fprintf(stderr,
+ "readdir result: %s (%d)\n",
+ strerror(rd.zr_retcode), rd.zr_retcode);
+ free(buf);
+ (void) close(fd);
+ return (rd.zr_retcode);
+ }
+ if (rd.zr_reqflags & ZUT_EXTRDDIR)
+ print_extd_entries(&rd);
+ else
+ print_entries(&rd);
+ }
+ free(buf);
+ } else {
+ int ierr;
+
+ if (argc - optind < 2)
+ usage(argv[0]); /* no return */
+
+ (void) strlcpy(lk.zl_dir, argv[optind], MAXPATHLEN);
+ (void) strlcpy(lk.zl_file, argv[optind + 1], MAXNAMELEN);
+ if (argc - optind > 2) {
+ (void) strlcpy(lk.zl_xfile,
+ argv[optind + 2], MAXNAMELEN);
+ lk.zl_reqflags |= ZUT_XATTR;
+ }
+
+ if ((ierr = ioctl(fd, ZUT_IOC_LOOKUP, &lk)) != 0) {
+ (void) fprintf(stderr,
+ "IOCTL error: %s (%d)\n",
+ strerror(ierr), ierr);
+ (void) close(fd);
+ return (ierr);
+ }
+
+ (void) printf("\nLookup of ");
+ if (lk.zl_reqflags & ZUT_XATTR) {
+ (void) printf("extended attribute \"%s\" of ",
+ lk.zl_xfile);
+ }
+ (void) printf("file \"%s\" ", lk.zl_file);
+ (void) printf("in directory \"%s\" ", lk.zl_dir);
+ if (lk.zl_retcode) {
+ (void) printf("failed: %s (%d)\n",
+ strerror(lk.zl_retcode), lk.zl_retcode);
+ (void) close(fd);
+ return (lk.zl_retcode);
+ }
+
+ (void) printf("succeeded.\n");
+ if (lk.zl_reqflags & ZUT_IGNORECASE) {
+ (void) printf("----------------------------\n");
+ (void) printf("dirent flags: 0x%0x\n", lk.zl_deflags);
+ (void) printf("real name: %s\n", lk.zl_real);
+ }
+ if (lk.zl_reqflags & ZUT_GETSTAT) {
+ (void) printf("----------------------------\n");
+ print_stats(&lk.zl_statbuf);
+ print_xvs(lk.zl_xvattrs);
+ }
+ }
+
+ (void) close(fd);
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
new file mode 100644
index 0000000..c1ac479
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7
@@ -0,0 +1,250 @@
+'\" te
+.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" Copyright (c) 2012 by Delphix. All rights reserved.
+.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 8, 2013
+.Dt ZPOOL-FEATURES 7
+.Os
+.Sh NAME
+.Nm zpool-features
+.Nd ZFS pool feature descriptions
+.Sh DESCRIPTION
+ZFS pool on\-disk format versions are specified via "features" which replace
+the old on\-disk format numbers (the last supported on\-disk format number is
+28).
+To enable a feature on a pool use the
+.Cm upgrade
+subcommand of the
+.Xr zpool 8
+command, or set the
+.Sy feature@feature_name
+property to
+.Ar enabled .
+.Pp
+The pool format does not affect file system version compatibility or the ability
+to send file systems between pools.
+.Pp
+Since most features can be enabled independently of each other the on\-disk
+format of the pool is specified by the set of all features marked as
+.Sy active
+on the pool. If the pool was created by another software version this set may
+include unsupported features.
+.Ss Identifying features
+Every feature has a guid of the form
+.Sy com.example:feature_name .
+The reverse DNS name ensures that the feature's guid is unique across all ZFS
+implementations. When unsupported features are encountered on a pool they will
+be identified by their guids.
+Refer to the documentation for the ZFS implementation that created the pool
+for information about those features.
+.Pp
+Each supported feature also has a short name.
+By convention a feature's short name is the portion of its guid which follows
+the ':' (e.g.
+.Sy com.example:feature_name
+would have the short name
+.Sy feature_name ),
+however a feature's short name may differ across ZFS implementations if
+following the convention would result in name conflicts.
+.Ss Feature states
+Features can be in one of three states:
+.Bl -tag -width "XXXXXXXX"
+.It Sy active
+This feature's on\-disk format changes are in effect on the pool.
+Support for this feature is required to import the pool in read\-write mode.
+If this feature is not read-only compatible, support is also required to
+import the pool in read\-only mode (see "Read\-only compatibility").
+.It Sy enabled
+An administrator has marked this feature as enabled on the pool, but the
+feature's on\-disk format changes have not been made yet.
+The pool can still be imported by software that does not support this feature,
+but changes may be made to the on\-disk format at any time which will move
+the feature to the
+.Sy active
+state.
+Some features may support returning to the
+.Sy enabled
+state after becoming
+.Sy active .
+See feature\-specific documentation for details.
+.It Sy disabled
+This feature's on\-disk format changes have not been made and will not be made
+unless an administrator moves the feature to the
+.Sy enabled
+state.
+Features cannot be disabled once they have been enabled.
+.El
+.Pp
+The state of supported features is exposed through pool properties of the form
+.Sy feature@short_name .
+.Ss Read\-only compatibility
+Some features may make on\-disk format changes that do not interfere with other
+software's ability to read from the pool.
+These features are referred to as "read\-only compatible".
+If all unsupported features on a pool are read\-only compatible, the pool can
+be imported in read\-only mode by setting the
+.Sy readonly
+property during import (see
+.Xr zpool 8
+for details on importing pools).
+.Ss Unsupported features
+For each unsupported feature enabled on an imported pool a pool property
+named
+.Sy unsupported@feature_guid
+will indicate why the import was allowed despite the unsupported feature.
+Possible values for this property are:
+.Bl -tag -width "XXXXXXXX"
+.It Sy inactive
+The feature is in the
+.Sy enabled
+state and therefore the pool's on\-disk format is still compatible with
+software that does not support this feature.
+.It Sy readonly
+The feature is read\-only compatible and the pool has been imported in
+read\-only mode.
+.El
+.Ss Feature dependencies
+Some features depend on other features being enabled in order to function
+properly.
+Enabling a feature will automatically enable any features it depends on.
+.Sh FEATURES
+The following features are supported on this system:
+.Bl -tag -width "XXXXXXXX"
+.It Sy async_destroy
+.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:async_destroy"
+.It GUID Ta com.delphix:async_destroy
+.It READ\-ONLY COMPATIBLE Ta yes
+.It DEPENDENCIES Ta none
+.El
+.Pp
+Destroying a file system requires traversing all of its data in order to
+return its used space to the pool.
+Without
+.Sy async_destroy
+the file system is not fully removed until all space has been reclaimed.
+If the destroy operation is interrupted by a reboot or power outage the next
+attempt to open the pool will need to complete the destroy operation
+synchronously.
+.Pp
+When
+.Sy async_destroy
+is enabled the file system's data will be reclaimed by a background process,
+allowing the destroy operation to complete without traversing the entire file
+system.
+The background process is able to resume interrupted destroys after the pool
+has been opened, eliminating the need to finish interrupted destroys as part
+of the open operation.
+The amount of space remaining to be reclaimed by the background process is
+available through the
+.Sy freeing
+property.
+.Pp
+This feature is only
+.Sy active
+while
+.Sy freeing
+is non\-zero.
+.It Sy empty_bpobj
+.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:empty_bpobj"
+.It GUID Ta com.delphix:empty_bpobj
+.It READ\-ONLY COMPATIBLE Ta yes
+.It DEPENDENCIES Ta none
+.El
+.Pp
+This feature increases the performance of creating and using a large number
+of snapshots of a single filesystem or volume, and also reduces the disk
+space required.
+.Pp
+When there are many snapshots, each snapshot uses many Block Pointer Objects
+.Pq bpobj's
+to track blocks associated with that snapshot.
+However, in common use cases, most of these bpobj's are empty.
+This feature allows us to create each bpobj on-demand, thus eliminating the
+empty bpobjs.
+.Pp
+This feature is
+.Sy active
+while there are any filesystems, volumes, or snapshots which were created
+after enabling this feature.
+.It Sy lz4_compress
+.Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress"
+.It GUID Ta org.illumos:lz4_compress
+.It READ\-ONLY COMPATIBLE Ta no
+.It DEPENDENCIES Ta none
+.El
+.Pp
+.Sy lz4
+is a high-performance real-time compression algorithm that
+features significantly faster compression and decompression as well as a
+higher compression ratio than the older
+.Sy lzjb
+compression.
+Typically,
+.Sy lz4
+compression is approximately 50% faster on
+compressible data and 200% faster on incompressible data than
+.Sy lzjb .
+It is also approximately 80% faster on decompression, while
+giving approximately 10% better compression ratio.
+.Pp
+When the
+.Sy lz4_compress
+feature is set to
+.Sy enabled ,
+the
+administrator can turn on
+.Sy lz4
+compression on any dataset on the
+pool using the
+.Xr zfs 8
+command. Please note that doing so will
+immediately activate the
+.Sy lz4_compress
+feature on the underlying
+pool (even before any data is written). Since this feature is not
+read-only compatible, this operation will render the pool unimportable
+on systems without support for the
+.Sy lz4_compress
+feature. At the
+moment, this operation cannot be reversed. Booting off of
+.Sy lz4
+-compressed root pools is supported.
+.El
+.Sh SEE ALSO
+.Xr zpool 8
+.Sh AUTHORS
+This manual page is a
+.Xr mdoc 7
+reimplementation of the
+.Tn illumos
+manual page
+.Em zpool-features(5) ,
+modified and customized for
+.Fx
+and licensed under the Common Development and Distribution License
+.Pq Tn CDDL .
+.Pp
+The
+.Xr mdoc 7
+implementation of this manual page was initially written by
+.An Martin Matuska Aq mm@FreeBSD.org .
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
new file mode 100644
index 0000000..715439b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
@@ -0,0 +1,1948 @@
+'\" te
+.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2011, Nexenta Systems, Inc. All Rights Reserved.
+.\" Copyright (c) 2011, Justin T. Gibbs <gibbs@FreeBSD.org>
+.\" Copyright (c) 2012 by Delphix. All Rights Reserved.
+.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 14, 2013
+.Dt ZPOOL 8
+.Os
+.Sh NAME
+.Nm zpool
+.Nd configures ZFS storage pools
+.Sh SYNOPSIS
+.Nm
+.Op Fl \&?
+.Nm
+.Cm add
+.Op Fl fn
+.Ar pool vdev ...
+.Nm
+.Cm attach
+.Op Fl f
+.Ar pool device new_device
+.Nm
+.Cm clear
+.Op Fl F Op Fl n
+.Ar pool
+.Op Ar device
+.Nm
+.Cm create
+.Op Fl fnd
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl O Ar file-system-property Ns = Ns Ar value
+.Ar ...
+.Op Fl m Ar mountpoint
+.Op Fl R Ar root
+.Ar pool vdev ...
+.Nm
+.Cm destroy
+.Op Fl f
+.Ar pool
+.Nm
+.Cm detach
+.Ar pool device
+.Nm
+.Cm export
+.Op Fl f
+.Ar pool ...
+.Nm
+.Cm get
+.Ar all | property Ns Op , Ns Ar ...
+.Ar pool ...
+.Nm
+.Cm history
+.Op Fl il
+.Op Ar pool
+.Ar ...
+.Nm
+.Cm import
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Nm
+.Cm import
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Op Fl f
+.Op Fl m
+.Op Fl N
+.Op Fl R Ar root
+.Op Fl F Op Fl n
+.Fl a
+.Nm
+.Cm import
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Op Fl f
+.Op Fl m
+.Op Fl N
+.Op Fl R Ar root
+.Op Fl F Op Fl n
+.Ar pool | id
+.Op Ar newpool
+.Nm
+.Cm iostat
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Fl v
+.Op Ar pool
+.Ar ...
+.Nm
+.Cm labelclear
+.Op Fl f
+.Ar device
+.Nm
+.Cm list
+.Op Fl H
+.Op Fl o Ar property Ns Op , Ns Ar ...
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Ar pool
+.Ar ...
+.Op Ar inverval Op Ar count
+.Nm
+.Cm offline
+.Op Fl t
+.Ar pool device ...
+.Nm
+.Cm online
+.Op Fl e
+.Ar pool device ...
+.Nm
+.Cm reguid
+.Ar pool
+.Nm
+.Cm remove
+.Ar pool device ...
+.Nm
+.Cm replace
+.Op Fl f
+.Ar pool device
+.Op Ar new_device
+.Nm
+.Cm scrub
+.Op Fl s
+.Ar pool ...
+.Nm
+.Cm set
+.Ar property Ns = Ns Ar value pool
+.Nm
+.Cm split
+.Op Fl n
+.Op Fl R Ar altroot
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar pool newpool
+.Op Ar device ...
+.Nm
+.Cm status
+.Op Fl vx
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Ar pool
+.Ar ...
+.Op Ar interval Op Ar count
+.Nm
+.Cm upgrade
+.Op Fl v
+.Nm
+.Cm upgrade
+.Op Fl V Ar version
+.Fl a | Ar pool ...
+.Sh DESCRIPTION
+The
+.Nm
+command configures
+.Tn ZFS
+storage pools. A storage pool is a collection of devices that provides physical
+storage and data replication for
+.Tn ZFS
+datasets.
+.Pp
+All datasets within a storage pool share the same space. See
+.Xr zfs 8
+for information on managing datasets.
+.Ss Virtual Devices (vdevs)
+A
+.Qq virtual device
+.Pq No vdev
+describes a single device or a collection of devices organized according to
+certain performance and fault characteristics. The following virtual devices
+are supported:
+.Bl -tag -width "XXXXXX"
+.It Sy disk
+A block device, typically located under
+.Pa /dev .
+.Tn ZFS
+can use individual slices or partitions, though the recommended mode of
+operation is to use whole disks. A disk can be specified by a full path to the
+device or the
+.Xr geom 4
+provider name. When given a whole disk,
+.Tn ZFS
+automatically labels the disk, if necessary.
+.It Sy file
+A regular file. The use of files as a backing store is strongly discouraged. It
+is designed primarily for experimental purposes, as the fault tolerance of a
+file is only as good the file system of which it is a part. A file must be
+specified by a full path.
+.It Sy mirror
+A mirror of two or more devices. Data is replicated in an identical fashion
+across all components of a mirror. A mirror with
+.Em N
+disks of size
+.Em X
+can hold
+.Em X
+bytes and can withstand
+.Pq Em N-1
+devices failing before data integrity is compromised.
+.It Sy raidz
+(or
+.Sy raidz1 raidz2 raidz3 ) .
+A variation on
+.Sy RAID-5
+that allows for better distribution of parity and eliminates the
+.Qq Sy RAID-5
+write hole (in which data and parity become inconsistent after a power loss).
+Data and parity is striped across all disks within a
+.No raidz
+group.
+.Pp
+A
+.No raidz
+group can have single-, double- , or triple parity, meaning that the
+.No raidz
+group can sustain one, two, or three failures, respectively, without
+losing any data. The
+.Sy raidz1 No vdev
+type specifies a single-parity
+.No raidz
+group; the
+.Sy raidz2 No vdev
+type specifies a double-parity
+.No raidz
+group; and the
+.Sy raidz3 No vdev
+type specifies a triple-parity
+.No raidz
+group. The
+.Sy raidz No vdev
+type is an alias for
+.Sy raidz1 .
+.Pp
+A
+.No raidz
+group with
+.Em N
+disks of size
+.Em X
+with
+.Em P
+parity disks can hold approximately
+.Sm off
+.Pq Em N-P
+*X
+.Sm on
+bytes and can withstand
+.Em P
+device(s) failing before data integrity is compromised. The minimum number of
+devices in a
+.No raidz
+group is one more than the number of parity disks. The
+recommended number is between 3 and 9 to help increase performance.
+.It Sy spare
+A special
+.No pseudo- Ns No vdev
+which keeps track of available hot spares for a pool.
+For more information, see the
+.Qq Sx Hot Spares
+section.
+.It Sy log
+A separate-intent log device. If more than one log device is specified, then
+writes are load-balanced between devices. Log devices can be mirrored. However,
+.No raidz
+.No vdev
+types are not supported for the intent log. For more information,
+see the
+.Qq Sx Intent Log
+section.
+.It Sy cache
+A device used to cache storage pool data. A cache device cannot be configured
+as a mirror or
+.No raidz
+group. For more information, see the
+.Qq Sx Cache Devices
+section.
+.El
+.Pp
+Virtual devices cannot be nested, so a mirror or
+.No raidz
+virtual device can only
+contain files or disks. Mirrors of mirrors (or other combinations) are not
+allowed.
+.Pp
+A pool can have any number of virtual devices at the top of the configuration
+(known as
+.Qq root
+.No vdev Ns s).
+Data is dynamically distributed across all top-level devices to balance data
+among devices. As new virtual devices are added,
+.Tn ZFS
+automatically places data on the newly available devices.
+.Pp
+Virtual devices are specified one at a time on the command line, separated by
+whitespace. The keywords
+.Qq mirror
+and
+.Qq raidz
+are used to distinguish where a group ends and another begins. For example, the
+following creates two root
+.No vdev Ns s,
+each a mirror of two disks:
+.Bd -literal -offset 2n
+.Li # Ic zpool create mypool mirror da0 da1 mirror da2 da3
+.Ed
+.Ss Device Failure and Recovery
+.Tn ZFS
+supports a rich set of mechanisms for handling device failure and data
+corruption. All metadata and data is checksummed, and
+.Tn ZFS
+automatically repairs bad data from a good copy when corruption is detected.
+.Pp
+In order to take advantage of these features, a pool must make use of some form
+of redundancy, using either mirrored or
+.No raidz
+groups. While
+.Tn ZFS
+supports running in a non-redundant configuration, where each root
+.No vdev
+is simply a disk or file, this is strongly discouraged. A single case of bit
+corruption can render some or all of your data unavailable.
+.Pp
+A pool's health status is described by one of three states: online, degraded,
+or faulted. An online pool has all devices operating normally. A degraded pool
+is one in which one or more devices have failed, but the data is still
+available due to a redundant configuration. A faulted pool has corrupted
+metadata, or one or more faulted devices, and insufficient replicas to continue
+functioning.
+.Pp
+The health of the top-level
+.No vdev ,
+such as mirror or
+.No raidz
+device, is
+potentially impacted by the state of its associated
+.No vdev Ns s,
+or component devices. A top-level
+.No vdev
+or component device is in one of the following states:
+.Bl -tag -width "DEGRADED"
+.It Sy DEGRADED
+One or more top-level
+.No vdev Ns s
+is in the degraded state because one or more
+component devices are offline. Sufficient replicas exist to continue
+functioning.
+.Pp
+One or more component devices is in the degraded or faulted state, but
+sufficient replicas exist to continue functioning. The underlying conditions
+are as follows:
+.Bl -bullet -offset 2n
+.It
+The number of checksum errors exceeds acceptable levels and the device is
+degraded as an indication that something may be wrong.
+.Tn ZFS
+continues to use the device as necessary.
+.It
+The number of
+.Tn I/O
+errors exceeds acceptable levels. The device could not be
+marked as faulted because there are insufficient replicas to continue
+functioning.
+.El
+.It Sy FAULTED
+One or more top-level
+.No vdev Ns s
+is in the faulted state because one or more
+component devices are offline. Insufficient replicas exist to continue
+functioning.
+.Pp
+One or more component devices is in the faulted state, and insufficient
+replicas exist to continue functioning. The underlying conditions are as
+follows:
+.Bl -bullet -offset 2n
+.It
+The device could be opened, but the contents did not match expected values.
+.It
+The number of
+.Tn I/O
+errors exceeds acceptable levels and the device is faulted to
+prevent further use of the device.
+.El
+.It Sy OFFLINE
+The device was explicitly taken offline by the
+.Qq Nm Cm offline
+command.
+.It Sy ONLINE
+The device is online and functioning.
+.It Sy REMOVED
+The device was physically removed while the system was running. Device removal
+detection is hardware-dependent and may not be supported on all platforms.
+.It Sy UNAVAIL
+The device could not be opened. If a pool is imported when a device was
+unavailable, then the device will be identified by a unique identifier instead
+of its path since the path was never correct in the first place.
+.El
+.Pp
+If a device is removed and later reattached to the system,
+.Tn ZFS
+attempts to put the device online automatically. Device attach detection is
+hardware-dependent and might not be supported on all platforms.
+.Ss Hot Spares
+.Tn ZFS
+allows devices to be associated with pools as
+.Qq hot spares .
+These devices are not actively used in the pool, but when an active device
+fails, it is automatically replaced by a hot spare. To create a pool with hot
+spares, specify a
+.Qq spare
+.No vdev
+with any number of devices. For example,
+.Bd -literal -offset 2n
+.Li # Ic zpool create pool mirror da0 da1 spare da2 da3
+.Ed
+.Pp
+Spares can be shared across multiple pools, and can be added with the
+.Qq Nm Cm add
+command and removed with the
+.Qq Nm Cm remove
+command. Once a spare replacement is initiated, a new "spare"
+.No vdev
+is created
+within the configuration that will remain there until the original device is
+replaced. At this point, the hot spare becomes available again if another
+device fails.
+.Pp
+If a pool has a shared spare that is currently being used, the pool can not be
+exported since other pools may use this shared spare, which may lead to
+potential data corruption.
+.Pp
+An in-progress spare replacement can be cancelled by detaching the hot spare.
+If the original faulted device is detached, then the hot spare assumes its
+place in the configuration, and is removed from the spare list of all active
+pools.
+.Pp
+Spares cannot replace log devices.
+.Ss Intent Log
+The
+.Tn ZFS
+Intent Log
+.Pq Tn ZIL
+satisfies
+.Tn POSIX
+requirements for synchronous transactions. For instance, databases often
+require their transactions to be on stable storage devices when returning from
+a system call.
+.Tn NFS
+and other applications can also use
+.Xr fsync 2
+to ensure data stability. By default, the intent log is allocated from blocks
+within the main pool. However, it might be possible to get better performance
+using separate intent log devices such as
+.Tn NVRAM
+or a dedicated disk. For example:
+.Bd -literal -offset 2n
+.Li # Ic zpool create pool da0 da1 log da2
+.Ed
+.Pp
+Multiple log devices can also be specified, and they can be mirrored. See the
+.Sx EXAMPLES
+section for an example of mirroring multiple log devices.
+.Pp
+Log devices can be added, replaced, attached, detached, imported and exported
+as part of the larger pool. Mirrored log devices can be removed by specifying
+the top-level mirror for the log.
+.Ss Cache devices
+Devices can be added to a storage pool as "cache devices." These devices
+provide an additional layer of caching between main memory and disk. For
+read-heavy workloads, where the working set size is much larger than what can
+be cached in main memory, using cache devices allow much more of this working
+set to be served from low latency media. Using cache devices provides the
+greatest performance improvement for random read-workloads of mostly static
+content.
+.Pp
+To create a pool with cache devices, specify a "cache"
+.No vdev
+with any number of devices. For example:
+.Bd -literal -offset 2n
+.Li # Ic zpool create pool da0 da1 cache da2 da3
+.Ed
+.Pp
+Cache devices cannot be mirrored or part of a
+.No raidz
+configuration. If a read
+error is encountered on a cache device, that read
+.Tn I/O
+is reissued to the original storage pool device, which might be part of a
+mirrored or
+.No raidz
+configuration.
+.Pp
+The content of the cache devices is considered volatile, as is the case with
+other system caches.
+.Ss Properties
+Each pool has several properties associated with it. Some properties are
+read-only statistics while others are configurable and change the behavior of
+the pool. The following are read-only properties:
+.Bl -tag -width "dedupratio"
+.It Sy alloc
+Amount of storage space within the pool that has been physically allocated.
+.It Sy capacity
+Percentage of pool space used. This property can also be referred to by its
+shortened column name, "cap".
+.It Sy comment
+A text string consisting of printable ASCII characters that will be stored
+such that it is available even if the pool becomes faulted. An administrator
+can provide additional information about a pool using this property.
+.It Sy dedupratio
+The deduplication ratio specified for a pool, expressed as a multiplier.
+For example, a
+.Sy dedupratio
+value of 1.76 indicates that 1.76 units of data were stored but only 1 unit of disk space was actually consumed. See
+.Xr zfs 8
+for a description of the deduplication feature.
+.It Sy free
+Number of blocks within the pool that are not allocated.
+.It Sy freeing
+After a file system or snapshot is destroyed, the space it was using is
+returned to the pool asynchronously.
+.Sy freeing
+is the amount of space remaining to be reclaimed.
+Over time
+.Sy freeing
+will decrease while
+.Sy free
+increases.
+.It Sy expandsize
+This property has currently no value on FreeBSD.
+.It Sy guid
+A unique identifier for the pool.
+.It Sy health
+The current health of the pool. Health can be
+.Qq Sy ONLINE ,
+.Qq Sy DEGRADED ,
+.Qq Sy FAULTED ,
+.Qq Sy OFFLINE ,
+.Qq Sy REMOVED ,
+or
+.Qq Sy UNAVAIL .
+.It Sy size
+Total size of the storage pool.
+.It Sy unsupported@ Ns Ar feature_guid
+Information about unsupported features that are enabled on the pool.
+See
+.Xr zpool-features 7
+for details.
+.It Sy used
+Amount of storage space used within the pool.
+.El
+.Pp
+The space usage properties report actual physical space available to the
+storage pool. The physical space can be different from the total amount of
+space that any contained datasets can actually use. The amount of space used in
+a
+.No raidz
+configuration depends on the characteristics of the data being written.
+In addition,
+.Tn ZFS
+reserves some space for internal accounting that the
+.Xr zfs 8
+command takes into account, but the
+.Xr zpool 8
+command does not. For non-full pools of a reasonable size, these effects should
+be invisible. For small pools, or pools that are close to being completely
+full, these discrepancies may become more noticeable.
+.Pp
+The following property can be set at creation time and import time:
+.Bl -tag -width 2n
+.It Sy altroot
+Alternate root directory. If set, this directory is prepended to any mount
+points within the pool. This can be used when examining an unknown pool where
+the mount points cannot be trusted, or in an alternate boot environment, where
+the typical paths are not valid.
+.Sy altroot
+is not a persistent property. It is valid only while the system is up.
+Setting
+.Sy altroot
+defaults to using
+.Cm cachefile=none ,
+though this may be overridden using an explicit setting.
+.El
+.Pp
+The following property can only be set at import time:
+.Bl -tag -width 2n
+.It Sy readonly Ns = Ns Cm on No | Cm off
+If set to
+.Cm on ,
+pool will be imported in read-only mode with the following restrictions:
+.Bl -bullet -offset 2n
+.It
+Synchronous data in the intent log will not be accessible
+.It
+Properties of the pool can not be changed
+.It
+Datasets of this pool can only be mounted read-only
+.It
+To write to a read-only pool, a export and import of the pool is required.
+.El
+.El
+.Pp
+The following properties can be set at creation time and import time, and later
+changed with the
+.Ic zpool set
+command:
+.Bl -tag -width 2n
+.It Sy autoexpand Ns = Ns Cm on No | Cm off
+Controls automatic pool expansion when the underlying LUN is grown. If set to
+.Qq Cm on ,
+the pool will be resized according to the size of the expanded
+device. If the device is part of a mirror or
+.No raidz
+then all devices within that
+.No mirror/ Ns No raidz
+group must be expanded before the new space is made available to
+the pool. The default behavior is
+.Qq off .
+This property can also be referred to by its shortened column name,
+.Sy expand .
+.It Sy autoreplace Ns = Ns Cm on No | Cm off
+Controls automatic device replacement. If set to
+.Qq Cm off ,
+device replacement must be initiated by the administrator by using the
+.Qq Nm Cm replace
+command. If set to
+.Qq Cm on ,
+any new device, found in the same
+physical location as a device that previously belonged to the pool, is
+automatically formatted and replaced. The default behavior is
+.Qq Cm off .
+This property can also be referred to by its shortened column name, "replace".
+.It Sy bootfs Ns = Ns Ar pool Ns / Ns Ar dataset
+Identifies the default bootable dataset for the root pool. This property is
+expected to be set mainly by the installation and upgrade programs.
+.It Sy cachefile Ns = Ns Ar path No | Cm none
+Controls the location of where the pool configuration is cached. Discovering
+all pools on system startup requires a cached copy of the configuration data
+that is stored on the root file system. All pools in this cache are
+automatically imported when the system boots. Some environments, such as
+install and clustering, need to cache this information in a different location
+so that pools are not automatically imported. Setting this property caches the
+pool configuration in a different location that can later be imported with
+.Qq Nm Cm import Fl c .
+Setting it to the special value
+.Qq Cm none
+creates a temporary pool that is never cached, and the special value
+.Cm ''
+(empty string) uses the default location.
+.It Sy comment Ns = Ns Ar text
+A text string consisting of printable ASCII characters that will be stored
+such that it is available even if the pool becomes faulted.
+An administrator can provide additional information about a pool using this
+property.
+.It Sy dedupditto Ns = Ns Ar number
+Threshold for the number of block ditto copies. If the reference count for a
+deduplicated block increases above this number, a new ditto copy of this block
+is automatically stored. Default setting is
+.Cm 0 .
+.It Sy delegation Ns = Ns Cm on No | Cm off
+Controls whether a non-privileged user is granted access based on the dataset
+permissions defined on the dataset. See
+.Xr zfs 8
+for more information on
+.Tn ZFS
+delegated administration.
+.It Sy failmode Ns = Ns Cm wait No | Cm continue No | Cm panic
+Controls the system behavior in the event of catastrophic pool failure. This
+condition is typically a result of a loss of connectivity to the underlying
+storage device(s) or a failure of all devices within the pool. The behavior of
+such an event is determined as follows:
+.Bl -tag -width indent
+.It Sy wait
+Blocks all
+.Tn I/O
+access until the device connectivity is recovered and the errors are cleared.
+This is the default behavior.
+.It Sy continue
+Returns
+.Em EIO
+to any new write
+.Tn I/O
+requests but allows reads to any of the remaining healthy devices. Any write
+requests that have yet to be committed to disk would be blocked.
+.It Sy panic
+Prints out a message to the console and generates a system crash dump.
+.El
+.It Sy feature@ Ns Ar feature_name Ns = Ns Sy enabled
+The value of this property is the current state of
+.Ar feature_name .
+The only valid value when setting this property is
+.Sy enabled
+which moves
+.Ar feature_name
+to the enabled state.
+See
+.Xr zpool-features 7
+for details on feature states.
+.It Sy listsnaps Ns = Ns Cm on No | Cm off
+Controls whether information about snapshots associated with this pool is
+output when
+.Qq Nm zfs Cm list
+is run without the
+.Fl t
+option. The default value is
+.Cm off .
+.It Sy version Ns = Ns Ar version
+The current on-disk version of the pool. This can be increased, but never
+decreased. The preferred method of updating pools is with the
+.Qq Nm Cm upgrade
+command, though this property can be used when a specific version is needed
+for backwards compatibility.
+Once feature flags is enabled on a pool this property will no longer have a
+value.
+.El
+.Sh SUBCOMMANDS
+All subcommands that modify state are logged persistently to the pool in their
+original form.
+.Pp
+The
+.Nm
+command provides subcommands to create and destroy storage pools, add capacity
+to storage pools, and provide information about the storage pools. The following
+subcommands are supported:
+.Bl -tag -width 2n
+.It Xo
+.Nm
+.Op Fl \&?
+.Xc
+.Pp
+Displays a help message.
+.It Xo
+.Nm
+.Cm add
+.Op Fl fn
+.Ar pool vdev ...
+.Xc
+.Pp
+Adds the specified virtual devices to the given pool. The
+.No vdev
+specification is described in the
+.Qq Sx Virtual Devices
+section. The behavior of the
+.Fl f
+option, and the device checks performed are described in the
+.Qq Nm Cm create
+subcommand.
+.Bl -tag -width indent
+.It Fl f
+Forces use of
+.Ar vdev ,
+even if they appear in use or specify a conflicting replication level.
+Not all devices can be overridden in this manner.
+.It Fl n
+Displays the configuration that would be used without actually adding the
+.Ar vdev Ns s.
+The actual pool creation can still fail due to insufficient privileges or device
+sharing.
+.Pp
+Do not add a disk that is currently configured as a quorum device to a zpool.
+After a disk is in the pool, that disk can then be configured as a quorum
+device.
+.El
+.It Xo
+.Nm
+.Cm attach
+.Op Fl f
+.Ar pool device new_device
+.Xc
+.Pp
+Attaches
+.Ar new_device
+to an existing
+.Sy zpool
+device. The existing device cannot be part of a
+.No raidz
+configuration. If
+.Ar device
+is not currently part of a mirrored configuration,
+.Ar device
+automatically transforms into a two-way mirror of
+.Ar device No and Ar new_device .
+If
+.Ar device
+is part of a two-way mirror, attaching
+.Ar new_device
+creates a three-way mirror, and so on. In either case,
+.Ar new_device
+begins to resilver immediately.
+.Bl -tag -width indent
+.It Fl f
+Forces use of
+.Ar new_device ,
+even if its appears to be in use. Not all devices can be overridden in this
+manner.
+.El
+.It Xo
+.Nm
+.Cm clear
+.Op Fl F Op Fl n
+.Ar pool
+.Op Ar device
+.Xc
+.Pp
+Clears device errors in a pool. If no arguments are specified, all device
+errors within the pool are cleared. If one or more devices is specified, only
+those errors associated with the specified device or devices are cleared.
+.Bl -tag -width indent
+.It Fl F
+Initiates recovery mode for an unopenable pool. Attempts to discard the last
+few transactions in the pool to return it to an openable state. Not all damaged
+pools can be recovered by using this option. If successful, the data from the
+discarded transactions is irretrievably lost.
+.It Fl n
+Used in combination with the
+.Fl F
+flag. Check whether discarding transactions would make the pool openable, but
+do not actually discard any transactions.
+.El
+.It Xo
+.Nm
+.Cm create
+.Op Fl fnd
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl O Ar file-system-property Ns = Ns Ar value
+.Ar ...
+.Op Fl m Ar mountpoint
+.Op Fl R Ar root
+.Ar pool vdev ...
+.Xc
+.Pp
+Creates a new storage pool containing the virtual devices specified on the
+command line. The pool name must begin with a letter, and can only contain
+alphanumeric characters as well as underscore ("_"), dash ("-"), and period
+("."). The pool names "mirror", "raidz", "spare" and "log" are reserved, as are
+names beginning with the pattern "c[0-9]". The
+.No vdev
+specification is described in the
+.Qq Sx Virtual Devices
+section.
+.Pp
+The command verifies that each device specified is accessible and not currently
+in use by another subsystem. There are some uses, such as being currently
+mounted, or specified as the dedicated dump device, that prevents a device from
+ever being used by
+.Tn ZFS
+Other uses, such as having a preexisting
+.Sy UFS
+file system, can be overridden with the
+.Fl f
+option.
+.Pp
+The command also checks that the replication strategy for the pool is
+consistent. An attempt to combine redundant and non-redundant storage in a
+single pool, or to mix disks and files, results in an error unless
+.Fl f
+is specified. The use of differently sized devices within a single
+.No raidz
+or mirror group is also flagged as an error unless
+.Fl f
+is specified.
+.Pp
+Unless the
+.Fl R
+option is specified, the default mount point is
+.Qq Pa /pool .
+The mount point must not exist or must be empty, or else the
+root dataset cannot be mounted. This can be overridden with the
+.Fl m
+option.
+.Pp
+By default all supported features are enabled on the new pool unless the
+.Fl d
+option is specified.
+.Bl -tag -width indent
+.It Fl f
+Forces use of
+.Ar vdev Ns s,
+even if they appear in use or specify a conflicting replication level.
+Not all devices can be overridden in this manner.
+.It Fl n
+Displays the configuration that would be used without actually creating the
+pool. The actual pool creation can still fail due to insufficient privileges or
+device sharing.
+.It Fl d
+Do not enable any features on the new pool.
+Individual features can be enabled by setting their corresponding properties
+to
+.Sy enabled
+with the
+.Fl o
+option.
+See
+.Xr zpool-features 7
+for details about feature properties.
+.It Xo
+.Fl o Ar property Ns = Ns Ar value
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Xc
+Sets the given pool properties. See the
+.Qq Sx Properties
+section for a list of valid properties that can be set.
+.It Xo
+.Fl O
+.Ar file-system-property Ns = Ns Ar value
+.Op Fl O Ar file-system-property Ns = Ns Ar value
+.Ar ...
+.Xc
+Sets the given file system properties in the root file system of the pool. See
+.Xr zfs 8 Properties
+for a list of valid properties that
+can be set.
+.It Fl R Ar root
+Equivalent to
+.Qq Fl o Cm cachefile=none,altroot= Ns Pa root
+.It Fl m Ar mountpoint
+Sets the mount point for the root dataset. The default mount point is
+.Qq Pa /pool
+or
+.Qq Cm altroot Ns Pa /pool
+if
+.Sy altroot
+is specified. The mount point must be an absolute path,
+.Qq Cm legacy ,
+or
+.Qq Cm none .
+For more information on dataset mount points, see
+.Xr zfs 8 .
+.El
+.It Xo
+.Nm
+.Cm destroy
+.Op Fl f
+.Ar pool
+.Xc
+.Pp
+Destroys the given pool, freeing up any devices for other use. This command
+tries to unmount any active datasets before destroying the pool.
+.Bl -tag -width indent
+.It Fl f
+Forces any active datasets contained within the pool to be unmounted.
+.El
+.It Xo
+.Nm
+.Cm detach
+.Ar pool device
+.Xc
+.Pp
+Detaches
+.Ar device
+from a mirror. The operation is refused if there are no other valid replicas
+of the data.
+.It Xo
+.Nm
+.Cm export
+.Op Fl f
+.Ar pool ...
+.Xc
+.Pp
+Exports the given pools from the system. All devices are marked as exported,
+but are still considered in use by other subsystems. The devices can be moved
+between systems (even those of different endianness) and imported as long as a
+sufficient number of devices are present.
+.Pp
+Before exporting the pool, all datasets within the pool are unmounted. A pool
+can not be exported if it has a shared spare that is currently being used.
+.Pp
+For pools to be portable, you must give the
+.Nm
+command whole disks, not just slices, so that
+.Tn ZFS
+can label the disks with portable
+.Sy EFI
+labels. Otherwise, disk drivers on platforms of different endianness will not
+recognize the disks.
+.Bl -tag -width indent
+.It Fl f
+Forcefully unmount all datasets, using the
+.Qq Nm unmount Fl f
+command.
+.Pp
+This command will forcefully export the pool even if it has a shared spare that
+is currently being used. This may lead to potential data corruption.
+.El
+.It Xo
+.Nm
+.Cm get
+.Ar all | property Ns Op , Ns Ar ...
+.Ar pool ...
+.Xc
+.Pp
+Retrieves the given list of properties (or all properties if
+.Qq Cm all
+is used) for the specified storage pool(s). These properties are displayed with
+the following fields:
+.Bl -column -offset indent "property"
+.It name Ta Name of storage pool
+.It property Ta Property name
+.It value Ta Property value
+.It source Ta Property source, either 'default' or 'local'.
+.El
+.Pp
+See the
+.Qq Sx Properties
+section for more information on the available pool properties.
+.It Xo
+.Nm
+.Cm history
+.Op Fl il
+.Op Ar pool
+.Ar ...
+.Xc
+.Pp
+Displays the command history of the specified pools or all pools if no pool is
+specified.
+.Bl -tag -width indent
+.It Fl i
+Displays internally logged
+.Tn ZFS
+events in addition to user initiated events.
+.It Fl l
+Displays log records in long format, which in addition to standard format
+includes, the user name, the hostname, and the zone in which the operation was
+performed.
+.El
+.It Xo
+.Nm
+.Cm import
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Xc
+.Pp
+Lists pools available to import. If the
+.Fl d
+option is not specified, this command searches for devices in
+.Qq Pa /dev .
+The
+.Fl d
+option can be specified multiple times, and all directories are searched. If
+the device appears to be part of an exported pool, this command displays a
+summary of the pool with the name of the pool, a numeric identifier, as well as
+the
+.No vdev
+layout and current health of the device for each device or file.
+Destroyed pools, pools that were previously destroyed with the
+.Qq Nm Cm destroy
+command, are not listed unless the
+.Fl D
+option is specified.
+.Pp
+The numeric identifier is unique, and can be used instead of the pool name when
+multiple exported pools of the same name are available.
+.Bl -tag -width indent
+.It Fl c Ar cachefile
+Reads configuration from the given
+.Ar cachefile
+that was created with the
+.Qq Sy cachefile
+pool property. This
+.Ar cachefile
+is used instead of searching for devices.
+.It Fl d Ar dir
+Searches for devices or files in
+.Ar dir .
+The
+.Fl d
+option can be specified multiple times.
+.It Fl D
+Lists destroyed pools only.
+.El
+.It Xo
+.Nm
+.Cm import
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Op Fl f
+.Op Fl m
+.Op Fl N
+.Op Fl R Ar root
+.Op Fl F Op Fl n
+.Fl a
+.Xc
+.Pp
+Imports all pools found in the search directories. Identical to the previous
+command, except that all pools with a sufficient number of devices available
+are imported. Destroyed pools, pools that were previously destroyed with the
+.Qq Nm Cm destroy
+command, will not be imported unless the
+.Fl D
+option is specified.
+.Bl -tag -width indent
+.It Fl o Ar mntopts
+Comma-separated list of mount options to use when mounting datasets within the
+pool. See
+.Xr zfs 8
+for a description of dataset properties and mount options.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property on the imported pool. See the
+.Qq Sx Properties
+section for more information on the available pool properties.
+.It Fl c Ar cachefile
+Reads configuration from the given
+.Ar cachefile
+that was created with the
+.Qq Sy cachefile
+pool property. This
+.Ar cachefile
+is used instead of searching for devices.
+.It Fl d Ar dir
+Searches for devices or files in
+.Ar dir .
+The
+.Fl d
+option can be specified multiple times. This option is incompatible with the
+.Fl c
+option.
+.It Fl D
+Imports destroyed pools only. The
+.Fl f
+option is also required.
+.It Fl f
+Forces import, even if the pool appears to be potentially active.
+.It Fl m
+Enables import with missing log devices.
+.It Fl N
+Do not mount any filesystems from the imported pool.
+.It Fl R Ar root
+Sets the
+.Qq Sy cachefile
+property to
+.Qq Cm none
+and the
+.Qq Sy altroot
+property to
+.Qq Ar root
+.It Fl F
+Recovery mode for a non-importable pool. Attempt to return the pool to an
+importable state by discarding the last few transactions. Not all damaged pools
+can be recovered by using this option. If successful, the data from the
+discarded transactions is irretrievably lost. This option is ignored if the
+pool is importable or already imported.
+.It Fl n
+Used with the
+.Fl F
+recovery option. Determines whether a non-importable pool can be made
+importable again, but does not actually perform the pool recovery. For more
+details about pool recovery mode, see the
+.Fl F
+option, above.
+.It Fl a
+Searches for and imports all pools found.
+.El
+.It Xo
+.Nm
+.Cm import
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar ...
+.Op Fl d Ar dir | Fl c Ar cachefile
+.Op Fl D
+.Op Fl f
+.Op Fl m
+.Op Fl N
+.Op Fl R Ar root
+.Op Fl F Op Fl n
+.Ar pool | id
+.Op Ar newpool
+.Xc
+.Pp
+Imports a specific pool. A pool can be identified by its name or the numeric
+identifier. If
+.Ar newpool
+is specified, the pool is imported using the name
+.Ar newpool .
+Otherwise, it is imported with the same name as its exported name.
+.Pp
+If a device is removed from a system without running
+.Qq Nm Cm export
+first, the device appears as potentially active. It cannot be determined if
+this was a failed export, or whether the device is really in use from another
+host. To import a pool in this state, the
+.Fl f
+option is required.
+.Bl -tag -width indent
+.It Fl o Ar mntopts
+Comma-separated list of mount options to use when mounting datasets within the
+pool. See
+.Xr zfs 8
+for a description of dataset properties and mount options.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property on the imported pool. See the
+.Qq Sx Properties
+section for more information on the available pool properties.
+.It Fl c Ar cachefile
+Reads configuration from the given
+.Ar cachefile
+that was created with the
+.Qq Sy cachefile
+pool property. This
+.Ar cachefile
+is used instead of searching for devices.
+.It Fl d Ar dir
+Searches for devices or files in
+.Ar dir .
+The
+.Fl d
+option can be specified multiple times. This option is incompatible with the
+.Fl c
+option.
+.It Fl D
+Imports destroyed pools only. The
+.Fl f
+option is also required.
+.It Fl f
+Forces import, even if the pool appears to be potentially active.
+.It Fl m
+Enables import with missing log devices.
+.It Fl N
+Do not mount any filesystems from the imported pool.
+.It Fl R Ar root
+Equivalent to
+.Qq Fl o Cm cachefile=none,altroot= Ns Pa root
+.It Fl F
+Recovery mode for a non-importable pool. Attempt to return the pool to an
+importable state by discarding the last few transactions. Not all damaged pools
+can be recovered by using this option. If successful, the data from the
+discarded transactions is irretrievably lost. This option is ignored if the
+pool is importable or already imported.
+.It Fl n
+Used with the
+.Fl F
+recovery option. Determines whether a non-importable pool can be made
+importable again, but does not actually perform the pool recovery. For more
+details about pool recovery mode, see the
+.Fl F
+option, above.
+.El
+.It Xo
+.Nm
+.Cm iostat
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Fl v
+.Op Ar pool
+.Ar ...
+.Op Ar interval Op Ar count
+.Xc
+.Pp
+Displays
+.Tn I/O
+statistics for the given pools. When given an interval, the statistics are
+printed every
+.Ar interval
+seconds until
+.Sy Ctrl-C
+is pressed. If no
+.Ar pools
+are specified, statistics for every pool in the system is shown. If
+.Ar count
+is specified, the command exits after
+.Ar count
+reports are printed.
+.Bl -tag -width indent
+.It Fl T Cm d Ns | Ns Cm u
+Print a timestamp.
+.Pp
+Use modifier
+.Cm d
+for standard date format. See
+.Xr date 1 .
+Use modifier
+.Cm u
+for unixtime
+.Pq equals Qq Ic date +%s .
+.It Fl v
+Verbose statistics. Reports usage statistics for individual
+.No vdev Ns s
+within the pool, in addition to the pool-wide statistics.
+.El
+.It Xo
+.Nm
+.Cm labelclear
+.Op Fl f
+.Ar device
+.Xc
+.Pp
+Removes
+.Tn ZFS
+label information from the specified
+.Ar device .
+The
+.Ar device
+must not be part of an active pool configuration.
+.Bl -tag -width indent
+.It Fl v
+Treat exported or foreign devices as inactive.
+.El
+.It Xo
+.Nm
+.Cm list
+.Op Fl Hv
+.Op Fl o Ar property Ns Op , Ns Ar ...
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Ar pool
+.Ar ...
+.Op Ar inverval Op Ar count
+.Xc
+.Pp
+Lists the given pools along with a health status and space usage. When given no
+arguments, all pools in the system are listed.
+.Pp
+When given an interval, the output is printed every
+.Ar interval
+seconds until
+.Sy Ctrl-C
+is pressed. If
+.Ar count
+is specified, the command exits after
+.Ar count
+reports are printed.
+.Bl -tag -width indent
+.It Fl H
+Scripted mode. Do not display headers, and separate fields by a single tab
+instead of arbitrary space.
+.It Fl v
+Show more detailed information.
+.It Fl o Ar property Ns Op , Ns Ar ...
+Comma-separated list of properties to display. See the
+.Qq Sx Properties
+section for a list of valid properties. The default list is
+.Sy name ,
+.Sy size ,
+.Sy used ,
+.Sy available ,
+.Sy capacity ,
+.Sy health ,
+.Sy altroot .
+.It Fl T Cm d Ns | Ns Cm u
+Print a timestamp.
+.Pp
+Use modifier
+.Cm d
+for standard date format. See
+.Xr date 1 .
+Use modifier
+.Cm u
+for unixtime
+.Pq equals Qq Ic date +%s .
+.El
+.It Xo
+.Nm
+.Cm offline
+.Op Fl t
+.Ar pool device ...
+.Xc
+.Pp
+Takes the specified physical device offline. While the
+.Ar device
+is offline, no attempt is made to read or write to the device.
+.Bl -tag -width indent
+.It Fl t
+Temporary. Upon reboot, the specified physical device reverts to its previous
+state.
+.El
+.It Xo
+.Nm
+.Cm online
+.Op Fl e
+.Ar pool device ...
+.Xc
+.Pp
+Brings the specified physical device online.
+.Pp
+This command is not applicable to spares or cache devices.
+.Bl -tag -width indent
+.It Fl e
+Expand the device to use all available space. If the device is part of a mirror
+or
+.No raidz
+then all devices must be expanded before the new space will become
+available to the pool.
+.El
+.It Xo
+.Nm
+.Cm reguid
+.Ar pool
+.Xc
+.Pp
+Generates a new unique identifier for the pool. You must ensure that all
+devices in this pool are online and healthy before performing this action.
+.It Xo
+.Nm
+.Cm remove
+.Ar pool device ...
+.Xc
+.Pp
+Removes the specified device from the pool. This command currently only
+supports removing hot spares, cache, and log devices. A mirrored log device can
+be removed by specifying the top-level mirror for the log. Non-log devices that
+are part of a mirrored configuration can be removed using the
+.Qq Nm Cm detach
+command. Non-redundant and
+.No raidz
+devices cannot be removed from a pool.
+.It Xo
+.Nm
+.Cm replace
+.Op Fl f
+.Ar pool device
+.Op Ar new_device
+.Xc
+.Pp
+Replaces
+.Ar old_device
+with
+.Ar new_device .
+This is equivalent to attaching
+.Ar new_device ,
+waiting for it to resilver, and then detaching
+.Ar old_device .
+.Pp
+The size of
+.Ar new_device
+must be greater than or equal to the minimum size
+of all the devices in a mirror or
+.No raidz
+configuration.
+.Pp
+.Ar new_device
+is required if the pool is not redundant. If
+.Ar new_device
+is not specified, it defaults to
+.Ar old_device .
+This form of replacement is useful after an existing disk has failed and has
+been physically replaced. In this case, the new disk may have the same
+.Pa /dev
+path as the old device, even though it is actually a different disk.
+.Tn ZFS
+recognizes this.
+.Bl -tag -width indent
+.It Fl f
+Forces use of
+.Ar new_device ,
+even if its appears to be in use. Not all devices can be overridden in this
+manner.
+.El
+.It Xo
+.Nm
+.Cm scrub
+.Op Fl s
+.Ar pool ...
+.Xc
+.Pp
+Begins a scrub. The scrub examines all data in the specified pools to verify
+that it checksums correctly. For replicated (mirror or
+.No raidz )
+devices,
+.Tn ZFS
+automatically repairs any damage discovered during the scrub. The
+.Qq Nm Cm status
+command reports the progress of the scrub and summarizes the results of the
+scrub upon completion.
+.Pp
+Scrubbing and resilvering are very similar operations. The difference is that
+resilvering only examines data that
+.Tn ZFS
+knows to be out of date (for example, when attaching a new device to a mirror
+or replacing an existing device), whereas scrubbing examines all data to
+discover silent errors due to hardware faults or disk failure.
+.Pp
+Because scrubbing and resilvering are
+.Tn I/O Ns -intensive
+operations,
+.Tn ZFS
+only allows one at a time. If a scrub is already in progress, the
+.Qq Nm Cm scrub
+command returns an error. To start a new scrub, you have to stop the old scrub
+with the
+.Qq Nm Cm scrub Fl s
+command first. If a resilver is in progress,
+.Tn ZFS
+does not allow a scrub to be started until the resilver completes.
+.Bl -tag -width indent
+.It Fl s
+Stop scrubbing.
+.El
+.It Xo
+.Nm
+.Cm set
+.Ar property Ns = Ns Ar value pool
+.Xc
+.Pp
+Sets the given property on the specified pool. See the
+.Qq Sx Properties
+section for more information on what properties can be set and acceptable
+values.
+.It Xo
+.Nm
+.Cm split
+.Op Fl n
+.Op Fl R Ar altroot
+.Op Fl o Ar mntopts
+.Op Fl o Ar property Ns = Ns Ar value
+.Ar pool newpool
+.Op Ar device ...
+.Xc
+.Pp
+Splits off one disk from each mirrored top-level
+.No vdev
+in a pool and creates a new pool from the split-off disks. The original pool
+must be made up of one or more mirrors and must not be in the process of
+resilvering. The
+.Cm split
+subcommand chooses the last device in each mirror
+.No vdev
+unless overridden by a device specification on the command line.
+.Pp
+When using a
+.Ar device
+argument,
+.Cm split
+includes the specified device(s) in a new pool and, should any devices remain
+unspecified, assigns the last device in each mirror
+.No vdev
+to that pool, as it does normally. If you are uncertain about the outcome of a
+.Cm split
+command, use the
+.Fl n
+("dry-run") option to ensure your command will have the effect you intend.
+.Bl -tag -width indent
+.It Fl R Ar altroot
+Automatically import the newly created pool after splitting, using the
+specified
+.Ar altroot
+parameter for the new pool's alternate root. See the
+.Sy altroot
+description in the
+.Qq Sx Properties
+section, above.
+.It Fl n
+Displays the configuration that would be created without actually splitting the
+pool. The actual pool split could still fail due to insufficient privileges or
+device status.
+.It Fl o Ar mntopts
+Comma-separated list of mount options to use when mounting datasets within the
+pool. See
+.Xr zfs 8
+for a description of dataset properties and mount options. Valid only in
+conjunction with the
+.Fl R
+option.
+.It Fl o Ar property Ns = Ns Ar value
+Sets the specified property on the new pool. See the
+.Qq Sx Properties
+section, above, for more information on the available pool properties.
+.El
+.It Xo
+.Nm
+.Cm status
+.Op Fl vx
+.Op Fl T Cm d Ns | Ns Cm u
+.Op Ar pool
+.Ar ...
+.Op Ar interval Op Ar count
+.Xc
+.Pp
+Displays the detailed health status for the given pools. If no
+.Ar pool
+is specified, then the status of each pool in the system is displayed. For more
+information on pool and device health, see the
+.Qq Sx Device Failure and Recovery
+section.
+.Pp
+When given an interval, the output is printed every
+.Ar interval
+seconds until
+.Sy Ctrl-C
+is pressed. If
+.Ar count
+is specified, the command exits after
+.Ar count
+reports are printed.
+.Pp
+If a scrub or resilver is in progress, this command reports the percentage
+done and the estimated time to completion. Both of these are only approximate,
+because the amount of data in the pool and the other workloads on the system
+can change.
+.Bl -tag -width indent
+.It Fl x
+Only display status for pools that are exhibiting errors or are otherwise
+unavailable.
+Warnings about pools not using the latest on-disk format will not be included.
+.It Fl v
+Displays verbose data error information, printing out a complete list of all
+data errors since the last complete pool scrub.
+.It Fl T Cm d Ns | Ns Cm u
+Print a timestamp.
+.Pp
+Use modifier
+.Cm d
+for standard date format. See
+.Xr date 1 .
+Use modifier
+.Cm u
+for unixtime
+.Pq equals Qq Ic date +%s .
+.El
+.It Xo
+.Nm
+.Cm upgrade
+.Op Fl v
+.Xc
+.Pp
+Displays pools which do not have all supported features enabled and pools
+formatted using a legacy
+.Tn ZFS
+version number.
+These pools can continue to be used, but some features may not be available.
+Use
+.Nm Cm upgrade Fl a
+to enable all features on all pools.
+.Bl -tag -width indent
+.It Fl v
+Displays legacy
+.Tn ZFS
+versions supported by the current software.
+See
+.Xr zpool-features 7
+for a description of feature flags features supported by the current software.
+.El
+.It Xo
+.Nm
+.Cm upgrade
+.Op Fl V Ar version
+.Fl a | Ar pool ...
+.Xc
+.Pp
+Enables all supported features on the given pool.
+Once this is done, the pool will no longer be accessible on systems that do
+not support feature flags.
+See
+.Xr zpool-features 7
+for details on compatability with system sthat support feature flags, but do
+not support all features enabled on the pool.
+.Bl -tag -width indent
+.It Fl a
+Enables all supported features on all pools.
+.It Fl V Ar version
+Upgrade to the specified legacy version. If the
+.Fl V
+flag is specified, no features will be enabled on the pool.
+This option can only be used to increase version number up to the last
+supported legacy version number.
+.El
+.El
+.Sh EXIT STATUS
+The following exit values are returned:
+.Bl -tag -offset 2n -width 2n
+.It 0
+Successful completion.
+.It 1
+An error occurred.
+.It 2
+Invalid command line options were specified.
+.El
+.Sh EXAMPLES
+.Bl -tag -width 0n
+.It Sy Example 1 No Creating a RAID-Z Storage Pool
+.Pp
+The following command creates a pool with a single
+.No raidz
+root
+.No vdev
+that consists of six disks.
+.Bd -literal -offset 2n
+.Li # Ic zpool create tank raidz da0 da1 da2 da3 da4 da5
+.Ed
+.It Sy Example 2 No Creating a Mirrored Storage Pool
+.Pp
+The following command creates a pool with two mirrors, where each mirror
+contains two disks.
+.Bd -literal -offset 2n
+.Li # Ic zpool create tank mirror da0 da1 mirror da2 da3
+.Ed
+.It Sy Example 3 No Creating a Tn ZFS No Storage Pool by Using Partitions
+.Pp
+The following command creates an unmirrored pool using two GPT partitions.
+.Bd -literal -offset 2n
+.Li # Ic zpool create tank da0p3 da1p3
+.Ed
+.It Sy Example 4 No Creating a Tn ZFS No Storage Pool by Using Files
+.Pp
+The following command creates an unmirrored pool using files. While not
+recommended, a pool based on files can be useful for experimental purposes.
+.Bd -literal -offset 2n
+.Li # Ic zpool create tank /path/to/file/a /path/to/file/b
+.Ed
+.It Sy Example 5 No Adding a Mirror to a Tn ZFS No Storage Pool
+.Pp
+The following command adds two mirrored disks to the pool
+.Em tank ,
+assuming the pool is already made up of two-way mirrors. The additional space
+is immediately available to any datasets within the pool.
+.Bd -literal -offset 2n
+.Li # Ic zpool add tank mirror da2 da3
+.Ed
+.It Sy Example 6 No Listing Available Tn ZFS No Storage Pools
+.Pp
+The following command lists all available pools on the system.
+.Bd -literal -offset 2n
+.Li # Ic zpool list
+NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
+pool 2.70T 473G 2.24T 17% 1.00x ONLINE -
+test 1.98G 89.5K 1.98G 0% 1.00x ONLINE -
+.Ed
+.It Sy Example 7 No Listing All Properties for a Pool
+.Pp
+The following command lists all the properties for a pool.
+.Bd -literal -offset 2n
+.Li # Ic zpool get all pool
+pool size 2.70T -
+pool capacity 17% -
+pool altroot - default
+pool health ONLINE -
+pool guid 2501120270416322443 default
+pool version 28 default
+pool bootfs pool/root local
+pool delegation on default
+pool autoreplace off default
+pool cachefile - default
+pool failmode wait default
+pool listsnapshots off default
+pool autoexpand off default
+pool dedupditto 0 default
+pool dedupratio 1.00x -
+pool free 2.24T -
+pool allocated 473G -
+pool readonly off -
+.Ed
+.It Sy Example 8 No Destroying a Tn ZFS No Storage Pool
+.Pp
+The following command destroys the pool
+.Qq Em tank
+and any datasets contained within.
+.Bd -literal -offset 2n
+.Li # Ic zpool destroy -f tank
+.Ed
+.It Sy Example 9 No Exporting a Tn ZFS No Storage Pool
+.Pp
+The following command exports the devices in pool
+.Em tank
+so that they can be relocated or later imported.
+.Bd -literal -offset 2n
+.Li # Ic zpool export tank
+.Ed
+.It Sy Example 10 No Importing a Tn ZFS No Storage Pool
+.Pp
+The following command displays available pools, and then imports the pool
+.Qq Em tank
+for use on the system.
+.Pp
+The results from this command are similar to the following:
+.Bd -literal -offset 2n
+.Li # Ic zpool import
+
+ pool: tank
+ id: 15451357997522795478
+ state: ONLINE
+action: The pool can be imported using its name or numeric identifier.
+config:
+
+ tank ONLINE
+ mirror ONLINE
+ da0 ONLINE
+ da1 ONLINE
+.Ed
+.It Xo
+.Sy Example 11
+Upgrading All
+.Tn ZFS
+Storage Pools to the Current Version
+.Xc
+.Pp
+The following command upgrades all
+.Tn ZFS
+Storage pools to the current version of
+the software.
+.Bd -literal -offset 2n
+.Li # Ic zpool upgrade -a
+This system is currently running ZFS pool version 28.
+.Ed
+.It Sy Example 12 No Managing Hot Spares
+.Pp
+The following command creates a new pool with an available hot spare:
+.Bd -literal -offset 2n
+.Li # Ic zpool create tank mirror da0 da1 spare da2
+.Ed
+.Pp
+If one of the disks were to fail, the pool would be reduced to the degraded
+state. The failed device can be replaced using the following command:
+.Bd -literal -offset 2n
+.Li # Ic zpool replace tank da0 da2
+.Ed
+.Pp
+Once the data has been resilvered, the spare is automatically removed and is
+made available should another device fails. The hot spare can be permanently
+removed from the pool using the following command:
+.Bd -literal -offset 2n
+.Li # Ic zpool remove tank da2
+.Ed
+.It Xo
+.Sy Example 13
+Creating a
+.Tn ZFS
+Pool with Mirrored Separate Intent Logs
+.Xc
+.Pp
+The following command creates a
+.Tn ZFS
+storage pool consisting of two, two-way
+mirrors and mirrored log devices:
+.Bd -literal -offset 2n
+.Li # Ic zpool create pool mirror da0 da1 mirror da2 da3 log mirror da4 da5
+.Ed
+.It Sy Example 14 No Adding Cache Devices to a Tn ZFS No Pool
+.Pp
+The following command adds two disks for use as cache devices to a
+.Tn ZFS
+storage pool:
+.Bd -literal -offset 2n
+.Li # Ic zpool add pool cache da2 da3
+.Ed
+.Pp
+Once added, the cache devices gradually fill with content from main memory.
+Depending on the size of your cache devices, it could take over an hour for
+them to fill. Capacity and reads can be monitored using the
+.Cm iostat
+subcommand as follows:
+.Bd -literal -offset 2n
+.Li # Ic zpool iostat -v pool 5
+.Ed
+.It Sy Example 15 No Removing a Mirrored Log Device
+.Pp
+The following command removes the mirrored log device
+.Em mirror-2 .
+.Pp
+Given this configuration:
+.Bd -literal -offset 2n
+ pool: tank
+ state: ONLINE
+ scrub: none requested
+ config:
+
+ NAME STATE READ WRITE CKSUM
+ tank ONLINE 0 0 0
+ mirror-0 ONLINE 0 0 0
+ da0 ONLINE 0 0 0
+ da1 ONLINE 0 0 0
+ mirror-1 ONLINE 0 0 0
+ da2 ONLINE 0 0 0
+ da3 ONLINE 0 0 0
+ logs
+ mirror-2 ONLINE 0 0 0
+ da4 ONLINE 0 0 0
+ da5 ONLINE 0 0 0
+.Ed
+.Pp
+The command to remove the mirrored log
+.Em mirror-2
+is:
+.Bd -literal -offset 2n
+.Li # Ic zpool remove tank mirror-2
+.Ed
+.It Sy Example 16 No Recovering a Faulted Tn ZFS No Pool
+.Pp
+If a pool is faulted but recoverable, a message indicating this state is
+provided by
+.Qq Nm Cm status
+if the pool was cached (see the
+.Fl c Ar cachefile
+argument above), or as part of the error output from a failed
+.Qq Nm Cm import
+of the pool.
+.Pp
+Recover a cached pool with the
+.Qq Nm Cm clear
+command:
+.Bd -literal -offset 2n
+.Li # Ic zpool clear -F data
+Pool data returned to its state as of Tue Sep 08 13:23:35 2009.
+Discarded approximately 29 seconds of transactions.
+.Ed
+.Pp
+If the pool configuration was not cached, use
+.Qq Nm Cm import
+with the recovery mode flag:
+.Bd -literal -offset 2n
+.Li # Ic zpool import -F data
+Pool data returned to its state as of Tue Sep 08 13:23:35 2009.
+Discarded approximately 29 seconds of transactions.
+.Ed
+.El
+.Sh SEE ALSO
+.Xr zpool-features 7 ,
+.Xr zfs 8
+.Sh AUTHORS
+This manual page is a
+.Xr mdoc 7
+reimplementation of the
+.Tn OpenSolaris
+manual page
+.Em zpool(1M) ,
+modified and customized for
+.Fx
+and licensed under the Common Development and Distribution License
+.Pq Tn CDDL .
+.Pp
+The
+.Xr mdoc 7
+implementation of this manual page was initially written by
+.An Martin Matuska Aq mm@FreeBSD.org .
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_iter.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_iter.c
new file mode 100644
index 0000000..6ba91b1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_iter.c
@@ -0,0 +1,253 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <solaris.h>
+#include <libintl.h>
+#include <libuutil.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <libzfs.h>
+
+#include "zpool_util.h"
+
+/*
+ * Private interface for iterating over pools specified on the command line.
+ * Most consumers will call for_each_pool, but in order to support iostat, we
+ * allow fined grained control through the zpool_list_t interface.
+ */
+
+typedef struct zpool_node {
+ zpool_handle_t *zn_handle;
+ uu_avl_node_t zn_avlnode;
+ int zn_mark;
+} zpool_node_t;
+
+struct zpool_list {
+ boolean_t zl_findall;
+ uu_avl_t *zl_avl;
+ uu_avl_pool_t *zl_pool;
+ zprop_list_t **zl_proplist;
+};
+
+/* ARGSUSED */
+static int
+zpool_compare(const void *larg, const void *rarg, void *unused)
+{
+ zpool_handle_t *l = ((zpool_node_t *)larg)->zn_handle;
+ zpool_handle_t *r = ((zpool_node_t *)rarg)->zn_handle;
+ const char *lname = zpool_get_name(l);
+ const char *rname = zpool_get_name(r);
+
+ return (strcmp(lname, rname));
+}
+
+/*
+ * Callback function for pool_list_get(). Adds the given pool to the AVL tree
+ * of known pools.
+ */
+static int
+add_pool(zpool_handle_t *zhp, void *data)
+{
+ zpool_list_t *zlp = data;
+ zpool_node_t *node = safe_malloc(sizeof (zpool_node_t));
+ uu_avl_index_t idx;
+
+ node->zn_handle = zhp;
+ uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
+ if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
+ if (zlp->zl_proplist &&
+ zpool_expand_proplist(zhp, zlp->zl_proplist) != 0) {
+ zpool_close(zhp);
+ free(node);
+ return (-1);
+ }
+ uu_avl_insert(zlp->zl_avl, node, idx);
+ } else {
+ zpool_close(zhp);
+ free(node);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Create a list of pools based on the given arguments. If we're given no
+ * arguments, then iterate over all pools in the system and add them to the AVL
+ * tree. Otherwise, add only those pool explicitly specified on the command
+ * line.
+ */
+zpool_list_t *
+pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
+{
+ zpool_list_t *zlp;
+
+ zlp = safe_malloc(sizeof (zpool_list_t));
+
+ zlp->zl_pool = uu_avl_pool_create("zfs_pool", sizeof (zpool_node_t),
+ offsetof(zpool_node_t, zn_avlnode), zpool_compare, UU_DEFAULT);
+
+ if (zlp->zl_pool == NULL)
+ zpool_no_memory();
+
+ if ((zlp->zl_avl = uu_avl_create(zlp->zl_pool, NULL,
+ UU_DEFAULT)) == NULL)
+ zpool_no_memory();
+
+ zlp->zl_proplist = proplist;
+
+ if (argc == 0) {
+ (void) zpool_iter(g_zfs, add_pool, zlp);
+ zlp->zl_findall = B_TRUE;
+ } else {
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ zpool_handle_t *zhp;
+
+ if (zhp = zpool_open_canfail(g_zfs, argv[i])) {
+ if (add_pool(zhp, zlp) != 0)
+ *err = B_TRUE;
+ } else {
+ *err = B_TRUE;
+ }
+ }
+ }
+
+ return (zlp);
+}
+
+/*
+ * Search for any new pools, adding them to the list. We only add pools when no
+ * options were given on the command line. Otherwise, we keep the list fixed as
+ * those that were explicitly specified.
+ */
+void
+pool_list_update(zpool_list_t *zlp)
+{
+ if (zlp->zl_findall)
+ (void) zpool_iter(g_zfs, add_pool, zlp);
+}
+
+/*
+ * Iterate over all pools in the list, executing the callback for each
+ */
+int
+pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
+ void *data)
+{
+ zpool_node_t *node, *next_node;
+ int ret = 0;
+
+ for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next_node) {
+ next_node = uu_avl_next(zlp->zl_avl, node);
+ if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL ||
+ unavail)
+ ret |= func(node->zn_handle, data);
+ }
+
+ return (ret);
+}
+
+/*
+ * Remove the given pool from the list. When running iostat, we want to remove
+ * those pools that no longer exist.
+ */
+void
+pool_list_remove(zpool_list_t *zlp, zpool_handle_t *zhp)
+{
+ zpool_node_t search, *node;
+
+ search.zn_handle = zhp;
+ if ((node = uu_avl_find(zlp->zl_avl, &search, NULL, NULL)) != NULL) {
+ uu_avl_remove(zlp->zl_avl, node);
+ zpool_close(node->zn_handle);
+ free(node);
+ }
+}
+
+/*
+ * Free all the handles associated with this list.
+ */
+void
+pool_list_free(zpool_list_t *zlp)
+{
+ uu_avl_walk_t *walk;
+ zpool_node_t *node;
+
+ if ((walk = uu_avl_walk_start(zlp->zl_avl, UU_WALK_ROBUST)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("internal error: out of memory"));
+ exit(1);
+ }
+
+ while ((node = uu_avl_walk_next(walk)) != NULL) {
+ uu_avl_remove(zlp->zl_avl, node);
+ zpool_close(node->zn_handle);
+ free(node);
+ }
+
+ uu_avl_walk_end(walk);
+ uu_avl_destroy(zlp->zl_avl);
+ uu_avl_pool_destroy(zlp->zl_pool);
+
+ free(zlp);
+}
+
+/*
+ * Returns the number of elements in the pool list.
+ */
+int
+pool_list_count(zpool_list_t *zlp)
+{
+ return (uu_avl_numnodes(zlp->zl_avl));
+}
+
+/*
+ * High level function which iterates over all pools given on the command line,
+ * using the pool_list_* interfaces.
+ */
+int
+for_each_pool(int argc, char **argv, boolean_t unavail,
+ zprop_list_t **proplist, zpool_iter_f func, void *data)
+{
+ zpool_list_t *list;
+ int ret = 0;
+
+ if ((list = pool_list_get(argc, argv, proplist, &ret)) == NULL)
+ return (1);
+
+ if (pool_list_iter(list, unavail, func, data) != 0)
+ ret = 1;
+
+ pool_list_free(list);
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
new file mode 100644
index 0000000..7e0fa18
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -0,0 +1,5351 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include <solaris.h>
+#include <assert.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <libuutil.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <priv.h>
+#include <pwd.h>
+#include <zone.h>
+#include <sys/time.h>
+#include <zfs_prop.h>
+#include <sys/fs/zfs.h>
+#include <sys/stat.h>
+
+#include <libzfs.h>
+
+#include "zpool_util.h"
+#include "zfs_comutil.h"
+#include "zfeature_common.h"
+
+#include "statcommon.h"
+
+static int zpool_do_create(int, char **);
+static int zpool_do_destroy(int, char **);
+
+static int zpool_do_add(int, char **);
+static int zpool_do_remove(int, char **);
+static int zpool_do_labelclear(int, char **);
+
+static int zpool_do_list(int, char **);
+static int zpool_do_iostat(int, char **);
+static int zpool_do_status(int, char **);
+
+static int zpool_do_online(int, char **);
+static int zpool_do_offline(int, char **);
+static int zpool_do_clear(int, char **);
+static int zpool_do_reopen(int, char **);
+
+static int zpool_do_reguid(int, char **);
+
+static int zpool_do_attach(int, char **);
+static int zpool_do_detach(int, char **);
+static int zpool_do_replace(int, char **);
+static int zpool_do_split(int, char **);
+
+static int zpool_do_scrub(int, char **);
+
+static int zpool_do_import(int, char **);
+static int zpool_do_export(int, char **);
+
+static int zpool_do_upgrade(int, char **);
+
+static int zpool_do_history(int, char **);
+
+static int zpool_do_get(int, char **);
+static int zpool_do_set(int, char **);
+
+/*
+ * These libumem hooks provide a reasonable set of defaults for the allocator's
+ * debugging facilities.
+ */
+
+#ifdef DEBUG
+const char *
+_umem_debug_init(void)
+{
+ return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+ return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
+#endif
+
+typedef enum {
+ HELP_ADD,
+ HELP_ATTACH,
+ HELP_CLEAR,
+ HELP_CREATE,
+ HELP_DESTROY,
+ HELP_DETACH,
+ HELP_EXPORT,
+ HELP_HISTORY,
+ HELP_IMPORT,
+ HELP_IOSTAT,
+ HELP_LABELCLEAR,
+ HELP_LIST,
+ HELP_OFFLINE,
+ HELP_ONLINE,
+ HELP_REPLACE,
+ HELP_REMOVE,
+ HELP_SCRUB,
+ HELP_STATUS,
+ HELP_UPGRADE,
+ HELP_GET,
+ HELP_SET,
+ HELP_SPLIT,
+ HELP_REGUID,
+ HELP_REOPEN
+} zpool_help_t;
+
+
+typedef struct zpool_command {
+ const char *name;
+ int (*func)(int, char **);
+ zpool_help_t usage;
+} zpool_command_t;
+
+/*
+ * Master command table. Each ZFS command has a name, associated function, and
+ * usage message. The usage messages need to be internationalized, so we have
+ * to have a function to return the usage message based on a command index.
+ *
+ * These commands are organized according to how they are displayed in the usage
+ * message. An empty command (one with a NULL name) indicates an empty line in
+ * the generic usage message.
+ */
+static zpool_command_t command_table[] = {
+ { "create", zpool_do_create, HELP_CREATE },
+ { "destroy", zpool_do_destroy, HELP_DESTROY },
+ { NULL },
+ { "add", zpool_do_add, HELP_ADD },
+ { "remove", zpool_do_remove, HELP_REMOVE },
+ { NULL },
+ { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR },
+ { NULL },
+ { "list", zpool_do_list, HELP_LIST },
+ { "iostat", zpool_do_iostat, HELP_IOSTAT },
+ { "status", zpool_do_status, HELP_STATUS },
+ { NULL },
+ { "online", zpool_do_online, HELP_ONLINE },
+ { "offline", zpool_do_offline, HELP_OFFLINE },
+ { "clear", zpool_do_clear, HELP_CLEAR },
+ { "reopen", zpool_do_reopen, HELP_REOPEN },
+ { NULL },
+ { "attach", zpool_do_attach, HELP_ATTACH },
+ { "detach", zpool_do_detach, HELP_DETACH },
+ { "replace", zpool_do_replace, HELP_REPLACE },
+ { "split", zpool_do_split, HELP_SPLIT },
+ { NULL },
+ { "scrub", zpool_do_scrub, HELP_SCRUB },
+ { NULL },
+ { "import", zpool_do_import, HELP_IMPORT },
+ { "export", zpool_do_export, HELP_EXPORT },
+ { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
+ { "reguid", zpool_do_reguid, HELP_REGUID },
+ { NULL },
+ { "history", zpool_do_history, HELP_HISTORY },
+ { "get", zpool_do_get, HELP_GET },
+ { "set", zpool_do_set, HELP_SET },
+};
+
+#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
+
+static zpool_command_t *current_command;
+static char history_str[HIS_MAX_RECORD_LEN];
+static boolean_t log_history = B_TRUE;
+static uint_t timestamp_fmt = NODATE;
+
+static const char *
+get_usage(zpool_help_t idx) {
+ switch (idx) {
+ case HELP_ADD:
+ return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
+ case HELP_ATTACH:
+ return (gettext("\tattach [-f] <pool> <device> "
+ "<new-device>\n"));
+ case HELP_CLEAR:
+ return (gettext("\tclear [-nF] <pool> [device]\n"));
+ case HELP_CREATE:
+ return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
+ "\t [-O file-system-property=value] ... \n"
+ "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
+ case HELP_DESTROY:
+ return (gettext("\tdestroy [-f] <pool>\n"));
+ case HELP_DETACH:
+ return (gettext("\tdetach <pool> <device>\n"));
+ case HELP_EXPORT:
+ return (gettext("\texport [-f] <pool> ...\n"));
+ case HELP_HISTORY:
+ return (gettext("\thistory [-il] [<pool>] ...\n"));
+ case HELP_IMPORT:
+ return (gettext("\timport [-d dir] [-D]\n"
+ "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
+ "\timport [-o mntopts] [-o property=value] ... \n"
+ "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
+ "[-R root] [-F [-n]] -a\n"
+ "\timport [-o mntopts] [-o property=value] ... \n"
+ "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
+ "[-R root] [-F [-n]]\n"
+ "\t <pool | id> [newpool]\n"));
+ case HELP_IOSTAT:
+ return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
+ "[count]]\n"));
+ case HELP_LABELCLEAR:
+ return (gettext("\tlabelclear [-f] <vdev>\n"));
+ case HELP_LIST:
+ return (gettext("\tlist [-Hv] [-o property[,...]] "
+ "[-T d|u] [pool] ... [interval [count]]\n"));
+ case HELP_OFFLINE:
+ return (gettext("\toffline [-t] <pool> <device> ...\n"));
+ case HELP_ONLINE:
+ return (gettext("\tonline [-e] <pool> <device> ...\n"));
+ case HELP_REPLACE:
+ return (gettext("\treplace [-f] <pool> <device> "
+ "[new-device]\n"));
+ case HELP_REMOVE:
+ return (gettext("\tremove <pool> <device> ...\n"));
+ case HELP_REOPEN:
+ return (""); /* Undocumented command */
+ case HELP_SCRUB:
+ return (gettext("\tscrub [-s] <pool> ...\n"));
+ case HELP_STATUS:
+ return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
+ "[count]]\n"));
+ case HELP_UPGRADE:
+ return (gettext("\tupgrade [-v]\n"
+ "\tupgrade [-V version] <-a | pool ...>\n"));
+ case HELP_GET:
+ return (gettext("\tget <\"all\" | property[,...]> "
+ "<pool> ...\n"));
+ case HELP_SET:
+ return (gettext("\tset <property=value> <pool> \n"));
+ case HELP_SPLIT:
+ return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
+ "\t [-o property=value] <pool> <newpool> "
+ "[<device> ...]\n"));
+ case HELP_REGUID:
+ return (gettext("\treguid <pool>\n"));
+ }
+
+ abort();
+ /* NOTREACHED */
+}
+
+
+/*
+ * Callback routine that will print out a pool property value.
+ */
+static int
+print_prop_cb(int prop, void *cb)
+{
+ FILE *fp = cb;
+
+ (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop));
+
+ if (zpool_prop_readonly(prop))
+ (void) fprintf(fp, " NO ");
+ else
+ (void) fprintf(fp, " YES ");
+
+ if (zpool_prop_values(prop) == NULL)
+ (void) fprintf(fp, "-\n");
+ else
+ (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
+
+ return (ZPROP_CONT);
+}
+
+/*
+ * Display usage message. If we're inside a command, display only the usage for
+ * that command. Otherwise, iterate over the entire command table and display
+ * a complete usage message.
+ */
+void
+usage(boolean_t requested)
+{
+ FILE *fp = requested ? stdout : stderr;
+
+ if (current_command == NULL) {
+ int i;
+
+ (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
+ (void) fprintf(fp,
+ gettext("where 'command' is one of the following:\n\n"));
+
+ for (i = 0; i < NCOMMAND; i++) {
+ if (command_table[i].name == NULL)
+ (void) fprintf(fp, "\n");
+ else
+ (void) fprintf(fp, "%s",
+ get_usage(command_table[i].usage));
+ }
+ } else {
+ (void) fprintf(fp, gettext("usage:\n"));
+ (void) fprintf(fp, "%s", get_usage(current_command->usage));
+ }
+
+ if (current_command != NULL &&
+ ((strcmp(current_command->name, "set") == 0) ||
+ (strcmp(current_command->name, "get") == 0) ||
+ (strcmp(current_command->name, "list") == 0))) {
+
+ (void) fprintf(fp,
+ gettext("\nthe following properties are supported:\n"));
+
+ (void) fprintf(fp, "\n\t%-15s %s %s\n\n",
+ "PROPERTY", "EDIT", "VALUES");
+
+ /* Iterate over all properties */
+ (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
+ ZFS_TYPE_POOL);
+
+ (void) fprintf(fp, "\t%-15s ", "feature@...");
+ (void) fprintf(fp, "YES disabled | enabled | active\n");
+
+ (void) fprintf(fp, gettext("\nThe feature@ properties must be "
+ "appended with a feature name.\nSee zpool-features(7).\n"));
+ }
+
+ /*
+ * See comments at end of main().
+ */
+ if (getenv("ZFS_ABORT") != NULL) {
+ (void) printf("dumping core by request\n");
+ abort();
+ }
+
+ exit(requested ? 0 : 2);
+}
+
+void
+print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
+ boolean_t print_logs)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ char *vname;
+
+ if (name != NULL)
+ (void) printf("\t%*s%s\n", indent, "", name);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ uint64_t is_log = B_FALSE;
+
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+ if ((is_log && !print_logs) || (!is_log && print_logs))
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
+ print_vdev_tree(zhp, vname, child[c], indent + 2,
+ B_FALSE);
+ free(vname);
+ }
+}
+
+static boolean_t
+prop_list_contains_feature(nvlist_t *proplist)
+{
+ nvpair_t *nvp;
+ for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
+ nvp = nvlist_next_nvpair(proplist, nvp)) {
+ if (zpool_prop_feature(nvpair_name(nvp)))
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
+/*
+ * Add a property pair (name, string-value) into a property nvlist.
+ */
+static int
+add_prop_list(const char *propname, char *propval, nvlist_t **props,
+ boolean_t poolprop)
+{
+ zpool_prop_t prop = ZPROP_INVAL;
+ zfs_prop_t fprop;
+ nvlist_t *proplist;
+ const char *normnm;
+ char *strval;
+
+ if (*props == NULL &&
+ nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
+ (void) fprintf(stderr,
+ gettext("internal error: out of memory\n"));
+ return (1);
+ }
+
+ proplist = *props;
+
+ if (poolprop) {
+ const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
+
+ if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
+ !zpool_prop_feature(propname)) {
+ (void) fprintf(stderr, gettext("property '%s' is "
+ "not a valid pool property\n"), propname);
+ return (2);
+ }
+
+ /*
+ * feature@ properties and version should not be specified
+ * at the same time.
+ */
+ if ((prop == ZPROP_INVAL && zpool_prop_feature(propname) &&
+ nvlist_exists(proplist, vname)) ||
+ (prop == ZPOOL_PROP_VERSION &&
+ prop_list_contains_feature(proplist))) {
+ (void) fprintf(stderr, gettext("'feature@' and "
+ "'version' properties cannot be specified "
+ "together\n"));
+ return (2);
+ }
+
+
+ if (zpool_prop_feature(propname))
+ normnm = propname;
+ else
+ normnm = zpool_prop_to_name(prop);
+ } else {
+ if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
+ normnm = zfs_prop_to_name(fprop);
+ } else {
+ normnm = propname;
+ }
+ }
+
+ if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
+ prop != ZPOOL_PROP_CACHEFILE) {
+ (void) fprintf(stderr, gettext("property '%s' "
+ "specified multiple times\n"), propname);
+ return (2);
+ }
+
+ if (nvlist_add_string(proplist, normnm, propval) != 0) {
+ (void) fprintf(stderr, gettext("internal "
+ "error: out of memory\n"));
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * zpool add [-fn] <pool> <vdev> ...
+ *
+ * -f Force addition of devices, even if they appear in use
+ * -n Do not add the devices, but display the resulting layout if
+ * they were to be added.
+ *
+ * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
+ * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
+ * libzfs.
+ */
+int
+zpool_do_add(int argc, char **argv)
+{
+ boolean_t force = B_FALSE;
+ boolean_t dryrun = B_FALSE;
+ int c;
+ nvlist_t *nvroot;
+ char *poolname;
+ int ret;
+ zpool_handle_t *zhp;
+ nvlist_t *config;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "fn")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ case 'n':
+ dryrun = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing vdev specification\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+
+ argc--;
+ argv++;
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ if ((config = zpool_get_config(zhp, NULL)) == NULL) {
+ (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
+ poolname);
+ zpool_close(zhp);
+ return (1);
+ }
+
+ /* pass off to get_vdev_spec for processing */
+ nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
+ argc, argv);
+ if (nvroot == NULL) {
+ zpool_close(zhp);
+ return (1);
+ }
+
+ if (dryrun) {
+ nvlist_t *poolnvroot;
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &poolnvroot) == 0);
+
+ (void) printf(gettext("would update '%s' to the following "
+ "configuration:\n"), zpool_get_name(zhp));
+
+ /* print original main pool and new tree */
+ print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
+ print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
+
+ /* Do the same for the logs */
+ if (num_logs(poolnvroot) > 0) {
+ print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
+ print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
+ } else if (num_logs(nvroot) > 0) {
+ print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
+ }
+
+ ret = 0;
+ } else {
+ ret = (zpool_add(zhp, nvroot) != 0);
+ }
+
+ nvlist_free(nvroot);
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool remove <pool> <vdev> ...
+ *
+ * Removes the given vdev from the pool. Currently, this supports removing
+ * spares, cache, and log devices from the pool.
+ */
+int
+zpool_do_remove(int argc, char **argv)
+{
+ char *poolname;
+ int i, ret = 0;
+ zpool_handle_t *zhp;
+
+ argc--;
+ argv++;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing device\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ for (i = 1; i < argc; i++) {
+ if (zpool_vdev_remove(zhp, argv[i]) != 0)
+ ret = 1;
+ }
+
+ return (ret);
+}
+
+/*
+ * zpool labelclear <vdev>
+ *
+ * Verifies that the vdev is not active and zeros out the label information
+ * on the device.
+ */
+int
+zpool_do_labelclear(int argc, char **argv)
+{
+ char *vdev, *name;
+ int c, fd = -1, ret = 0;
+ pool_state_t state;
+ boolean_t inuse = B_FALSE;
+ boolean_t force = B_FALSE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ default:
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get vdev name */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing vdev device name\n"));
+ usage(B_FALSE);
+ }
+
+ vdev = argv[0];
+ if ((fd = open(vdev, O_RDWR)) < 0) {
+ (void) fprintf(stderr, gettext("Unable to open %s\n"), vdev);
+ return (B_FALSE);
+ }
+
+ name = NULL;
+ if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0) {
+ if (force)
+ goto wipe_label;
+
+ (void) fprintf(stderr,
+ gettext("Unable to determine pool state for %s\n"
+ "Use -f to force the clearing any label data\n"), vdev);
+
+ return (1);
+ }
+
+ if (inuse) {
+ switch (state) {
+ default:
+ case POOL_STATE_ACTIVE:
+ case POOL_STATE_SPARE:
+ case POOL_STATE_L2CACHE:
+ (void) fprintf(stderr,
+gettext("labelclear operation failed.\n"
+ "\tVdev %s is a member (%s), of pool \"%s\".\n"
+ "\tTo remove label information from this device, export or destroy\n"
+ "\tthe pool, or remove %s from the configuration of this pool\n"
+ "\tand retry the labelclear operation\n"),
+ vdev, zpool_pool_state_to_name(state), name, vdev);
+ ret = 1;
+ goto errout;
+
+ case POOL_STATE_EXPORTED:
+ if (force)
+ break;
+
+ (void) fprintf(stderr,
+gettext("labelclear operation failed.\n"
+ "\tVdev %s is a member of the exported pool \"%s\".\n"
+ "\tUse \"zpool labelclear -f %s\" to force the removal of label\n"
+ "\tinformation.\n"),
+ vdev, name, vdev);
+ ret = 1;
+ goto errout;
+
+ case POOL_STATE_POTENTIALLY_ACTIVE:
+ if (force)
+ break;
+
+ (void) fprintf(stderr,
+gettext("labelclear operation failed.\n"
+ "\tVdev %s is a member of the pool \"%s\".\n"
+ "\tThis pool is unknown to this system, but may be active on\n"
+ "\tanother system. Use \'zpool labelclear -f %s\' to force the\n"
+ "\tremoval of label information.\n"),
+ vdev, name, vdev);
+ ret = 1;
+ goto errout;
+
+ case POOL_STATE_DESTROYED:
+ /* inuse should never be set for a destoryed pool... */
+ break;
+ }
+ }
+
+wipe_label:
+ if (zpool_clear_label(fd) != 0) {
+ (void) fprintf(stderr,
+ gettext("Label clear failed on vdev %s\n"), vdev);
+ ret = 1;
+ }
+
+errout:
+ close(fd);
+ if (name != NULL)
+ free(name);
+
+ return (ret);
+}
+
+/*
+ * zpool create [-fnd] [-o property=value] ...
+ * [-O file-system-property=value] ...
+ * [-R root] [-m mountpoint] <pool> <dev> ...
+ *
+ * -f Force creation, even if devices appear in use
+ * -n Do not create the pool, but display the resulting layout if it
+ * were to be created.
+ * -R Create a pool under an alternate root
+ * -m Set default mountpoint for the root dataset. By default it's
+ * '/<pool>'
+ * -o Set property=value.
+ * -d Don't automatically enable all supported pool features
+ * (individual features can be enabled with -o).
+ * -O Set fsproperty=value in the pool's root file system
+ *
+ * Creates the named pool according to the given vdev specification. The
+ * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
+ * we get the nvlist back from get_vdev_spec(), we either print out the contents
+ * (if '-n' was specified), or pass it to libzfs to do the creation.
+ */
+int
+zpool_do_create(int argc, char **argv)
+{
+ boolean_t force = B_FALSE;
+ boolean_t dryrun = B_FALSE;
+ boolean_t enable_all_pool_feat = B_TRUE;
+ int c;
+ nvlist_t *nvroot = NULL;
+ char *poolname;
+ int ret = 1;
+ char *altroot = NULL;
+ char *mountpoint = NULL;
+ nvlist_t *fsprops = NULL;
+ nvlist_t *props = NULL;
+ char *propval;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ case 'n':
+ dryrun = B_TRUE;
+ break;
+ case 'd':
+ enable_all_pool_feat = B_FALSE;
+ break;
+ case 'R':
+ altroot = optarg;
+ if (add_prop_list(zpool_prop_to_name(
+ ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
+ goto errout;
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
+ &propval) == 0)
+ break;
+ if (add_prop_list(zpool_prop_to_name(
+ ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
+ goto errout;
+ break;
+ case 'm':
+ mountpoint = optarg;
+ break;
+ case 'o':
+ if ((propval = strchr(optarg, '=')) == NULL) {
+ (void) fprintf(stderr, gettext("missing "
+ "'=' for -o option\n"));
+ goto errout;
+ }
+ *propval = '\0';
+ propval++;
+
+ if (add_prop_list(optarg, propval, &props, B_TRUE))
+ goto errout;
+
+ /*
+ * If the user is creating a pool that doesn't support
+ * feature flags, don't enable any features.
+ */
+ if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
+ char *end;
+ u_longlong_t ver;
+
+ ver = strtoull(propval, &end, 10);
+ if (*end == '\0' &&
+ ver < SPA_VERSION_FEATURES) {
+ enable_all_pool_feat = B_FALSE;
+ }
+ }
+ break;
+ case 'O':
+ if ((propval = strchr(optarg, '=')) == NULL) {
+ (void) fprintf(stderr, gettext("missing "
+ "'=' for -O option\n"));
+ goto errout;
+ }
+ *propval = '\0';
+ propval++;
+
+ if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
+ goto errout;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ goto badusage;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ goto badusage;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ goto badusage;
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing vdev specification\n"));
+ goto badusage;
+ }
+
+ poolname = argv[0];
+
+ /*
+ * As a special case, check for use of '/' in the name, and direct the
+ * user to use 'zfs create' instead.
+ */
+ if (strchr(poolname, '/') != NULL) {
+ (void) fprintf(stderr, gettext("cannot create '%s': invalid "
+ "character '/' in pool name\n"), poolname);
+ (void) fprintf(stderr, gettext("use 'zfs create' to "
+ "create a dataset\n"));
+ goto errout;
+ }
+
+ /* pass off to get_vdev_spec for bulk processing */
+ nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
+ argc - 1, argv + 1);
+ if (nvroot == NULL)
+ goto errout;
+
+ /* make_root_vdev() allows 0 toplevel children if there are spares */
+ if (!zfs_allocatable_devs(nvroot)) {
+ (void) fprintf(stderr, gettext("invalid vdev "
+ "specification: at least one toplevel vdev must be "
+ "specified\n"));
+ goto errout;
+ }
+
+ if (altroot != NULL && altroot[0] != '/') {
+ (void) fprintf(stderr, gettext("invalid alternate root '%s': "
+ "must be an absolute path\n"), altroot);
+ goto errout;
+ }
+
+ /*
+ * Check the validity of the mountpoint and direct the user to use the
+ * '-m' mountpoint option if it looks like its in use.
+ * Ignore the checks if the '-f' option is given.
+ */
+ if (!force && (mountpoint == NULL ||
+ (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
+ strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0))) {
+ char buf[MAXPATHLEN];
+ DIR *dirp;
+
+ if (mountpoint && mountpoint[0] != '/') {
+ (void) fprintf(stderr, gettext("invalid mountpoint "
+ "'%s': must be an absolute path, 'legacy', or "
+ "'none'\n"), mountpoint);
+ goto errout;
+ }
+
+ if (mountpoint == NULL) {
+ if (altroot != NULL)
+ (void) snprintf(buf, sizeof (buf), "%s/%s",
+ altroot, poolname);
+ else
+ (void) snprintf(buf, sizeof (buf), "/%s",
+ poolname);
+ } else {
+ if (altroot != NULL)
+ (void) snprintf(buf, sizeof (buf), "%s%s",
+ altroot, mountpoint);
+ else
+ (void) snprintf(buf, sizeof (buf), "%s",
+ mountpoint);
+ }
+
+ if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
+ (void) fprintf(stderr, gettext("mountpoint '%s' : "
+ "%s\n"), buf, strerror(errno));
+ (void) fprintf(stderr, gettext("use '-m' "
+ "option to provide a different default\n"));
+ goto errout;
+ } else if (dirp) {
+ int count = 0;
+
+ while (count < 3 && readdir(dirp) != NULL)
+ count++;
+ (void) closedir(dirp);
+
+ if (count > 2) {
+ (void) fprintf(stderr, gettext("mountpoint "
+ "'%s' exists and is not empty\n"), buf);
+ (void) fprintf(stderr, gettext("use '-m' "
+ "option to provide a "
+ "different default\n"));
+ goto errout;
+ }
+ }
+ }
+
+ if (dryrun) {
+ /*
+ * For a dry run invocation, print out a basic message and run
+ * through all the vdevs in the list and print out in an
+ * appropriate hierarchy.
+ */
+ (void) printf(gettext("would create '%s' with the "
+ "following layout:\n\n"), poolname);
+
+ print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
+ if (num_logs(nvroot) > 0)
+ print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
+
+ ret = 0;
+ } else {
+ /*
+ * Hand off to libzfs.
+ */
+ if (enable_all_pool_feat) {
+ int i;
+ for (i = 0; i < SPA_FEATURES; i++) {
+ char propname[MAXPATHLEN];
+ zfeature_info_t *feat = &spa_feature_table[i];
+
+ (void) snprintf(propname, sizeof (propname),
+ "feature@%s", feat->fi_uname);
+
+ /*
+ * Skip feature if user specified it manually
+ * on the command line.
+ */
+ if (nvlist_exists(props, propname))
+ continue;
+
+ if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
+ &props, B_TRUE) != 0)
+ goto errout;
+ }
+ }
+ if (zpool_create(g_zfs, poolname,
+ nvroot, props, fsprops) == 0) {
+ zfs_handle_t *pool = zfs_open(g_zfs, poolname,
+ ZFS_TYPE_FILESYSTEM);
+ if (pool != NULL) {
+ if (mountpoint != NULL)
+ verify(zfs_prop_set(pool,
+ zfs_prop_to_name(
+ ZFS_PROP_MOUNTPOINT),
+ mountpoint) == 0);
+ if (zfs_mount(pool, NULL, 0) == 0)
+ ret = zfs_shareall(pool);
+ zfs_close(pool);
+ }
+ } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
+ (void) fprintf(stderr, gettext("pool name may have "
+ "been omitted\n"));
+ }
+ }
+
+errout:
+ nvlist_free(nvroot);
+ nvlist_free(fsprops);
+ nvlist_free(props);
+ return (ret);
+badusage:
+ nvlist_free(fsprops);
+ nvlist_free(props);
+ usage(B_FALSE);
+ return (2);
+}
+
+/*
+ * zpool destroy <pool>
+ *
+ * -f Forcefully unmount any datasets
+ *
+ * Destroy the given pool. Automatically unmounts any datasets in the pool.
+ */
+int
+zpool_do_destroy(int argc, char **argv)
+{
+ boolean_t force = B_FALSE;
+ int c;
+ char *pool;
+ zpool_handle_t *zhp;
+ int ret;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool argument\n"));
+ usage(B_FALSE);
+ }
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ pool = argv[0];
+
+ if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
+ /*
+ * As a special case, check for use of '/' in the name, and
+ * direct the user to use 'zfs destroy' instead.
+ */
+ if (strchr(pool, '/') != NULL)
+ (void) fprintf(stderr, gettext("use 'zfs destroy' to "
+ "destroy a dataset\n"));
+ return (1);
+ }
+
+ if (zpool_disable_datasets(zhp, force) != 0) {
+ (void) fprintf(stderr, gettext("could not destroy '%s': "
+ "could not unmount datasets\n"), zpool_get_name(zhp));
+ return (1);
+ }
+
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
+ ret = (zpool_destroy(zhp, history_str) != 0);
+
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool export [-f] <pool> ...
+ *
+ * -f Forcefully unmount datasets
+ *
+ * Export the given pools. By default, the command will attempt to cleanly
+ * unmount any active datasets within the pool. If the '-f' flag is specified,
+ * then the datasets will be forcefully unmounted.
+ */
+int
+zpool_do_export(int argc, char **argv)
+{
+ boolean_t force = B_FALSE;
+ boolean_t hardforce = B_FALSE;
+ int c;
+ zpool_handle_t *zhp;
+ int ret;
+ int i;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "fF")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ case 'F':
+ hardforce = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* check arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool argument\n"));
+ usage(B_FALSE);
+ }
+
+ ret = 0;
+ for (i = 0; i < argc; i++) {
+ if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
+ ret = 1;
+ continue;
+ }
+
+ if (zpool_disable_datasets(zhp, force) != 0) {
+ ret = 1;
+ zpool_close(zhp);
+ continue;
+ }
+
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
+ if (hardforce) {
+ if (zpool_export_force(zhp, history_str) != 0)
+ ret = 1;
+ } else if (zpool_export(zhp, force, history_str) != 0) {
+ ret = 1;
+ }
+
+ zpool_close(zhp);
+ }
+
+ return (ret);
+}
+
+/*
+ * Given a vdev configuration, determine the maximum width needed for the device
+ * name column.
+ */
+static int
+max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
+{
+ char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
+ nvlist_t **child;
+ uint_t c, children;
+ int ret;
+
+ if (strlen(name) + depth > max)
+ max = strlen(name) + depth;
+
+ free(name);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if ((ret = max_width(zhp, child[c], depth + 2,
+ max)) > max)
+ max = ret;
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if ((ret = max_width(zhp, child[c], depth + 2,
+ max)) > max)
+ max = ret;
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if ((ret = max_width(zhp, child[c], depth + 2,
+ max)) > max)
+ max = ret;
+ }
+
+
+ return (max);
+}
+
+typedef struct spare_cbdata {
+ uint64_t cb_guid;
+ zpool_handle_t *cb_zhp;
+} spare_cbdata_t;
+
+static boolean_t
+find_vdev(nvlist_t *nv, uint64_t search)
+{
+ uint64_t guid;
+ nvlist_t **child;
+ uint_t c, children;
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
+ search == guid)
+ return (B_TRUE);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if (find_vdev(child[c], search))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+static int
+find_spare(zpool_handle_t *zhp, void *data)
+{
+ spare_cbdata_t *cbp = data;
+ nvlist_t *config, *nvroot;
+
+ config = zpool_get_config(zhp, NULL);
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+
+ if (find_vdev(nvroot, cbp->cb_guid)) {
+ cbp->cb_zhp = zhp;
+ return (1);
+ }
+
+ zpool_close(zhp);
+ return (0);
+}
+
+/*
+ * Print out configuration state as requested by status_callback.
+ */
+void
+print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
+ int namewidth, int depth, boolean_t isspare)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ pool_scan_stat_t *ps = NULL;
+ vdev_stat_t *vs;
+ char rbuf[6], wbuf[6], cbuf[6];
+ char *vname;
+ uint64_t notpresent;
+ spare_cbdata_t cb;
+ const char *state;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ children = 0;
+
+ verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) == 0);
+
+ state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
+ if (isspare) {
+ /*
+ * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
+ * online drives.
+ */
+ if (vs->vs_aux == VDEV_AUX_SPARED)
+ state = "INUSE";
+ else if (vs->vs_state == VDEV_STATE_HEALTHY)
+ state = "AVAIL";
+ }
+
+ (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
+ name, state);
+
+ if (!isspare) {
+ zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
+ zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
+ zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
+ (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
+ }
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
+ &notpresent) == 0 ||
+ vs->vs_state <= VDEV_STATE_CANT_OPEN) {
+ char *path;
+ if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0)
+ (void) printf(" was %s", path);
+ } else if (vs->vs_aux != 0) {
+ (void) printf(" ");
+
+ switch (vs->vs_aux) {
+ case VDEV_AUX_OPEN_FAILED:
+ (void) printf(gettext("cannot open"));
+ break;
+
+ case VDEV_AUX_BAD_GUID_SUM:
+ (void) printf(gettext("missing device"));
+ break;
+
+ case VDEV_AUX_NO_REPLICAS:
+ (void) printf(gettext("insufficient replicas"));
+ break;
+
+ case VDEV_AUX_VERSION_NEWER:
+ (void) printf(gettext("newer version"));
+ break;
+
+ case VDEV_AUX_UNSUP_FEAT:
+ (void) printf(gettext("unsupported feature(s)"));
+ break;
+
+ case VDEV_AUX_SPARED:
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
+ &cb.cb_guid) == 0);
+ if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
+ if (strcmp(zpool_get_name(cb.cb_zhp),
+ zpool_get_name(zhp)) == 0)
+ (void) printf(gettext("currently in "
+ "use"));
+ else
+ (void) printf(gettext("in use by "
+ "pool '%s'"),
+ zpool_get_name(cb.cb_zhp));
+ zpool_close(cb.cb_zhp);
+ } else {
+ (void) printf(gettext("currently in use"));
+ }
+ break;
+
+ case VDEV_AUX_ERR_EXCEEDED:
+ (void) printf(gettext("too many errors"));
+ break;
+
+ case VDEV_AUX_IO_FAILURE:
+ (void) printf(gettext("experienced I/O failures"));
+ break;
+
+ case VDEV_AUX_BAD_LOG:
+ (void) printf(gettext("bad intent log"));
+ break;
+
+ case VDEV_AUX_EXTERNAL:
+ (void) printf(gettext("external device fault"));
+ break;
+
+ case VDEV_AUX_SPLIT_POOL:
+ (void) printf(gettext("split into new pool"));
+ break;
+
+ default:
+ (void) printf(gettext("corrupted data"));
+ break;
+ }
+ }
+
+ (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
+ (uint64_t **)&ps, &c);
+
+ if (ps && ps->pss_state == DSS_SCANNING &&
+ vs->vs_scan_processed != 0 && children == 0) {
+ (void) printf(gettext(" (%s)"),
+ (ps->pss_func == POOL_SCAN_RESILVER) ?
+ "resilvering" : "repairing");
+ }
+
+ (void) printf("\n");
+
+ for (c = 0; c < children; c++) {
+ uint64_t islog = B_FALSE, ishole = B_FALSE;
+
+ /* Don't print logs or holes here */
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &islog);
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
+ &ishole);
+ if (islog || ishole)
+ continue;
+ vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
+ print_status_config(zhp, vname, child[c],
+ namewidth, depth + 2, isspare);
+ free(vname);
+ }
+}
+
+
+/*
+ * Print the configuration of an exported pool. Iterate over all vdevs in the
+ * pool, printing out the name and status for each one.
+ */
+void
+print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ vdev_stat_t *vs;
+ char *type, *vname;
+
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
+ if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
+ strcmp(type, VDEV_TYPE_HOLE) == 0)
+ return;
+
+ verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) == 0);
+
+ (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
+ (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
+
+ if (vs->vs_aux != 0) {
+ (void) printf(" ");
+
+ switch (vs->vs_aux) {
+ case VDEV_AUX_OPEN_FAILED:
+ (void) printf(gettext("cannot open"));
+ break;
+
+ case VDEV_AUX_BAD_GUID_SUM:
+ (void) printf(gettext("missing device"));
+ break;
+
+ case VDEV_AUX_NO_REPLICAS:
+ (void) printf(gettext("insufficient replicas"));
+ break;
+
+ case VDEV_AUX_VERSION_NEWER:
+ (void) printf(gettext("newer version"));
+ break;
+
+ case VDEV_AUX_UNSUP_FEAT:
+ (void) printf(gettext("unsupported feature(s)"));
+ break;
+
+ case VDEV_AUX_ERR_EXCEEDED:
+ (void) printf(gettext("too many errors"));
+ break;
+
+ default:
+ (void) printf(gettext("corrupted data"));
+ break;
+ }
+ }
+ (void) printf("\n");
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ uint64_t is_log = B_FALSE;
+
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+ if (is_log)
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
+ print_import_config(vname, child[c], namewidth, depth + 2);
+ free(vname);
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0) {
+ (void) printf(gettext("\tcache\n"));
+ for (c = 0; c < children; c++) {
+ vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
+ (void) printf("\t %s\n", vname);
+ free(vname);
+ }
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0) {
+ (void) printf(gettext("\tspares\n"));
+ for (c = 0; c < children; c++) {
+ vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
+ (void) printf("\t %s\n", vname);
+ free(vname);
+ }
+ }
+}
+
+/*
+ * Print log vdevs.
+ * Logs are recorded as top level vdevs in the main pool child array
+ * but with "is_log" set to 1. We use either print_status_config() or
+ * print_import_config() to print the top level logs then any log
+ * children (eg mirrored slogs) are printed recursively - which
+ * works because only the top level vdev is marked "is_log"
+ */
+static void
+print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
+{
+ uint_t c, children;
+ nvlist_t **child;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
+ &children) != 0)
+ return;
+
+ (void) printf(gettext("\tlogs\n"));
+
+ for (c = 0; c < children; c++) {
+ uint64_t is_log = B_FALSE;
+ char *name;
+
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+ if (!is_log)
+ continue;
+ name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
+ if (verbose)
+ print_status_config(zhp, name, child[c], namewidth,
+ 2, B_FALSE);
+ else
+ print_import_config(name, child[c], namewidth, 2);
+ free(name);
+ }
+}
+
+/*
+ * Display the status for the given pool.
+ */
+static void
+show_import(nvlist_t *config)
+{
+ uint64_t pool_state;
+ vdev_stat_t *vs;
+ char *name;
+ uint64_t guid;
+ char *msgid;
+ nvlist_t *nvroot;
+ int reason;
+ const char *health;
+ uint_t vsc;
+ int namewidth;
+ char *comment;
+
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &guid) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &pool_state) == 0);
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+
+ verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &vsc) == 0);
+ health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
+
+ reason = zpool_import_status(config, &msgid);
+
+ (void) printf(gettext(" pool: %s\n"), name);
+ (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
+ (void) printf(gettext(" state: %s"), health);
+ if (pool_state == POOL_STATE_DESTROYED)
+ (void) printf(gettext(" (DESTROYED)"));
+ (void) printf("\n");
+
+ switch (reason) {
+ case ZPOOL_STATUS_MISSING_DEV_R:
+ case ZPOOL_STATUS_MISSING_DEV_NR:
+ case ZPOOL_STATUS_BAD_GUID_SUM:
+ (void) printf(gettext(" status: One or more devices are "
+ "missing from the system.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_LABEL_R:
+ case ZPOOL_STATUS_CORRUPT_LABEL_NR:
+ (void) printf(gettext(" status: One or more devices contains "
+ "corrupted data.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_DATA:
+ (void) printf(
+ gettext(" status: The pool data is corrupted.\n"));
+ break;
+
+ case ZPOOL_STATUS_OFFLINE_DEV:
+ (void) printf(gettext(" status: One or more devices "
+ "are offlined.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_POOL:
+ (void) printf(gettext(" status: The pool metadata is "
+ "corrupted.\n"));
+ break;
+
+ case ZPOOL_STATUS_VERSION_OLDER:
+ (void) printf(gettext(" status: The pool is formatted using a "
+ "legacy on-disk version.\n"));
+ break;
+
+ case ZPOOL_STATUS_VERSION_NEWER:
+ (void) printf(gettext(" status: The pool is formatted using an "
+ "incompatible version.\n"));
+ break;
+
+ case ZPOOL_STATUS_FEAT_DISABLED:
+ (void) printf(gettext(" status: Some supported features are "
+ "not enabled on the pool.\n"));
+ break;
+
+ case ZPOOL_STATUS_UNSUP_FEAT_READ:
+ (void) printf(gettext("status: The pool uses the following "
+ "feature(s) not supported on this sytem:\n"));
+ zpool_print_unsup_feat(config);
+ break;
+
+ case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
+ (void) printf(gettext("status: The pool can only be accessed "
+ "in read-only mode on this system. It\n\tcannot be "
+ "accessed in read-write mode because it uses the "
+ "following\n\tfeature(s) not supported on this system:\n"));
+ zpool_print_unsup_feat(config);
+ break;
+
+ case ZPOOL_STATUS_HOSTID_MISMATCH:
+ (void) printf(gettext(" status: The pool was last accessed by "
+ "another system.\n"));
+ break;
+
+ case ZPOOL_STATUS_FAULTED_DEV_R:
+ case ZPOOL_STATUS_FAULTED_DEV_NR:
+ (void) printf(gettext(" status: One or more devices are "
+ "faulted.\n"));
+ break;
+
+ case ZPOOL_STATUS_BAD_LOG:
+ (void) printf(gettext(" status: An intent log record cannot be "
+ "read.\n"));
+ break;
+
+ case ZPOOL_STATUS_RESILVERING:
+ (void) printf(gettext(" status: One or more devices were being "
+ "resilvered.\n"));
+ break;
+
+ default:
+ /*
+ * No other status can be seen when importing pools.
+ */
+ assert(reason == ZPOOL_STATUS_OK);
+ }
+
+ /*
+ * Print out an action according to the overall state of the pool.
+ */
+ if (vs->vs_state == VDEV_STATE_HEALTHY) {
+ if (reason == ZPOOL_STATUS_VERSION_OLDER ||
+ reason == ZPOOL_STATUS_FEAT_DISABLED) {
+ (void) printf(gettext(" action: The pool can be "
+ "imported using its name or numeric identifier, "
+ "though\n\tsome features will not be available "
+ "without an explicit 'zpool upgrade'.\n"));
+ } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
+ (void) printf(gettext(" action: The pool can be "
+ "imported using its name or numeric "
+ "identifier and\n\tthe '-f' flag.\n"));
+ } else {
+ (void) printf(gettext(" action: The pool can be "
+ "imported using its name or numeric "
+ "identifier.\n"));
+ }
+ } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
+ (void) printf(gettext(" action: The pool can be imported "
+ "despite missing or damaged devices. The\n\tfault "
+ "tolerance of the pool may be compromised if imported.\n"));
+ } else {
+ switch (reason) {
+ case ZPOOL_STATUS_VERSION_NEWER:
+ (void) printf(gettext(" action: The pool cannot be "
+ "imported. Access the pool on a system running "
+ "newer\n\tsoftware, or recreate the pool from "
+ "backup.\n"));
+ break;
+ case ZPOOL_STATUS_UNSUP_FEAT_READ:
+ (void) printf(gettext("action: The pool cannot be "
+ "imported. Access the pool on a system that "
+ "supports\n\tthe required feature(s), or recreate "
+ "the pool from backup.\n"));
+ break;
+ case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
+ (void) printf(gettext("action: The pool cannot be "
+ "imported in read-write mode. Import the pool "
+ "with\n"
+ "\t\"-o readonly=on\", access the pool on a system "
+ "that supports the\n\trequired feature(s), or "
+ "recreate the pool from backup.\n"));
+ break;
+ case ZPOOL_STATUS_MISSING_DEV_R:
+ case ZPOOL_STATUS_MISSING_DEV_NR:
+ case ZPOOL_STATUS_BAD_GUID_SUM:
+ (void) printf(gettext(" action: The pool cannot be "
+ "imported. Attach the missing\n\tdevices and try "
+ "again.\n"));
+ break;
+ default:
+ (void) printf(gettext(" action: The pool cannot be "
+ "imported due to damaged devices or data.\n"));
+ }
+ }
+
+ /* Print the comment attached to the pool. */
+ if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
+ (void) printf(gettext("comment: %s\n"), comment);
+
+ /*
+ * If the state is "closed" or "can't open", and the aux state
+ * is "corrupt data":
+ */
+ if (((vs->vs_state == VDEV_STATE_CLOSED) ||
+ (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
+ (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
+ if (pool_state == POOL_STATE_DESTROYED)
+ (void) printf(gettext("\tThe pool was destroyed, "
+ "but can be imported using the '-Df' flags.\n"));
+ else if (pool_state != POOL_STATE_EXPORTED)
+ (void) printf(gettext("\tThe pool may be active on "
+ "another system, but can be imported using\n\t"
+ "the '-f' flag.\n"));
+ }
+
+ if (msgid != NULL)
+ (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
+ msgid);
+
+ (void) printf(gettext(" config:\n\n"));
+
+ namewidth = max_width(NULL, nvroot, 0, 0);
+ if (namewidth < 10)
+ namewidth = 10;
+
+ print_import_config(name, nvroot, namewidth, 0);
+ if (num_logs(nvroot) > 0)
+ print_logs(NULL, nvroot, namewidth, B_FALSE);
+
+ if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
+ (void) printf(gettext("\n\tAdditional devices are known to "
+ "be part of this pool, though their\n\texact "
+ "configuration cannot be determined.\n"));
+ }
+}
+
+/*
+ * Perform the import for the given configuration. This passes the heavy
+ * lifting off to zpool_import_props(), and then mounts the datasets contained
+ * within the pool.
+ */
+static int
+do_import(nvlist_t *config, const char *newname, const char *mntopts,
+ nvlist_t *props, int flags)
+{
+ zpool_handle_t *zhp;
+ char *name;
+ uint64_t state;
+ uint64_t version;
+
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_STATE, &state) == 0);
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_VERSION, &version) == 0);
+ if (!SPA_VERSION_IS_SUPPORTED(version)) {
+ (void) fprintf(stderr, gettext("cannot import '%s': pool "
+ "is formatted using an unsupported ZFS version\n"), name);
+ return (1);
+ } else if (state != POOL_STATE_EXPORTED &&
+ !(flags & ZFS_IMPORT_ANY_HOST)) {
+ uint64_t hostid;
+
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
+ &hostid) == 0) {
+ if ((unsigned long)hostid != gethostid()) {
+ char *hostname;
+ uint64_t timestamp;
+ time_t t;
+
+ verify(nvlist_lookup_string(config,
+ ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
+ t = timestamp;
+ (void) fprintf(stderr, gettext("cannot import "
+ "'%s': pool may be in use from other "
+ "system, it was last accessed by %s "
+ "(hostid: 0x%lx) on %s"), name, hostname,
+ (unsigned long)hostid,
+ asctime(localtime(&t)));
+ (void) fprintf(stderr, gettext("use '-f' to "
+ "import anyway\n"));
+ return (1);
+ }
+ } else {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "pool may be in use from other system\n"), name);
+ (void) fprintf(stderr, gettext("use '-f' to import "
+ "anyway\n"));
+ return (1);
+ }
+ }
+
+ if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
+ return (1);
+
+ if (newname != NULL)
+ name = (char *)newname;
+
+ if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
+ return (1);
+
+ if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
+ !(flags & ZFS_IMPORT_ONLY) &&
+ zpool_enable_datasets(zhp, mntopts, 0) != 0) {
+ zpool_close(zhp);
+ return (1);
+ }
+
+ zpool_close(zhp);
+ return (0);
+}
+
+/*
+ * zpool import [-d dir] [-D]
+ * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
+ * [-d dir | -c cachefile] [-f] -a
+ * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
+ * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
+ *
+ * -c Read pool information from a cachefile instead of searching
+ * devices.
+ *
+ * -d Scan in a specific directory, other than /dev/dsk. More than
+ * one directory can be specified using multiple '-d' options.
+ *
+ * -D Scan for previously destroyed pools or import all or only
+ * specified destroyed pools.
+ *
+ * -R Temporarily import the pool, with all mountpoints relative to
+ * the given root. The pool will remain exported when the machine
+ * is rebooted.
+ *
+ * -V Import even in the presence of faulted vdevs. This is an
+ * intentionally undocumented option for testing purposes, and
+ * treats the pool configuration as complete, leaving any bad
+ * vdevs in the FAULTED state. In other words, it does verbatim
+ * import.
+ *
+ * -f Force import, even if it appears that the pool is active.
+ *
+ * -F Attempt rewind if necessary.
+ *
+ * -n See if rewind would work, but don't actually rewind.
+ *
+ * -N Import the pool but don't mount datasets.
+ *
+ * -T Specify a starting txg to use for import. This option is
+ * intentionally undocumented option for testing purposes.
+ *
+ * -a Import all pools found.
+ *
+ * -o Set property=value and/or temporary mount options (without '=').
+ *
+ * The import command scans for pools to import, and import pools based on pool
+ * name and GUID. The pool can also be renamed as part of the import process.
+ */
+int
+zpool_do_import(int argc, char **argv)
+{
+ char **searchdirs = NULL;
+ int nsearch = 0;
+ int c;
+ int err = 0;
+ nvlist_t *pools = NULL;
+ boolean_t do_all = B_FALSE;
+ boolean_t do_destroyed = B_FALSE;
+ char *mntopts = NULL;
+ nvpair_t *elem;
+ nvlist_t *config;
+ uint64_t searchguid = 0;
+ char *searchname = NULL;
+ char *propval;
+ nvlist_t *found_config;
+ nvlist_t *policy = NULL;
+ nvlist_t *props = NULL;
+ boolean_t first;
+ int flags = ZFS_IMPORT_NORMAL;
+ uint32_t rewind_policy = ZPOOL_NO_REWIND;
+ boolean_t dryrun = B_FALSE;
+ boolean_t do_rewind = B_FALSE;
+ boolean_t xtreme_rewind = B_FALSE;
+ uint64_t pool_state, txg = -1ULL;
+ char *cachefile = NULL;
+ importargs_t idata = { 0 };
+ char *endptr;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
+ switch (c) {
+ case 'a':
+ do_all = B_TRUE;
+ break;
+ case 'c':
+ cachefile = optarg;
+ break;
+ case 'd':
+ if (searchdirs == NULL) {
+ searchdirs = safe_malloc(sizeof (char *));
+ } else {
+ char **tmp = safe_malloc((nsearch + 1) *
+ sizeof (char *));
+ bcopy(searchdirs, tmp, nsearch *
+ sizeof (char *));
+ free(searchdirs);
+ searchdirs = tmp;
+ }
+ searchdirs[nsearch++] = optarg;
+ break;
+ case 'D':
+ do_destroyed = B_TRUE;
+ break;
+ case 'f':
+ flags |= ZFS_IMPORT_ANY_HOST;
+ break;
+ case 'F':
+ do_rewind = B_TRUE;
+ break;
+ case 'm':
+ flags |= ZFS_IMPORT_MISSING_LOG;
+ break;
+ case 'n':
+ dryrun = B_TRUE;
+ break;
+ case 'N':
+ flags |= ZFS_IMPORT_ONLY;
+ break;
+ case 'o':
+ if ((propval = strchr(optarg, '=')) != NULL) {
+ *propval = '\0';
+ propval++;
+ if (add_prop_list(optarg, propval,
+ &props, B_TRUE))
+ goto error;
+ } else {
+ mntopts = optarg;
+ }
+ break;
+ case 'R':
+ if (add_prop_list(zpool_prop_to_name(
+ ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
+ goto error;
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
+ &propval) == 0)
+ break;
+ if (add_prop_list(zpool_prop_to_name(
+ ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
+ goto error;
+ break;
+ case 'T':
+ errno = 0;
+ txg = strtoull(optarg, &endptr, 10);
+ if (errno != 0 || *endptr != '\0') {
+ (void) fprintf(stderr,
+ gettext("invalid txg value\n"));
+ usage(B_FALSE);
+ }
+ rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
+ break;
+ case 'V':
+ flags |= ZFS_IMPORT_VERBATIM;
+ break;
+ case 'X':
+ xtreme_rewind = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (cachefile && nsearch != 0) {
+ (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
+ usage(B_FALSE);
+ }
+
+ if ((dryrun || xtreme_rewind) && !do_rewind) {
+ (void) fprintf(stderr,
+ gettext("-n or -X only meaningful with -F\n"));
+ usage(B_FALSE);
+ }
+ if (dryrun)
+ rewind_policy = ZPOOL_TRY_REWIND;
+ else if (do_rewind)
+ rewind_policy = ZPOOL_DO_REWIND;
+ if (xtreme_rewind)
+ rewind_policy |= ZPOOL_EXTREME_REWIND;
+
+ /* In the future, we can capture further policy and include it here */
+ if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
+ nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
+ nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
+ goto error;
+
+ if (searchdirs == NULL) {
+ searchdirs = safe_malloc(sizeof (char *));
+ searchdirs[0] = "/dev";
+ nsearch = 1;
+ }
+
+ /* check argument count */
+ if (do_all) {
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+ } else {
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ /*
+ * Check for the SYS_CONFIG privilege. We do this explicitly
+ * here because otherwise any attempt to discover pools will
+ * silently fail.
+ */
+ if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
+ (void) fprintf(stderr, gettext("cannot "
+ "discover pools: permission denied\n"));
+ free(searchdirs);
+ nvlist_free(policy);
+ return (1);
+ }
+ }
+
+ /*
+ * Depending on the arguments given, we do one of the following:
+ *
+ * <none> Iterate through all pools and display information about
+ * each one.
+ *
+ * -a Iterate through all pools and try to import each one.
+ *
+ * <id> Find the pool that corresponds to the given GUID/pool
+ * name and import that one.
+ *
+ * -D Above options applies only to destroyed pools.
+ */
+ if (argc != 0) {
+ char *endptr;
+
+ errno = 0;
+ searchguid = strtoull(argv[0], &endptr, 10);
+ if (errno != 0 || *endptr != '\0')
+ searchname = argv[0];
+ found_config = NULL;
+
+ /*
+ * User specified a name or guid. Ensure it's unique.
+ */
+ idata.unique = B_TRUE;
+ }
+
+
+ idata.path = searchdirs;
+ idata.paths = nsearch;
+ idata.poolname = searchname;
+ idata.guid = searchguid;
+ idata.cachefile = cachefile;
+
+ pools = zpool_search_import(g_zfs, &idata);
+
+ if (pools != NULL && idata.exists &&
+ (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "a pool with that name already exists\n"),
+ argv[0]);
+ (void) fprintf(stderr, gettext("use the form '%s "
+ "<pool | id> <newpool>' to give it a new name\n"),
+ "zpool import");
+ err = 1;
+ } else if (pools == NULL && idata.exists) {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "a pool with that name is already created/imported,\n"),
+ argv[0]);
+ (void) fprintf(stderr, gettext("and no additional pools "
+ "with that name were found\n"));
+ err = 1;
+ } else if (pools == NULL) {
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "no such pool available\n"), argv[0]);
+ }
+ err = 1;
+ }
+
+ if (err == 1) {
+ free(searchdirs);
+ nvlist_free(policy);
+ return (1);
+ }
+
+ /*
+ * At this point we have a list of import candidate configs. Even if
+ * we were searching by pool name or guid, we still need to
+ * post-process the list to deal with pool state and possible
+ * duplicate names.
+ */
+ err = 0;
+ elem = NULL;
+ first = B_TRUE;
+ while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
+
+ verify(nvpair_value_nvlist(elem, &config) == 0);
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &pool_state) == 0);
+ if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
+ continue;
+ if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
+ continue;
+
+ verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
+ policy) == 0);
+
+ if (argc == 0) {
+ if (first)
+ first = B_FALSE;
+ else if (!do_all)
+ (void) printf("\n");
+
+ if (do_all) {
+ err |= do_import(config, NULL, mntopts,
+ props, flags);
+ } else {
+ show_import(config);
+ }
+ } else if (searchname != NULL) {
+ char *name;
+
+ /*
+ * We are searching for a pool based on name.
+ */
+ verify(nvlist_lookup_string(config,
+ ZPOOL_CONFIG_POOL_NAME, &name) == 0);
+
+ if (strcmp(name, searchname) == 0) {
+ if (found_config != NULL) {
+ (void) fprintf(stderr, gettext(
+ "cannot import '%s': more than "
+ "one matching pool\n"), searchname);
+ (void) fprintf(stderr, gettext(
+ "import by numeric ID instead\n"));
+ err = B_TRUE;
+ }
+ found_config = config;
+ }
+ } else {
+ uint64_t guid;
+
+ /*
+ * Search for a pool by guid.
+ */
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
+
+ if (guid == searchguid)
+ found_config = config;
+ }
+ }
+
+ /*
+ * If we were searching for a specific pool, verify that we found a
+ * pool, and then do the import.
+ */
+ if (argc != 0 && err == 0) {
+ if (found_config == NULL) {
+ (void) fprintf(stderr, gettext("cannot import '%s': "
+ "no such pool available\n"), argv[0]);
+ err = B_TRUE;
+ } else {
+ err |= do_import(found_config, argc == 1 ? NULL :
+ argv[1], mntopts, props, flags);
+ }
+ }
+
+ /*
+ * If we were just looking for pools, report an error if none were
+ * found.
+ */
+ if (argc == 0 && first)
+ (void) fprintf(stderr,
+ gettext("no pools available to import\n"));
+
+error:
+ nvlist_free(props);
+ nvlist_free(pools);
+ nvlist_free(policy);
+ free(searchdirs);
+
+ return (err ? 1 : 0);
+}
+
+typedef struct iostat_cbdata {
+ boolean_t cb_verbose;
+ int cb_namewidth;
+ int cb_iteration;
+ zpool_list_t *cb_list;
+} iostat_cbdata_t;
+
+static void
+print_iostat_separator(iostat_cbdata_t *cb)
+{
+ int i = 0;
+
+ for (i = 0; i < cb->cb_namewidth; i++)
+ (void) printf("-");
+ (void) printf(" ----- ----- ----- ----- ----- -----\n");
+}
+
+static void
+print_iostat_header(iostat_cbdata_t *cb)
+{
+ (void) printf("%*s capacity operations bandwidth\n",
+ cb->cb_namewidth, "");
+ (void) printf("%-*s alloc free read write read write\n",
+ cb->cb_namewidth, "pool");
+ print_iostat_separator(cb);
+}
+
+/*
+ * Display a single statistic.
+ */
+static void
+print_one_stat(uint64_t value)
+{
+ char buf[64];
+
+ zfs_nicenum(value, buf, sizeof (buf));
+ (void) printf(" %5s", buf);
+}
+
+/*
+ * Print out all the statistics for the given vdev. This can either be the
+ * toplevel configuration, or called recursively. If 'name' is NULL, then this
+ * is a verbose output, and we don't want to display the toplevel pool stats.
+ */
+void
+print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
+ nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
+{
+ nvlist_t **oldchild, **newchild;
+ uint_t c, children;
+ vdev_stat_t *oldvs, *newvs;
+ vdev_stat_t zerovs = { 0 };
+ uint64_t tdelta;
+ double scale;
+ char *vname;
+
+ if (oldnv != NULL) {
+ verify(nvlist_lookup_uint64_array(oldnv,
+ ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
+ } else {
+ oldvs = &zerovs;
+ }
+
+ verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&newvs, &c) == 0);
+
+ if (strlen(name) + depth > cb->cb_namewidth)
+ (void) printf("%*s%s", depth, "", name);
+ else
+ (void) printf("%*s%s%*s", depth, "", name,
+ (int)(cb->cb_namewidth - strlen(name) - depth), "");
+
+ tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
+
+ if (tdelta == 0)
+ scale = 1.0;
+ else
+ scale = (double)NANOSEC / tdelta;
+
+ /* only toplevel vdevs have capacity stats */
+ if (newvs->vs_space == 0) {
+ (void) printf(" - -");
+ } else {
+ print_one_stat(newvs->vs_alloc);
+ print_one_stat(newvs->vs_space - newvs->vs_alloc);
+ }
+
+ print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
+ oldvs->vs_ops[ZIO_TYPE_READ])));
+
+ print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
+ oldvs->vs_ops[ZIO_TYPE_WRITE])));
+
+ print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
+ oldvs->vs_bytes[ZIO_TYPE_READ])));
+
+ print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
+ oldvs->vs_bytes[ZIO_TYPE_WRITE])));
+
+ (void) printf("\n");
+
+ if (!cb->cb_verbose)
+ return;
+
+ if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
+ &newchild, &children) != 0)
+ return;
+
+ if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
+ &oldchild, &c) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ uint64_t ishole = B_FALSE, islog = B_FALSE;
+
+ (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
+ &ishole);
+
+ (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
+ &islog);
+
+ if (ishole || islog)
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
+ print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
+ newchild[c], cb, depth + 2);
+ free(vname);
+ }
+
+ /*
+ * Log device section
+ */
+
+ if (num_logs(newnv) > 0) {
+ (void) printf("%-*s - - - - - "
+ "-\n", cb->cb_namewidth, "logs");
+
+ for (c = 0; c < children; c++) {
+ uint64_t islog = B_FALSE;
+ (void) nvlist_lookup_uint64(newchild[c],
+ ZPOOL_CONFIG_IS_LOG, &islog);
+
+ if (islog) {
+ vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
+ B_FALSE);
+ print_vdev_stats(zhp, vname, oldnv ?
+ oldchild[c] : NULL, newchild[c],
+ cb, depth + 2);
+ free(vname);
+ }
+ }
+
+ }
+
+ /*
+ * Include level 2 ARC devices in iostat output
+ */
+ if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
+ &newchild, &children) != 0)
+ return;
+
+ if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
+ &oldchild, &c) != 0)
+ return;
+
+ if (children > 0) {
+ (void) printf("%-*s - - - - - "
+ "-\n", cb->cb_namewidth, "cache");
+ for (c = 0; c < children; c++) {
+ vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
+ B_FALSE);
+ print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
+ newchild[c], cb, depth + 2);
+ free(vname);
+ }
+ }
+}
+
+static int
+refresh_iostat(zpool_handle_t *zhp, void *data)
+{
+ iostat_cbdata_t *cb = data;
+ boolean_t missing;
+
+ /*
+ * If the pool has disappeared, remove it from the list and continue.
+ */
+ if (zpool_refresh_stats(zhp, &missing) != 0)
+ return (-1);
+
+ if (missing)
+ pool_list_remove(cb->cb_list, zhp);
+
+ return (0);
+}
+
+/*
+ * Callback to print out the iostats for the given pool.
+ */
+int
+print_iostat(zpool_handle_t *zhp, void *data)
+{
+ iostat_cbdata_t *cb = data;
+ nvlist_t *oldconfig, *newconfig;
+ nvlist_t *oldnvroot, *newnvroot;
+
+ newconfig = zpool_get_config(zhp, &oldconfig);
+
+ if (cb->cb_iteration == 1)
+ oldconfig = NULL;
+
+ verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
+ &newnvroot) == 0);
+
+ if (oldconfig == NULL)
+ oldnvroot = NULL;
+ else
+ verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
+ &oldnvroot) == 0);
+
+ /*
+ * Print out the statistics for the pool.
+ */
+ print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
+
+ if (cb->cb_verbose)
+ print_iostat_separator(cb);
+
+ return (0);
+}
+
+int
+get_namewidth(zpool_handle_t *zhp, void *data)
+{
+ iostat_cbdata_t *cb = data;
+ nvlist_t *config, *nvroot;
+
+ if ((config = zpool_get_config(zhp, NULL)) != NULL) {
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ if (!cb->cb_verbose)
+ cb->cb_namewidth = strlen(zpool_get_name(zhp));
+ else
+ cb->cb_namewidth = max_width(zhp, nvroot, 0,
+ cb->cb_namewidth);
+ }
+
+ /*
+ * The width must fall into the range [10,38]. The upper limit is the
+ * maximum we can have and still fit in 80 columns.
+ */
+ if (cb->cb_namewidth < 10)
+ cb->cb_namewidth = 10;
+ if (cb->cb_namewidth > 38)
+ cb->cb_namewidth = 38;
+
+ return (0);
+}
+
+/*
+ * Parse the input string, get the 'interval' and 'count' value if there is one.
+ */
+static void
+get_interval_count(int *argcp, char **argv, unsigned long *iv,
+ unsigned long *cnt)
+{
+ unsigned long interval = 0, count = 0;
+ int argc = *argcp, errno;
+
+ /*
+ * Determine if the last argument is an integer or a pool name
+ */
+ if (argc > 0 && isdigit(argv[argc - 1][0])) {
+ char *end;
+
+ errno = 0;
+ interval = strtoul(argv[argc - 1], &end, 10);
+
+ if (*end == '\0' && errno == 0) {
+ if (interval == 0) {
+ (void) fprintf(stderr, gettext("interval "
+ "cannot be zero\n"));
+ usage(B_FALSE);
+ }
+ /*
+ * Ignore the last parameter
+ */
+ argc--;
+ } else {
+ /*
+ * If this is not a valid number, just plow on. The
+ * user will get a more informative error message later
+ * on.
+ */
+ interval = 0;
+ }
+ }
+
+ /*
+ * If the last argument is also an integer, then we have both a count
+ * and an interval.
+ */
+ if (argc > 0 && isdigit(argv[argc - 1][0])) {
+ char *end;
+
+ errno = 0;
+ count = interval;
+ interval = strtoul(argv[argc - 1], &end, 10);
+
+ if (*end == '\0' && errno == 0) {
+ if (interval == 0) {
+ (void) fprintf(stderr, gettext("interval "
+ "cannot be zero\n"));
+ usage(B_FALSE);
+ }
+
+ /*
+ * Ignore the last parameter
+ */
+ argc--;
+ } else {
+ interval = 0;
+ }
+ }
+
+ *iv = interval;
+ *cnt = count;
+ *argcp = argc;
+}
+
+static void
+get_timestamp_arg(char c)
+{
+ if (c == 'u')
+ timestamp_fmt = UDATE;
+ else if (c == 'd')
+ timestamp_fmt = DDATE;
+ else
+ usage(B_FALSE);
+}
+
+/*
+ * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
+ *
+ * -v Display statistics for individual vdevs
+ * -T Display a timestamp in date(1) or Unix format
+ *
+ * This command can be tricky because we want to be able to deal with pool
+ * creation/destruction as well as vdev configuration changes. The bulk of this
+ * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
+ * on pool_list_update() to detect the addition of new pools. Configuration
+ * changes are all handled within libzfs.
+ */
+int
+zpool_do_iostat(int argc, char **argv)
+{
+ int c;
+ int ret;
+ int npools;
+ unsigned long interval = 0, count = 0;
+ zpool_list_t *list;
+ boolean_t verbose = B_FALSE;
+ iostat_cbdata_t cb;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "T:v")) != -1) {
+ switch (c) {
+ case 'T':
+ get_timestamp_arg(*optarg);
+ break;
+ case 'v':
+ verbose = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ get_interval_count(&argc, argv, &interval, &count);
+
+ /*
+ * Construct the list of all interesting pools.
+ */
+ ret = 0;
+ if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
+ return (1);
+
+ if (pool_list_count(list) == 0 && argc != 0) {
+ pool_list_free(list);
+ return (1);
+ }
+
+ if (pool_list_count(list) == 0 && interval == 0) {
+ pool_list_free(list);
+ (void) fprintf(stderr, gettext("no pools available\n"));
+ return (1);
+ }
+
+ /*
+ * Enter the main iostat loop.
+ */
+ cb.cb_list = list;
+ cb.cb_verbose = verbose;
+ cb.cb_iteration = 0;
+ cb.cb_namewidth = 0;
+
+ for (;;) {
+ pool_list_update(list);
+
+ if ((npools = pool_list_count(list)) == 0)
+ break;
+
+ /*
+ * Refresh all statistics. This is done as an explicit step
+ * before calculating the maximum name width, so that any
+ * configuration changes are properly accounted for.
+ */
+ (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
+
+ /*
+ * Iterate over all pools to determine the maximum width
+ * for the pool / device name column across all pools.
+ */
+ cb.cb_namewidth = 0;
+ (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
+
+ if (timestamp_fmt != NODATE)
+ print_timestamp(timestamp_fmt);
+
+ /*
+ * If it's the first time, or verbose mode, print the header.
+ */
+ if (++cb.cb_iteration == 1 || verbose)
+ print_iostat_header(&cb);
+
+ (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
+
+ /*
+ * If there's more than one pool, and we're not in verbose mode
+ * (which prints a separator for us), then print a separator.
+ */
+ if (npools > 1 && !verbose)
+ print_iostat_separator(&cb);
+
+ if (verbose)
+ (void) printf("\n");
+
+ /*
+ * Flush the output so that redirection to a file isn't buffered
+ * indefinitely.
+ */
+ (void) fflush(stdout);
+
+ if (interval == 0)
+ break;
+
+ if (count != 0 && --count == 0)
+ break;
+
+ (void) sleep(interval);
+ }
+
+ pool_list_free(list);
+
+ return (ret);
+}
+
+typedef struct list_cbdata {
+ boolean_t cb_verbose;
+ int cb_namewidth;
+ boolean_t cb_scripted;
+ zprop_list_t *cb_proplist;
+} list_cbdata_t;
+
+/*
+ * Given a list of columns to display, output appropriate headers for each one.
+ */
+static void
+print_header(list_cbdata_t *cb)
+{
+ zprop_list_t *pl = cb->cb_proplist;
+ char headerbuf[ZPOOL_MAXPROPLEN];
+ const char *header;
+ boolean_t first = B_TRUE;
+ boolean_t right_justify;
+ size_t width = 0;
+
+ for (; pl != NULL; pl = pl->pl_next) {
+ width = pl->pl_width;
+ if (first && cb->cb_verbose) {
+ /*
+ * Reset the width to accommodate the verbose listing
+ * of devices.
+ */
+ width = cb->cb_namewidth;
+ }
+
+ if (!first)
+ (void) printf(" ");
+ else
+ first = B_FALSE;
+
+ right_justify = B_FALSE;
+ if (pl->pl_prop != ZPROP_INVAL) {
+ header = zpool_prop_column_name(pl->pl_prop);
+ right_justify = zpool_prop_align_right(pl->pl_prop);
+ } else {
+ int i;
+
+ for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
+ headerbuf[i] = toupper(pl->pl_user_prop[i]);
+ headerbuf[i] = '\0';
+ header = headerbuf;
+ }
+
+ if (pl->pl_next == NULL && !right_justify)
+ (void) printf("%s", header);
+ else if (right_justify)
+ (void) printf("%*s", width, header);
+ else
+ (void) printf("%-*s", width, header);
+
+ }
+
+ (void) printf("\n");
+}
+
+/*
+ * Given a pool and a list of properties, print out all the properties according
+ * to the described layout.
+ */
+static void
+print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
+{
+ zprop_list_t *pl = cb->cb_proplist;
+ boolean_t first = B_TRUE;
+ char property[ZPOOL_MAXPROPLEN];
+ char *propstr;
+ boolean_t right_justify;
+ size_t width;
+
+ for (; pl != NULL; pl = pl->pl_next) {
+
+ width = pl->pl_width;
+ if (first && cb->cb_verbose) {
+ /*
+ * Reset the width to accommodate the verbose listing
+ * of devices.
+ */
+ width = cb->cb_namewidth;
+ }
+
+ if (!first) {
+ if (cb->cb_scripted)
+ (void) printf("\t");
+ else
+ (void) printf(" ");
+ } else {
+ first = B_FALSE;
+ }
+
+ right_justify = B_FALSE;
+ if (pl->pl_prop != ZPROP_INVAL) {
+ if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
+ zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
+ propstr = "-";
+ else if (zpool_get_prop(zhp, pl->pl_prop, property,
+ sizeof (property), NULL) != 0)
+ propstr = "-";
+ else
+ propstr = property;
+
+ right_justify = zpool_prop_align_right(pl->pl_prop);
+ } else if ((zpool_prop_feature(pl->pl_user_prop) ||
+ zpool_prop_unsupported(pl->pl_user_prop)) &&
+ zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
+ sizeof (property)) == 0) {
+ propstr = property;
+ } else {
+ propstr = "-";
+ }
+
+
+ /*
+ * If this is being called in scripted mode, or if this is the
+ * last column and it is left-justified, don't include a width
+ * format specifier.
+ */
+ if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
+ (void) printf("%s", propstr);
+ else if (right_justify)
+ (void) printf("%*s", width, propstr);
+ else
+ (void) printf("%-*s", width, propstr);
+ }
+
+ (void) printf("\n");
+}
+
+static void
+print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted)
+{
+ char propval[64];
+ boolean_t fixed;
+ size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
+
+ zfs_nicenum(value, propval, sizeof (propval));
+
+ if (prop == ZPOOL_PROP_EXPANDSZ && value == 0)
+ (void) strlcpy(propval, "-", sizeof (propval));
+
+ if (scripted)
+ (void) printf("\t%s", propval);
+ else
+ (void) printf(" %*s", width, propval);
+}
+
+void
+print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
+ list_cbdata_t *cb, int depth)
+{
+ nvlist_t **child;
+ vdev_stat_t *vs;
+ uint_t c, children;
+ char *vname;
+ boolean_t scripted = cb->cb_scripted;
+
+ verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) == 0);
+
+ if (name != NULL) {
+ if (scripted)
+ (void) printf("\t%s", name);
+ else if (strlen(name) + depth > cb->cb_namewidth)
+ (void) printf("%*s%s", depth, "", name);
+ else
+ (void) printf("%*s%s%*s", depth, "", name,
+ (int)(cb->cb_namewidth - strlen(name) - depth), "");
+
+ /* only toplevel vdevs have capacity stats */
+ if (vs->vs_space == 0) {
+ if (scripted)
+ (void) printf("\t-\t-\t-");
+ else
+ (void) printf(" - - -");
+ } else {
+ print_one_column(ZPOOL_PROP_SIZE, vs->vs_space,
+ scripted);
+ print_one_column(ZPOOL_PROP_CAPACITY, vs->vs_alloc,
+ scripted);
+ print_one_column(ZPOOL_PROP_FREE,
+ vs->vs_space - vs->vs_alloc, scripted);
+ }
+ print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize,
+ scripted);
+ (void) printf("\n");
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ uint64_t ishole = B_FALSE;
+
+ if (nvlist_lookup_uint64(child[c],
+ ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
+ continue;
+
+ vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
+ print_list_stats(zhp, vname, child[c], cb, depth + 2);
+ free(vname);
+ }
+
+ /*
+ * Include level 2 ARC devices in iostat output
+ */
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) != 0)
+ return;
+
+ if (children > 0) {
+ (void) printf("%-*s - - - - - "
+ "-\n", cb->cb_namewidth, "cache");
+ for (c = 0; c < children; c++) {
+ vname = zpool_vdev_name(g_zfs, zhp, child[c],
+ B_FALSE);
+ print_list_stats(zhp, vname, child[c], cb, depth + 2);
+ free(vname);
+ }
+ }
+}
+
+
+/*
+ * Generic callback function to list a pool.
+ */
+int
+list_callback(zpool_handle_t *zhp, void *data)
+{
+ list_cbdata_t *cbp = data;
+ nvlist_t *config;
+ nvlist_t *nvroot;
+
+ config = zpool_get_config(zhp, NULL);
+
+ print_pool(zhp, cbp);
+ if (!cbp->cb_verbose)
+ return (0);
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ print_list_stats(zhp, NULL, nvroot, cbp, 0);
+
+ return (0);
+}
+
+/*
+ * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
+ *
+ * -H Scripted mode. Don't display headers, and separate properties
+ * by a single tab.
+ * -o List of properties to display. Defaults to
+ * "name,size,allocated,free,capacity,health,altroot"
+ * -T Display a timestamp in date(1) or Unix format
+ *
+ * List all pools in the system, whether or not they're healthy. Output space
+ * statistics for each one, as well as health status summary.
+ */
+int
+zpool_do_list(int argc, char **argv)
+{
+ int c;
+ int ret;
+ list_cbdata_t cb = { 0 };
+ static char default_props[] =
+ "name,size,allocated,free,capacity,dedupratio,"
+ "health,altroot";
+ char *props = default_props;
+ unsigned long interval = 0, count = 0;
+ zpool_list_t *list;
+ boolean_t first = B_TRUE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
+ switch (c) {
+ case 'H':
+ cb.cb_scripted = B_TRUE;
+ break;
+ case 'o':
+ props = optarg;
+ break;
+ case 'T':
+ get_timestamp_arg(*optarg);
+ break;
+ case 'v':
+ cb.cb_verbose = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ get_interval_count(&argc, argv, &interval, &count);
+
+ if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
+ usage(B_FALSE);
+
+ if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL)
+ return (1);
+
+ if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
+ (void) printf(gettext("no pools available\n"));
+ zprop_free_list(cb.cb_proplist);
+ return (0);
+ }
+
+ for (;;) {
+ pool_list_update(list);
+
+ if (pool_list_count(list) == 0)
+ break;
+
+ cb.cb_namewidth = 0;
+ (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
+
+ if (timestamp_fmt != NODATE)
+ print_timestamp(timestamp_fmt);
+
+ if (!cb.cb_scripted && (first || cb.cb_verbose)) {
+ print_header(&cb);
+ first = B_FALSE;
+ }
+ ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
+
+ if (interval == 0)
+ break;
+
+ if (count != 0 && --count == 0)
+ break;
+
+ (void) sleep(interval);
+ }
+
+ zprop_free_list(cb.cb_proplist);
+ return (ret);
+}
+
+static nvlist_t *
+zpool_get_vdev_by_name(nvlist_t *nv, char *name)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ nvlist_t *match;
+ char *path;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) {
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
+ if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ name += sizeof(_PATH_DEV) - 1;
+ if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ path += sizeof(_PATH_DEV) - 1;
+ if (strcmp(name, path) == 0)
+ return (nv);
+ return (NULL);
+ }
+
+ for (c = 0; c < children; c++)
+ if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
+ return (match);
+
+ return (NULL);
+}
+
+static int
+zpool_do_attach_or_replace(int argc, char **argv, int replacing)
+{
+ boolean_t force = B_FALSE;
+ int c;
+ nvlist_t *nvroot;
+ char *poolname, *old_disk, *new_disk;
+ zpool_handle_t *zhp;
+ int ret;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ force = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+
+ if (argc < 2) {
+ (void) fprintf(stderr,
+ gettext("missing <device> specification\n"));
+ usage(B_FALSE);
+ }
+
+ old_disk = argv[1];
+
+ if (argc < 3) {
+ if (!replacing) {
+ (void) fprintf(stderr,
+ gettext("missing <new_device> specification\n"));
+ usage(B_FALSE);
+ }
+ new_disk = old_disk;
+ argc -= 1;
+ argv += 1;
+ } else {
+ new_disk = argv[2];
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ if (zpool_get_config(zhp, NULL) == NULL) {
+ (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
+ poolname);
+ zpool_close(zhp);
+ return (1);
+ }
+
+ nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
+ argc, argv);
+ if (nvroot == NULL) {
+ zpool_close(zhp);
+ return (1);
+ }
+
+ ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
+
+ nvlist_free(nvroot);
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool replace [-f] <pool> <device> <new_device>
+ *
+ * -f Force attach, even if <new_device> appears to be in use.
+ *
+ * Replace <device> with <new_device>.
+ */
+/* ARGSUSED */
+int
+zpool_do_replace(int argc, char **argv)
+{
+ return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
+}
+
+/*
+ * zpool attach [-f] <pool> <device> <new_device>
+ *
+ * -f Force attach, even if <new_device> appears to be in use.
+ *
+ * Attach <new_device> to the mirror containing <device>. If <device> is not
+ * part of a mirror, then <device> will be transformed into a mirror of
+ * <device> and <new_device>. In either case, <new_device> will begin life
+ * with a DTL of [0, now], and will immediately begin to resilver itself.
+ */
+int
+zpool_do_attach(int argc, char **argv)
+{
+ return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
+}
+
+/*
+ * zpool detach [-f] <pool> <device>
+ *
+ * -f Force detach of <device>, even if DTLs argue against it
+ * (not supported yet)
+ *
+ * Detach a device from a mirror. The operation will be refused if <device>
+ * is the last device in the mirror, or if the DTLs indicate that this device
+ * has the only valid copy of some data.
+ */
+/* ARGSUSED */
+int
+zpool_do_detach(int argc, char **argv)
+{
+ int c;
+ char *poolname, *path;
+ zpool_handle_t *zhp;
+ int ret;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "f")) != -1) {
+ switch (c) {
+ case 'f':
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc < 2) {
+ (void) fprintf(stderr,
+ gettext("missing <device> specification\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+ path = argv[1];
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ ret = zpool_vdev_detach(zhp, path);
+
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool split [-n] [-o prop=val] ...
+ * [-o mntopt] ...
+ * [-R altroot] <pool> <newpool> [<device> ...]
+ *
+ * -n Do not split the pool, but display the resulting layout if
+ * it were to be split.
+ * -o Set property=value, or set mount options.
+ * -R Mount the split-off pool under an alternate root.
+ *
+ * Splits the named pool and gives it the new pool name. Devices to be split
+ * off may be listed, provided that no more than one device is specified
+ * per top-level vdev mirror. The newly split pool is left in an exported
+ * state unless -R is specified.
+ *
+ * Restrictions: the top-level of the pool pool must only be made up of
+ * mirrors; all devices in the pool must be healthy; no device may be
+ * undergoing a resilvering operation.
+ */
+int
+zpool_do_split(int argc, char **argv)
+{
+ char *srcpool, *newpool, *propval;
+ char *mntopts = NULL;
+ splitflags_t flags;
+ int c, ret = 0;
+ zpool_handle_t *zhp;
+ nvlist_t *config, *props = NULL;
+
+ flags.dryrun = B_FALSE;
+ flags.import = B_FALSE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":R:no:")) != -1) {
+ switch (c) {
+ case 'R':
+ flags.import = B_TRUE;
+ if (add_prop_list(
+ zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
+ &props, B_TRUE) != 0) {
+ if (props)
+ nvlist_free(props);
+ usage(B_FALSE);
+ }
+ break;
+ case 'n':
+ flags.dryrun = B_TRUE;
+ break;
+ case 'o':
+ if ((propval = strchr(optarg, '=')) != NULL) {
+ *propval = '\0';
+ propval++;
+ if (add_prop_list(optarg, propval,
+ &props, B_TRUE) != 0) {
+ if (props)
+ nvlist_free(props);
+ usage(B_FALSE);
+ }
+ } else {
+ mntopts = optarg;
+ }
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ break;
+ }
+ }
+
+ if (!flags.import && mntopts != NULL) {
+ (void) fprintf(stderr, gettext("setting mntopts is only "
+ "valid when importing the pool\n"));
+ usage(B_FALSE);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("Missing pool name\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("Missing new pool name\n"));
+ usage(B_FALSE);
+ }
+
+ srcpool = argv[0];
+ newpool = argv[1];
+
+ argc -= 2;
+ argv += 2;
+
+ if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
+ return (1);
+
+ config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
+ if (config == NULL) {
+ ret = 1;
+ } else {
+ if (flags.dryrun) {
+ (void) printf(gettext("would create '%s' with the "
+ "following layout:\n\n"), newpool);
+ print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
+ }
+ nvlist_free(config);
+ }
+
+ zpool_close(zhp);
+
+ if (ret != 0 || flags.dryrun || !flags.import)
+ return (ret);
+
+ /*
+ * The split was successful. Now we need to open the new
+ * pool and import it.
+ */
+ if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
+ return (1);
+ if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
+ zpool_enable_datasets(zhp, mntopts, 0) != 0) {
+ ret = 1;
+ (void) fprintf(stderr, gettext("Split was successful, but "
+ "the datasets could not all be mounted\n"));
+ (void) fprintf(stderr, gettext("Try doing '%s' with a "
+ "different altroot\n"), "zpool import");
+ }
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+
+
+/*
+ * zpool online <pool> <device> ...
+ */
+int
+zpool_do_online(int argc, char **argv)
+{
+ int c, i;
+ char *poolname;
+ zpool_handle_t *zhp;
+ int ret = 0;
+ vdev_state_t newstate;
+ int flags = 0;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "et")) != -1) {
+ switch (c) {
+ case 'e':
+ flags |= ZFS_ONLINE_EXPAND;
+ break;
+ case 't':
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing device name\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ for (i = 1; i < argc; i++) {
+ if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
+ if (newstate != VDEV_STATE_HEALTHY) {
+ (void) printf(gettext("warning: device '%s' "
+ "onlined, but remains in faulted state\n"),
+ argv[i]);
+ if (newstate == VDEV_STATE_FAULTED)
+ (void) printf(gettext("use 'zpool "
+ "clear' to restore a faulted "
+ "device\n"));
+ else
+ (void) printf(gettext("use 'zpool "
+ "replace' to replace devices "
+ "that are no longer present\n"));
+ }
+ } else {
+ ret = 1;
+ }
+ }
+
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool offline [-ft] <pool> <device> ...
+ *
+ * -f Force the device into the offline state, even if doing
+ * so would appear to compromise pool availability.
+ * (not supported yet)
+ *
+ * -t Only take the device off-line temporarily. The offline
+ * state will not be persistent across reboots.
+ */
+/* ARGSUSED */
+int
+zpool_do_offline(int argc, char **argv)
+{
+ int c, i;
+ char *poolname;
+ zpool_handle_t *zhp;
+ int ret = 0;
+ boolean_t istmp = B_FALSE;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "ft")) != -1) {
+ switch (c) {
+ case 't':
+ istmp = B_TRUE;
+ break;
+ case 'f':
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name\n"));
+ usage(B_FALSE);
+ }
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing device name\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ for (i = 1; i < argc; i++) {
+ if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
+ ret = 1;
+ }
+
+ zpool_close(zhp);
+
+ return (ret);
+}
+
+/*
+ * zpool clear <pool> [device]
+ *
+ * Clear all errors associated with a pool or a particular device.
+ */
+int
+zpool_do_clear(int argc, char **argv)
+{
+ int c;
+ int ret = 0;
+ boolean_t dryrun = B_FALSE;
+ boolean_t do_rewind = B_FALSE;
+ boolean_t xtreme_rewind = B_FALSE;
+ uint32_t rewind_policy = ZPOOL_NO_REWIND;
+ nvlist_t *policy = NULL;
+ zpool_handle_t *zhp;
+ char *pool, *device;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "FnX")) != -1) {
+ switch (c) {
+ case 'F':
+ do_rewind = B_TRUE;
+ break;
+ case 'n':
+ dryrun = B_TRUE;
+ break;
+ case 'X':
+ xtreme_rewind = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc > 2) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if ((dryrun || xtreme_rewind) && !do_rewind) {
+ (void) fprintf(stderr,
+ gettext("-n or -X only meaningful with -F\n"));
+ usage(B_FALSE);
+ }
+ if (dryrun)
+ rewind_policy = ZPOOL_TRY_REWIND;
+ else if (do_rewind)
+ rewind_policy = ZPOOL_DO_REWIND;
+ if (xtreme_rewind)
+ rewind_policy |= ZPOOL_EXTREME_REWIND;
+
+ /* In future, further rewind policy choices can be passed along here */
+ if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
+ nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
+ return (1);
+
+ pool = argv[0];
+ device = argc == 2 ? argv[1] : NULL;
+
+ if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
+ nvlist_free(policy);
+ return (1);
+ }
+
+ if (zpool_clear(zhp, device, policy) != 0)
+ ret = 1;
+
+ zpool_close(zhp);
+
+ nvlist_free(policy);
+
+ return (ret);
+}
+
+/*
+ * zpool reguid <pool>
+ */
+int
+zpool_do_reguid(int argc, char **argv)
+{
+ int c;
+ char *poolname;
+ zpool_handle_t *zhp;
+ int ret = 0;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "")) != -1) {
+ switch (c) {
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* get pool name and check number of arguments */
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc > 1) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ poolname = argv[0];
+ if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+ return (1);
+
+ ret = zpool_reguid(zhp);
+
+ zpool_close(zhp);
+ return (ret);
+}
+
+
+/*
+ * zpool reopen <pool>
+ *
+ * Reopen the pool so that the kernel can update the sizes of all vdevs.
+ *
+ * NOTE: This command is currently undocumented. If the command is ever
+ * exposed then the appropriate usage() messages will need to be made.
+ */
+int
+zpool_do_reopen(int argc, char **argv)
+{
+ int ret = 0;
+ zpool_handle_t *zhp;
+ char *pool;
+
+ argc--;
+ argv++;
+
+ if (argc != 1)
+ return (2);
+
+ pool = argv[0];
+ if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
+ return (1);
+
+ ret = zpool_reopen(zhp);
+ zpool_close(zhp);
+ return (ret);
+}
+
+typedef struct scrub_cbdata {
+ int cb_type;
+ int cb_argc;
+ char **cb_argv;
+} scrub_cbdata_t;
+
+int
+scrub_callback(zpool_handle_t *zhp, void *data)
+{
+ scrub_cbdata_t *cb = data;
+ int err;
+
+ /*
+ * Ignore faulted pools.
+ */
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
+ "currently unavailable\n"), zpool_get_name(zhp));
+ return (1);
+ }
+
+ err = zpool_scan(zhp, cb->cb_type);
+
+ return (err != 0);
+}
+
+/*
+ * zpool scrub [-s] <pool> ...
+ *
+ * -s Stop. Stops any in-progress scrub.
+ */
+int
+zpool_do_scrub(int argc, char **argv)
+{
+ int c;
+ scrub_cbdata_t cb;
+
+ cb.cb_type = POOL_SCAN_SCRUB;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "s")) != -1) {
+ switch (c) {
+ case 's':
+ cb.cb_type = POOL_SCAN_NONE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ cb.cb_argc = argc;
+ cb.cb_argv = argv;
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ (void) fprintf(stderr, gettext("missing pool name argument\n"));
+ usage(B_FALSE);
+ }
+
+ return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
+}
+
+typedef struct status_cbdata {
+ int cb_count;
+ boolean_t cb_allpools;
+ boolean_t cb_verbose;
+ boolean_t cb_explain;
+ boolean_t cb_first;
+ boolean_t cb_dedup_stats;
+} status_cbdata_t;
+
+/*
+ * Print out detailed scrub status.
+ */
+void
+print_scan_status(pool_scan_stat_t *ps)
+{
+ time_t start, end;
+ uint64_t elapsed, mins_left, hours_left;
+ uint64_t pass_exam, examined, total;
+ uint_t rate;
+ double fraction_done;
+ char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
+
+ (void) printf(gettext(" scan: "));
+
+ /* If there's never been a scan, there's not much to say. */
+ if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
+ ps->pss_func >= POOL_SCAN_FUNCS) {
+ (void) printf(gettext("none requested\n"));
+ return;
+ }
+
+ start = ps->pss_start_time;
+ end = ps->pss_end_time;
+ zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
+
+ assert(ps->pss_func == POOL_SCAN_SCRUB ||
+ ps->pss_func == POOL_SCAN_RESILVER);
+ /*
+ * Scan is finished or canceled.
+ */
+ if (ps->pss_state == DSS_FINISHED) {
+ uint64_t minutes_taken = (end - start) / 60;
+ char *fmt;
+
+ if (ps->pss_func == POOL_SCAN_SCRUB) {
+ fmt = gettext("scrub repaired %s in %lluh%um with "
+ "%llu errors on %s");
+ } else if (ps->pss_func == POOL_SCAN_RESILVER) {
+ fmt = gettext("resilvered %s in %lluh%um with "
+ "%llu errors on %s");
+ }
+ /* LINTED */
+ (void) printf(fmt, processed_buf,
+ (u_longlong_t)(minutes_taken / 60),
+ (uint_t)(minutes_taken % 60),
+ (u_longlong_t)ps->pss_errors,
+ ctime((time_t *)&end));
+ return;
+ } else if (ps->pss_state == DSS_CANCELED) {
+ if (ps->pss_func == POOL_SCAN_SCRUB) {
+ (void) printf(gettext("scrub canceled on %s"),
+ ctime(&end));
+ } else if (ps->pss_func == POOL_SCAN_RESILVER) {
+ (void) printf(gettext("resilver canceled on %s"),
+ ctime(&end));
+ }
+ return;
+ }
+
+ assert(ps->pss_state == DSS_SCANNING);
+
+ /*
+ * Scan is in progress.
+ */
+ if (ps->pss_func == POOL_SCAN_SCRUB) {
+ (void) printf(gettext("scrub in progress since %s"),
+ ctime(&start));
+ } else if (ps->pss_func == POOL_SCAN_RESILVER) {
+ (void) printf(gettext("resilver in progress since %s"),
+ ctime(&start));
+ }
+
+ examined = ps->pss_examined ? ps->pss_examined : 1;
+ total = ps->pss_to_examine;
+ fraction_done = (double)examined / total;
+
+ /* elapsed time for this pass */
+ elapsed = time(NULL) - ps->pss_pass_start;
+ elapsed = elapsed ? elapsed : 1;
+ pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
+ rate = pass_exam / elapsed;
+ rate = rate ? rate : 1;
+ mins_left = ((total - examined) / rate) / 60;
+ hours_left = mins_left / 60;
+
+ zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
+ zfs_nicenum(total, total_buf, sizeof (total_buf));
+ zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
+
+ /*
+ * do not print estimated time if hours_left is more than 30 days
+ */
+ (void) printf(gettext(" %s scanned out of %s at %s/s"),
+ examined_buf, total_buf, rate_buf);
+ if (hours_left < (30 * 24)) {
+ (void) printf(gettext(", %lluh%um to go\n"),
+ (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
+ } else {
+ (void) printf(gettext(
+ ", (scan is slow, no estimated time)\n"));
+ }
+
+ if (ps->pss_func == POOL_SCAN_RESILVER) {
+ (void) printf(gettext(" %s resilvered, %.2f%% done\n"),
+ processed_buf, 100 * fraction_done);
+ } else if (ps->pss_func == POOL_SCAN_SCRUB) {
+ (void) printf(gettext(" %s repaired, %.2f%% done\n"),
+ processed_buf, 100 * fraction_done);
+ }
+}
+
+static void
+print_error_log(zpool_handle_t *zhp)
+{
+ nvlist_t *nverrlist = NULL;
+ nvpair_t *elem;
+ char *pathname;
+ size_t len = MAXPATHLEN * 2;
+
+ if (zpool_get_errlog(zhp, &nverrlist) != 0) {
+ (void) printf("errors: List of errors unavailable "
+ "(insufficient privileges)\n");
+ return;
+ }
+
+ (void) printf("errors: Permanent errors have been "
+ "detected in the following files:\n\n");
+
+ pathname = safe_malloc(len);
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
+ nvlist_t *nv;
+ uint64_t dsobj, obj;
+
+ verify(nvpair_value_nvlist(elem, &nv) == 0);
+ verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
+ &dsobj) == 0);
+ verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
+ &obj) == 0);
+ zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
+ (void) printf("%7s %s\n", "", pathname);
+ }
+ free(pathname);
+ nvlist_free(nverrlist);
+}
+
+static void
+print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
+ int namewidth)
+{
+ uint_t i;
+ char *name;
+
+ if (nspares == 0)
+ return;
+
+ (void) printf(gettext("\tspares\n"));
+
+ for (i = 0; i < nspares; i++) {
+ name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
+ print_status_config(zhp, name, spares[i],
+ namewidth, 2, B_TRUE);
+ free(name);
+ }
+}
+
+static void
+print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
+ int namewidth)
+{
+ uint_t i;
+ char *name;
+
+ if (nl2cache == 0)
+ return;
+
+ (void) printf(gettext("\tcache\n"));
+
+ for (i = 0; i < nl2cache; i++) {
+ name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
+ print_status_config(zhp, name, l2cache[i],
+ namewidth, 2, B_FALSE);
+ free(name);
+ }
+}
+
+static void
+print_dedup_stats(nvlist_t *config)
+{
+ ddt_histogram_t *ddh;
+ ddt_stat_t *dds;
+ ddt_object_t *ddo;
+ uint_t c;
+
+ /*
+ * If the pool was faulted then we may not have been able to
+ * obtain the config. Otherwise, if have anything in the dedup
+ * table continue processing the stats.
+ */
+ if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
+ (uint64_t **)&ddo, &c) != 0)
+ return;
+
+ (void) printf("\n");
+ (void) printf(gettext(" dedup: "));
+ if (ddo->ddo_count == 0) {
+ (void) printf(gettext("no DDT entries\n"));
+ return;
+ }
+
+ (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
+ (u_longlong_t)ddo->ddo_count,
+ (u_longlong_t)ddo->ddo_dspace,
+ (u_longlong_t)ddo->ddo_mspace);
+
+ verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
+ (uint64_t **)&dds, &c) == 0);
+ verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
+ (uint64_t **)&ddh, &c) == 0);
+ zpool_dump_ddt(dds, ddh);
+}
+
+/*
+ * Display a summary of pool status. Displays a summary such as:
+ *
+ * pool: tank
+ * status: DEGRADED
+ * reason: One or more devices ...
+ * see: http://illumos.org/msg/ZFS-xxxx-01
+ * config:
+ * mirror DEGRADED
+ * c1t0d0 OK
+ * c2t0d0 UNAVAIL
+ *
+ * When given the '-v' option, we print out the complete config. If the '-e'
+ * option is specified, then we print out error rate information as well.
+ */
+int
+status_callback(zpool_handle_t *zhp, void *data)
+{
+ status_cbdata_t *cbp = data;
+ nvlist_t *config, *nvroot;
+ char *msgid;
+ int reason;
+ const char *health;
+ uint_t c;
+ vdev_stat_t *vs;
+
+ config = zpool_get_config(zhp, NULL);
+ reason = zpool_get_status(zhp, &msgid);
+
+ cbp->cb_count++;
+
+ /*
+ * If we were given 'zpool status -x', only report those pools with
+ * problems.
+ */
+ if (cbp->cb_explain &&
+ (reason == ZPOOL_STATUS_OK ||
+ reason == ZPOOL_STATUS_VERSION_OLDER ||
+ reason == ZPOOL_STATUS_FEAT_DISABLED)) {
+ if (!cbp->cb_allpools) {
+ (void) printf(gettext("pool '%s' is healthy\n"),
+ zpool_get_name(zhp));
+ if (cbp->cb_first)
+ cbp->cb_first = B_FALSE;
+ }
+ return (0);
+ }
+
+ if (cbp->cb_first)
+ cbp->cb_first = B_FALSE;
+ else
+ (void) printf("\n");
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) == 0);
+ health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
+
+ (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
+ (void) printf(gettext(" state: %s\n"), health);
+
+ switch (reason) {
+ case ZPOOL_STATUS_MISSING_DEV_R:
+ (void) printf(gettext("status: One or more devices could not "
+ "be opened. Sufficient replicas exist for\n\tthe pool to "
+ "continue functioning in a degraded state.\n"));
+ (void) printf(gettext("action: Attach the missing device and "
+ "online it using 'zpool online'.\n"));
+ break;
+
+ case ZPOOL_STATUS_MISSING_DEV_NR:
+ (void) printf(gettext("status: One or more devices could not "
+ "be opened. There are insufficient\n\treplicas for the "
+ "pool to continue functioning.\n"));
+ (void) printf(gettext("action: Attach the missing device and "
+ "online it using 'zpool online'.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_LABEL_R:
+ (void) printf(gettext("status: One or more devices could not "
+ "be used because the label is missing or\n\tinvalid. "
+ "Sufficient replicas exist for the pool to continue\n\t"
+ "functioning in a degraded state.\n"));
+ (void) printf(gettext("action: Replace the device using "
+ "'zpool replace'.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_LABEL_NR:
+ (void) printf(gettext("status: One or more devices could not "
+ "be used because the label is missing \n\tor invalid. "
+ "There are insufficient replicas for the pool to "
+ "continue\n\tfunctioning.\n"));
+ zpool_explain_recover(zpool_get_handle(zhp),
+ zpool_get_name(zhp), reason, config);
+ break;
+
+ case ZPOOL_STATUS_FAILING_DEV:
+ (void) printf(gettext("status: One or more devices has "
+ "experienced an unrecoverable error. An\n\tattempt was "
+ "made to correct the error. Applications are "
+ "unaffected.\n"));
+ (void) printf(gettext("action: Determine if the device needs "
+ "to be replaced, and clear the errors\n\tusing "
+ "'zpool clear' or replace the device with 'zpool "
+ "replace'.\n"));
+ break;
+
+ case ZPOOL_STATUS_OFFLINE_DEV:
+ (void) printf(gettext("status: One or more devices has "
+ "been taken offline by the administrator.\n\tSufficient "
+ "replicas exist for the pool to continue functioning in "
+ "a\n\tdegraded state.\n"));
+ (void) printf(gettext("action: Online the device using "
+ "'zpool online' or replace the device with\n\t'zpool "
+ "replace'.\n"));
+ break;
+
+ case ZPOOL_STATUS_REMOVED_DEV:
+ (void) printf(gettext("status: One or more devices has "
+ "been removed by the administrator.\n\tSufficient "
+ "replicas exist for the pool to continue functioning in "
+ "a\n\tdegraded state.\n"));
+ (void) printf(gettext("action: Online the device using "
+ "'zpool online' or replace the device with\n\t'zpool "
+ "replace'.\n"));
+ break;
+
+ case ZPOOL_STATUS_RESILVERING:
+ (void) printf(gettext("status: One or more devices is "
+ "currently being resilvered. The pool will\n\tcontinue "
+ "to function, possibly in a degraded state.\n"));
+ (void) printf(gettext("action: Wait for the resilver to "
+ "complete.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_DATA:
+ (void) printf(gettext("status: One or more devices has "
+ "experienced an error resulting in data\n\tcorruption. "
+ "Applications may be affected.\n"));
+ (void) printf(gettext("action: Restore the file in question "
+ "if possible. Otherwise restore the\n\tentire pool from "
+ "backup.\n"));
+ break;
+
+ case ZPOOL_STATUS_CORRUPT_POOL:
+ (void) printf(gettext("status: The pool metadata is corrupted "
+ "and the pool cannot be opened.\n"));
+ zpool_explain_recover(zpool_get_handle(zhp),
+ zpool_get_name(zhp), reason, config);
+ break;
+
+ case ZPOOL_STATUS_VERSION_OLDER:
+ (void) printf(gettext("status: The pool is formatted using a "
+ "legacy on-disk format. The pool can\n\tstill be used, "
+ "but some features are unavailable.\n"));
+ (void) printf(gettext("action: Upgrade the pool using 'zpool "
+ "upgrade'. Once this is done, the\n\tpool will no longer "
+ "be accessible on software that does not support feature\n"
+ "\tflags.\n"));
+ break;
+
+ case ZPOOL_STATUS_VERSION_NEWER:
+ (void) printf(gettext("status: The pool has been upgraded to a "
+ "newer, incompatible on-disk version.\n\tThe pool cannot "
+ "be accessed on this system.\n"));
+ (void) printf(gettext("action: Access the pool from a system "
+ "running more recent software, or\n\trestore the pool from "
+ "backup.\n"));
+ break;
+
+ case ZPOOL_STATUS_FEAT_DISABLED:
+ (void) printf(gettext("status: Some supported features are not "
+ "enabled on the pool. The pool can\n\tstill be used, but "
+ "some features are unavailable.\n"));
+ (void) printf(gettext("action: Enable all features using "
+ "'zpool upgrade'. Once this is done,\n\tthe pool may no "
+ "longer be accessible by software that does not support\n\t"
+ "the features. See zpool-features(7) for details.\n"));
+ break;
+
+ case ZPOOL_STATUS_UNSUP_FEAT_READ:
+ (void) printf(gettext("status: The pool cannot be accessed on "
+ "this system because it uses the\n\tfollowing feature(s) "
+ "not supported on this system:\n"));
+ zpool_print_unsup_feat(config);
+ (void) printf("\n");
+ (void) printf(gettext("action: Access the pool from a system "
+ "that supports the required feature(s),\n\tor restore the "
+ "pool from backup.\n"));
+ break;
+
+ case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
+ (void) printf(gettext("status: The pool can only be accessed "
+ "in read-only mode on this system. It\n\tcannot be "
+ "accessed in read-write mode because it uses the "
+ "following\n\tfeature(s) not supported on this system:\n"));
+ zpool_print_unsup_feat(config);
+ (void) printf("\n");
+ (void) printf(gettext("action: The pool cannot be accessed in "
+ "read-write mode. Import the pool with\n"
+ "\t\"-o readonly=on\", access the pool from a system that "
+ "supports the\n\trequired feature(s), or restore the "
+ "pool from backup.\n"));
+ break;
+
+ case ZPOOL_STATUS_FAULTED_DEV_R:
+ (void) printf(gettext("status: One or more devices are "
+ "faulted in response to persistent errors.\n\tSufficient "
+ "replicas exist for the pool to continue functioning "
+ "in a\n\tdegraded state.\n"));
+ (void) printf(gettext("action: Replace the faulted device, "
+ "or use 'zpool clear' to mark the device\n\trepaired.\n"));
+ break;
+
+ case ZPOOL_STATUS_FAULTED_DEV_NR:
+ (void) printf(gettext("status: One or more devices are "
+ "faulted in response to persistent errors. There are "
+ "insufficient replicas for the pool to\n\tcontinue "
+ "functioning.\n"));
+ (void) printf(gettext("action: Destroy and re-create the pool "
+ "from a backup source. Manually marking the device\n"
+ "\trepaired using 'zpool clear' may allow some data "
+ "to be recovered.\n"));
+ break;
+
+ case ZPOOL_STATUS_IO_FAILURE_WAIT:
+ case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
+ (void) printf(gettext("status: One or more devices are "
+ "faulted in response to IO failures.\n"));
+ (void) printf(gettext("action: Make sure the affected devices "
+ "are connected, then run 'zpool clear'.\n"));
+ break;
+
+ case ZPOOL_STATUS_BAD_LOG:
+ (void) printf(gettext("status: An intent log record "
+ "could not be read.\n"
+ "\tWaiting for adminstrator intervention to fix the "
+ "faulted pool.\n"));
+ (void) printf(gettext("action: Either restore the affected "
+ "device(s) and run 'zpool online',\n"
+ "\tor ignore the intent log records by running "
+ "'zpool clear'.\n"));
+ break;
+
+ default:
+ /*
+ * The remaining errors can't actually be generated, yet.
+ */
+ assert(reason == ZPOOL_STATUS_OK);
+ }
+
+ if (msgid != NULL)
+ (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
+ msgid);
+
+ if (config != NULL) {
+ int namewidth;
+ uint64_t nerr;
+ nvlist_t **spares, **l2cache;
+ uint_t nspares, nl2cache;
+ pool_scan_stat_t *ps = NULL;
+
+ (void) nvlist_lookup_uint64_array(nvroot,
+ ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
+ print_scan_status(ps);
+
+ namewidth = max_width(zhp, nvroot, 0, 0);
+ if (namewidth < 10)
+ namewidth = 10;
+
+ (void) printf(gettext("config:\n\n"));
+ (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
+ "NAME", "STATE", "READ", "WRITE", "CKSUM");
+ print_status_config(zhp, zpool_get_name(zhp), nvroot,
+ namewidth, 0, B_FALSE);
+
+ if (num_logs(nvroot) > 0)
+ print_logs(zhp, nvroot, namewidth, B_TRUE);
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+ &l2cache, &nl2cache) == 0)
+ print_l2cache(zhp, l2cache, nl2cache, namewidth);
+
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ &spares, &nspares) == 0)
+ print_spares(zhp, spares, nspares, namewidth);
+
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
+ &nerr) == 0) {
+ nvlist_t *nverrlist = NULL;
+
+ /*
+ * If the approximate error count is small, get a
+ * precise count by fetching the entire log and
+ * uniquifying the results.
+ */
+ if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
+ zpool_get_errlog(zhp, &nverrlist) == 0) {
+ nvpair_t *elem;
+
+ elem = NULL;
+ nerr = 0;
+ while ((elem = nvlist_next_nvpair(nverrlist,
+ elem)) != NULL) {
+ nerr++;
+ }
+ }
+ nvlist_free(nverrlist);
+
+ (void) printf("\n");
+
+ if (nerr == 0)
+ (void) printf(gettext("errors: No known data "
+ "errors\n"));
+ else if (!cbp->cb_verbose)
+ (void) printf(gettext("errors: %llu data "
+ "errors, use '-v' for a list\n"),
+ (u_longlong_t)nerr);
+ else
+ print_error_log(zhp);
+ }
+
+ if (cbp->cb_dedup_stats)
+ print_dedup_stats(config);
+ } else {
+ (void) printf(gettext("config: The configuration cannot be "
+ "determined.\n"));
+ }
+
+ return (0);
+}
+
+/*
+ * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
+ *
+ * -v Display complete error logs
+ * -x Display only pools with potential problems
+ * -D Display dedup status (undocumented)
+ * -T Display a timestamp in date(1) or Unix format
+ *
+ * Describes the health status of all pools or some subset.
+ */
+int
+zpool_do_status(int argc, char **argv)
+{
+ int c;
+ int ret;
+ unsigned long interval = 0, count = 0;
+ status_cbdata_t cb = { 0 };
+
+ /* check options */
+ while ((c = getopt(argc, argv, "vxDT:")) != -1) {
+ switch (c) {
+ case 'v':
+ cb.cb_verbose = B_TRUE;
+ break;
+ case 'x':
+ cb.cb_explain = B_TRUE;
+ break;
+ case 'D':
+ cb.cb_dedup_stats = B_TRUE;
+ break;
+ case 'T':
+ get_timestamp_arg(*optarg);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ get_interval_count(&argc, argv, &interval, &count);
+
+ if (argc == 0)
+ cb.cb_allpools = B_TRUE;
+
+ cb.cb_first = B_TRUE;
+
+ for (;;) {
+ if (timestamp_fmt != NODATE)
+ print_timestamp(timestamp_fmt);
+
+ ret = for_each_pool(argc, argv, B_TRUE, NULL,
+ status_callback, &cb);
+
+ if (argc == 0 && cb.cb_count == 0)
+ (void) printf(gettext("no pools available\n"));
+ else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
+ (void) printf(gettext("all pools are healthy\n"));
+
+ if (ret != 0)
+ return (ret);
+
+ if (interval == 0)
+ break;
+
+ if (count != 0 && --count == 0)
+ break;
+
+ (void) sleep(interval);
+ }
+
+ return (0);
+}
+
+typedef struct upgrade_cbdata {
+ int cb_first;
+ char cb_poolname[ZPOOL_MAXNAMELEN];
+ int cb_argc;
+ uint64_t cb_version;
+ char **cb_argv;
+} upgrade_cbdata_t;
+
+#ifdef __FreeBSD__
+static int
+is_root_pool(zpool_handle_t *zhp)
+{
+ static struct statfs sfs;
+ static char *poolname = NULL;
+ static boolean_t stated = B_FALSE;
+ char *slash;
+
+ if (!stated) {
+ stated = B_TRUE;
+ if (statfs("/", &sfs) == -1) {
+ (void) fprintf(stderr,
+ "Unable to stat root file system: %s.\n",
+ strerror(errno));
+ return (0);
+ }
+ if (strcmp(sfs.f_fstypename, "zfs") != 0)
+ return (0);
+ poolname = sfs.f_mntfromname;
+ if ((slash = strchr(poolname, '/')) != NULL)
+ *slash = '\0';
+ }
+ return (poolname != NULL && strcmp(poolname, zpool_get_name(zhp)) == 0);
+}
+
+static void
+root_pool_upgrade_check(zpool_handle_t *zhp, char *poolname, int size) {
+
+ if (poolname[0] == '\0' && is_root_pool(zhp))
+ (void) strlcpy(poolname, zpool_get_name(zhp), size);
+}
+#endif /* FreeBSD */
+
+static int
+upgrade_version(zpool_handle_t *zhp, uint64_t version)
+{
+ int ret;
+ nvlist_t *config;
+ uint64_t oldversion;
+
+ config = zpool_get_config(zhp, NULL);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &oldversion) == 0);
+
+ assert(SPA_VERSION_IS_SUPPORTED(oldversion));
+ assert(oldversion < version);
+
+ ret = zpool_upgrade(zhp, version);
+ if (ret != 0)
+ return (ret);
+
+ if (version >= SPA_VERSION_FEATURES) {
+ (void) printf(gettext("Successfully upgraded "
+ "'%s' from version %llu to feature flags.\n"),
+ zpool_get_name(zhp), oldversion);
+ } else {
+ (void) printf(gettext("Successfully upgraded "
+ "'%s' from version %llu to version %llu.\n"),
+ zpool_get_name(zhp), oldversion, version);
+ }
+
+ return (0);
+}
+
+static int
+upgrade_enable_all(zpool_handle_t *zhp, int *countp)
+{
+ int i, ret, count;
+ boolean_t firstff = B_TRUE;
+ nvlist_t *enabled = zpool_get_features(zhp);
+
+ count = 0;
+ for (i = 0; i < SPA_FEATURES; i++) {
+ const char *fname = spa_feature_table[i].fi_uname;
+ const char *fguid = spa_feature_table[i].fi_guid;
+ if (!nvlist_exists(enabled, fguid)) {
+ char *propname;
+ verify(-1 != asprintf(&propname, "feature@%s", fname));
+ ret = zpool_set_prop(zhp, propname,
+ ZFS_FEATURE_ENABLED);
+ if (ret != 0) {
+ free(propname);
+ return (ret);
+ }
+ count++;
+
+ if (firstff) {
+ (void) printf(gettext("Enabled the "
+ "following features on '%s':\n"),
+ zpool_get_name(zhp));
+ firstff = B_FALSE;
+ }
+ (void) printf(gettext(" %s\n"), fname);
+ free(propname);
+ }
+ }
+
+ if (countp != NULL)
+ *countp = count;
+ return (0);
+}
+
+static int
+upgrade_cb(zpool_handle_t *zhp, void *arg)
+{
+ upgrade_cbdata_t *cbp = arg;
+ nvlist_t *config;
+ uint64_t version;
+ boolean_t printnl = B_FALSE;
+ int ret;
+
+ config = zpool_get_config(zhp, NULL);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &version) == 0);
+
+ assert(SPA_VERSION_IS_SUPPORTED(version));
+
+ if (version < cbp->cb_version) {
+ cbp->cb_first = B_FALSE;
+ ret = upgrade_version(zhp, cbp->cb_version);
+ if (ret != 0)
+ return (ret);
+#ifdef __FreeBSD__
+ root_pool_upgrade_check(zhp, cbp->cb_poolname,
+ sizeof(cbp->cb_poolname));
+#endif /* ___FreeBSD__ */
+ printnl = B_TRUE;
+
+#ifdef illumos
+ /*
+ * If they did "zpool upgrade -a", then we could
+ * be doing ioctls to different pools. We need
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
+ */
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
+#endif
+ }
+
+ if (cbp->cb_version >= SPA_VERSION_FEATURES) {
+ int count;
+ ret = upgrade_enable_all(zhp, &count);
+ if (ret != 0)
+ return (ret);
+
+ if (count > 0) {
+ cbp->cb_first = B_FALSE;
+ printnl = B_TRUE;
+ /*
+ * If they did "zpool upgrade -a", then we could
+ * be doing ioctls to different pools. We need
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
+ */
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
+ }
+ }
+
+ if (printnl) {
+ (void) printf(gettext("\n"));
+ }
+
+ return (0);
+}
+
+static int
+upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
+{
+ upgrade_cbdata_t *cbp = arg;
+ nvlist_t *config;
+ uint64_t version;
+
+ config = zpool_get_config(zhp, NULL);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &version) == 0);
+
+ assert(SPA_VERSION_IS_SUPPORTED(version));
+
+ if (version < SPA_VERSION_FEATURES) {
+ if (cbp->cb_first) {
+ (void) printf(gettext("The following pools are "
+ "formatted with legacy version numbers and can\n"
+ "be upgraded to use feature flags. After "
+ "being upgraded, these pools\nwill no "
+ "longer be accessible by software that does not "
+ "support feature\nflags.\n\n"));
+ (void) printf(gettext("VER POOL\n"));
+ (void) printf(gettext("--- ------------\n"));
+ cbp->cb_first = B_FALSE;
+ }
+
+ (void) printf("%2llu %s\n", (u_longlong_t)version,
+ zpool_get_name(zhp));
+ }
+
+ return (0);
+}
+
+static int
+upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
+{
+ upgrade_cbdata_t *cbp = arg;
+ nvlist_t *config;
+ uint64_t version;
+
+ config = zpool_get_config(zhp, NULL);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &version) == 0);
+
+ if (version >= SPA_VERSION_FEATURES) {
+ int i;
+ boolean_t poolfirst = B_TRUE;
+ nvlist_t *enabled = zpool_get_features(zhp);
+
+ for (i = 0; i < SPA_FEATURES; i++) {
+ const char *fguid = spa_feature_table[i].fi_guid;
+ const char *fname = spa_feature_table[i].fi_uname;
+ if (!nvlist_exists(enabled, fguid)) {
+ if (cbp->cb_first) {
+ (void) printf(gettext("\nSome "
+ "supported features are not "
+ "enabled on the following pools. "
+ "Once a\nfeature is enabled the "
+ "pool may become incompatible with "
+ "software\nthat does not support "
+ "the feature. See "
+ "zpool-features(7) for "
+ "details.\n\n"));
+ (void) printf(gettext("POOL "
+ "FEATURE\n"));
+ (void) printf(gettext("------"
+ "---------\n"));
+ cbp->cb_first = B_FALSE;
+ }
+
+ if (poolfirst) {
+ (void) printf(gettext("%s\n"),
+ zpool_get_name(zhp));
+ poolfirst = B_FALSE;
+ }
+
+ (void) printf(gettext(" %s\n"), fname);
+ }
+ }
+ }
+
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+upgrade_one(zpool_handle_t *zhp, void *data)
+{
+ boolean_t printnl = B_FALSE;
+ upgrade_cbdata_t *cbp = data;
+ uint64_t cur_version;
+ int ret;
+
+ if (strcmp("log", zpool_get_name(zhp)) == 0) {
+ (void) printf(gettext("'log' is now a reserved word\n"
+ "Pool 'log' must be renamed using export and import"
+ " to upgrade.\n"));
+ return (1);
+ }
+
+ cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
+ if (cur_version > cbp->cb_version) {
+ (void) printf(gettext("Pool '%s' is already formatted "
+ "using more current version '%llu'.\n\n"),
+ zpool_get_name(zhp), cur_version);
+ return (0);
+ }
+
+ if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
+ (void) printf(gettext("Pool '%s' is already formatted "
+ "using version %llu.\n\n"), zpool_get_name(zhp),
+ cbp->cb_version);
+ return (0);
+ }
+
+ if (cur_version != cbp->cb_version) {
+ printnl = B_TRUE;
+ ret = upgrade_version(zhp, cbp->cb_version);
+ if (ret != 0)
+ return (ret);
+#ifdef __FreeBSD__
+ root_pool_upgrade_check(zhp, cbp->cb_poolname,
+ sizeof(cbp->cb_poolname));
+#endif /* ___FreeBSD__ */
+ }
+
+ if (cbp->cb_version >= SPA_VERSION_FEATURES) {
+ int count = 0;
+ ret = upgrade_enable_all(zhp, &count);
+ if (ret != 0)
+ return (ret);
+
+ if (count != 0) {
+ printnl = B_TRUE;
+#ifdef __FreeBSD__
+ root_pool_upgrade_check(zhp, cbp->cb_poolname,
+ sizeof(cbp->cb_poolname));
+#endif /* __FreeBSD __*/
+ } else if (cur_version == SPA_VERSION) {
+ (void) printf(gettext("Pool '%s' already has all "
+ "supported features enabled.\n"),
+ zpool_get_name(zhp));
+ }
+ }
+
+ if (printnl) {
+ (void) printf(gettext("\n"));
+ }
+
+ return (0);
+}
+
+/*
+ * zpool upgrade
+ * zpool upgrade -v
+ * zpool upgrade [-V version] <-a | pool ...>
+ *
+ * With no arguments, display downrev'd ZFS pool available for upgrade.
+ * Individual pools can be upgraded by specifying the pool, and '-a' will
+ * upgrade all pools.
+ */
+int
+zpool_do_upgrade(int argc, char **argv)
+{
+ int c;
+ upgrade_cbdata_t cb = { 0 };
+ int ret = 0;
+ boolean_t showversions = B_FALSE;
+ boolean_t upgradeall = B_FALSE;
+ char *end;
+
+
+ /* check options */
+ while ((c = getopt(argc, argv, ":avV:")) != -1) {
+ switch (c) {
+ case 'a':
+ upgradeall = B_TRUE;
+ break;
+ case 'v':
+ showversions = B_TRUE;
+ break;
+ case 'V':
+ cb.cb_version = strtoll(optarg, &end, 10);
+ if (*end != '\0' ||
+ !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
+ (void) fprintf(stderr,
+ gettext("invalid version '%s'\n"), optarg);
+ usage(B_FALSE);
+ }
+ break;
+ case ':':
+ (void) fprintf(stderr, gettext("missing argument for "
+ "'%c' option\n"), optopt);
+ usage(B_FALSE);
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+
+ cb.cb_argc = argc;
+ cb.cb_argv = argv;
+ argc -= optind;
+ argv += optind;
+
+ if (cb.cb_version == 0) {
+ cb.cb_version = SPA_VERSION;
+ } else if (!upgradeall && argc == 0) {
+ (void) fprintf(stderr, gettext("-V option is "
+ "incompatible with other arguments\n"));
+ usage(B_FALSE);
+ }
+
+ if (showversions) {
+ if (upgradeall || argc != 0) {
+ (void) fprintf(stderr, gettext("-v option is "
+ "incompatible with other arguments\n"));
+ usage(B_FALSE);
+ }
+ } else if (upgradeall) {
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("-a option should not "
+ "be used along with a pool name\n"));
+ usage(B_FALSE);
+ }
+ }
+
+ (void) printf(gettext("This system supports ZFS pool feature "
+ "flags.\n\n"));
+ if (showversions) {
+ int i;
+
+ (void) printf(gettext("The following features are "
+ "supported:\n\n"));
+ (void) printf(gettext("FEAT DESCRIPTION\n"));
+ (void) printf("----------------------------------------------"
+ "---------------\n");
+ for (i = 0; i < SPA_FEATURES; i++) {
+ zfeature_info_t *fi = &spa_feature_table[i];
+ const char *ro = fi->fi_can_readonly ?
+ " (read-only compatible)" : "";
+
+ (void) printf("%-37s%s\n", fi->fi_uname, ro);
+ (void) printf(" %s\n", fi->fi_desc);
+ }
+ (void) printf("\n");
+
+ (void) printf(gettext("The following legacy versions are also "
+ "supported:\n\n"));
+ (void) printf(gettext("VER DESCRIPTION\n"));
+ (void) printf("--- -----------------------------------------"
+ "---------------\n");
+ (void) printf(gettext(" 1 Initial ZFS version\n"));
+ (void) printf(gettext(" 2 Ditto blocks "
+ "(replicated metadata)\n"));
+ (void) printf(gettext(" 3 Hot spares and double parity "
+ "RAID-Z\n"));
+ (void) printf(gettext(" 4 zpool history\n"));
+ (void) printf(gettext(" 5 Compression using the gzip "
+ "algorithm\n"));
+ (void) printf(gettext(" 6 bootfs pool property\n"));
+ (void) printf(gettext(" 7 Separate intent log devices\n"));
+ (void) printf(gettext(" 8 Delegated administration\n"));
+ (void) printf(gettext(" 9 refquota and refreservation "
+ "properties\n"));
+ (void) printf(gettext(" 10 Cache devices\n"));
+ (void) printf(gettext(" 11 Improved scrub performance\n"));
+ (void) printf(gettext(" 12 Snapshot properties\n"));
+ (void) printf(gettext(" 13 snapused property\n"));
+ (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
+ (void) printf(gettext(" 15 user/group space accounting\n"));
+ (void) printf(gettext(" 16 stmf property support\n"));
+ (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
+ (void) printf(gettext(" 18 Snapshot user holds\n"));
+ (void) printf(gettext(" 19 Log device removal\n"));
+ (void) printf(gettext(" 20 Compression using zle "
+ "(zero-length encoding)\n"));
+ (void) printf(gettext(" 21 Deduplication\n"));
+ (void) printf(gettext(" 22 Received properties\n"));
+ (void) printf(gettext(" 23 Slim ZIL\n"));
+ (void) printf(gettext(" 24 System attributes\n"));
+ (void) printf(gettext(" 25 Improved scrub stats\n"));
+ (void) printf(gettext(" 26 Improved snapshot deletion "
+ "performance\n"));
+ (void) printf(gettext(" 27 Improved snapshot creation "
+ "performance\n"));
+ (void) printf(gettext(" 28 Multiple vdev replacements\n"));
+ (void) printf(gettext("\nFor more information on a particular "
+ "version, including supported releases,\n"));
+ (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
+ } else if (argc == 0 && upgradeall) {
+ cb.cb_first = B_TRUE;
+ ret = zpool_iter(g_zfs, upgrade_cb, &cb);
+ if (ret == 0 && cb.cb_first) {
+ if (cb.cb_version == SPA_VERSION) {
+ (void) printf(gettext("All pools are already "
+ "formatted using feature flags.\n\n"));
+ (void) printf(gettext("Every feature flags "
+ "pool already has all supported features "
+ "enabled.\n"));
+ } else {
+ (void) printf(gettext("All pools are already "
+ "formatted with version %llu or higher.\n"),
+ cb.cb_version);
+ }
+ }
+ } else if (argc == 0) {
+ cb.cb_first = B_TRUE;
+ ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
+ assert(ret == 0);
+
+ if (cb.cb_first) {
+ (void) printf(gettext("All pools are formatted "
+ "using feature flags.\n\n"));
+ } else {
+ (void) printf(gettext("\nUse 'zpool upgrade -v' "
+ "for a list of available legacy versions.\n"));
+ }
+
+ cb.cb_first = B_TRUE;
+ ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
+ assert(ret == 0);
+
+ if (cb.cb_first) {
+ (void) printf(gettext("Every feature flags pool has "
+ "all supported features enabled.\n"));
+ } else {
+ (void) printf(gettext("\n"));
+ }
+ } else {
+ ret = for_each_pool(argc, argv, B_FALSE, NULL,
+ upgrade_one, &cb);
+ }
+
+ if (cb.cb_poolname[0] != '\0') {
+ (void) printf(
+ "If you boot from pool '%s', don't forget to update boot code.\n"
+ "Assuming you use GPT partitioning and da0 is your boot disk\n"
+ "the following command will do it:\n"
+ "\n"
+ "\tgpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0\n\n",
+ cb.cb_poolname);
+ }
+
+ return (ret);
+}
+
+typedef struct hist_cbdata {
+ boolean_t first;
+ boolean_t longfmt;
+ boolean_t internal;
+} hist_cbdata_t;
+
+/*
+ * Print out the command history for a specific pool.
+ */
+static int
+get_history_one(zpool_handle_t *zhp, void *data)
+{
+ nvlist_t *nvhis;
+ nvlist_t **records;
+ uint_t numrecords;
+ int ret, i;
+ hist_cbdata_t *cb = (hist_cbdata_t *)data;
+
+ cb->first = B_FALSE;
+
+ (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
+
+ if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
+ return (ret);
+
+ verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
+ &records, &numrecords) == 0);
+ for (i = 0; i < numrecords; i++) {
+ nvlist_t *rec = records[i];
+ char tbuf[30] = "";
+
+ if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
+ time_t tsec;
+ struct tm t;
+
+ tsec = fnvlist_lookup_uint64(records[i],
+ ZPOOL_HIST_TIME);
+ (void) localtime_r(&tsec, &t);
+ (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
+ }
+
+ if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
+ (void) printf("%s %s", tbuf,
+ fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
+ int ievent =
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
+ if (!cb->internal)
+ continue;
+ if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
+ (void) printf("%s unrecognized record:\n",
+ tbuf);
+ dump_nvlist(rec, 4);
+ continue;
+ }
+ (void) printf("%s [internal %s txg:%lld] %s", tbuf,
+ zfs_history_event_names[ievent],
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
+ fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
+ if (!cb->internal)
+ continue;
+ (void) printf("%s [txg:%lld] %s", tbuf,
+ fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
+ fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
+ if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
+ (void) printf(" %s (%llu)",
+ fnvlist_lookup_string(rec,
+ ZPOOL_HIST_DSNAME),
+ fnvlist_lookup_uint64(rec,
+ ZPOOL_HIST_DSID));
+ }
+ (void) printf(" %s", fnvlist_lookup_string(rec,
+ ZPOOL_HIST_INT_STR));
+ } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
+ if (!cb->internal)
+ continue;
+ (void) printf("%s ioctl %s\n", tbuf,
+ fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
+ if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
+ (void) printf(" input:\n");
+ dump_nvlist(fnvlist_lookup_nvlist(rec,
+ ZPOOL_HIST_INPUT_NVL), 8);
+ }
+ if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
+ (void) printf(" output:\n");
+ dump_nvlist(fnvlist_lookup_nvlist(rec,
+ ZPOOL_HIST_OUTPUT_NVL), 8);
+ }
+ } else {
+ if (!cb->internal)
+ continue;
+ (void) printf("%s unrecognized record:\n", tbuf);
+ dump_nvlist(rec, 4);
+ }
+
+ if (!cb->longfmt) {
+ (void) printf("\n");
+ continue;
+ }
+ (void) printf(" [");
+ if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
+ uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
+ struct passwd *pwd = getpwuid(who);
+ (void) printf("user %d ", (int)who);
+ if (pwd != NULL)
+ (void) printf("(%s) ", pwd->pw_name);
+ }
+ if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
+ (void) printf("on %s",
+ fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
+ }
+ if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
+ (void) printf(":%s",
+ fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
+ }
+ (void) printf("]");
+ (void) printf("\n");
+ }
+ (void) printf("\n");
+ nvlist_free(nvhis);
+
+ return (ret);
+}
+
+/*
+ * zpool history <pool>
+ *
+ * Displays the history of commands that modified pools.
+ */
+int
+zpool_do_history(int argc, char **argv)
+{
+ hist_cbdata_t cbdata = { 0 };
+ int ret;
+ int c;
+
+ cbdata.first = B_TRUE;
+ /* check options */
+ while ((c = getopt(argc, argv, "li")) != -1) {
+ switch (c) {
+ case 'l':
+ cbdata.longfmt = B_TRUE;
+ break;
+ case 'i':
+ cbdata.internal = B_TRUE;
+ break;
+ case '?':
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ optopt);
+ usage(B_FALSE);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
+ &cbdata);
+
+ if (argc == 0 && cbdata.first == B_TRUE) {
+ (void) printf(gettext("no pools available\n"));
+ return (0);
+ }
+
+ return (ret);
+}
+
+static int
+get_callback(zpool_handle_t *zhp, void *data)
+{
+ zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
+ char value[MAXNAMELEN];
+ zprop_source_t srctype;
+ zprop_list_t *pl;
+
+ for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
+
+ /*
+ * Skip the special fake placeholder. This will also skip
+ * over the name property when 'all' is specified.
+ */
+ if (pl->pl_prop == ZPOOL_PROP_NAME &&
+ pl == cbp->cb_proplist)
+ continue;
+
+ if (pl->pl_prop == ZPROP_INVAL &&
+ (zpool_prop_feature(pl->pl_user_prop) ||
+ zpool_prop_unsupported(pl->pl_user_prop))) {
+ srctype = ZPROP_SRC_LOCAL;
+
+ if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
+ value, sizeof (value)) == 0) {
+ zprop_print_one_property(zpool_get_name(zhp),
+ cbp, pl->pl_user_prop, value, srctype,
+ NULL, NULL);
+ }
+ } else {
+ if (zpool_get_prop(zhp, pl->pl_prop, value,
+ sizeof (value), &srctype) != 0)
+ continue;
+
+ zprop_print_one_property(zpool_get_name(zhp), cbp,
+ zpool_prop_to_name(pl->pl_prop), value, srctype,
+ NULL, NULL);
+ }
+ }
+ return (0);
+}
+
+int
+zpool_do_get(int argc, char **argv)
+{
+ zprop_get_cbdata_t cb = { 0 };
+ zprop_list_t fake_name = { 0 };
+ int ret;
+
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing property "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+
+ cb.cb_first = B_TRUE;
+ cb.cb_sources = ZPROP_SRC_ALL;
+ cb.cb_columns[0] = GET_COL_NAME;
+ cb.cb_columns[1] = GET_COL_PROPERTY;
+ cb.cb_columns[2] = GET_COL_VALUE;
+ cb.cb_columns[3] = GET_COL_SOURCE;
+ cb.cb_type = ZFS_TYPE_POOL;
+
+ if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
+ ZFS_TYPE_POOL) != 0)
+ usage(B_FALSE);
+
+ if (cb.cb_proplist != NULL) {
+ fake_name.pl_prop = ZPOOL_PROP_NAME;
+ fake_name.pl_width = strlen(gettext("NAME"));
+ fake_name.pl_next = cb.cb_proplist;
+ cb.cb_proplist = &fake_name;
+ }
+
+ ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
+ get_callback, &cb);
+
+ if (cb.cb_proplist == &fake_name)
+ zprop_free_list(fake_name.pl_next);
+ else
+ zprop_free_list(cb.cb_proplist);
+
+ return (ret);
+}
+
+typedef struct set_cbdata {
+ char *cb_propname;
+ char *cb_value;
+ boolean_t cb_any_successful;
+} set_cbdata_t;
+
+int
+set_callback(zpool_handle_t *zhp, void *data)
+{
+ int error;
+ set_cbdata_t *cb = (set_cbdata_t *)data;
+
+ error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
+
+ if (!error)
+ cb->cb_any_successful = B_TRUE;
+
+ return (error);
+}
+
+int
+zpool_do_set(int argc, char **argv)
+{
+ set_cbdata_t cb = { 0 };
+ int error;
+
+ if (argc > 1 && argv[1][0] == '-') {
+ (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+ argv[1][1]);
+ usage(B_FALSE);
+ }
+
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing property=value "
+ "argument\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc < 3) {
+ (void) fprintf(stderr, gettext("missing pool name\n"));
+ usage(B_FALSE);
+ }
+
+ if (argc > 3) {
+ (void) fprintf(stderr, gettext("too many pool names\n"));
+ usage(B_FALSE);
+ }
+
+ cb.cb_propname = argv[1];
+ cb.cb_value = strchr(cb.cb_propname, '=');
+ if (cb.cb_value == NULL) {
+ (void) fprintf(stderr, gettext("missing value in "
+ "property=value argument\n"));
+ usage(B_FALSE);
+ }
+
+ *(cb.cb_value) = '\0';
+ cb.cb_value++;
+
+ error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
+ set_callback, &cb);
+
+ return (error);
+}
+
+static int
+find_command_idx(char *command, int *idx)
+{
+ int i;
+
+ for (i = 0; i < NCOMMAND; i++) {
+ if (command_table[i].name == NULL)
+ continue;
+
+ if (strcmp(command, command_table[i].name) == 0) {
+ *idx = i;
+ return (0);
+ }
+ }
+ return (1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ int i;
+ char *cmdname;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((g_zfs = libzfs_init()) == NULL) {
+ (void) fprintf(stderr, gettext("internal error: failed to "
+ "initialize ZFS library\n"));
+ return (1);
+ }
+
+ libzfs_print_on_error(g_zfs, B_TRUE);
+
+ opterr = 0;
+
+ /*
+ * Make sure the user has specified some command.
+ */
+ if (argc < 2) {
+ (void) fprintf(stderr, gettext("missing command\n"));
+ usage(B_FALSE);
+ }
+
+ cmdname = argv[1];
+
+ /*
+ * Special case '-?'
+ */
+ if (strcmp(cmdname, "-?") == 0)
+ usage(B_TRUE);
+
+ zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
+
+ /*
+ * Run the appropriate command.
+ */
+ if (find_command_idx(cmdname, &i) == 0) {
+ current_command = &command_table[i];
+ ret = command_table[i].func(argc - 1, argv + 1);
+ } else if (strchr(cmdname, '=')) {
+ verify(find_command_idx("set", &i) == 0);
+ current_command = &command_table[i];
+ ret = command_table[i].func(argc, argv);
+ } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
+ /*
+ * 'freeze' is a vile debugging abomination, so we treat
+ * it as such.
+ */
+ char buf[16384];
+ int fd = open(ZFS_DEV, O_RDWR);
+ (void) strcpy((void *)buf, argv[2]);
+ return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
+ } else {
+ (void) fprintf(stderr, gettext("unrecognized "
+ "command '%s'\n"), cmdname);
+ usage(B_FALSE);
+ }
+
+ if (ret == 0 && log_history)
+ (void) zpool_log_history(g_zfs, history_str);
+
+ libzfs_fini(g_zfs);
+
+ /*
+ * The 'ZFS_ABORT' environment variable causes us to dump core on exit
+ * for the purposes of running ::findleaks.
+ */
+ if (getenv("ZFS_ABORT") != NULL) {
+ (void) printf("dumping core by request\n");
+ abort();
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_util.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_util.c
new file mode 100644
index 0000000..c7a002e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_util.c
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <errno.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include "zpool_util.h"
+
+/*
+ * Utility function to guarantee malloc() success.
+ */
+void *
+safe_malloc(size_t size)
+{
+ void *data;
+
+ if ((data = calloc(1, size)) == NULL) {
+ (void) fprintf(stderr, "internal error: out of memory\n");
+ exit(1);
+ }
+
+ return (data);
+}
+
+/*
+ * Display an out of memory error message and abort the current program.
+ */
+void
+zpool_no_memory(void)
+{
+ assert(errno == ENOMEM);
+ (void) fprintf(stderr,
+ gettext("internal error: out of memory\n"));
+ exit(1);
+}
+
+/*
+ * Return the number of logs in supplied nvlist
+ */
+uint_t
+num_logs(nvlist_t *nv)
+{
+ uint_t nlogs = 0;
+ uint_t c, children;
+ nvlist_t **child;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return (0);
+
+ for (c = 0; c < children; c++) {
+ uint64_t is_log = B_FALSE;
+
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+ if (is_log)
+ nlogs++;
+ }
+ return (nlogs);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_util.h b/cddl/contrib/opensolaris/cmd/zpool/zpool_util.h
new file mode 100644
index 0000000..134c730
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_util.h
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef ZPOOL_UTIL_H
+#define ZPOOL_UTIL_H
+
+#include <libnvpair.h>
+#include <libzfs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Basic utility functions
+ */
+void *safe_malloc(size_t);
+void zpool_no_memory(void);
+uint_t num_logs(nvlist_t *nv);
+
+/*
+ * Virtual device functions
+ */
+
+nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
+ boolean_t replacing, boolean_t dryrun, int argc, char **argv);
+nvlist_t *split_mirror_vdev(zpool_handle_t *zhp, char *newname,
+ nvlist_t *props, splitflags_t flags, int argc, char **argv);
+
+/*
+ * Pool list functions
+ */
+int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
+ zpool_iter_f, void *);
+
+typedef struct zpool_list zpool_list_t;
+
+zpool_list_t *pool_list_get(int, char **, zprop_list_t **, int *);
+void pool_list_update(zpool_list_t *);
+int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
+void pool_list_free(zpool_list_t *);
+int pool_list_count(zpool_list_t *);
+void pool_list_remove(zpool_list_t *, zpool_handle_t *);
+
+libzfs_handle_t *g_zfs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZPOOL_UTIL_H */
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
new file mode 100644
index 0000000..5ffd39a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
@@ -0,0 +1,1514 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Functions to convert between a list of vdevs and an nvlist representing the
+ * configuration. Each entry in the list can be one of:
+ *
+ * Device vdevs
+ * disk=(path=..., devid=...)
+ * file=(path=...)
+ *
+ * Group vdevs
+ * raidz[1|2]=(...)
+ * mirror=(...)
+ *
+ * Hot spares
+ *
+ * While the underlying implementation supports it, group vdevs cannot contain
+ * other group vdevs. All userland verification of devices is contained within
+ * this file. If successful, the nvlist returned can be passed directly to the
+ * kernel; we've done as much verification as possible in userland.
+ *
+ * Hot spares are a special case, and passed down as an array of disk vdevs, at
+ * the same level as the root of the vdev tree.
+ *
+ * The only function exported by this file is 'make_root_vdev'. The
+ * function performs several passes:
+ *
+ * 1. Construct the vdev specification. Performs syntax validation and
+ * makes sure each device is valid.
+ * 2. Check for devices in use. Using libdiskmgt, makes sure that no
+ * devices are also in use. Some can be overridden using the 'force'
+ * flag, others cannot.
+ * 3. Check for replication errors if the 'force' flag is not specified.
+ * validates that the replication level is consistent across the
+ * entire pool.
+ * 4. Call libzfs to label any whole disks with an EFI label.
+ */
+
+#include <assert.h>
+#include <devid.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libintl.h>
+#include <libnvpair.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <sys/stat.h>
+#include <sys/disk.h>
+#include <sys/mntent.h>
+#include <libgeom.h>
+
+#include "zpool_util.h"
+
+#define DISK_ROOT "/dev/dsk"
+#define RDISK_ROOT "/dev/rdsk"
+#define BACKUP_SLICE "s2"
+
+/*
+ * For any given vdev specification, we can have multiple errors. The
+ * vdev_error() function keeps track of whether we have seen an error yet, and
+ * prints out a header if its the first error we've seen.
+ */
+boolean_t error_seen;
+boolean_t is_force;
+
+/*PRINTFLIKE1*/
+static void
+vdev_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!error_seen) {
+ (void) fprintf(stderr, gettext("invalid vdev specification\n"));
+ if (!is_force)
+ (void) fprintf(stderr, gettext("use '-f' to override "
+ "the following errors:\n"));
+ else
+ (void) fprintf(stderr, gettext("the following errors "
+ "must be manually repaired:\n"));
+ error_seen = B_TRUE;
+ }
+
+ va_start(ap, fmt);
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+#ifdef sun
+static void
+libdiskmgt_error(int error)
+{
+ /*
+ * ENXIO/ENODEV is a valid error message if the device doesn't live in
+ * /dev/dsk. Don't bother printing an error message in this case.
+ */
+ if (error == ENXIO || error == ENODEV)
+ return;
+
+ (void) fprintf(stderr, gettext("warning: device in use checking "
+ "failed: %s\n"), strerror(error));
+}
+
+/*
+ * Validate a device, passing the bulk of the work off to libdiskmgt.
+ */
+static int
+check_slice(const char *path, int force, boolean_t wholedisk, boolean_t isspare)
+{
+ char *msg;
+ int error = 0;
+ dm_who_type_t who;
+
+ if (force)
+ who = DM_WHO_ZPOOL_FORCE;
+ else if (isspare)
+ who = DM_WHO_ZPOOL_SPARE;
+ else
+ who = DM_WHO_ZPOOL;
+
+ if (dm_inuse((char *)path, &msg, who, &error) || error) {
+ if (error != 0) {
+ libdiskmgt_error(error);
+ return (0);
+ } else {
+ vdev_error("%s", msg);
+ free(msg);
+ return (-1);
+ }
+ }
+
+ /*
+ * If we're given a whole disk, ignore overlapping slices since we're
+ * about to label it anyway.
+ */
+ error = 0;
+ if (!wholedisk && !force &&
+ (dm_isoverlapping((char *)path, &msg, &error) || error)) {
+ if (error == 0) {
+ /* dm_isoverlapping returned -1 */
+ vdev_error(gettext("%s overlaps with %s\n"), path, msg);
+ free(msg);
+ return (-1);
+ } else if (error != ENODEV) {
+ /* libdiskmgt's devcache only handles physical drives */
+ libdiskmgt_error(error);
+ return (0);
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * Validate a whole disk. Iterate over all slices on the disk and make sure
+ * that none is in use by calling check_slice().
+ */
+static int
+check_disk(const char *name, dm_descriptor_t disk, int force, int isspare)
+{
+ dm_descriptor_t *drive, *media, *slice;
+ int err = 0;
+ int i;
+ int ret;
+
+ /*
+ * Get the drive associated with this disk. This should never fail,
+ * because we already have an alias handle open for the device.
+ */
+ if ((drive = dm_get_associated_descriptors(disk, DM_DRIVE,
+ &err)) == NULL || *drive == NULL) {
+ if (err)
+ libdiskmgt_error(err);
+ return (0);
+ }
+
+ if ((media = dm_get_associated_descriptors(*drive, DM_MEDIA,
+ &err)) == NULL) {
+ dm_free_descriptors(drive);
+ if (err)
+ libdiskmgt_error(err);
+ return (0);
+ }
+
+ dm_free_descriptors(drive);
+
+ /*
+ * It is possible that the user has specified a removable media drive,
+ * and the media is not present.
+ */
+ if (*media == NULL) {
+ dm_free_descriptors(media);
+ vdev_error(gettext("'%s' has no media in drive\n"), name);
+ return (-1);
+ }
+
+ if ((slice = dm_get_associated_descriptors(*media, DM_SLICE,
+ &err)) == NULL) {
+ dm_free_descriptors(media);
+ if (err)
+ libdiskmgt_error(err);
+ return (0);
+ }
+
+ dm_free_descriptors(media);
+
+ ret = 0;
+
+ /*
+ * Iterate over all slices and report any errors. We don't care about
+ * overlapping slices because we are using the whole disk.
+ */
+ for (i = 0; slice[i] != NULL; i++) {
+ char *name = dm_get_name(slice[i], &err);
+
+ if (check_slice(name, force, B_TRUE, isspare) != 0)
+ ret = -1;
+
+ dm_free_name(name);
+ }
+
+ dm_free_descriptors(slice);
+ return (ret);
+}
+
+/*
+ * Validate a device.
+ */
+static int
+check_device(const char *path, boolean_t force, boolean_t isspare)
+{
+ dm_descriptor_t desc;
+ int err;
+ char *dev;
+
+ /*
+ * For whole disks, libdiskmgt does not include the leading dev path.
+ */
+ dev = strrchr(path, '/');
+ assert(dev != NULL);
+ dev++;
+ if ((desc = dm_get_descriptor_by_name(DM_ALIAS, dev, &err)) != NULL) {
+ err = check_disk(path, desc, force, isspare);
+ dm_free_descriptor(desc);
+ return (err);
+ }
+
+ return (check_slice(path, force, B_FALSE, isspare));
+}
+#endif /* sun */
+
+/*
+ * Check that a file is valid. All we can do in this case is check that it's
+ * not in use by another pool, and not in use by swap.
+ */
+static int
+check_file(const char *file, boolean_t force, boolean_t isspare)
+{
+ char *name;
+ int fd;
+ int ret = 0;
+ int err;
+ pool_state_t state;
+ boolean_t inuse;
+
+#ifdef sun
+ if (dm_inuse_swap(file, &err)) {
+ if (err)
+ libdiskmgt_error(err);
+ else
+ vdev_error(gettext("%s is currently used by swap. "
+ "Please see swap(1M).\n"), file);
+ return (-1);
+ }
+#endif
+
+ if ((fd = open(file, O_RDONLY)) < 0)
+ return (0);
+
+ if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) == 0 && inuse) {
+ const char *desc;
+
+ switch (state) {
+ case POOL_STATE_ACTIVE:
+ desc = gettext("active");
+ break;
+
+ case POOL_STATE_EXPORTED:
+ desc = gettext("exported");
+ break;
+
+ case POOL_STATE_POTENTIALLY_ACTIVE:
+ desc = gettext("potentially active");
+ break;
+
+ default:
+ desc = gettext("unknown");
+ break;
+ }
+
+ /*
+ * Allow hot spares to be shared between pools.
+ */
+ if (state == POOL_STATE_SPARE && isspare)
+ return (0);
+
+ if (state == POOL_STATE_ACTIVE ||
+ state == POOL_STATE_SPARE || !force) {
+ switch (state) {
+ case POOL_STATE_SPARE:
+ vdev_error(gettext("%s is reserved as a hot "
+ "spare for pool %s\n"), file, name);
+ break;
+ default:
+ vdev_error(gettext("%s is part of %s pool "
+ "'%s'\n"), file, desc, name);
+ break;
+ }
+ ret = -1;
+ }
+
+ free(name);
+ }
+
+ (void) close(fd);
+ return (ret);
+}
+
+static int
+check_device(const char *name, boolean_t force, boolean_t isspare)
+{
+ char path[MAXPATHLEN];
+
+ if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) != 0)
+ snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name);
+ else
+ strlcpy(path, name, sizeof(path));
+
+ return (check_file(path, force, isspare));
+}
+
+/*
+ * By "whole disk" we mean an entire physical disk (something we can
+ * label, toggle the write cache on, etc.) as opposed to the full
+ * capacity of a pseudo-device such as lofi or did. We act as if we
+ * are labeling the disk, which should be a pretty good test of whether
+ * it's a viable device or not. Returns B_TRUE if it is and B_FALSE if
+ * it isn't.
+ */
+static boolean_t
+is_whole_disk(const char *arg)
+{
+#ifdef sun
+ struct dk_gpt *label;
+ int fd;
+ char path[MAXPATHLEN];
+
+ (void) snprintf(path, sizeof (path), "%s%s%s",
+ RDISK_ROOT, strrchr(arg, '/'), BACKUP_SLICE);
+ if ((fd = open(path, O_RDWR | O_NDELAY)) < 0)
+ return (B_FALSE);
+ if (efi_alloc_and_init(fd, EFI_NUMPAR, &label) != 0) {
+ (void) close(fd);
+ return (B_FALSE);
+ }
+ efi_free(label);
+ (void) close(fd);
+ return (B_TRUE);
+#else
+ int fd;
+
+ fd = g_open(arg, 0);
+ if (fd >= 0) {
+ g_close(fd);
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+#endif
+}
+
+/*
+ * Create a leaf vdev. Determine if this is a file or a device. If it's a
+ * device, fill in the device id to make a complete nvlist. Valid forms for a
+ * leaf vdev are:
+ *
+ * /dev/dsk/xxx Complete disk path
+ * /xxx Full path to file
+ * xxx Shorthand for /dev/dsk/xxx
+ */
+static nvlist_t *
+make_leaf_vdev(const char *arg, uint64_t is_log)
+{
+ char path[MAXPATHLEN];
+ struct stat64 statbuf;
+ nvlist_t *vdev = NULL;
+ char *type = NULL;
+ boolean_t wholedisk = B_FALSE;
+
+ /*
+ * Determine what type of vdev this is, and put the full path into
+ * 'path'. We detect whether this is a device of file afterwards by
+ * checking the st_mode of the file.
+ */
+ if (arg[0] == '/') {
+ /*
+ * Complete device or file path. Exact type is determined by
+ * examining the file descriptor afterwards.
+ */
+ wholedisk = is_whole_disk(arg);
+ if (!wholedisk && (stat64(arg, &statbuf) != 0)) {
+ (void) fprintf(stderr,
+ gettext("cannot open '%s': %s\n"),
+ arg, strerror(errno));
+ return (NULL);
+ }
+
+ (void) strlcpy(path, arg, sizeof (path));
+ } else {
+ /*
+ * This may be a short path for a device, or it could be total
+ * gibberish. Check to see if it's a known device in
+ * /dev/dsk/. As part of this check, see if we've been given a
+ * an entire disk (minus the slice number).
+ */
+ if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ strlcpy(path, arg, sizeof (path));
+ else
+ snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
+ wholedisk = is_whole_disk(path);
+ if (!wholedisk && (stat64(path, &statbuf) != 0)) {
+ /*
+ * If we got ENOENT, then the user gave us
+ * gibberish, so try to direct them with a
+ * reasonable error message. Otherwise,
+ * regurgitate strerror() since it's the best we
+ * can do.
+ */
+ if (errno == ENOENT) {
+ (void) fprintf(stderr,
+ gettext("cannot open '%s': no such "
+ "GEOM provider\n"), arg);
+ (void) fprintf(stderr,
+ gettext("must be a full path or "
+ "shorthand device name\n"));
+ return (NULL);
+ } else {
+ (void) fprintf(stderr,
+ gettext("cannot open '%s': %s\n"),
+ path, strerror(errno));
+ return (NULL);
+ }
+ }
+ }
+
+#ifdef __FreeBSD__
+ if (S_ISCHR(statbuf.st_mode)) {
+ statbuf.st_mode &= ~S_IFCHR;
+ statbuf.st_mode |= S_IFBLK;
+ wholedisk = B_FALSE;
+ }
+#endif
+
+ /*
+ * Determine whether this is a device or a file.
+ */
+ if (wholedisk || S_ISBLK(statbuf.st_mode)) {
+ type = VDEV_TYPE_DISK;
+ } else if (S_ISREG(statbuf.st_mode)) {
+ type = VDEV_TYPE_FILE;
+ } else {
+ (void) fprintf(stderr, gettext("cannot use '%s': must be a "
+ "GEOM provider or regular file\n"), path);
+ return (NULL);
+ }
+
+ /*
+ * Finally, we have the complete device or file, and we know that it is
+ * acceptable to use. Construct the nvlist to describe this vdev. All
+ * vdevs have a 'path' element, and devices also have a 'devid' element.
+ */
+ verify(nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) == 0);
+ verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
+ verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
+ verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
+ if (strcmp(type, VDEV_TYPE_DISK) == 0)
+ verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
+ (uint64_t)wholedisk) == 0);
+
+ /*
+ * For a whole disk, defer getting its devid until after labeling it.
+ */
+ if (S_ISBLK(statbuf.st_mode) && !wholedisk) {
+ /*
+ * Get the devid for the device.
+ */
+ int fd;
+ ddi_devid_t devid;
+ char *minor = NULL, *devid_str = NULL;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ (void) fprintf(stderr, gettext("cannot open '%s': "
+ "%s\n"), path, strerror(errno));
+ nvlist_free(vdev);
+ return (NULL);
+ }
+
+ if (devid_get(fd, &devid) == 0) {
+ if (devid_get_minor_name(fd, &minor) == 0 &&
+ (devid_str = devid_str_encode(devid, minor)) !=
+ NULL) {
+ verify(nvlist_add_string(vdev,
+ ZPOOL_CONFIG_DEVID, devid_str) == 0);
+ }
+ if (devid_str != NULL)
+ devid_str_free(devid_str);
+ if (minor != NULL)
+ devid_str_free(minor);
+ devid_free(devid);
+ }
+
+ (void) close(fd);
+ }
+
+ return (vdev);
+}
+
+/*
+ * Go through and verify the replication level of the pool is consistent.
+ * Performs the following checks:
+ *
+ * For the new spec, verifies that devices in mirrors and raidz are the
+ * same size.
+ *
+ * If the current configuration already has inconsistent replication
+ * levels, ignore any other potential problems in the new spec.
+ *
+ * Otherwise, make sure that the current spec (if there is one) and the new
+ * spec have consistent replication levels.
+ */
+typedef struct replication_level {
+ char *zprl_type;
+ uint64_t zprl_children;
+ uint64_t zprl_parity;
+} replication_level_t;
+
+#define ZPOOL_FUZZ (16 * 1024 * 1024)
+
+/*
+ * Given a list of toplevel vdevs, return the current replication level. If
+ * the config is inconsistent, then NULL is returned. If 'fatal' is set, then
+ * an error message will be displayed for each self-inconsistent vdev.
+ */
+static replication_level_t *
+get_replication(nvlist_t *nvroot, boolean_t fatal)
+{
+ nvlist_t **top;
+ uint_t t, toplevels;
+ nvlist_t **child;
+ uint_t c, children;
+ nvlist_t *nv;
+ char *type;
+ replication_level_t lastrep, rep, *ret;
+ boolean_t dontreport;
+
+ ret = safe_malloc(sizeof (replication_level_t));
+
+ verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ &top, &toplevels) == 0);
+
+ lastrep.zprl_type = NULL;
+ for (t = 0; t < toplevels; t++) {
+ uint64_t is_log = B_FALSE;
+
+ nv = top[t];
+
+ /*
+ * For separate logs we ignore the top level vdev replication
+ * constraints.
+ */
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
+ if (is_log)
+ continue;
+
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE,
+ &type) == 0);
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) {
+ /*
+ * This is a 'file' or 'disk' vdev.
+ */
+ rep.zprl_type = type;
+ rep.zprl_children = 1;
+ rep.zprl_parity = 0;
+ } else {
+ uint64_t vdev_size;
+
+ /*
+ * This is a mirror or RAID-Z vdev. Go through and make
+ * sure the contents are all the same (files vs. disks),
+ * keeping track of the number of elements in the
+ * process.
+ *
+ * We also check that the size of each vdev (if it can
+ * be determined) is the same.
+ */
+ rep.zprl_type = type;
+ rep.zprl_children = 0;
+
+ if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
+ verify(nvlist_lookup_uint64(nv,
+ ZPOOL_CONFIG_NPARITY,
+ &rep.zprl_parity) == 0);
+ assert(rep.zprl_parity != 0);
+ } else {
+ rep.zprl_parity = 0;
+ }
+
+ /*
+ * The 'dontreport' variable indicates that we've
+ * already reported an error for this spec, so don't
+ * bother doing it again.
+ */
+ type = NULL;
+ dontreport = 0;
+ vdev_size = -1ULL;
+ for (c = 0; c < children; c++) {
+ nvlist_t *cnv = child[c];
+ char *path;
+ struct stat64 statbuf;
+ uint64_t size = -1ULL;
+ char *childtype;
+ int fd, err;
+
+ rep.zprl_children++;
+
+ verify(nvlist_lookup_string(cnv,
+ ZPOOL_CONFIG_TYPE, &childtype) == 0);
+
+ /*
+ * If this is a replacing or spare vdev, then
+ * get the real first child of the vdev.
+ */
+ if (strcmp(childtype,
+ VDEV_TYPE_REPLACING) == 0 ||
+ strcmp(childtype, VDEV_TYPE_SPARE) == 0) {
+ nvlist_t **rchild;
+ uint_t rchildren;
+
+ verify(nvlist_lookup_nvlist_array(cnv,
+ ZPOOL_CONFIG_CHILDREN, &rchild,
+ &rchildren) == 0);
+ assert(rchildren == 2);
+ cnv = rchild[0];
+
+ verify(nvlist_lookup_string(cnv,
+ ZPOOL_CONFIG_TYPE,
+ &childtype) == 0);
+ }
+
+ verify(nvlist_lookup_string(cnv,
+ ZPOOL_CONFIG_PATH, &path) == 0);
+
+ /*
+ * If we have a raidz/mirror that combines disks
+ * with files, report it as an error.
+ */
+ if (!dontreport && type != NULL &&
+ strcmp(type, childtype) != 0) {
+ if (ret != NULL)
+ free(ret);
+ ret = NULL;
+ if (fatal)
+ vdev_error(gettext(
+ "mismatched replication "
+ "level: %s contains both "
+ "files and devices\n"),
+ rep.zprl_type);
+ else
+ return (NULL);
+ dontreport = B_TRUE;
+ }
+
+ /*
+ * According to stat(2), the value of 'st_size'
+ * is undefined for block devices and character
+ * devices. But there is no effective way to
+ * determine the real size in userland.
+ *
+ * Instead, we'll take advantage of an
+ * implementation detail of spec_size(). If the
+ * device is currently open, then we (should)
+ * return a valid size.
+ *
+ * If we still don't get a valid size (indicated
+ * by a size of 0 or MAXOFFSET_T), then ignore
+ * this device altogether.
+ */
+ if ((fd = open(path, O_RDONLY)) >= 0) {
+ err = fstat64(fd, &statbuf);
+ (void) close(fd);
+ } else {
+ err = stat64(path, &statbuf);
+ }
+
+ if (err != 0 ||
+ statbuf.st_size == 0 ||
+ statbuf.st_size == MAXOFFSET_T)
+ continue;
+
+ size = statbuf.st_size;
+
+ /*
+ * Also make sure that devices and
+ * slices have a consistent size. If
+ * they differ by a significant amount
+ * (~16MB) then report an error.
+ */
+ if (!dontreport &&
+ (vdev_size != -1ULL &&
+ (labs(size - vdev_size) >
+ ZPOOL_FUZZ))) {
+ if (ret != NULL)
+ free(ret);
+ ret = NULL;
+ if (fatal)
+ vdev_error(gettext(
+ "%s contains devices of "
+ "different sizes\n"),
+ rep.zprl_type);
+ else
+ return (NULL);
+ dontreport = B_TRUE;
+ }
+
+ type = childtype;
+ vdev_size = size;
+ }
+ }
+
+ /*
+ * At this point, we have the replication of the last toplevel
+ * vdev in 'rep'. Compare it to 'lastrep' to see if its
+ * different.
+ */
+ if (lastrep.zprl_type != NULL) {
+ if (strcmp(lastrep.zprl_type, rep.zprl_type) != 0) {
+ if (ret != NULL)
+ free(ret);
+ ret = NULL;
+ if (fatal)
+ vdev_error(gettext(
+ "mismatched replication level: "
+ "both %s and %s vdevs are "
+ "present\n"),
+ lastrep.zprl_type, rep.zprl_type);
+ else
+ return (NULL);
+ } else if (lastrep.zprl_parity != rep.zprl_parity) {
+ if (ret)
+ free(ret);
+ ret = NULL;
+ if (fatal)
+ vdev_error(gettext(
+ "mismatched replication level: "
+ "both %llu and %llu device parity "
+ "%s vdevs are present\n"),
+ lastrep.zprl_parity,
+ rep.zprl_parity,
+ rep.zprl_type);
+ else
+ return (NULL);
+ } else if (lastrep.zprl_children != rep.zprl_children) {
+ if (ret)
+ free(ret);
+ ret = NULL;
+ if (fatal)
+ vdev_error(gettext(
+ "mismatched replication level: "
+ "both %llu-way and %llu-way %s "
+ "vdevs are present\n"),
+ lastrep.zprl_children,
+ rep.zprl_children,
+ rep.zprl_type);
+ else
+ return (NULL);
+ }
+ }
+ lastrep = rep;
+ }
+
+ if (ret != NULL)
+ *ret = rep;
+
+ return (ret);
+}
+
+/*
+ * Check the replication level of the vdev spec against the current pool. Calls
+ * get_replication() to make sure the new spec is self-consistent. If the pool
+ * has a consistent replication level, then we ignore any errors. Otherwise,
+ * report any difference between the two.
+ */
+static int
+check_replication(nvlist_t *config, nvlist_t *newroot)
+{
+ nvlist_t **child;
+ uint_t children;
+ replication_level_t *current = NULL, *new;
+ int ret;
+
+ /*
+ * If we have a current pool configuration, check to see if it's
+ * self-consistent. If not, simply return success.
+ */
+ if (config != NULL) {
+ nvlist_t *nvroot;
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ if ((current = get_replication(nvroot, B_FALSE)) == NULL)
+ return (0);
+ }
+ /*
+ * for spares there may be no children, and therefore no
+ * replication level to check
+ */
+ if ((nvlist_lookup_nvlist_array(newroot, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) || (children == 0)) {
+ free(current);
+ return (0);
+ }
+
+ /*
+ * If all we have is logs then there's no replication level to check.
+ */
+ if (num_logs(newroot) == children) {
+ free(current);
+ return (0);
+ }
+
+ /*
+ * Get the replication level of the new vdev spec, reporting any
+ * inconsistencies found.
+ */
+ if ((new = get_replication(newroot, B_TRUE)) == NULL) {
+ free(current);
+ return (-1);
+ }
+
+ /*
+ * Check to see if the new vdev spec matches the replication level of
+ * the current pool.
+ */
+ ret = 0;
+ if (current != NULL) {
+ if (strcmp(current->zprl_type, new->zprl_type) != 0) {
+ vdev_error(gettext(
+ "mismatched replication level: pool uses %s "
+ "and new vdev is %s\n"),
+ current->zprl_type, new->zprl_type);
+ ret = -1;
+ } else if (current->zprl_parity != new->zprl_parity) {
+ vdev_error(gettext(
+ "mismatched replication level: pool uses %llu "
+ "device parity and new vdev uses %llu\n"),
+ current->zprl_parity, new->zprl_parity);
+ ret = -1;
+ } else if (current->zprl_children != new->zprl_children) {
+ vdev_error(gettext(
+ "mismatched replication level: pool uses %llu-way "
+ "%s and new vdev uses %llu-way %s\n"),
+ current->zprl_children, current->zprl_type,
+ new->zprl_children, new->zprl_type);
+ ret = -1;
+ }
+ }
+
+ free(new);
+ if (current != NULL)
+ free(current);
+
+ return (ret);
+}
+
+#ifdef sun
+/*
+ * Go through and find any whole disks in the vdev specification, labelling them
+ * as appropriate. When constructing the vdev spec, we were unable to open this
+ * device in order to provide a devid. Now that we have labelled the disk and
+ * know that slice 0 is valid, we can construct the devid now.
+ *
+ * If the disk was already labeled with an EFI label, we will have gotten the
+ * devid already (because we were able to open the whole disk). Otherwise, we
+ * need to get the devid after we label the disk.
+ */
+static int
+make_disks(zpool_handle_t *zhp, nvlist_t *nv)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ char *type, *path, *diskname;
+ char buf[MAXPATHLEN];
+ uint64_t wholedisk;
+ int fd;
+ int ret;
+ ddi_devid_t devid;
+ char *minor = NULL, *devid_str = NULL;
+
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) {
+
+ if (strcmp(type, VDEV_TYPE_DISK) != 0)
+ return (0);
+
+ /*
+ * We have a disk device. Get the path to the device
+ * and see if it's a whole disk by appending the backup
+ * slice and stat()ing the device.
+ */
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+ &wholedisk) != 0 || !wholedisk)
+ return (0);
+
+ diskname = strrchr(path, '/');
+ assert(diskname != NULL);
+ diskname++;
+ if (zpool_label_disk(g_zfs, zhp, diskname) == -1)
+ return (-1);
+
+ /*
+ * Fill in the devid, now that we've labeled the disk.
+ */
+ (void) snprintf(buf, sizeof (buf), "%ss0", path);
+ if ((fd = open(buf, O_RDONLY)) < 0) {
+ (void) fprintf(stderr,
+ gettext("cannot open '%s': %s\n"),
+ buf, strerror(errno));
+ return (-1);
+ }
+
+ if (devid_get(fd, &devid) == 0) {
+ if (devid_get_minor_name(fd, &minor) == 0 &&
+ (devid_str = devid_str_encode(devid, minor)) !=
+ NULL) {
+ verify(nvlist_add_string(nv,
+ ZPOOL_CONFIG_DEVID, devid_str) == 0);
+ }
+ if (devid_str != NULL)
+ devid_str_free(devid_str);
+ if (minor != NULL)
+ devid_str_free(minor);
+ devid_free(devid);
+ }
+
+ /*
+ * Update the path to refer to the 's0' slice. The presence of
+ * the 'whole_disk' field indicates to the CLI that we should
+ * chop off the slice number when displaying the device in
+ * future output.
+ */
+ verify(nvlist_add_string(nv, ZPOOL_CONFIG_PATH, buf) == 0);
+
+ (void) close(fd);
+
+ return (0);
+ }
+
+ for (c = 0; c < children; c++)
+ if ((ret = make_disks(zhp, child[c])) != 0)
+ return (ret);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0)
+ for (c = 0; c < children; c++)
+ if ((ret = make_disks(zhp, child[c])) != 0)
+ return (ret);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0)
+ for (c = 0; c < children; c++)
+ if ((ret = make_disks(zhp, child[c])) != 0)
+ return (ret);
+
+ return (0);
+}
+#endif /* sun */
+
+/*
+ * Determine if the given path is a hot spare within the given configuration.
+ */
+static boolean_t
+is_spare(nvlist_t *config, const char *path)
+{
+ int fd;
+ pool_state_t state;
+ char *name = NULL;
+ nvlist_t *label;
+ uint64_t guid, spareguid;
+ nvlist_t *nvroot;
+ nvlist_t **spares;
+ uint_t i, nspares;
+ boolean_t inuse;
+
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return (B_FALSE);
+
+ if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0 ||
+ !inuse ||
+ state != POOL_STATE_SPARE ||
+ zpool_read_label(fd, &label) != 0) {
+ free(name);
+ (void) close(fd);
+ return (B_FALSE);
+ }
+ free(name);
+ (void) close(fd);
+
+ verify(nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) == 0);
+ nvlist_free(label);
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ &spares, &nspares) == 0) {
+ for (i = 0; i < nspares; i++) {
+ verify(nvlist_lookup_uint64(spares[i],
+ ZPOOL_CONFIG_GUID, &spareguid) == 0);
+ if (spareguid == guid)
+ return (B_TRUE);
+ }
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * Go through and find any devices that are in use. We rely on libdiskmgt for
+ * the majority of this task.
+ */
+static int
+check_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
+ boolean_t replacing, boolean_t isspare)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ char *type, *path;
+ int ret;
+ char buf[MAXPATHLEN];
+ uint64_t wholedisk;
+
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0) {
+
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
+
+ /*
+ * As a generic check, we look to see if this is a replace of a
+ * hot spare within the same pool. If so, we allow it
+ * regardless of what libdiskmgt or zpool_in_use() says.
+ */
+ if (replacing) {
+#ifdef sun
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+ &wholedisk) == 0 && wholedisk)
+ (void) snprintf(buf, sizeof (buf), "%ss0",
+ path);
+ else
+#endif
+ (void) strlcpy(buf, path, sizeof (buf));
+
+ if (is_spare(config, buf))
+ return (0);
+ }
+
+ if (strcmp(type, VDEV_TYPE_DISK) == 0)
+ ret = check_device(path, force, isspare);
+
+ if (strcmp(type, VDEV_TYPE_FILE) == 0)
+ ret = check_file(path, force, isspare);
+
+ return (ret);
+ }
+
+ for (c = 0; c < children; c++)
+ if ((ret = check_in_use(config, child[c], force,
+ replacing, B_FALSE)) != 0)
+ return (ret);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0)
+ for (c = 0; c < children; c++)
+ if ((ret = check_in_use(config, child[c], force,
+ replacing, B_TRUE)) != 0)
+ return (ret);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0)
+ for (c = 0; c < children; c++)
+ if ((ret = check_in_use(config, child[c], force,
+ replacing, B_FALSE)) != 0)
+ return (ret);
+
+ return (0);
+}
+
+static const char *
+is_grouping(const char *type, int *mindev, int *maxdev)
+{
+ if (strncmp(type, "raidz", 5) == 0) {
+ const char *p = type + 5;
+ char *end;
+ long nparity;
+
+ if (*p == '\0') {
+ nparity = 1;
+ } else if (*p == '0') {
+ return (NULL); /* no zero prefixes allowed */
+ } else {
+ errno = 0;
+ nparity = strtol(p, &end, 10);
+ if (errno != 0 || nparity < 1 || nparity >= 255 ||
+ *end != '\0')
+ return (NULL);
+ }
+
+ if (mindev != NULL)
+ *mindev = nparity + 1;
+ if (maxdev != NULL)
+ *maxdev = 255;
+ return (VDEV_TYPE_RAIDZ);
+ }
+
+ if (maxdev != NULL)
+ *maxdev = INT_MAX;
+
+ if (strcmp(type, "mirror") == 0) {
+ if (mindev != NULL)
+ *mindev = 2;
+ return (VDEV_TYPE_MIRROR);
+ }
+
+ if (strcmp(type, "spare") == 0) {
+ if (mindev != NULL)
+ *mindev = 1;
+ return (VDEV_TYPE_SPARE);
+ }
+
+ if (strcmp(type, "log") == 0) {
+ if (mindev != NULL)
+ *mindev = 1;
+ return (VDEV_TYPE_LOG);
+ }
+
+ if (strcmp(type, "cache") == 0) {
+ if (mindev != NULL)
+ *mindev = 1;
+ return (VDEV_TYPE_L2CACHE);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Construct a syntactically valid vdev specification,
+ * and ensure that all devices and files exist and can be opened.
+ * Note: we don't bother freeing anything in the error paths
+ * because the program is just going to exit anyway.
+ */
+nvlist_t *
+construct_spec(int argc, char **argv)
+{
+ nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
+ int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
+ const char *type;
+ uint64_t is_log;
+ boolean_t seen_logs;
+
+ top = NULL;
+ toplevels = 0;
+ spares = NULL;
+ l2cache = NULL;
+ nspares = 0;
+ nlogs = 0;
+ nl2cache = 0;
+ is_log = B_FALSE;
+ seen_logs = B_FALSE;
+
+ while (argc > 0) {
+ nv = NULL;
+
+ /*
+ * If it's a mirror or raidz, the subsequent arguments are
+ * its leaves -- until we encounter the next mirror or raidz.
+ */
+ if ((type = is_grouping(argv[0], &mindev, &maxdev)) != NULL) {
+ nvlist_t **child = NULL;
+ int c, children = 0;
+
+ if (strcmp(type, VDEV_TYPE_SPARE) == 0) {
+ if (spares != NULL) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: 'spare' can be "
+ "specified only once\n"));
+ return (NULL);
+ }
+ is_log = B_FALSE;
+ }
+
+ if (strcmp(type, VDEV_TYPE_LOG) == 0) {
+ if (seen_logs) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: 'log' can be "
+ "specified only once\n"));
+ return (NULL);
+ }
+ seen_logs = B_TRUE;
+ is_log = B_TRUE;
+ argc--;
+ argv++;
+ /*
+ * A log is not a real grouping device.
+ * We just set is_log and continue.
+ */
+ continue;
+ }
+
+ if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
+ if (l2cache != NULL) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: 'cache' can be "
+ "specified only once\n"));
+ return (NULL);
+ }
+ is_log = B_FALSE;
+ }
+
+ if (is_log) {
+ if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: unsupported 'log' "
+ "device: %s\n"), type);
+ return (NULL);
+ }
+ nlogs++;
+ }
+
+ for (c = 1; c < argc; c++) {
+ if (is_grouping(argv[c], NULL, NULL) != NULL)
+ break;
+ children++;
+ child = realloc(child,
+ children * sizeof (nvlist_t *));
+ if (child == NULL)
+ zpool_no_memory();
+ if ((nv = make_leaf_vdev(argv[c], B_FALSE))
+ == NULL)
+ return (NULL);
+ child[children - 1] = nv;
+ }
+
+ if (children < mindev) {
+ (void) fprintf(stderr, gettext("invalid vdev "
+ "specification: %s requires at least %d "
+ "devices\n"), argv[0], mindev);
+ return (NULL);
+ }
+
+ if (children > maxdev) {
+ (void) fprintf(stderr, gettext("invalid vdev "
+ "specification: %s supports no more than "
+ "%d devices\n"), argv[0], maxdev);
+ return (NULL);
+ }
+
+ argc -= c;
+ argv += c;
+
+ if (strcmp(type, VDEV_TYPE_SPARE) == 0) {
+ spares = child;
+ nspares = children;
+ continue;
+ } else if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
+ l2cache = child;
+ nl2cache = children;
+ continue;
+ } else {
+ verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
+ 0) == 0);
+ verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
+ type) == 0);
+ verify(nvlist_add_uint64(nv,
+ ZPOOL_CONFIG_IS_LOG, is_log) == 0);
+ if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
+ verify(nvlist_add_uint64(nv,
+ ZPOOL_CONFIG_NPARITY,
+ mindev - 1) == 0);
+ }
+ verify(nvlist_add_nvlist_array(nv,
+ ZPOOL_CONFIG_CHILDREN, child,
+ children) == 0);
+
+ for (c = 0; c < children; c++)
+ nvlist_free(child[c]);
+ free(child);
+ }
+ } else {
+ /*
+ * We have a device. Pass off to make_leaf_vdev() to
+ * construct the appropriate nvlist describing the vdev.
+ */
+ if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
+ return (NULL);
+ if (is_log)
+ nlogs++;
+ argc--;
+ argv++;
+ }
+
+ toplevels++;
+ top = realloc(top, toplevels * sizeof (nvlist_t *));
+ if (top == NULL)
+ zpool_no_memory();
+ top[toplevels - 1] = nv;
+ }
+
+ if (toplevels == 0 && nspares == 0 && nl2cache == 0) {
+ (void) fprintf(stderr, gettext("invalid vdev "
+ "specification: at least one toplevel vdev must be "
+ "specified\n"));
+ return (NULL);
+ }
+
+ if (seen_logs && nlogs == 0) {
+ (void) fprintf(stderr, gettext("invalid vdev specification: "
+ "log requires at least 1 device\n"));
+ return (NULL);
+ }
+
+ /*
+ * Finally, create nvroot and add all top-level vdevs to it.
+ */
+ verify(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, 0) == 0);
+ verify(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_ROOT) == 0);
+ verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ top, toplevels) == 0);
+ if (nspares != 0)
+ verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ spares, nspares) == 0);
+ if (nl2cache != 0)
+ verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+ l2cache, nl2cache) == 0);
+
+ for (t = 0; t < toplevels; t++)
+ nvlist_free(top[t]);
+ for (t = 0; t < nspares; t++)
+ nvlist_free(spares[t]);
+ for (t = 0; t < nl2cache; t++)
+ nvlist_free(l2cache[t]);
+ if (spares)
+ free(spares);
+ if (l2cache)
+ free(l2cache);
+ free(top);
+
+ return (nvroot);
+}
+
+nvlist_t *
+split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
+ splitflags_t flags, int argc, char **argv)
+{
+ nvlist_t *newroot = NULL, **child;
+ uint_t c, children;
+
+ if (argc > 0) {
+ if ((newroot = construct_spec(argc, argv)) == NULL) {
+ (void) fprintf(stderr, gettext("Unable to build a "
+ "pool from the specified devices\n"));
+ return (NULL);
+ }
+
+#ifdef sun
+ if (!flags.dryrun && make_disks(zhp, newroot) != 0) {
+ nvlist_free(newroot);
+ return (NULL);
+ }
+#endif
+
+ /* avoid any tricks in the spec */
+ verify(nvlist_lookup_nvlist_array(newroot,
+ ZPOOL_CONFIG_CHILDREN, &child, &children) == 0);
+ for (c = 0; c < children; c++) {
+ char *path;
+ const char *type;
+ int min, max;
+
+ verify(nvlist_lookup_string(child[c],
+ ZPOOL_CONFIG_PATH, &path) == 0);
+ if ((type = is_grouping(path, &min, &max)) != NULL) {
+ (void) fprintf(stderr, gettext("Cannot use "
+ "'%s' as a device for splitting\n"), type);
+ nvlist_free(newroot);
+ return (NULL);
+ }
+ }
+ }
+
+ if (zpool_vdev_split(zhp, newname, &newroot, props, flags) != 0) {
+ if (newroot != NULL)
+ nvlist_free(newroot);
+ return (NULL);
+ }
+
+ return (newroot);
+}
+
+/*
+ * Get and validate the contents of the given vdev specification. This ensures
+ * that the nvlist returned is well-formed, that all the devices exist, and that
+ * they are not currently in use by any other known consumer. The 'poolconfig'
+ * parameter is the current configuration of the pool when adding devices
+ * existing pool, and is used to perform additional checks, such as changing the
+ * replication level of the pool. It can be 'NULL' to indicate that this is a
+ * new pool. The 'force' flag controls whether devices should be forcefully
+ * added, even if they appear in use.
+ */
+nvlist_t *
+make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
+ boolean_t replacing, boolean_t dryrun, int argc, char **argv)
+{
+ nvlist_t *newroot;
+ nvlist_t *poolconfig = NULL;
+ is_force = force;
+
+ /*
+ * Construct the vdev specification. If this is successful, we know
+ * that we have a valid specification, and that all devices can be
+ * opened.
+ */
+ if ((newroot = construct_spec(argc, argv)) == NULL)
+ return (NULL);
+
+ if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
+ return (NULL);
+
+ /*
+ * Validate each device to make sure that its not shared with another
+ * subsystem. We do this even if 'force' is set, because there are some
+ * uses (such as a dedicated dump device) that even '-f' cannot
+ * override.
+ */
+ if (check_in_use(poolconfig, newroot, force, replacing, B_FALSE) != 0) {
+ nvlist_free(newroot);
+ return (NULL);
+ }
+
+ /*
+ * Check the replication level of the given vdevs and report any errors
+ * found. We include the existing pool spec, if any, as we need to
+ * catch changes against the existing replication level.
+ */
+ if (check_rep && check_replication(poolconfig, newroot) != 0) {
+ nvlist_free(newroot);
+ return (NULL);
+ }
+
+#ifdef sun
+ /*
+ * Run through the vdev specification and label any whole disks found.
+ */
+ if (!dryrun && make_disks(zhp, newroot) != 0) {
+ nvlist_free(newroot);
+ return (NULL);
+ }
+#endif
+
+ return (newroot);
+}
diff --git a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1 b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1
new file mode 100644
index 0000000..6f8ca6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.1
@@ -0,0 +1,67 @@
+'\" te
+.\" Copyright (c) 2011, Martin Matuska <mm@FreeBSD.org>.
+.\" All Rights Reserved.
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 26, 2011
+.Dt ZSTREAMDUMP 8
+.Os
+.Sh NAME
+.Nm zstreamdump
+.Nd filter data in zfs send stream
+.Sh SYNOPSIS
+.Nm
+.Op Fl C
+.Op Fl v
+.Sh DESCRIPTION
+The
+.Nm
+utility reads from the output of the
+.Qq Nm zfs Cm send
+command, then displays headers and some statistics from that output. See
+.Xr zfs 8 .
+.Pp
+The following options are supported:
+.Bl -tag -width indent
+.It Fl C
+Suppress the validation of checksums.
+.It Fl v
+Verbose. Dump all headers, not only begin and end headers.
+.El
+.Sh SEE ALSO
+.Xr zfs 8
+.Sh AUTHORS
+This manual page is a
+.Xr mdoc 7
+reimplementation of the
+.Tn OpenSolaris
+manual page
+.Em zstreamdump(1M) ,
+modified and customized for
+.Fx
+and licensed under the
+.Tn Common Development and Distribution License
+.Pq Tn CDDL .
+.Pp
+The
+.Xr mdoc 7
+implementation of this manual page was initially written by
+.An Martin Matuska Aq mm@FreeBSD.org .
diff --git a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c
new file mode 100644
index 0000000..df23cc1
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c
@@ -0,0 +1,429 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <libnvpair.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <sys/dmu.h>
+#include <sys/zfs_ioctl.h>
+#include <zfs_fletcher.h>
+
+uint64_t drr_record_count[DRR_NUMTYPES];
+uint64_t total_write_size = 0;
+uint64_t total_stream_len = 0;
+FILE *send_stream = 0;
+boolean_t do_byteswap = B_FALSE;
+boolean_t do_cksum = B_TRUE;
+#define INITIAL_BUFLEN (1<<20)
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, "usage: zstreamdump [-v] [-C] < file\n");
+ (void) fprintf(stderr, "\t -v -- verbose\n");
+ (void) fprintf(stderr, "\t -C -- suppress checksum verification\n");
+ exit(1);
+}
+
+/*
+ * ssread - send stream read.
+ *
+ * Read while computing incremental checksum
+ */
+
+static size_t
+ssread(void *buf, size_t len, zio_cksum_t *cksum)
+{
+ size_t outlen;
+
+ if ((outlen = fread(buf, len, 1, send_stream)) == 0)
+ return (0);
+
+ if (do_cksum && cksum) {
+ if (do_byteswap)
+ fletcher_4_incremental_byteswap(buf, len, cksum);
+ else
+ fletcher_4_incremental_native(buf, len, cksum);
+ }
+ total_stream_len += len;
+ return (outlen);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *buf = malloc(INITIAL_BUFLEN);
+ dmu_replay_record_t thedrr;
+ dmu_replay_record_t *drr = &thedrr;
+ struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
+ struct drr_end *drre = &thedrr.drr_u.drr_end;
+ struct drr_object *drro = &thedrr.drr_u.drr_object;
+ struct drr_freeobjects *drrfo = &thedrr.drr_u.drr_freeobjects;
+ struct drr_write *drrw = &thedrr.drr_u.drr_write;
+ struct drr_write_byref *drrwbr = &thedrr.drr_u.drr_write_byref;
+ struct drr_free *drrf = &thedrr.drr_u.drr_free;
+ struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
+ char c;
+ boolean_t verbose = B_FALSE;
+ boolean_t first = B_TRUE;
+ int err;
+ zio_cksum_t zc = { 0 };
+ zio_cksum_t pcksum = { 0 };
+
+ while ((c = getopt(argc, argv, ":vC")) != -1) {
+ switch (c) {
+ case 'C':
+ do_cksum = B_FALSE;
+ break;
+ case 'v':
+ verbose = B_TRUE;
+ break;
+ case ':':
+ (void) fprintf(stderr,
+ "missing argument for '%c' option\n", optopt);
+ usage();
+ break;
+ case '?':
+ (void) fprintf(stderr, "invalid option '%c'\n",
+ optopt);
+ usage();
+ }
+ }
+
+ if (isatty(STDIN_FILENO)) {
+ (void) fprintf(stderr,
+ "Error: Backup stream can not be read "
+ "from a terminal.\n"
+ "You must redirect standard input.\n");
+ exit(1);
+ }
+
+ send_stream = stdin;
+ pcksum = zc;
+ while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {
+
+ if (first) {
+ if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
+ do_byteswap = B_TRUE;
+ if (do_cksum) {
+ ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
+ /*
+ * recalculate header checksum now
+ * that we know it needs to be
+ * byteswapped.
+ */
+ fletcher_4_incremental_byteswap(drr,
+ sizeof (dmu_replay_record_t), &zc);
+ }
+ } else if (drrb->drr_magic != DMU_BACKUP_MAGIC) {
+ (void) fprintf(stderr, "Invalid stream "
+ "(bad magic number)\n");
+ exit(1);
+ }
+ first = B_FALSE;
+ }
+ if (do_byteswap) {
+ drr->drr_type = BSWAP_32(drr->drr_type);
+ drr->drr_payloadlen =
+ BSWAP_32(drr->drr_payloadlen);
+ }
+
+ /*
+ * At this point, the leading fields of the replay record
+ * (drr_type and drr_payloadlen) have been byte-swapped if
+ * necessary, but the rest of the data structure (the
+ * union of type-specific structures) is still in its
+ * original state.
+ */
+ if (drr->drr_type >= DRR_NUMTYPES) {
+ (void) printf("INVALID record found: type 0x%x\n",
+ drr->drr_type);
+ (void) printf("Aborting.\n");
+ exit(1);
+ }
+
+ drr_record_count[drr->drr_type]++;
+
+ switch (drr->drr_type) {
+ case DRR_BEGIN:
+ if (do_byteswap) {
+ drrb->drr_magic = BSWAP_64(drrb->drr_magic);
+ drrb->drr_versioninfo =
+ BSWAP_64(drrb->drr_versioninfo);
+ drrb->drr_creation_time =
+ BSWAP_64(drrb->drr_creation_time);
+ drrb->drr_type = BSWAP_32(drrb->drr_type);
+ drrb->drr_flags = BSWAP_32(drrb->drr_flags);
+ drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
+ drrb->drr_fromguid =
+ BSWAP_64(drrb->drr_fromguid);
+ }
+
+ (void) printf("BEGIN record\n");
+ (void) printf("\thdrtype = %lld\n",
+ DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo));
+ (void) printf("\tfeatures = %llx\n",
+ DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo));
+ (void) printf("\tmagic = %llx\n",
+ (u_longlong_t)drrb->drr_magic);
+ (void) printf("\tcreation_time = %llx\n",
+ (u_longlong_t)drrb->drr_creation_time);
+ (void) printf("\ttype = %u\n", drrb->drr_type);
+ (void) printf("\tflags = 0x%x\n", drrb->drr_flags);
+ (void) printf("\ttoguid = %llx\n",
+ (u_longlong_t)drrb->drr_toguid);
+ (void) printf("\tfromguid = %llx\n",
+ (u_longlong_t)drrb->drr_fromguid);
+ (void) printf("\ttoname = %s\n", drrb->drr_toname);
+ if (verbose)
+ (void) printf("\n");
+
+ if ((DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
+ DMU_COMPOUNDSTREAM) && drr->drr_payloadlen != 0) {
+ nvlist_t *nv;
+ int sz = drr->drr_payloadlen;
+
+ if (sz > 1<<20) {
+ free(buf);
+ buf = malloc(sz);
+ }
+ (void) ssread(buf, sz, &zc);
+ if (ferror(send_stream))
+ perror("fread");
+ err = nvlist_unpack(buf, sz, &nv, 0);
+ if (err)
+ perror(strerror(err));
+ nvlist_print(stdout, nv);
+ nvlist_free(nv);
+ }
+ break;
+
+ case DRR_END:
+ if (do_byteswap) {
+ drre->drr_checksum.zc_word[0] =
+ BSWAP_64(drre->drr_checksum.zc_word[0]);
+ drre->drr_checksum.zc_word[1] =
+ BSWAP_64(drre->drr_checksum.zc_word[1]);
+ drre->drr_checksum.zc_word[2] =
+ BSWAP_64(drre->drr_checksum.zc_word[2]);
+ drre->drr_checksum.zc_word[3] =
+ BSWAP_64(drre->drr_checksum.zc_word[3]);
+ }
+ /*
+ * We compare against the *previous* checksum
+ * value, because the stored checksum is of
+ * everything before the DRR_END record.
+ */
+ if (do_cksum && !ZIO_CHECKSUM_EQUAL(drre->drr_checksum,
+ pcksum)) {
+ (void) printf("Expected checksum differs from "
+ "checksum in stream.\n");
+ (void) printf("Expected checksum = "
+ "%llx/%llx/%llx/%llx\n",
+ pcksum.zc_word[0],
+ pcksum.zc_word[1],
+ pcksum.zc_word[2],
+ pcksum.zc_word[3]);
+ }
+ (void) printf("END checksum = %llx/%llx/%llx/%llx\n",
+ drre->drr_checksum.zc_word[0],
+ drre->drr_checksum.zc_word[1],
+ drre->drr_checksum.zc_word[2],
+ drre->drr_checksum.zc_word[3]);
+
+ ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
+ break;
+
+ case DRR_OBJECT:
+ if (do_byteswap) {
+ drro->drr_object = BSWAP_64(drro->drr_object);
+ drro->drr_type = BSWAP_32(drro->drr_type);
+ drro->drr_bonustype =
+ BSWAP_32(drro->drr_bonustype);
+ drro->drr_blksz = BSWAP_32(drro->drr_blksz);
+ drro->drr_bonuslen =
+ BSWAP_32(drro->drr_bonuslen);
+ drro->drr_toguid = BSWAP_64(drro->drr_toguid);
+ }
+ if (verbose) {
+ (void) printf("OBJECT object = %llu type = %u "
+ "bonustype = %u blksz = %u bonuslen = %u\n",
+ (u_longlong_t)drro->drr_object,
+ drro->drr_type,
+ drro->drr_bonustype,
+ drro->drr_blksz,
+ drro->drr_bonuslen);
+ }
+ if (drro->drr_bonuslen > 0) {
+ (void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen,
+ 8), &zc);
+ }
+ break;
+
+ case DRR_FREEOBJECTS:
+ if (do_byteswap) {
+ drrfo->drr_firstobj =
+ BSWAP_64(drrfo->drr_firstobj);
+ drrfo->drr_numobjs =
+ BSWAP_64(drrfo->drr_numobjs);
+ drrfo->drr_toguid = BSWAP_64(drrfo->drr_toguid);
+ }
+ if (verbose) {
+ (void) printf("FREEOBJECTS firstobj = %llu "
+ "numobjs = %llu\n",
+ (u_longlong_t)drrfo->drr_firstobj,
+ (u_longlong_t)drrfo->drr_numobjs);
+ }
+ break;
+
+ case DRR_WRITE:
+ if (do_byteswap) {
+ drrw->drr_object = BSWAP_64(drrw->drr_object);
+ drrw->drr_type = BSWAP_32(drrw->drr_type);
+ drrw->drr_offset = BSWAP_64(drrw->drr_offset);
+ drrw->drr_length = BSWAP_64(drrw->drr_length);
+ drrw->drr_toguid = BSWAP_64(drrw->drr_toguid);
+ drrw->drr_key.ddk_prop =
+ BSWAP_64(drrw->drr_key.ddk_prop);
+ }
+ if (verbose) {
+ (void) printf("WRITE object = %llu type = %u "
+ "checksum type = %u\n"
+ "offset = %llu length = %llu "
+ "props = %llx\n",
+ (u_longlong_t)drrw->drr_object,
+ drrw->drr_type,
+ drrw->drr_checksumtype,
+ (u_longlong_t)drrw->drr_offset,
+ (u_longlong_t)drrw->drr_length,
+ (u_longlong_t)drrw->drr_key.ddk_prop);
+ }
+ (void) ssread(buf, drrw->drr_length, &zc);
+ total_write_size += drrw->drr_length;
+ break;
+
+ case DRR_WRITE_BYREF:
+ if (do_byteswap) {
+ drrwbr->drr_object =
+ BSWAP_64(drrwbr->drr_object);
+ drrwbr->drr_offset =
+ BSWAP_64(drrwbr->drr_offset);
+ drrwbr->drr_length =
+ BSWAP_64(drrwbr->drr_length);
+ drrwbr->drr_toguid =
+ BSWAP_64(drrwbr->drr_toguid);
+ drrwbr->drr_refguid =
+ BSWAP_64(drrwbr->drr_refguid);
+ drrwbr->drr_refobject =
+ BSWAP_64(drrwbr->drr_refobject);
+ drrwbr->drr_refoffset =
+ BSWAP_64(drrwbr->drr_refoffset);
+ drrwbr->drr_key.ddk_prop =
+ BSWAP_64(drrwbr->drr_key.ddk_prop);
+ }
+ if (verbose) {
+ (void) printf("WRITE_BYREF object = %llu "
+ "checksum type = %u props = %llx\n"
+ "offset = %llu length = %llu\n"
+ "toguid = %llx refguid = %llx\n"
+ "refobject = %llu refoffset = %llu\n",
+ (u_longlong_t)drrwbr->drr_object,
+ drrwbr->drr_checksumtype,
+ (u_longlong_t)drrwbr->drr_key.ddk_prop,
+ (u_longlong_t)drrwbr->drr_offset,
+ (u_longlong_t)drrwbr->drr_length,
+ (u_longlong_t)drrwbr->drr_toguid,
+ (u_longlong_t)drrwbr->drr_refguid,
+ (u_longlong_t)drrwbr->drr_refobject,
+ (u_longlong_t)drrwbr->drr_refoffset);
+ }
+ break;
+
+ case DRR_FREE:
+ if (do_byteswap) {
+ drrf->drr_object = BSWAP_64(drrf->drr_object);
+ drrf->drr_offset = BSWAP_64(drrf->drr_offset);
+ drrf->drr_length = BSWAP_64(drrf->drr_length);
+ }
+ if (verbose) {
+ (void) printf("FREE object = %llu "
+ "offset = %llu length = %lld\n",
+ (u_longlong_t)drrf->drr_object,
+ (u_longlong_t)drrf->drr_offset,
+ (longlong_t)drrf->drr_length);
+ }
+ break;
+ case DRR_SPILL:
+ if (do_byteswap) {
+ drrs->drr_object = BSWAP_64(drrs->drr_object);
+ drrs->drr_length = BSWAP_64(drrs->drr_length);
+ }
+ if (verbose) {
+ (void) printf("SPILL block for object = %llu "
+ "length = %llu\n", drrs->drr_object,
+ drrs->drr_length);
+ }
+ (void) ssread(buf, drrs->drr_length, &zc);
+ break;
+ }
+ pcksum = zc;
+ }
+ free(buf);
+
+ /* Print final summary */
+
+ (void) printf("SUMMARY:\n");
+ (void) printf("\tTotal DRR_BEGIN records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_BEGIN]);
+ (void) printf("\tTotal DRR_END records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_END]);
+ (void) printf("\tTotal DRR_OBJECT records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_OBJECT]);
+ (void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_FREEOBJECTS]);
+ (void) printf("\tTotal DRR_WRITE records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_WRITE]);
+ (void) printf("\tTotal DRR_FREE records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_FREE]);
+ (void) printf("\tTotal DRR_SPILL records = %lld\n",
+ (u_longlong_t)drr_record_count[DRR_SPILL]);
+ (void) printf("\tTotal records = %lld\n",
+ (u_longlong_t)(drr_record_count[DRR_BEGIN] +
+ drr_record_count[DRR_OBJECT] +
+ drr_record_count[DRR_FREEOBJECTS] +
+ drr_record_count[DRR_WRITE] +
+ drr_record_count[DRR_FREE] +
+ drr_record_count[DRR_SPILL] +
+ drr_record_count[DRR_END]));
+ (void) printf("\tTotal write size = %lld (0x%llx)\n",
+ (u_longlong_t)total_write_size, (u_longlong_t)total_write_size);
+ (void) printf("\tTotal stream length = %lld (0x%llx)\n",
+ (u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
new file mode 100644
index 0000000..ef776a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -0,0 +1,6228 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+/*
+ * The objective of this program is to provide a DMU/ZAP/SPA stress test
+ * that runs entirely in userland, is easy to use, and easy to extend.
+ *
+ * The overall design of the ztest program is as follows:
+ *
+ * (1) For each major functional area (e.g. adding vdevs to a pool,
+ * creating and destroying datasets, reading and writing objects, etc)
+ * we have a simple routine to test that functionality. These
+ * individual routines do not have to do anything "stressful".
+ *
+ * (2) We turn these simple functionality tests into a stress test by
+ * running them all in parallel, with as many threads as desired,
+ * and spread across as many datasets, objects, and vdevs as desired.
+ *
+ * (3) While all this is happening, we inject faults into the pool to
+ * verify that self-healing data really works.
+ *
+ * (4) Every time we open a dataset, we change its checksum and compression
+ * functions. Thus even individual objects vary from block to block
+ * in which checksum they use and whether they're compressed.
+ *
+ * (5) To verify that we never lose on-disk consistency after a crash,
+ * we run the entire test in a child of the main process.
+ * At random times, the child self-immolates with a SIGKILL.
+ * This is the software equivalent of pulling the power cord.
+ * The parent then runs the test again, using the existing
+ * storage pool, as many times as desired. If backwards compatability
+ * testing is enabled ztest will sometimes run the "older" version
+ * of ztest after a SIGKILL.
+ *
+ * (6) To verify that we don't have future leaks or temporal incursions,
+ * many of the functional tests record the transaction group number
+ * as part of their data. When reading old data, they verify that
+ * the transaction group number is less than the current, open txg.
+ * If you add a new test, please do this if applicable.
+ *
+ * When run with no arguments, ztest runs for about five minutes and
+ * produces no output if successful. To get a little bit of information,
+ * specify -V. To get more information, specify -VV, and so on.
+ *
+ * To turn this into an overnight stress test, use -T to specify run time.
+ *
+ * You can ask more more vdevs [-v], datasets [-d], or threads [-t]
+ * to increase the pool capacity, fanout, and overall stress level.
+ *
+ * Use the -k option to set the desired frequency of kills.
+ *
+ * When ztest invokes itself it passes all relevant information through a
+ * temporary file which is mmap-ed in the child process. This allows shared
+ * memory to survive the exec syscall. The ztest_shared_hdr_t struct is always
+ * stored at offset 0 of this file and contains information on the size and
+ * number of shared structures in the file. The information stored in this file
+ * must remain backwards compatible with older versions of ztest so that
+ * ztest can invoke them during backwards compatibility testing (-B).
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/dmu.h>
+#include <sys/txg.h>
+#include <sys/dbuf.h>
+#include <sys/zap.h>
+#include <sys/dmu_objset.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/zio.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+#include <sys/vdev_impl.h>
+#include <sys/vdev_file.h>
+#include <sys/spa_impl.h>
+#include <sys/metaslab_impl.h>
+#include <sys/dsl_prop.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_destroy.h>
+#include <sys/dsl_scan.h>
+#include <sys/zio_checksum.h>
+#include <sys/refcount.h>
+#include <sys/zfeature.h>
+#include <sys/dsl_userhold.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <umem.h>
+#include <dlfcn.h>
+#include <ctype.h>
+#include <math.h>
+#include <errno.h>
+#include <sys/fs/zfs.h>
+#include <libnvpair.h>
+
+static int ztest_fd_data = -1;
+static int ztest_fd_rand = -1;
+
+typedef struct ztest_shared_hdr {
+ uint64_t zh_hdr_size;
+ uint64_t zh_opts_size;
+ uint64_t zh_size;
+ uint64_t zh_stats_size;
+ uint64_t zh_stats_count;
+ uint64_t zh_ds_size;
+ uint64_t zh_ds_count;
+} ztest_shared_hdr_t;
+
+static ztest_shared_hdr_t *ztest_shared_hdr;
+
+typedef struct ztest_shared_opts {
+ char zo_pool[MAXNAMELEN];
+ char zo_dir[MAXNAMELEN];
+ char zo_alt_ztest[MAXNAMELEN];
+ char zo_alt_libpath[MAXNAMELEN];
+ uint64_t zo_vdevs;
+ uint64_t zo_vdevtime;
+ size_t zo_vdev_size;
+ int zo_ashift;
+ int zo_mirrors;
+ int zo_raidz;
+ int zo_raidz_parity;
+ int zo_datasets;
+ int zo_threads;
+ uint64_t zo_passtime;
+ uint64_t zo_killrate;
+ int zo_verbose;
+ int zo_init;
+ uint64_t zo_time;
+ uint64_t zo_maxloops;
+ uint64_t zo_metaslab_gang_bang;
+} ztest_shared_opts_t;
+
+static const ztest_shared_opts_t ztest_opts_defaults = {
+ .zo_pool = { 'z', 't', 'e', 's', 't', '\0' },
+ .zo_dir = { '/', 't', 'm', 'p', '\0' },
+ .zo_alt_ztest = { '\0' },
+ .zo_alt_libpath = { '\0' },
+ .zo_vdevs = 5,
+ .zo_ashift = SPA_MINBLOCKSHIFT,
+ .zo_mirrors = 2,
+ .zo_raidz = 4,
+ .zo_raidz_parity = 1,
+ .zo_vdev_size = SPA_MINDEVSIZE,
+ .zo_datasets = 7,
+ .zo_threads = 23,
+ .zo_passtime = 60, /* 60 seconds */
+ .zo_killrate = 70, /* 70% kill rate */
+ .zo_verbose = 0,
+ .zo_init = 1,
+ .zo_time = 300, /* 5 minutes */
+ .zo_maxloops = 50, /* max loops during spa_freeze() */
+ .zo_metaslab_gang_bang = 32 << 10
+};
+
+extern uint64_t metaslab_gang_bang;
+extern uint64_t metaslab_df_alloc_threshold;
+
+static ztest_shared_opts_t *ztest_shared_opts;
+static ztest_shared_opts_t ztest_opts;
+
+typedef struct ztest_shared_ds {
+ uint64_t zd_seq;
+} ztest_shared_ds_t;
+
+static ztest_shared_ds_t *ztest_shared_ds;
+#define ZTEST_GET_SHARED_DS(d) (&ztest_shared_ds[d])
+
+#define BT_MAGIC 0x123456789abcdefULL
+#define MAXFAULTS() \
+ (MAX(zs->zs_mirrors, 1) * (ztest_opts.zo_raidz_parity + 1) - 1)
+
+enum ztest_io_type {
+ ZTEST_IO_WRITE_TAG,
+ ZTEST_IO_WRITE_PATTERN,
+ ZTEST_IO_WRITE_ZEROES,
+ ZTEST_IO_TRUNCATE,
+ ZTEST_IO_SETATTR,
+ ZTEST_IO_REWRITE,
+ ZTEST_IO_TYPES
+};
+
+typedef struct ztest_block_tag {
+ uint64_t bt_magic;
+ uint64_t bt_objset;
+ uint64_t bt_object;
+ uint64_t bt_offset;
+ uint64_t bt_gen;
+ uint64_t bt_txg;
+ uint64_t bt_crtxg;
+} ztest_block_tag_t;
+
+typedef struct bufwad {
+ uint64_t bw_index;
+ uint64_t bw_txg;
+ uint64_t bw_data;
+} bufwad_t;
+
+/*
+ * XXX -- fix zfs range locks to be generic so we can use them here.
+ */
+typedef enum {
+ RL_READER,
+ RL_WRITER,
+ RL_APPEND
+} rl_type_t;
+
+typedef struct rll {
+ void *rll_writer;
+ int rll_readers;
+ mutex_t rll_lock;
+ cond_t rll_cv;
+} rll_t;
+
+typedef struct rl {
+ uint64_t rl_object;
+ uint64_t rl_offset;
+ uint64_t rl_size;
+ rll_t *rl_lock;
+} rl_t;
+
+#define ZTEST_RANGE_LOCKS 64
+#define ZTEST_OBJECT_LOCKS 64
+
+/*
+ * Object descriptor. Used as a template for object lookup/create/remove.
+ */
+typedef struct ztest_od {
+ uint64_t od_dir;
+ uint64_t od_object;
+ dmu_object_type_t od_type;
+ dmu_object_type_t od_crtype;
+ uint64_t od_blocksize;
+ uint64_t od_crblocksize;
+ uint64_t od_gen;
+ uint64_t od_crgen;
+ char od_name[MAXNAMELEN];
+} ztest_od_t;
+
+/*
+ * Per-dataset state.
+ */
+typedef struct ztest_ds {
+ ztest_shared_ds_t *zd_shared;
+ objset_t *zd_os;
+ rwlock_t zd_zilog_lock;
+ zilog_t *zd_zilog;
+ ztest_od_t *zd_od; /* debugging aid */
+ char zd_name[MAXNAMELEN];
+ mutex_t zd_dirobj_lock;
+ rll_t zd_object_lock[ZTEST_OBJECT_LOCKS];
+ rll_t zd_range_lock[ZTEST_RANGE_LOCKS];
+} ztest_ds_t;
+
+/*
+ * Per-iteration state.
+ */
+typedef void ztest_func_t(ztest_ds_t *zd, uint64_t id);
+
+typedef struct ztest_info {
+ ztest_func_t *zi_func; /* test function */
+ uint64_t zi_iters; /* iterations per execution */
+ uint64_t *zi_interval; /* execute every <interval> seconds */
+} ztest_info_t;
+
+typedef struct ztest_shared_callstate {
+ uint64_t zc_count; /* per-pass count */
+ uint64_t zc_time; /* per-pass time */
+ uint64_t zc_next; /* next time to call this function */
+} ztest_shared_callstate_t;
+
+static ztest_shared_callstate_t *ztest_shared_callstate;
+#define ZTEST_GET_SHARED_CALLSTATE(c) (&ztest_shared_callstate[c])
+
+/*
+ * Note: these aren't static because we want dladdr() to work.
+ */
+ztest_func_t ztest_dmu_read_write;
+ztest_func_t ztest_dmu_write_parallel;
+ztest_func_t ztest_dmu_object_alloc_free;
+ztest_func_t ztest_dmu_commit_callbacks;
+ztest_func_t ztest_zap;
+ztest_func_t ztest_zap_parallel;
+ztest_func_t ztest_zil_commit;
+ztest_func_t ztest_zil_remount;
+ztest_func_t ztest_dmu_read_write_zcopy;
+ztest_func_t ztest_dmu_objset_create_destroy;
+ztest_func_t ztest_dmu_prealloc;
+ztest_func_t ztest_fzap;
+ztest_func_t ztest_dmu_snapshot_create_destroy;
+ztest_func_t ztest_dsl_prop_get_set;
+ztest_func_t ztest_spa_prop_get_set;
+ztest_func_t ztest_spa_create_destroy;
+ztest_func_t ztest_fault_inject;
+ztest_func_t ztest_ddt_repair;
+ztest_func_t ztest_dmu_snapshot_hold;
+ztest_func_t ztest_spa_rename;
+ztest_func_t ztest_scrub;
+ztest_func_t ztest_dsl_dataset_promote_busy;
+ztest_func_t ztest_vdev_attach_detach;
+ztest_func_t ztest_vdev_LUN_growth;
+ztest_func_t ztest_vdev_add_remove;
+ztest_func_t ztest_vdev_aux_add_remove;
+ztest_func_t ztest_split_pool;
+ztest_func_t ztest_reguid;
+ztest_func_t ztest_spa_upgrade;
+
+uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
+uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
+uint64_t zopt_often = 1ULL * NANOSEC; /* every second */
+uint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */
+uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */
+
+ztest_info_t ztest_info[] = {
+ { ztest_dmu_read_write, 1, &zopt_always },
+ { ztest_dmu_write_parallel, 10, &zopt_always },
+ { ztest_dmu_object_alloc_free, 1, &zopt_always },
+ { ztest_dmu_commit_callbacks, 1, &zopt_always },
+ { ztest_zap, 30, &zopt_always },
+ { ztest_zap_parallel, 100, &zopt_always },
+ { ztest_split_pool, 1, &zopt_always },
+ { ztest_zil_commit, 1, &zopt_incessant },
+ { ztest_zil_remount, 1, &zopt_sometimes },
+ { ztest_dmu_read_write_zcopy, 1, &zopt_often },
+ { ztest_dmu_objset_create_destroy, 1, &zopt_often },
+ { ztest_dsl_prop_get_set, 1, &zopt_often },
+ { ztest_spa_prop_get_set, 1, &zopt_sometimes },
+#if 0
+ { ztest_dmu_prealloc, 1, &zopt_sometimes },
+#endif
+ { ztest_fzap, 1, &zopt_sometimes },
+ { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes },
+ { ztest_spa_create_destroy, 1, &zopt_sometimes },
+ { ztest_fault_inject, 1, &zopt_sometimes },
+ { ztest_ddt_repair, 1, &zopt_sometimes },
+ { ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
+ { ztest_reguid, 1, &zopt_sometimes },
+ { ztest_spa_rename, 1, &zopt_rarely },
+ { ztest_scrub, 1, &zopt_rarely },
+ { ztest_spa_upgrade, 1, &zopt_rarely },
+ { ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
+ { ztest_vdev_attach_detach, 1, &zopt_sometimes },
+ { ztest_vdev_LUN_growth, 1, &zopt_rarely },
+ { ztest_vdev_add_remove, 1,
+ &ztest_opts.zo_vdevtime },
+ { ztest_vdev_aux_add_remove, 1,
+ &ztest_opts.zo_vdevtime },
+};
+
+#define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t))
+
+/*
+ * The following struct is used to hold a list of uncalled commit callbacks.
+ * The callbacks are ordered by txg number.
+ */
+typedef struct ztest_cb_list {
+ mutex_t zcl_callbacks_lock;
+ list_t zcl_callbacks;
+} ztest_cb_list_t;
+
+/*
+ * Stuff we need to share writably between parent and child.
+ */
+typedef struct ztest_shared {
+ boolean_t zs_do_init;
+ hrtime_t zs_proc_start;
+ hrtime_t zs_proc_stop;
+ hrtime_t zs_thread_start;
+ hrtime_t zs_thread_stop;
+ hrtime_t zs_thread_kill;
+ uint64_t zs_enospc_count;
+ uint64_t zs_vdev_next_leaf;
+ uint64_t zs_vdev_aux;
+ uint64_t zs_alloc;
+ uint64_t zs_space;
+ uint64_t zs_splits;
+ uint64_t zs_mirrors;
+ uint64_t zs_metaslab_sz;
+ uint64_t zs_metaslab_df_alloc_threshold;
+ uint64_t zs_guid;
+} ztest_shared_t;
+
+#define ID_PARALLEL -1ULL
+
+static char ztest_dev_template[] = "%s/%s.%llua";
+static char ztest_aux_template[] = "%s/%s.%s.%llu";
+ztest_shared_t *ztest_shared;
+
+static spa_t *ztest_spa = NULL;
+static ztest_ds_t *ztest_ds;
+
+static mutex_t ztest_vdev_lock;
+
+/*
+ * The ztest_name_lock protects the pool and dataset namespace used by
+ * the individual tests. To modify the namespace, consumers must grab
+ * this lock as writer. Grabbing the lock as reader will ensure that the
+ * namespace does not change while the lock is held.
+ */
+static rwlock_t ztest_name_lock;
+
+static boolean_t ztest_dump_core = B_TRUE;
+static boolean_t ztest_exiting;
+
+/* Global commit callback list */
+static ztest_cb_list_t zcl;
+
+enum ztest_object {
+ ZTEST_META_DNODE = 0,
+ ZTEST_DIROBJ,
+ ZTEST_OBJECTS
+};
+
+static void usage(boolean_t) __NORETURN;
+
+/*
+ * These libumem hooks provide a reasonable set of defaults for the allocator's
+ * debugging facilities.
+ */
+const char *
+_umem_debug_init()
+{
+ return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+ return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
+
+#define FATAL_MSG_SZ 1024
+
+char *fatal_msg;
+
+static void
+fatal(int do_perror, char *message, ...)
+{
+ va_list args;
+ int save_errno = errno;
+ char buf[FATAL_MSG_SZ];
+
+ (void) fflush(stdout);
+
+ va_start(args, message);
+ (void) sprintf(buf, "ztest: ");
+ /* LINTED */
+ (void) vsprintf(buf + strlen(buf), message, args);
+ va_end(args);
+ if (do_perror) {
+ (void) snprintf(buf + strlen(buf), FATAL_MSG_SZ - strlen(buf),
+ ": %s", strerror(save_errno));
+ }
+ (void) fprintf(stderr, "%s\n", buf);
+ fatal_msg = buf; /* to ease debugging */
+ if (ztest_dump_core)
+ abort();
+ exit(3);
+}
+
+static int
+str2shift(const char *buf)
+{
+ const char *ends = "BKMGTPEZ";
+ int i;
+
+ if (buf[0] == '\0')
+ return (0);
+ for (i = 0; i < strlen(ends); i++) {
+ if (toupper(buf[0]) == ends[i])
+ break;
+ }
+ if (i == strlen(ends)) {
+ (void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n",
+ buf);
+ usage(B_FALSE);
+ }
+ if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
+ return (10*i);
+ }
+ (void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n", buf);
+ usage(B_FALSE);
+ /* NOTREACHED */
+}
+
+static uint64_t
+nicenumtoull(const char *buf)
+{
+ char *end;
+ uint64_t val;
+
+ val = strtoull(buf, &end, 0);
+ if (end == buf) {
+ (void) fprintf(stderr, "ztest: bad numeric value: %s\n", buf);
+ usage(B_FALSE);
+ } else if (end[0] == '.') {
+ double fval = strtod(buf, &end);
+ fval *= pow(2, str2shift(end));
+ if (fval > UINT64_MAX) {
+ (void) fprintf(stderr, "ztest: value too large: %s\n",
+ buf);
+ usage(B_FALSE);
+ }
+ val = (uint64_t)fval;
+ } else {
+ int shift = str2shift(end);
+ if (shift >= 64 || (val << shift) >> shift != val) {
+ (void) fprintf(stderr, "ztest: value too large: %s\n",
+ buf);
+ usage(B_FALSE);
+ }
+ val <<= shift;
+ }
+ return (val);
+}
+
+static void
+usage(boolean_t requested)
+{
+ const ztest_shared_opts_t *zo = &ztest_opts_defaults;
+
+ char nice_vdev_size[10];
+ char nice_gang_bang[10];
+ FILE *fp = requested ? stdout : stderr;
+
+ nicenum(zo->zo_vdev_size, nice_vdev_size);
+ nicenum(zo->zo_metaslab_gang_bang, nice_gang_bang);
+
+ (void) fprintf(fp, "Usage: %s\n"
+ "\t[-v vdevs (default: %llu)]\n"
+ "\t[-s size_of_each_vdev (default: %s)]\n"
+ "\t[-a alignment_shift (default: %d)] use 0 for random\n"
+ "\t[-m mirror_copies (default: %d)]\n"
+ "\t[-r raidz_disks (default: %d)]\n"
+ "\t[-R raidz_parity (default: %d)]\n"
+ "\t[-d datasets (default: %d)]\n"
+ "\t[-t threads (default: %d)]\n"
+ "\t[-g gang_block_threshold (default: %s)]\n"
+ "\t[-i init_count (default: %d)] initialize pool i times\n"
+ "\t[-k kill_percentage (default: %llu%%)]\n"
+ "\t[-p pool_name (default: %s)]\n"
+ "\t[-f dir (default: %s)] file directory for vdev files\n"
+ "\t[-V] verbose (use multiple times for ever more blather)\n"
+ "\t[-E] use existing pool instead of creating new one\n"
+ "\t[-T time (default: %llu sec)] total run time\n"
+ "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
+ "\t[-P passtime (default: %llu sec)] time per pass\n"
+ "\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
+ "\t[-h] (print help)\n"
+ "",
+ zo->zo_pool,
+ (u_longlong_t)zo->zo_vdevs, /* -v */
+ nice_vdev_size, /* -s */
+ zo->zo_ashift, /* -a */
+ zo->zo_mirrors, /* -m */
+ zo->zo_raidz, /* -r */
+ zo->zo_raidz_parity, /* -R */
+ zo->zo_datasets, /* -d */
+ zo->zo_threads, /* -t */
+ nice_gang_bang, /* -g */
+ zo->zo_init, /* -i */
+ (u_longlong_t)zo->zo_killrate, /* -k */
+ zo->zo_pool, /* -p */
+ zo->zo_dir, /* -f */
+ (u_longlong_t)zo->zo_time, /* -T */
+ (u_longlong_t)zo->zo_maxloops, /* -F */
+ (u_longlong_t)zo->zo_passtime);
+ exit(requested ? 0 : 1);
+}
+
+static void
+process_options(int argc, char **argv)
+{
+ char *path;
+ ztest_shared_opts_t *zo = &ztest_opts;
+
+ int opt;
+ uint64_t value;
+ char altdir[MAXNAMELEN] = { 0 };
+
+ bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
+
+ while ((opt = getopt(argc, argv,
+ "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
+ value = 0;
+ switch (opt) {
+ case 'v':
+ case 's':
+ case 'a':
+ case 'm':
+ case 'r':
+ case 'R':
+ case 'd':
+ case 't':
+ case 'g':
+ case 'i':
+ case 'k':
+ case 'T':
+ case 'P':
+ case 'F':
+ value = nicenumtoull(optarg);
+ }
+ switch (opt) {
+ case 'v':
+ zo->zo_vdevs = value;
+ break;
+ case 's':
+ zo->zo_vdev_size = MAX(SPA_MINDEVSIZE, value);
+ break;
+ case 'a':
+ zo->zo_ashift = value;
+ break;
+ case 'm':
+ zo->zo_mirrors = value;
+ break;
+ case 'r':
+ zo->zo_raidz = MAX(1, value);
+ break;
+ case 'R':
+ zo->zo_raidz_parity = MIN(MAX(value, 1), 3);
+ break;
+ case 'd':
+ zo->zo_datasets = MAX(1, value);
+ break;
+ case 't':
+ zo->zo_threads = MAX(1, value);
+ break;
+ case 'g':
+ zo->zo_metaslab_gang_bang = MAX(SPA_MINBLOCKSIZE << 1,
+ value);
+ break;
+ case 'i':
+ zo->zo_init = value;
+ break;
+ case 'k':
+ zo->zo_killrate = value;
+ break;
+ case 'p':
+ (void) strlcpy(zo->zo_pool, optarg,
+ sizeof (zo->zo_pool));
+ break;
+ case 'f':
+ path = realpath(optarg, NULL);
+ if (path == NULL) {
+ (void) fprintf(stderr, "error: %s: %s\n",
+ optarg, strerror(errno));
+ usage(B_FALSE);
+ } else {
+ (void) strlcpy(zo->zo_dir, path,
+ sizeof (zo->zo_dir));
+ }
+ break;
+ case 'V':
+ zo->zo_verbose++;
+ break;
+ case 'E':
+ zo->zo_init = 0;
+ break;
+ case 'T':
+ zo->zo_time = value;
+ break;
+ case 'P':
+ zo->zo_passtime = MAX(1, value);
+ break;
+ case 'F':
+ zo->zo_maxloops = MAX(1, value);
+ break;
+ case 'B':
+ (void) strlcpy(altdir, optarg, sizeof (altdir));
+ break;
+ case 'h':
+ usage(B_TRUE);
+ break;
+ case '?':
+ default:
+ usage(B_FALSE);
+ break;
+ }
+ }
+
+ zo->zo_raidz_parity = MIN(zo->zo_raidz_parity, zo->zo_raidz - 1);
+
+ zo->zo_vdevtime =
+ (zo->zo_vdevs > 0 ? zo->zo_time * NANOSEC / zo->zo_vdevs :
+ UINT64_MAX >> 2);
+
+ if (strlen(altdir) > 0) {
+ char *cmd;
+ char *realaltdir;
+ char *bin;
+ char *ztest;
+ char *isa;
+ int isalen;
+
+ cmd = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
+ realaltdir = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
+
+ VERIFY(NULL != realpath(getexecname(), cmd));
+ if (0 != access(altdir, F_OK)) {
+ ztest_dump_core = B_FALSE;
+ fatal(B_TRUE, "invalid alternate ztest path: %s",
+ altdir);
+ }
+ VERIFY(NULL != realpath(altdir, realaltdir));
+
+ /*
+ * 'cmd' should be of the form "<anything>/usr/bin/<isa>/ztest".
+ * We want to extract <isa> to determine if we should use
+ * 32 or 64 bit binaries.
+ */
+ bin = strstr(cmd, "/usr/bin/");
+ ztest = strstr(bin, "/ztest");
+ isa = bin + 9;
+ isalen = ztest - isa;
+ (void) snprintf(zo->zo_alt_ztest, sizeof (zo->zo_alt_ztest),
+ "%s/usr/bin/%.*s/ztest", realaltdir, isalen, isa);
+ (void) snprintf(zo->zo_alt_libpath, sizeof (zo->zo_alt_libpath),
+ "%s/usr/lib/%.*s", realaltdir, isalen, isa);
+
+ if (0 != access(zo->zo_alt_ztest, X_OK)) {
+ ztest_dump_core = B_FALSE;
+ fatal(B_TRUE, "invalid alternate ztest: %s",
+ zo->zo_alt_ztest);
+ } else if (0 != access(zo->zo_alt_libpath, X_OK)) {
+ ztest_dump_core = B_FALSE;
+ fatal(B_TRUE, "invalid alternate lib directory %s",
+ zo->zo_alt_libpath);
+ }
+
+ umem_free(cmd, MAXPATHLEN);
+ umem_free(realaltdir, MAXPATHLEN);
+ }
+}
+
+static void
+ztest_kill(ztest_shared_t *zs)
+{
+ zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(ztest_spa));
+ zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa));
+ (void) kill(getpid(), SIGKILL);
+}
+
+static uint64_t
+ztest_random(uint64_t range)
+{
+ uint64_t r;
+
+ ASSERT3S(ztest_fd_rand, >=, 0);
+
+ if (range == 0)
+ return (0);
+
+ if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
+ fatal(1, "short read from /dev/urandom");
+
+ return (r % range);
+}
+
+/* ARGSUSED */
+static void
+ztest_record_enospc(const char *s)
+{
+ ztest_shared->zs_enospc_count++;
+}
+
+static uint64_t
+ztest_get_ashift(void)
+{
+ if (ztest_opts.zo_ashift == 0)
+ return (SPA_MINBLOCKSHIFT + ztest_random(3));
+ return (ztest_opts.zo_ashift);
+}
+
+static nvlist_t *
+make_vdev_file(char *path, char *aux, char *pool, size_t size, uint64_t ashift)
+{
+ char pathbuf[MAXPATHLEN];
+ uint64_t vdev;
+ nvlist_t *file;
+
+ if (ashift == 0)
+ ashift = ztest_get_ashift();
+
+ if (path == NULL) {
+ path = pathbuf;
+
+ if (aux != NULL) {
+ vdev = ztest_shared->zs_vdev_aux;
+ (void) snprintf(path, sizeof (pathbuf),
+ ztest_aux_template, ztest_opts.zo_dir,
+ pool == NULL ? ztest_opts.zo_pool : pool,
+ aux, vdev);
+ } else {
+ vdev = ztest_shared->zs_vdev_next_leaf++;
+ (void) snprintf(path, sizeof (pathbuf),
+ ztest_dev_template, ztest_opts.zo_dir,
+ pool == NULL ? ztest_opts.zo_pool : pool, vdev);
+ }
+ }
+
+ if (size != 0) {
+ int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ if (fd == -1)
+ fatal(1, "can't open %s", path);
+ if (ftruncate(fd, size) != 0)
+ fatal(1, "can't ftruncate %s", path);
+ (void) close(fd);
+ }
+
+ VERIFY(nvlist_alloc(&file, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE) == 0);
+ VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, path) == 0);
+ VERIFY(nvlist_add_uint64(file, ZPOOL_CONFIG_ASHIFT, ashift) == 0);
+
+ return (file);
+}
+
+static nvlist_t *
+make_vdev_raidz(char *path, char *aux, char *pool, size_t size,
+ uint64_t ashift, int r)
+{
+ nvlist_t *raidz, **child;
+ int c;
+
+ if (r < 2)
+ return (make_vdev_file(path, aux, pool, size, ashift));
+ child = umem_alloc(r * sizeof (nvlist_t *), UMEM_NOFAIL);
+
+ for (c = 0; c < r; c++)
+ child[c] = make_vdev_file(path, aux, pool, size, ashift);
+
+ VERIFY(nvlist_alloc(&raidz, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_string(raidz, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_RAIDZ) == 0);
+ VERIFY(nvlist_add_uint64(raidz, ZPOOL_CONFIG_NPARITY,
+ ztest_opts.zo_raidz_parity) == 0);
+ VERIFY(nvlist_add_nvlist_array(raidz, ZPOOL_CONFIG_CHILDREN,
+ child, r) == 0);
+
+ for (c = 0; c < r; c++)
+ nvlist_free(child[c]);
+
+ umem_free(child, r * sizeof (nvlist_t *));
+
+ return (raidz);
+}
+
+static nvlist_t *
+make_vdev_mirror(char *path, char *aux, char *pool, size_t size,
+ uint64_t ashift, int r, int m)
+{
+ nvlist_t *mirror, **child;
+ int c;
+
+ if (m < 1)
+ return (make_vdev_raidz(path, aux, pool, size, ashift, r));
+
+ child = umem_alloc(m * sizeof (nvlist_t *), UMEM_NOFAIL);
+
+ for (c = 0; c < m; c++)
+ child[c] = make_vdev_raidz(path, aux, pool, size, ashift, r);
+
+ VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_MIRROR) == 0);
+ VERIFY(nvlist_add_nvlist_array(mirror, ZPOOL_CONFIG_CHILDREN,
+ child, m) == 0);
+
+ for (c = 0; c < m; c++)
+ nvlist_free(child[c]);
+
+ umem_free(child, m * sizeof (nvlist_t *));
+
+ return (mirror);
+}
+
+static nvlist_t *
+make_vdev_root(char *path, char *aux, char *pool, size_t size, uint64_t ashift,
+ int log, int r, int m, int t)
+{
+ nvlist_t *root, **child;
+ int c;
+
+ ASSERT(t > 0);
+
+ child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
+
+ for (c = 0; c < t; c++) {
+ child[c] = make_vdev_mirror(path, aux, pool, size, ashift,
+ r, m);
+ VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ log) == 0);
+ }
+
+ VERIFY(nvlist_alloc(&root, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0);
+ VERIFY(nvlist_add_nvlist_array(root, aux ? aux : ZPOOL_CONFIG_CHILDREN,
+ child, t) == 0);
+
+ for (c = 0; c < t; c++)
+ nvlist_free(child[c]);
+
+ umem_free(child, t * sizeof (nvlist_t *));
+
+ return (root);
+}
+
+/*
+ * Find a random spa version. Returns back a random spa version in the
+ * range [initial_version, SPA_VERSION_FEATURES].
+ */
+static uint64_t
+ztest_random_spa_version(uint64_t initial_version)
+{
+ uint64_t version = initial_version;
+
+ if (version <= SPA_VERSION_BEFORE_FEATURES) {
+ version = version +
+ ztest_random(SPA_VERSION_BEFORE_FEATURES - version + 1);
+ }
+
+ if (version > SPA_VERSION_BEFORE_FEATURES)
+ version = SPA_VERSION_FEATURES;
+
+ ASSERT(SPA_VERSION_IS_SUPPORTED(version));
+ return (version);
+}
+
+static int
+ztest_random_blocksize(void)
+{
+ return (1 << (SPA_MINBLOCKSHIFT +
+ ztest_random(SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1)));
+}
+
+static int
+ztest_random_ibshift(void)
+{
+ return (DN_MIN_INDBLKSHIFT +
+ ztest_random(DN_MAX_INDBLKSHIFT - DN_MIN_INDBLKSHIFT + 1));
+}
+
+static uint64_t
+ztest_random_vdev_top(spa_t *spa, boolean_t log_ok)
+{
+ uint64_t top;
+ vdev_t *rvd = spa->spa_root_vdev;
+ vdev_t *tvd;
+
+ ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
+
+ do {
+ top = ztest_random(rvd->vdev_children);
+ tvd = rvd->vdev_child[top];
+ } while (tvd->vdev_ishole || (tvd->vdev_islog && !log_ok) ||
+ tvd->vdev_mg == NULL || tvd->vdev_mg->mg_class == NULL);
+
+ return (top);
+}
+
+static uint64_t
+ztest_random_dsl_prop(zfs_prop_t prop)
+{
+ uint64_t value;
+
+ do {
+ value = zfs_prop_random_value(prop, ztest_random(-1ULL));
+ } while (prop == ZFS_PROP_CHECKSUM && value == ZIO_CHECKSUM_OFF);
+
+ return (value);
+}
+
+static int
+ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value,
+ boolean_t inherit)
+{
+ const char *propname = zfs_prop_to_name(prop);
+ const char *valname;
+ char setpoint[MAXPATHLEN];
+ uint64_t curval;
+ int error;
+
+ error = dsl_prop_set_int(osname, propname,
+ (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), value);
+
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ return (error);
+ }
+ ASSERT0(error);
+
+ VERIFY0(dsl_prop_get_integer(osname, propname, &curval, setpoint));
+
+ if (ztest_opts.zo_verbose >= 6) {
+ VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0);
+ (void) printf("%s %s = %s at '%s'\n",
+ osname, propname, valname, setpoint);
+ }
+
+ return (error);
+}
+
+static int
+ztest_spa_prop_set_uint64(zpool_prop_t prop, uint64_t value)
+{
+ spa_t *spa = ztest_spa;
+ nvlist_t *props = NULL;
+ int error;
+
+ VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_uint64(props, zpool_prop_to_name(prop), value) == 0);
+
+ error = spa_prop_set(spa, props);
+
+ nvlist_free(props);
+
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ return (error);
+ }
+ ASSERT0(error);
+
+ return (error);
+}
+
+static void
+ztest_rll_init(rll_t *rll)
+{
+ rll->rll_writer = NULL;
+ rll->rll_readers = 0;
+ VERIFY(_mutex_init(&rll->rll_lock, USYNC_THREAD, NULL) == 0);
+ VERIFY(cond_init(&rll->rll_cv, USYNC_THREAD, NULL) == 0);
+}
+
+static void
+ztest_rll_destroy(rll_t *rll)
+{
+ ASSERT(rll->rll_writer == NULL);
+ ASSERT(rll->rll_readers == 0);
+ VERIFY(_mutex_destroy(&rll->rll_lock) == 0);
+ VERIFY(cond_destroy(&rll->rll_cv) == 0);
+}
+
+static void
+ztest_rll_lock(rll_t *rll, rl_type_t type)
+{
+ VERIFY(mutex_lock(&rll->rll_lock) == 0);
+
+ if (type == RL_READER) {
+ while (rll->rll_writer != NULL)
+ (void) cond_wait(&rll->rll_cv, &rll->rll_lock);
+ rll->rll_readers++;
+ } else {
+ while (rll->rll_writer != NULL || rll->rll_readers)
+ (void) cond_wait(&rll->rll_cv, &rll->rll_lock);
+ rll->rll_writer = curthread;
+ }
+
+ VERIFY(mutex_unlock(&rll->rll_lock) == 0);
+}
+
+static void
+ztest_rll_unlock(rll_t *rll)
+{
+ VERIFY(mutex_lock(&rll->rll_lock) == 0);
+
+ if (rll->rll_writer) {
+ ASSERT(rll->rll_readers == 0);
+ rll->rll_writer = NULL;
+ } else {
+ ASSERT(rll->rll_readers != 0);
+ ASSERT(rll->rll_writer == NULL);
+ rll->rll_readers--;
+ }
+
+ if (rll->rll_writer == NULL && rll->rll_readers == 0)
+ VERIFY(cond_broadcast(&rll->rll_cv) == 0);
+
+ VERIFY(mutex_unlock(&rll->rll_lock) == 0);
+}
+
+static void
+ztest_object_lock(ztest_ds_t *zd, uint64_t object, rl_type_t type)
+{
+ rll_t *rll = &zd->zd_object_lock[object & (ZTEST_OBJECT_LOCKS - 1)];
+
+ ztest_rll_lock(rll, type);
+}
+
+static void
+ztest_object_unlock(ztest_ds_t *zd, uint64_t object)
+{
+ rll_t *rll = &zd->zd_object_lock[object & (ZTEST_OBJECT_LOCKS - 1)];
+
+ ztest_rll_unlock(rll);
+}
+
+static rl_t *
+ztest_range_lock(ztest_ds_t *zd, uint64_t object, uint64_t offset,
+ uint64_t size, rl_type_t type)
+{
+ uint64_t hash = object ^ (offset % (ZTEST_RANGE_LOCKS + 1));
+ rll_t *rll = &zd->zd_range_lock[hash & (ZTEST_RANGE_LOCKS - 1)];
+ rl_t *rl;
+
+ rl = umem_alloc(sizeof (*rl), UMEM_NOFAIL);
+ rl->rl_object = object;
+ rl->rl_offset = offset;
+ rl->rl_size = size;
+ rl->rl_lock = rll;
+
+ ztest_rll_lock(rll, type);
+
+ return (rl);
+}
+
+static void
+ztest_range_unlock(rl_t *rl)
+{
+ rll_t *rll = rl->rl_lock;
+
+ ztest_rll_unlock(rll);
+
+ umem_free(rl, sizeof (*rl));
+}
+
+static void
+ztest_zd_init(ztest_ds_t *zd, ztest_shared_ds_t *szd, objset_t *os)
+{
+ zd->zd_os = os;
+ zd->zd_zilog = dmu_objset_zil(os);
+ zd->zd_shared = szd;
+ dmu_objset_name(os, zd->zd_name);
+
+ if (zd->zd_shared != NULL)
+ zd->zd_shared->zd_seq = 0;
+
+ VERIFY(rwlock_init(&zd->zd_zilog_lock, USYNC_THREAD, NULL) == 0);
+ VERIFY(_mutex_init(&zd->zd_dirobj_lock, USYNC_THREAD, NULL) == 0);
+
+ for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
+ ztest_rll_init(&zd->zd_object_lock[l]);
+
+ for (int l = 0; l < ZTEST_RANGE_LOCKS; l++)
+ ztest_rll_init(&zd->zd_range_lock[l]);
+}
+
+static void
+ztest_zd_fini(ztest_ds_t *zd)
+{
+ VERIFY(_mutex_destroy(&zd->zd_dirobj_lock) == 0);
+
+ for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
+ ztest_rll_destroy(&zd->zd_object_lock[l]);
+
+ for (int l = 0; l < ZTEST_RANGE_LOCKS; l++)
+ ztest_rll_destroy(&zd->zd_range_lock[l]);
+}
+
+#define TXG_MIGHTWAIT (ztest_random(10) == 0 ? TXG_NOWAIT : TXG_WAIT)
+
+static uint64_t
+ztest_tx_assign(dmu_tx_t *tx, uint64_t txg_how, const char *tag)
+{
+ uint64_t txg;
+ int error;
+
+ /*
+ * Attempt to assign tx to some transaction group.
+ */
+ error = dmu_tx_assign(tx, txg_how);
+ if (error) {
+ if (error == ERESTART) {
+ ASSERT(txg_how == TXG_NOWAIT);
+ dmu_tx_wait(tx);
+ } else {
+ ASSERT3U(error, ==, ENOSPC);
+ ztest_record_enospc(tag);
+ }
+ dmu_tx_abort(tx);
+ return (0);
+ }
+ txg = dmu_tx_get_txg(tx);
+ ASSERT(txg != 0);
+ return (txg);
+}
+
+static void
+ztest_pattern_set(void *buf, uint64_t size, uint64_t value)
+{
+ uint64_t *ip = buf;
+ uint64_t *ip_end = (uint64_t *)((uintptr_t)buf + (uintptr_t)size);
+
+ while (ip < ip_end)
+ *ip++ = value;
+}
+
+static boolean_t
+ztest_pattern_match(void *buf, uint64_t size, uint64_t value)
+{
+ uint64_t *ip = buf;
+ uint64_t *ip_end = (uint64_t *)((uintptr_t)buf + (uintptr_t)size);
+ uint64_t diff = 0;
+
+ while (ip < ip_end)
+ diff |= (value - *ip++);
+
+ return (diff == 0);
+}
+
+static void
+ztest_bt_generate(ztest_block_tag_t *bt, objset_t *os, uint64_t object,
+ uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg)
+{
+ bt->bt_magic = BT_MAGIC;
+ bt->bt_objset = dmu_objset_id(os);
+ bt->bt_object = object;
+ bt->bt_offset = offset;
+ bt->bt_gen = gen;
+ bt->bt_txg = txg;
+ bt->bt_crtxg = crtxg;
+}
+
+static void
+ztest_bt_verify(ztest_block_tag_t *bt, objset_t *os, uint64_t object,
+ uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg)
+{
+ ASSERT(bt->bt_magic == BT_MAGIC);
+ ASSERT(bt->bt_objset == dmu_objset_id(os));
+ ASSERT(bt->bt_object == object);
+ ASSERT(bt->bt_offset == offset);
+ ASSERT(bt->bt_gen <= gen);
+ ASSERT(bt->bt_txg <= txg);
+ ASSERT(bt->bt_crtxg == crtxg);
+}
+
+static ztest_block_tag_t *
+ztest_bt_bonus(dmu_buf_t *db)
+{
+ dmu_object_info_t doi;
+ ztest_block_tag_t *bt;
+
+ dmu_object_info_from_db(db, &doi);
+ ASSERT3U(doi.doi_bonus_size, <=, db->db_size);
+ ASSERT3U(doi.doi_bonus_size, >=, sizeof (*bt));
+ bt = (void *)((char *)db->db_data + doi.doi_bonus_size - sizeof (*bt));
+
+ return (bt);
+}
+
+/*
+ * ZIL logging ops
+ */
+
+#define lrz_type lr_mode
+#define lrz_blocksize lr_uid
+#define lrz_ibshift lr_gid
+#define lrz_bonustype lr_rdev
+#define lrz_bonuslen lr_crtime[1]
+
+static void
+ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
+{
+ char *name = (void *)(lr + 1); /* name follows lr */
+ size_t namesize = strlen(name) + 1;
+ itx_t *itx;
+
+ if (zil_replaying(zd->zd_zilog, tx))
+ return;
+
+ itx = zil_itx_create(TX_CREATE, sizeof (*lr) + namesize);
+ bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
+ sizeof (*lr) + namesize - sizeof (lr_t));
+
+ zil_itx_assign(zd->zd_zilog, itx, tx);
+}
+
+static void
+ztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr, uint64_t object)
+{
+ char *name = (void *)(lr + 1); /* name follows lr */
+ size_t namesize = strlen(name) + 1;
+ itx_t *itx;
+
+ if (zil_replaying(zd->zd_zilog, tx))
+ return;
+
+ itx = zil_itx_create(TX_REMOVE, sizeof (*lr) + namesize);
+ bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
+ sizeof (*lr) + namesize - sizeof (lr_t));
+
+ itx->itx_oid = object;
+ zil_itx_assign(zd->zd_zilog, itx, tx);
+}
+
+static void
+ztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
+{
+ itx_t *itx;
+ itx_wr_state_t write_state = ztest_random(WR_NUM_STATES);
+
+ if (zil_replaying(zd->zd_zilog, tx))
+ return;
+
+ if (lr->lr_length > ZIL_MAX_LOG_DATA)
+ write_state = WR_INDIRECT;
+
+ itx = zil_itx_create(TX_WRITE,
+ sizeof (*lr) + (write_state == WR_COPIED ? lr->lr_length : 0));
+
+ if (write_state == WR_COPIED &&
+ dmu_read(zd->zd_os, lr->lr_foid, lr->lr_offset, lr->lr_length,
+ ((lr_write_t *)&itx->itx_lr) + 1, DMU_READ_NO_PREFETCH) != 0) {
+ zil_itx_destroy(itx);
+ itx = zil_itx_create(TX_WRITE, sizeof (*lr));
+ write_state = WR_NEED_COPY;
+ }
+ itx->itx_private = zd;
+ itx->itx_wr_state = write_state;
+ itx->itx_sync = (ztest_random(8) == 0);
+ itx->itx_sod += (write_state == WR_NEED_COPY ? lr->lr_length : 0);
+
+ bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
+ sizeof (*lr) - sizeof (lr_t));
+
+ zil_itx_assign(zd->zd_zilog, itx, tx);
+}
+
+static void
+ztest_log_truncate(ztest_ds_t *zd, dmu_tx_t *tx, lr_truncate_t *lr)
+{
+ itx_t *itx;
+
+ if (zil_replaying(zd->zd_zilog, tx))
+ return;
+
+ itx = zil_itx_create(TX_TRUNCATE, sizeof (*lr));
+ bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
+ sizeof (*lr) - sizeof (lr_t));
+
+ itx->itx_sync = B_FALSE;
+ zil_itx_assign(zd->zd_zilog, itx, tx);
+}
+
+static void
+ztest_log_setattr(ztest_ds_t *zd, dmu_tx_t *tx, lr_setattr_t *lr)
+{
+ itx_t *itx;
+
+ if (zil_replaying(zd->zd_zilog, tx))
+ return;
+
+ itx = zil_itx_create(TX_SETATTR, sizeof (*lr));
+ bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
+ sizeof (*lr) - sizeof (lr_t));
+
+ itx->itx_sync = B_FALSE;
+ zil_itx_assign(zd->zd_zilog, itx, tx);
+}
+
+/*
+ * ZIL replay ops
+ */
+static int
+ztest_replay_create(ztest_ds_t *zd, lr_create_t *lr, boolean_t byteswap)
+{
+ char *name = (void *)(lr + 1); /* name follows lr */
+ objset_t *os = zd->zd_os;
+ ztest_block_tag_t *bbt;
+ dmu_buf_t *db;
+ dmu_tx_t *tx;
+ uint64_t txg;
+ int error = 0;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ ASSERT(lr->lr_doid == ZTEST_DIROBJ);
+ ASSERT(name[0] != '\0');
+
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_zap(tx, lr->lr_doid, B_TRUE, name);
+
+ if (lr->lrz_type == DMU_OT_ZAP_OTHER) {
+ dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
+ } else {
+ dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
+ }
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0)
+ return (ENOSPC);
+
+ ASSERT(dmu_objset_zil(os)->zl_replay == !!lr->lr_foid);
+
+ if (lr->lrz_type == DMU_OT_ZAP_OTHER) {
+ if (lr->lr_foid == 0) {
+ lr->lr_foid = zap_create(os,
+ lr->lrz_type, lr->lrz_bonustype,
+ lr->lrz_bonuslen, tx);
+ } else {
+ error = zap_create_claim(os, lr->lr_foid,
+ lr->lrz_type, lr->lrz_bonustype,
+ lr->lrz_bonuslen, tx);
+ }
+ } else {
+ if (lr->lr_foid == 0) {
+ lr->lr_foid = dmu_object_alloc(os,
+ lr->lrz_type, 0, lr->lrz_bonustype,
+ lr->lrz_bonuslen, tx);
+ } else {
+ error = dmu_object_claim(os, lr->lr_foid,
+ lr->lrz_type, 0, lr->lrz_bonustype,
+ lr->lrz_bonuslen, tx);
+ }
+ }
+
+ if (error) {
+ ASSERT3U(error, ==, EEXIST);
+ ASSERT(zd->zd_zilog->zl_replay);
+ dmu_tx_commit(tx);
+ return (error);
+ }
+
+ ASSERT(lr->lr_foid != 0);
+
+ if (lr->lrz_type != DMU_OT_ZAP_OTHER)
+ VERIFY3U(0, ==, dmu_object_set_blocksize(os, lr->lr_foid,
+ lr->lrz_blocksize, lr->lrz_ibshift, tx));
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
+ bbt = ztest_bt_bonus(db);
+ dmu_buf_will_dirty(db, tx);
+ ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_gen, txg, txg);
+ dmu_buf_rele(db, FTAG);
+
+ VERIFY3U(0, ==, zap_add(os, lr->lr_doid, name, sizeof (uint64_t), 1,
+ &lr->lr_foid, tx));
+
+ (void) ztest_log_create(zd, tx, lr);
+
+ dmu_tx_commit(tx);
+
+ return (0);
+}
+
+static int
+ztest_replay_remove(ztest_ds_t *zd, lr_remove_t *lr, boolean_t byteswap)
+{
+ char *name = (void *)(lr + 1); /* name follows lr */
+ objset_t *os = zd->zd_os;
+ dmu_object_info_t doi;
+ dmu_tx_t *tx;
+ uint64_t object, txg;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ ASSERT(lr->lr_doid == ZTEST_DIROBJ);
+ ASSERT(name[0] != '\0');
+
+ VERIFY3U(0, ==,
+ zap_lookup(os, lr->lr_doid, name, sizeof (object), 1, &object));
+ ASSERT(object != 0);
+
+ ztest_object_lock(zd, object, RL_WRITER);
+
+ VERIFY3U(0, ==, dmu_object_info(os, object, &doi));
+
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_zap(tx, lr->lr_doid, B_FALSE, name);
+ dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0) {
+ ztest_object_unlock(zd, object);
+ return (ENOSPC);
+ }
+
+ if (doi.doi_type == DMU_OT_ZAP_OTHER) {
+ VERIFY3U(0, ==, zap_destroy(os, object, tx));
+ } else {
+ VERIFY3U(0, ==, dmu_object_free(os, object, tx));
+ }
+
+ VERIFY3U(0, ==, zap_remove(os, lr->lr_doid, name, tx));
+
+ (void) ztest_log_remove(zd, tx, lr, object);
+
+ dmu_tx_commit(tx);
+
+ ztest_object_unlock(zd, object);
+
+ return (0);
+}
+
+static int
+ztest_replay_write(ztest_ds_t *zd, lr_write_t *lr, boolean_t byteswap)
+{
+ objset_t *os = zd->zd_os;
+ void *data = lr + 1; /* data follows lr */
+ uint64_t offset, length;
+ ztest_block_tag_t *bt = data;
+ ztest_block_tag_t *bbt;
+ uint64_t gen, txg, lrtxg, crtxg;
+ dmu_object_info_t doi;
+ dmu_tx_t *tx;
+ dmu_buf_t *db;
+ arc_buf_t *abuf = NULL;
+ rl_t *rl;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ offset = lr->lr_offset;
+ length = lr->lr_length;
+
+ /* If it's a dmu_sync() block, write the whole block */
+ if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
+ uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr);
+ if (length < blocksize) {
+ offset -= offset % blocksize;
+ length = blocksize;
+ }
+ }
+
+ if (bt->bt_magic == BSWAP_64(BT_MAGIC))
+ byteswap_uint64_array(bt, sizeof (*bt));
+
+ if (bt->bt_magic != BT_MAGIC)
+ bt = NULL;
+
+ ztest_object_lock(zd, lr->lr_foid, RL_READER);
+ rl = ztest_range_lock(zd, lr->lr_foid, offset, length, RL_WRITER);
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
+
+ dmu_object_info_from_db(db, &doi);
+
+ bbt = ztest_bt_bonus(db);
+ ASSERT3U(bbt->bt_magic, ==, BT_MAGIC);
+ gen = bbt->bt_gen;
+ crtxg = bbt->bt_crtxg;
+ lrtxg = lr->lr_common.lrc_txg;
+
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_write(tx, lr->lr_foid, offset, length);
+
+ if (ztest_random(8) == 0 && length == doi.doi_data_block_size &&
+ P2PHASE(offset, length) == 0)
+ abuf = dmu_request_arcbuf(db, length);
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0) {
+ if (abuf != NULL)
+ dmu_return_arcbuf(abuf);
+ dmu_buf_rele(db, FTAG);
+ ztest_range_unlock(rl);
+ ztest_object_unlock(zd, lr->lr_foid);
+ return (ENOSPC);
+ }
+
+ if (bt != NULL) {
+ /*
+ * Usually, verify the old data before writing new data --
+ * but not always, because we also want to verify correct
+ * behavior when the data was not recently read into cache.
+ */
+ ASSERT(offset % doi.doi_data_block_size == 0);
+ if (ztest_random(4) != 0) {
+ int prefetch = ztest_random(2) ?
+ DMU_READ_PREFETCH : DMU_READ_NO_PREFETCH;
+ ztest_block_tag_t rbt;
+
+ VERIFY(dmu_read(os, lr->lr_foid, offset,
+ sizeof (rbt), &rbt, prefetch) == 0);
+ if (rbt.bt_magic == BT_MAGIC) {
+ ztest_bt_verify(&rbt, os, lr->lr_foid,
+ offset, gen, txg, crtxg);
+ }
+ }
+
+ /*
+ * Writes can appear to be newer than the bonus buffer because
+ * the ztest_get_data() callback does a dmu_read() of the
+ * open-context data, which may be different than the data
+ * as it was when the write was generated.
+ */
+ if (zd->zd_zilog->zl_replay) {
+ ztest_bt_verify(bt, os, lr->lr_foid, offset,
+ MAX(gen, bt->bt_gen), MAX(txg, lrtxg),
+ bt->bt_crtxg);
+ }
+
+ /*
+ * Set the bt's gen/txg to the bonus buffer's gen/txg
+ * so that all of the usual ASSERTs will work.
+ */
+ ztest_bt_generate(bt, os, lr->lr_foid, offset, gen, txg, crtxg);
+ }
+
+ if (abuf == NULL) {
+ dmu_write(os, lr->lr_foid, offset, length, data, tx);
+ } else {
+ bcopy(data, abuf->b_data, length);
+ dmu_assign_arcbuf(db, offset, abuf, tx);
+ }
+
+ (void) ztest_log_write(zd, tx, lr);
+
+ dmu_buf_rele(db, FTAG);
+
+ dmu_tx_commit(tx);
+
+ ztest_range_unlock(rl);
+ ztest_object_unlock(zd, lr->lr_foid);
+
+ return (0);
+}
+
+static int
+ztest_replay_truncate(ztest_ds_t *zd, lr_truncate_t *lr, boolean_t byteswap)
+{
+ objset_t *os = zd->zd_os;
+ dmu_tx_t *tx;
+ uint64_t txg;
+ rl_t *rl;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ ztest_object_lock(zd, lr->lr_foid, RL_READER);
+ rl = ztest_range_lock(zd, lr->lr_foid, lr->lr_offset, lr->lr_length,
+ RL_WRITER);
+
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_free(tx, lr->lr_foid, lr->lr_offset, lr->lr_length);
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0) {
+ ztest_range_unlock(rl);
+ ztest_object_unlock(zd, lr->lr_foid);
+ return (ENOSPC);
+ }
+
+ VERIFY(dmu_free_range(os, lr->lr_foid, lr->lr_offset,
+ lr->lr_length, tx) == 0);
+
+ (void) ztest_log_truncate(zd, tx, lr);
+
+ dmu_tx_commit(tx);
+
+ ztest_range_unlock(rl);
+ ztest_object_unlock(zd, lr->lr_foid);
+
+ return (0);
+}
+
+static int
+ztest_replay_setattr(ztest_ds_t *zd, lr_setattr_t *lr, boolean_t byteswap)
+{
+ objset_t *os = zd->zd_os;
+ dmu_tx_t *tx;
+ dmu_buf_t *db;
+ ztest_block_tag_t *bbt;
+ uint64_t txg, lrtxg, crtxg;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ ztest_object_lock(zd, lr->lr_foid, RL_WRITER);
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
+
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_bonus(tx, lr->lr_foid);
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0) {
+ dmu_buf_rele(db, FTAG);
+ ztest_object_unlock(zd, lr->lr_foid);
+ return (ENOSPC);
+ }
+
+ bbt = ztest_bt_bonus(db);
+ ASSERT3U(bbt->bt_magic, ==, BT_MAGIC);
+ crtxg = bbt->bt_crtxg;
+ lrtxg = lr->lr_common.lrc_txg;
+
+ if (zd->zd_zilog->zl_replay) {
+ ASSERT(lr->lr_size != 0);
+ ASSERT(lr->lr_mode != 0);
+ ASSERT(lrtxg != 0);
+ } else {
+ /*
+ * Randomly change the size and increment the generation.
+ */
+ lr->lr_size = (ztest_random(db->db_size / sizeof (*bbt)) + 1) *
+ sizeof (*bbt);
+ lr->lr_mode = bbt->bt_gen + 1;
+ ASSERT(lrtxg == 0);
+ }
+
+ /*
+ * Verify that the current bonus buffer is not newer than our txg.
+ */
+ ztest_bt_verify(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode,
+ MAX(txg, lrtxg), crtxg);
+
+ dmu_buf_will_dirty(db, tx);
+
+ ASSERT3U(lr->lr_size, >=, sizeof (*bbt));
+ ASSERT3U(lr->lr_size, <=, db->db_size);
+ VERIFY0(dmu_set_bonus(db, lr->lr_size, tx));
+ bbt = ztest_bt_bonus(db);
+
+ ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode, txg, crtxg);
+
+ dmu_buf_rele(db, FTAG);
+
+ (void) ztest_log_setattr(zd, tx, lr);
+
+ dmu_tx_commit(tx);
+
+ ztest_object_unlock(zd, lr->lr_foid);
+
+ return (0);
+}
+
+zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
+ NULL, /* 0 no such transaction type */
+ ztest_replay_create, /* TX_CREATE */
+ NULL, /* TX_MKDIR */
+ NULL, /* TX_MKXATTR */
+ NULL, /* TX_SYMLINK */
+ ztest_replay_remove, /* TX_REMOVE */
+ NULL, /* TX_RMDIR */
+ NULL, /* TX_LINK */
+ NULL, /* TX_RENAME */
+ ztest_replay_write, /* TX_WRITE */
+ ztest_replay_truncate, /* TX_TRUNCATE */
+ ztest_replay_setattr, /* TX_SETATTR */
+ NULL, /* TX_ACL */
+ NULL, /* TX_CREATE_ACL */
+ NULL, /* TX_CREATE_ATTR */
+ NULL, /* TX_CREATE_ACL_ATTR */
+ NULL, /* TX_MKDIR_ACL */
+ NULL, /* TX_MKDIR_ATTR */
+ NULL, /* TX_MKDIR_ACL_ATTR */
+ NULL, /* TX_WRITE2 */
+};
+
+/*
+ * ZIL get_data callbacks
+ */
+
+static void
+ztest_get_done(zgd_t *zgd, int error)
+{
+ ztest_ds_t *zd = zgd->zgd_private;
+ uint64_t object = zgd->zgd_rl->rl_object;
+
+ if (zgd->zgd_db)
+ dmu_buf_rele(zgd->zgd_db, zgd);
+
+ ztest_range_unlock(zgd->zgd_rl);
+ ztest_object_unlock(zd, object);
+
+ if (error == 0 && zgd->zgd_bp)
+ zil_add_block(zgd->zgd_zilog, zgd->zgd_bp);
+
+ umem_free(zgd, sizeof (*zgd));
+}
+
+static int
+ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
+{
+ ztest_ds_t *zd = arg;
+ objset_t *os = zd->zd_os;
+ uint64_t object = lr->lr_foid;
+ uint64_t offset = lr->lr_offset;
+ uint64_t size = lr->lr_length;
+ blkptr_t *bp = &lr->lr_blkptr;
+ uint64_t txg = lr->lr_common.lrc_txg;
+ uint64_t crtxg;
+ dmu_object_info_t doi;
+ dmu_buf_t *db;
+ zgd_t *zgd;
+ int error;
+
+ ztest_object_lock(zd, object, RL_READER);
+ error = dmu_bonus_hold(os, object, FTAG, &db);
+ if (error) {
+ ztest_object_unlock(zd, object);
+ return (error);
+ }
+
+ crtxg = ztest_bt_bonus(db)->bt_crtxg;
+
+ if (crtxg == 0 || crtxg > txg) {
+ dmu_buf_rele(db, FTAG);
+ ztest_object_unlock(zd, object);
+ return (ENOENT);
+ }
+
+ dmu_object_info_from_db(db, &doi);
+ dmu_buf_rele(db, FTAG);
+ db = NULL;
+
+ zgd = umem_zalloc(sizeof (*zgd), UMEM_NOFAIL);
+ zgd->zgd_zilog = zd->zd_zilog;
+ zgd->zgd_private = zd;
+
+ if (buf != NULL) { /* immediate write */
+ zgd->zgd_rl = ztest_range_lock(zd, object, offset, size,
+ RL_READER);
+
+ error = dmu_read(os, object, offset, size, buf,
+ DMU_READ_NO_PREFETCH);
+ ASSERT(error == 0);
+ } else {
+ size = doi.doi_data_block_size;
+ if (ISP2(size)) {
+ offset = P2ALIGN(offset, size);
+ } else {
+ ASSERT(offset < size);
+ offset = 0;
+ }
+
+ zgd->zgd_rl = ztest_range_lock(zd, object, offset, size,
+ RL_READER);
+
+ error = dmu_buf_hold(os, object, offset, zgd, &db,
+ DMU_READ_NO_PREFETCH);
+
+ if (error == 0) {
+ blkptr_t *obp = dmu_buf_get_blkptr(db);
+ if (obp) {
+ ASSERT(BP_IS_HOLE(bp));
+ *bp = *obp;
+ }
+
+ zgd->zgd_db = db;
+ zgd->zgd_bp = bp;
+
+ ASSERT(db->db_offset == offset);
+ ASSERT(db->db_size == size);
+
+ error = dmu_sync(zio, lr->lr_common.lrc_txg,
+ ztest_get_done, zgd);
+
+ if (error == 0)
+ return (0);
+ }
+ }
+
+ ztest_get_done(zgd, error);
+
+ return (error);
+}
+
+static void *
+ztest_lr_alloc(size_t lrsize, char *name)
+{
+ char *lr;
+ size_t namesize = name ? strlen(name) + 1 : 0;
+
+ lr = umem_zalloc(lrsize + namesize, UMEM_NOFAIL);
+
+ if (name)
+ bcopy(name, lr + lrsize, namesize);
+
+ return (lr);
+}
+
+void
+ztest_lr_free(void *lr, size_t lrsize, char *name)
+{
+ size_t namesize = name ? strlen(name) + 1 : 0;
+
+ umem_free(lr, lrsize + namesize);
+}
+
+/*
+ * Lookup a bunch of objects. Returns the number of objects not found.
+ */
+static int
+ztest_lookup(ztest_ds_t *zd, ztest_od_t *od, int count)
+{
+ int missing = 0;
+ int error;
+
+ ASSERT(_mutex_held(&zd->zd_dirobj_lock));
+
+ for (int i = 0; i < count; i++, od++) {
+ od->od_object = 0;
+ error = zap_lookup(zd->zd_os, od->od_dir, od->od_name,
+ sizeof (uint64_t), 1, &od->od_object);
+ if (error) {
+ ASSERT(error == ENOENT);
+ ASSERT(od->od_object == 0);
+ missing++;
+ } else {
+ dmu_buf_t *db;
+ ztest_block_tag_t *bbt;
+ dmu_object_info_t doi;
+
+ ASSERT(od->od_object != 0);
+ ASSERT(missing == 0); /* there should be no gaps */
+
+ ztest_object_lock(zd, od->od_object, RL_READER);
+ VERIFY3U(0, ==, dmu_bonus_hold(zd->zd_os,
+ od->od_object, FTAG, &db));
+ dmu_object_info_from_db(db, &doi);
+ bbt = ztest_bt_bonus(db);
+ ASSERT3U(bbt->bt_magic, ==, BT_MAGIC);
+ od->od_type = doi.doi_type;
+ od->od_blocksize = doi.doi_data_block_size;
+ od->od_gen = bbt->bt_gen;
+ dmu_buf_rele(db, FTAG);
+ ztest_object_unlock(zd, od->od_object);
+ }
+ }
+
+ return (missing);
+}
+
+static int
+ztest_create(ztest_ds_t *zd, ztest_od_t *od, int count)
+{
+ int missing = 0;
+
+ ASSERT(_mutex_held(&zd->zd_dirobj_lock));
+
+ for (int i = 0; i < count; i++, od++) {
+ if (missing) {
+ od->od_object = 0;
+ missing++;
+ continue;
+ }
+
+ lr_create_t *lr = ztest_lr_alloc(sizeof (*lr), od->od_name);
+
+ lr->lr_doid = od->od_dir;
+ lr->lr_foid = 0; /* 0 to allocate, > 0 to claim */
+ lr->lrz_type = od->od_crtype;
+ lr->lrz_blocksize = od->od_crblocksize;
+ lr->lrz_ibshift = ztest_random_ibshift();
+ lr->lrz_bonustype = DMU_OT_UINT64_OTHER;
+ lr->lrz_bonuslen = dmu_bonus_max();
+ lr->lr_gen = od->od_crgen;
+ lr->lr_crtime[0] = time(NULL);
+
+ if (ztest_replay_create(zd, lr, B_FALSE) != 0) {
+ ASSERT(missing == 0);
+ od->od_object = 0;
+ missing++;
+ } else {
+ od->od_object = lr->lr_foid;
+ od->od_type = od->od_crtype;
+ od->od_blocksize = od->od_crblocksize;
+ od->od_gen = od->od_crgen;
+ ASSERT(od->od_object != 0);
+ }
+
+ ztest_lr_free(lr, sizeof (*lr), od->od_name);
+ }
+
+ return (missing);
+}
+
+static int
+ztest_remove(ztest_ds_t *zd, ztest_od_t *od, int count)
+{
+ int missing = 0;
+ int error;
+
+ ASSERT(_mutex_held(&zd->zd_dirobj_lock));
+
+ od += count - 1;
+
+ for (int i = count - 1; i >= 0; i--, od--) {
+ if (missing) {
+ missing++;
+ continue;
+ }
+
+ /*
+ * No object was found.
+ */
+ if (od->od_object == 0)
+ continue;
+
+ lr_remove_t *lr = ztest_lr_alloc(sizeof (*lr), od->od_name);
+
+ lr->lr_doid = od->od_dir;
+
+ if ((error = ztest_replay_remove(zd, lr, B_FALSE)) != 0) {
+ ASSERT3U(error, ==, ENOSPC);
+ missing++;
+ } else {
+ od->od_object = 0;
+ }
+ ztest_lr_free(lr, sizeof (*lr), od->od_name);
+ }
+
+ return (missing);
+}
+
+static int
+ztest_write(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size,
+ void *data)
+{
+ lr_write_t *lr;
+ int error;
+
+ lr = ztest_lr_alloc(sizeof (*lr) + size, NULL);
+
+ lr->lr_foid = object;
+ lr->lr_offset = offset;
+ lr->lr_length = size;
+ lr->lr_blkoff = 0;
+ BP_ZERO(&lr->lr_blkptr);
+
+ bcopy(data, lr + 1, size);
+
+ error = ztest_replay_write(zd, lr, B_FALSE);
+
+ ztest_lr_free(lr, sizeof (*lr) + size, NULL);
+
+ return (error);
+}
+
+static int
+ztest_truncate(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
+{
+ lr_truncate_t *lr;
+ int error;
+
+ lr = ztest_lr_alloc(sizeof (*lr), NULL);
+
+ lr->lr_foid = object;
+ lr->lr_offset = offset;
+ lr->lr_length = size;
+
+ error = ztest_replay_truncate(zd, lr, B_FALSE);
+
+ ztest_lr_free(lr, sizeof (*lr), NULL);
+
+ return (error);
+}
+
+static int
+ztest_setattr(ztest_ds_t *zd, uint64_t object)
+{
+ lr_setattr_t *lr;
+ int error;
+
+ lr = ztest_lr_alloc(sizeof (*lr), NULL);
+
+ lr->lr_foid = object;
+ lr->lr_size = 0;
+ lr->lr_mode = 0;
+
+ error = ztest_replay_setattr(zd, lr, B_FALSE);
+
+ ztest_lr_free(lr, sizeof (*lr), NULL);
+
+ return (error);
+}
+
+static void
+ztest_prealloc(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
+{
+ objset_t *os = zd->zd_os;
+ dmu_tx_t *tx;
+ uint64_t txg;
+ rl_t *rl;
+
+ txg_wait_synced(dmu_objset_pool(os), 0);
+
+ ztest_object_lock(zd, object, RL_READER);
+ rl = ztest_range_lock(zd, object, offset, size, RL_WRITER);
+
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_write(tx, object, offset, size);
+
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+
+ if (txg != 0) {
+ dmu_prealloc(os, object, offset, size, tx);
+ dmu_tx_commit(tx);
+ txg_wait_synced(dmu_objset_pool(os), txg);
+ } else {
+ (void) dmu_free_long_range(os, object, offset, size);
+ }
+
+ ztest_range_unlock(rl);
+ ztest_object_unlock(zd, object);
+}
+
+static void
+ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
+{
+ int err;
+ ztest_block_tag_t wbt;
+ dmu_object_info_t doi;
+ enum ztest_io_type io_type;
+ uint64_t blocksize;
+ void *data;
+
+ VERIFY(dmu_object_info(zd->zd_os, object, &doi) == 0);
+ blocksize = doi.doi_data_block_size;
+ data = umem_alloc(blocksize, UMEM_NOFAIL);
+
+ /*
+ * Pick an i/o type at random, biased toward writing block tags.
+ */
+ io_type = ztest_random(ZTEST_IO_TYPES);
+ if (ztest_random(2) == 0)
+ io_type = ZTEST_IO_WRITE_TAG;
+
+ (void) rw_rdlock(&zd->zd_zilog_lock);
+
+ switch (io_type) {
+
+ case ZTEST_IO_WRITE_TAG:
+ ztest_bt_generate(&wbt, zd->zd_os, object, offset, 0, 0, 0);
+ (void) ztest_write(zd, object, offset, sizeof (wbt), &wbt);
+ break;
+
+ case ZTEST_IO_WRITE_PATTERN:
+ (void) memset(data, 'a' + (object + offset) % 5, blocksize);
+ if (ztest_random(2) == 0) {
+ /*
+ * Induce fletcher2 collisions to ensure that
+ * zio_ddt_collision() detects and resolves them
+ * when using fletcher2-verify for deduplication.
+ */
+ ((uint64_t *)data)[0] ^= 1ULL << 63;
+ ((uint64_t *)data)[4] ^= 1ULL << 63;
+ }
+ (void) ztest_write(zd, object, offset, blocksize, data);
+ break;
+
+ case ZTEST_IO_WRITE_ZEROES:
+ bzero(data, blocksize);
+ (void) ztest_write(zd, object, offset, blocksize, data);
+ break;
+
+ case ZTEST_IO_TRUNCATE:
+ (void) ztest_truncate(zd, object, offset, blocksize);
+ break;
+
+ case ZTEST_IO_SETATTR:
+ (void) ztest_setattr(zd, object);
+ break;
+
+ case ZTEST_IO_REWRITE:
+ (void) rw_rdlock(&ztest_name_lock);
+ err = ztest_dsl_prop_set_uint64(zd->zd_name,
+ ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
+ B_FALSE);
+ VERIFY(err == 0 || err == ENOSPC);
+ err = ztest_dsl_prop_set_uint64(zd->zd_name,
+ ZFS_PROP_COMPRESSION,
+ ztest_random_dsl_prop(ZFS_PROP_COMPRESSION),
+ B_FALSE);
+ VERIFY(err == 0 || err == ENOSPC);
+ (void) rw_unlock(&ztest_name_lock);
+
+ VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
+ DMU_READ_NO_PREFETCH));
+
+ (void) ztest_write(zd, object, offset, blocksize, data);
+ break;
+ }
+
+ (void) rw_unlock(&zd->zd_zilog_lock);
+
+ umem_free(data, blocksize);
+}
+
+/*
+ * Initialize an object description template.
+ */
+static void
+ztest_od_init(ztest_od_t *od, uint64_t id, char *tag, uint64_t index,
+ dmu_object_type_t type, uint64_t blocksize, uint64_t gen)
+{
+ od->od_dir = ZTEST_DIROBJ;
+ od->od_object = 0;
+
+ od->od_crtype = type;
+ od->od_crblocksize = blocksize ? blocksize : ztest_random_blocksize();
+ od->od_crgen = gen;
+
+ od->od_type = DMU_OT_NONE;
+ od->od_blocksize = 0;
+ od->od_gen = 0;
+
+ (void) snprintf(od->od_name, sizeof (od->od_name), "%s(%lld)[%llu]",
+ tag, (int64_t)id, index);
+}
+
+/*
+ * Lookup or create the objects for a test using the od template.
+ * If the objects do not all exist, or if 'remove' is specified,
+ * remove any existing objects and create new ones. Otherwise,
+ * use the existing objects.
+ */
+static int
+ztest_object_init(ztest_ds_t *zd, ztest_od_t *od, size_t size, boolean_t remove)
+{
+ int count = size / sizeof (*od);
+ int rv = 0;
+
+ VERIFY(mutex_lock(&zd->zd_dirobj_lock) == 0);
+ if ((ztest_lookup(zd, od, count) != 0 || remove) &&
+ (ztest_remove(zd, od, count) != 0 ||
+ ztest_create(zd, od, count) != 0))
+ rv = -1;
+ zd->zd_od = od;
+ VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
+
+ return (rv);
+}
+
+/* ARGSUSED */
+void
+ztest_zil_commit(ztest_ds_t *zd, uint64_t id)
+{
+ zilog_t *zilog = zd->zd_zilog;
+
+ (void) rw_rdlock(&zd->zd_zilog_lock);
+
+ zil_commit(zilog, ztest_random(ZTEST_OBJECTS));
+
+ /*
+ * Remember the committed values in zd, which is in parent/child
+ * shared memory. If we die, the next iteration of ztest_run()
+ * will verify that the log really does contain this record.
+ */
+ mutex_enter(&zilog->zl_lock);
+ ASSERT(zd->zd_shared != NULL);
+ ASSERT3U(zd->zd_shared->zd_seq, <=, zilog->zl_commit_lr_seq);
+ zd->zd_shared->zd_seq = zilog->zl_commit_lr_seq;
+ mutex_exit(&zilog->zl_lock);
+
+ (void) rw_unlock(&zd->zd_zilog_lock);
+}
+
+/*
+ * This function is designed to simulate the operations that occur during a
+ * mount/unmount operation. We hold the dataset across these operations in an
+ * attempt to expose any implicit assumptions about ZIL management.
+ */
+/* ARGSUSED */
+void
+ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+
+ /*
+ * We grab the zd_dirobj_lock to ensure that no other thread is
+ * updating the zil (i.e. adding in-memory log records) and the
+ * zd_zilog_lock to block any I/O.
+ */
+ VERIFY0(mutex_lock(&zd->zd_dirobj_lock));
+ (void) rw_wrlock(&zd->zd_zilog_lock);
+
+ /* zfsvfs_teardown() */
+ zil_close(zd->zd_zilog);
+
+ /* zfsvfs_setup() */
+ VERIFY(zil_open(os, ztest_get_data) == zd->zd_zilog);
+ zil_replay(os, zd, ztest_replay_vector);
+
+ (void) rw_unlock(&zd->zd_zilog_lock);
+ VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
+}
+
+/*
+ * Verify that we can't destroy an active pool, create an existing pool,
+ * or create a pool with a bad vdev spec.
+ */
+/* ARGSUSED */
+void
+ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_opts_t *zo = &ztest_opts;
+ spa_t *spa;
+ nvlist_t *nvroot;
+
+ /*
+ * Attempt to create using a bad file.
+ */
+ nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
+ VERIFY3U(ENOENT, ==,
+ spa_create("ztest_bad_file", nvroot, NULL, NULL));
+ nvlist_free(nvroot);
+
+ /*
+ * Attempt to create using a bad mirror.
+ */
+ nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 2, 1);
+ VERIFY3U(ENOENT, ==,
+ spa_create("ztest_bad_mirror", nvroot, NULL, NULL));
+ nvlist_free(nvroot);
+
+ /*
+ * Attempt to create an existing pool. It shouldn't matter
+ * what's in the nvroot; we should fail with EEXIST.
+ */
+ (void) rw_rdlock(&ztest_name_lock);
+ nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
+ VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL));
+ nvlist_free(nvroot);
+ VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
+ VERIFY3U(EBUSY, ==, spa_destroy(zo->zo_pool));
+ spa_close(spa, FTAG);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/* ARGSUSED */
+void
+ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa;
+ uint64_t initial_version = SPA_VERSION_INITIAL;
+ uint64_t version, newversion;
+ nvlist_t *nvroot, *props;
+ char *name;
+
+ VERIFY0(mutex_lock(&ztest_vdev_lock));
+ name = kmem_asprintf("%s_upgrade", ztest_opts.zo_pool);
+
+ /*
+ * Clean up from previous runs.
+ */
+ (void) spa_destroy(name);
+
+ nvroot = make_vdev_root(NULL, NULL, name, ztest_opts.zo_vdev_size, 0,
+ 0, ztest_opts.zo_raidz, ztest_opts.zo_mirrors, 1);
+
+ /*
+ * If we're configuring a RAIDZ device then make sure that the
+ * the initial version is capable of supporting that feature.
+ */
+ switch (ztest_opts.zo_raidz_parity) {
+ case 0:
+ case 1:
+ initial_version = SPA_VERSION_INITIAL;
+ break;
+ case 2:
+ initial_version = SPA_VERSION_RAIDZ2;
+ break;
+ case 3:
+ initial_version = SPA_VERSION_RAIDZ3;
+ break;
+ }
+
+ /*
+ * Create a pool with a spa version that can be upgraded. Pick
+ * a value between initial_version and SPA_VERSION_BEFORE_FEATURES.
+ */
+ do {
+ version = ztest_random_spa_version(initial_version);
+ } while (version > SPA_VERSION_BEFORE_FEATURES);
+
+ props = fnvlist_alloc();
+ fnvlist_add_uint64(props,
+ zpool_prop_to_name(ZPOOL_PROP_VERSION), version);
+ VERIFY0(spa_create(name, nvroot, props, NULL));
+ fnvlist_free(nvroot);
+ fnvlist_free(props);
+
+ VERIFY0(spa_open(name, &spa, FTAG));
+ VERIFY3U(spa_version(spa), ==, version);
+ newversion = ztest_random_spa_version(version + 1);
+
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("upgrading spa version from %llu to %llu\n",
+ (u_longlong_t)version, (u_longlong_t)newversion);
+ }
+
+ spa_upgrade(spa, newversion);
+ VERIFY3U(spa_version(spa), >, version);
+ VERIFY3U(spa_version(spa), ==, fnvlist_lookup_uint64(spa->spa_config,
+ zpool_prop_to_name(ZPOOL_PROP_VERSION)));
+ spa_close(spa, FTAG);
+
+ strfree(name);
+ VERIFY0(mutex_unlock(&ztest_vdev_lock));
+}
+
+static vdev_t *
+vdev_lookup_by_path(vdev_t *vd, const char *path)
+{
+ vdev_t *mvd;
+
+ if (vd->vdev_path != NULL && strcmp(path, vd->vdev_path) == 0)
+ return (vd);
+
+ for (int c = 0; c < vd->vdev_children; c++)
+ if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) !=
+ NULL)
+ return (mvd);
+
+ return (NULL);
+}
+
+/*
+ * Find the first available hole which can be used as a top-level.
+ */
+int
+find_vdev_hole(spa_t *spa)
+{
+ vdev_t *rvd = spa->spa_root_vdev;
+ int c;
+
+ ASSERT(spa_config_held(spa, SCL_VDEV, RW_READER) == SCL_VDEV);
+
+ for (c = 0; c < rvd->vdev_children; c++) {
+ vdev_t *cvd = rvd->vdev_child[c];
+
+ if (cvd->vdev_ishole)
+ break;
+ }
+ return (c);
+}
+
+/*
+ * Verify that vdev_add() works as expected.
+ */
+/* ARGSUSED */
+void
+ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ uint64_t leaves;
+ uint64_t guid;
+ nvlist_t *nvroot;
+ int error;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
+
+ spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+ ztest_shared->zs_vdev_next_leaf = find_vdev_hole(spa) * leaves;
+
+ /*
+ * If we have slogs then remove them 1/4 of the time.
+ */
+ if (spa_has_slogs(spa) && ztest_random(4) == 0) {
+ /*
+ * Grab the guid from the head of the log class rotor.
+ */
+ guid = spa_log_class(spa)->mc_rotor->mg_vd->vdev_guid;
+
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ /*
+ * We have to grab the zs_name_lock as writer to
+ * prevent a race between removing a slog (dmu_objset_find)
+ * and destroying a dataset. Removing the slog will
+ * grab a reference on the dataset which may cause
+ * dmu_objset_destroy() to fail with EBUSY thus
+ * leaving the dataset in an inconsistent state.
+ */
+ VERIFY(rw_wrlock(&ztest_name_lock) == 0);
+ error = spa_vdev_remove(spa, guid, B_FALSE);
+ VERIFY(rw_unlock(&ztest_name_lock) == 0);
+
+ if (error && error != EEXIST)
+ fatal(0, "spa_vdev_remove() = %d", error);
+ } else {
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ /*
+ * Make 1/4 of the devices be log devices.
+ */
+ nvroot = make_vdev_root(NULL, NULL, NULL,
+ ztest_opts.zo_vdev_size, 0,
+ ztest_random(4) == 0, ztest_opts.zo_raidz,
+ zs->zs_mirrors, 1);
+
+ error = spa_vdev_add(spa, nvroot);
+ nvlist_free(nvroot);
+
+ if (error == ENOSPC)
+ ztest_record_enospc("spa_vdev_add");
+ else if (error != 0)
+ fatal(0, "spa_vdev_add() = %d", error);
+ }
+
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+}
+
+/*
+ * Verify that adding/removing aux devices (l2arc, hot spare) works as expected.
+ */
+/* ARGSUSED */
+void
+ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ vdev_t *rvd = spa->spa_root_vdev;
+ spa_aux_vdev_t *sav;
+ char *aux;
+ uint64_t guid = 0;
+ int error;
+
+ if (ztest_random(2) == 0) {
+ sav = &spa->spa_spares;
+ aux = ZPOOL_CONFIG_SPARES;
+ } else {
+ sav = &spa->spa_l2cache;
+ aux = ZPOOL_CONFIG_L2CACHE;
+ }
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+
+ spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+ if (sav->sav_count != 0 && ztest_random(4) == 0) {
+ /*
+ * Pick a random device to remove.
+ */
+ guid = sav->sav_vdevs[ztest_random(sav->sav_count)]->vdev_guid;
+ } else {
+ /*
+ * Find an unused device we can add.
+ */
+ zs->zs_vdev_aux = 0;
+ for (;;) {
+ char path[MAXPATHLEN];
+ int c;
+ (void) snprintf(path, sizeof (path), ztest_aux_template,
+ ztest_opts.zo_dir, ztest_opts.zo_pool, aux,
+ zs->zs_vdev_aux);
+ for (c = 0; c < sav->sav_count; c++)
+ if (strcmp(sav->sav_vdevs[c]->vdev_path,
+ path) == 0)
+ break;
+ if (c == sav->sav_count &&
+ vdev_lookup_by_path(rvd, path) == NULL)
+ break;
+ zs->zs_vdev_aux++;
+ }
+ }
+
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ if (guid == 0) {
+ /*
+ * Add a new device.
+ */
+ nvlist_t *nvroot = make_vdev_root(NULL, aux, NULL,
+ (ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
+ error = spa_vdev_add(spa, nvroot);
+ if (error != 0)
+ fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
+ nvlist_free(nvroot);
+ } else {
+ /*
+ * Remove an existing device. Sometimes, dirty its
+ * vdev state first to make sure we handle removal
+ * of devices that have pending state changes.
+ */
+ if (ztest_random(2) == 0)
+ (void) vdev_online(spa, guid, 0, NULL);
+
+ error = spa_vdev_remove(spa, guid, B_FALSE);
+ if (error != 0 && error != EBUSY)
+ fatal(0, "spa_vdev_remove(%llu) = %d", guid, error);
+ }
+
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+}
+
+/*
+ * split a pool if it has mirror tlvdevs
+ */
+/* ARGSUSED */
+void
+ztest_split_pool(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ vdev_t *rvd = spa->spa_root_vdev;
+ nvlist_t *tree, **child, *config, *split, **schild;
+ uint_t c, children, schildren = 0, lastlogid = 0;
+ int error = 0;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+
+ /* ensure we have a useable config; mirrors of raidz aren't supported */
+ if (zs->zs_mirrors < 3 || ztest_opts.zo_raidz > 1) {
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ return;
+ }
+
+ /* clean up the old pool, if any */
+ (void) spa_destroy("splitp");
+
+ spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+ /* generate a config from the existing config */
+ mutex_enter(&spa->spa_props_lock);
+ VERIFY(nvlist_lookup_nvlist(spa->spa_config, ZPOOL_CONFIG_VDEV_TREE,
+ &tree) == 0);
+ mutex_exit(&spa->spa_props_lock);
+
+ VERIFY(nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
+ &children) == 0);
+
+ schild = malloc(rvd->vdev_children * sizeof (nvlist_t *));
+ for (c = 0; c < children; c++) {
+ vdev_t *tvd = rvd->vdev_child[c];
+ nvlist_t **mchild;
+ uint_t mchildren;
+
+ if (tvd->vdev_islog || tvd->vdev_ops == &vdev_hole_ops) {
+ VERIFY(nvlist_alloc(&schild[schildren], NV_UNIQUE_NAME,
+ 0) == 0);
+ VERIFY(nvlist_add_string(schild[schildren],
+ ZPOOL_CONFIG_TYPE, VDEV_TYPE_HOLE) == 0);
+ VERIFY(nvlist_add_uint64(schild[schildren],
+ ZPOOL_CONFIG_IS_HOLE, 1) == 0);
+ if (lastlogid == 0)
+ lastlogid = schildren;
+ ++schildren;
+ continue;
+ }
+ lastlogid = 0;
+ VERIFY(nvlist_lookup_nvlist_array(child[c],
+ ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
+ VERIFY(nvlist_dup(mchild[0], &schild[schildren++], 0) == 0);
+ }
+
+ /* OK, create a config that can be used to split */
+ VERIFY(nvlist_alloc(&split, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_string(split, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_ROOT) == 0);
+ VERIFY(nvlist_add_nvlist_array(split, ZPOOL_CONFIG_CHILDREN, schild,
+ lastlogid != 0 ? lastlogid : schildren) == 0);
+
+ VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, 0) == 0);
+ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, split) == 0);
+
+ for (c = 0; c < schildren; c++)
+ nvlist_free(schild[c]);
+ free(schild);
+ nvlist_free(split);
+
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ (void) rw_wrlock(&ztest_name_lock);
+ error = spa_vdev_split_mirror(spa, "splitp", config, NULL, B_FALSE);
+ (void) rw_unlock(&ztest_name_lock);
+
+ nvlist_free(config);
+
+ if (error == 0) {
+ (void) printf("successful split - results:\n");
+ mutex_enter(&spa_namespace_lock);
+ show_pool_stats(spa);
+ show_pool_stats(spa_lookup("splitp"));
+ mutex_exit(&spa_namespace_lock);
+ ++zs->zs_splits;
+ --zs->zs_mirrors;
+ }
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+
+}
+
+/*
+ * Verify that we can attach and detach devices.
+ */
+/* ARGSUSED */
+void
+ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ spa_aux_vdev_t *sav = &spa->spa_spares;
+ vdev_t *rvd = spa->spa_root_vdev;
+ vdev_t *oldvd, *newvd, *pvd;
+ nvlist_t *root;
+ uint64_t leaves;
+ uint64_t leaf, top;
+ uint64_t ashift = ztest_get_ashift();
+ uint64_t oldguid, pguid;
+ size_t oldsize, newsize;
+ char oldpath[MAXPATHLEN], newpath[MAXPATHLEN];
+ int replacing;
+ int oldvd_has_siblings = B_FALSE;
+ int newvd_is_spare = B_FALSE;
+ int oldvd_is_log;
+ int error, expected_error;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
+
+ spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
+
+ /*
+ * Decide whether to do an attach or a replace.
+ */
+ replacing = ztest_random(2);
+
+ /*
+ * Pick a random top-level vdev.
+ */
+ top = ztest_random_vdev_top(spa, B_TRUE);
+
+ /*
+ * Pick a random leaf within it.
+ */
+ leaf = ztest_random(leaves);
+
+ /*
+ * Locate this vdev.
+ */
+ oldvd = rvd->vdev_child[top];
+ if (zs->zs_mirrors >= 1) {
+ ASSERT(oldvd->vdev_ops == &vdev_mirror_ops);
+ ASSERT(oldvd->vdev_children >= zs->zs_mirrors);
+ oldvd = oldvd->vdev_child[leaf / ztest_opts.zo_raidz];
+ }
+ if (ztest_opts.zo_raidz > 1) {
+ ASSERT(oldvd->vdev_ops == &vdev_raidz_ops);
+ ASSERT(oldvd->vdev_children == ztest_opts.zo_raidz);
+ oldvd = oldvd->vdev_child[leaf % ztest_opts.zo_raidz];
+ }
+
+ /*
+ * If we're already doing an attach or replace, oldvd may be a
+ * mirror vdev -- in which case, pick a random child.
+ */
+ while (oldvd->vdev_children != 0) {
+ oldvd_has_siblings = B_TRUE;
+ ASSERT(oldvd->vdev_children >= 2);
+ oldvd = oldvd->vdev_child[ztest_random(oldvd->vdev_children)];
+ }
+
+ oldguid = oldvd->vdev_guid;
+ oldsize = vdev_get_min_asize(oldvd);
+ oldvd_is_log = oldvd->vdev_top->vdev_islog;
+ (void) strcpy(oldpath, oldvd->vdev_path);
+ pvd = oldvd->vdev_parent;
+ pguid = pvd->vdev_guid;
+
+ /*
+ * If oldvd has siblings, then half of the time, detach it.
+ */
+ if (oldvd_has_siblings && ztest_random(2) == 0) {
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+ error = spa_vdev_detach(spa, oldguid, pguid, B_FALSE);
+ if (error != 0 && error != ENODEV && error != EBUSY &&
+ error != ENOTSUP)
+ fatal(0, "detach (%s) returned %d", oldpath, error);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ return;
+ }
+
+ /*
+ * For the new vdev, choose with equal probability between the two
+ * standard paths (ending in either 'a' or 'b') or a random hot spare.
+ */
+ if (sav->sav_count != 0 && ztest_random(3) == 0) {
+ newvd = sav->sav_vdevs[ztest_random(sav->sav_count)];
+ newvd_is_spare = B_TRUE;
+ (void) strcpy(newpath, newvd->vdev_path);
+ } else {
+ (void) snprintf(newpath, sizeof (newpath), ztest_dev_template,
+ ztest_opts.zo_dir, ztest_opts.zo_pool,
+ top * leaves + leaf);
+ if (ztest_random(2) == 0)
+ newpath[strlen(newpath) - 1] = 'b';
+ newvd = vdev_lookup_by_path(rvd, newpath);
+ }
+
+ if (newvd) {
+ newsize = vdev_get_min_asize(newvd);
+ } else {
+ /*
+ * Make newsize a little bigger or smaller than oldsize.
+ * If it's smaller, the attach should fail.
+ * If it's larger, and we're doing a replace,
+ * we should get dynamic LUN growth when we're done.
+ */
+ newsize = 10 * oldsize / (9 + ztest_random(3));
+ }
+
+ /*
+ * If pvd is not a mirror or root, the attach should fail with ENOTSUP,
+ * unless it's a replace; in that case any non-replacing parent is OK.
+ *
+ * If newvd is already part of the pool, it should fail with EBUSY.
+ *
+ * If newvd is too small, it should fail with EOVERFLOW.
+ */
+ if (pvd->vdev_ops != &vdev_mirror_ops &&
+ pvd->vdev_ops != &vdev_root_ops && (!replacing ||
+ pvd->vdev_ops == &vdev_replacing_ops ||
+ pvd->vdev_ops == &vdev_spare_ops))
+ expected_error = ENOTSUP;
+ else if (newvd_is_spare && (!replacing || oldvd_is_log))
+ expected_error = ENOTSUP;
+ else if (newvd == oldvd)
+ expected_error = replacing ? 0 : EBUSY;
+ else if (vdev_lookup_by_path(rvd, newpath) != NULL)
+ expected_error = EBUSY;
+ else if (newsize < oldsize)
+ expected_error = EOVERFLOW;
+ else if (ashift > oldvd->vdev_top->vdev_ashift)
+ expected_error = EDOM;
+ else
+ expected_error = 0;
+
+ spa_config_exit(spa, SCL_VDEV, FTAG);
+
+ /*
+ * Build the nvlist describing newpath.
+ */
+ root = make_vdev_root(newpath, NULL, NULL, newvd == NULL ? newsize : 0,
+ ashift, 0, 0, 0, 1);
+
+ error = spa_vdev_attach(spa, oldguid, root, replacing);
+
+ nvlist_free(root);
+
+ /*
+ * If our parent was the replacing vdev, but the replace completed,
+ * then instead of failing with ENOTSUP we may either succeed,
+ * fail with ENODEV, or fail with EOVERFLOW.
+ */
+ if (expected_error == ENOTSUP &&
+ (error == 0 || error == ENODEV || error == EOVERFLOW))
+ expected_error = error;
+
+ /*
+ * If someone grew the LUN, the replacement may be too small.
+ */
+ if (error == EOVERFLOW || error == EBUSY)
+ expected_error = error;
+
+ /* XXX workaround 6690467 */
+ if (error != expected_error && expected_error != EBUSY) {
+ fatal(0, "attach (%s %llu, %s %llu, %d) "
+ "returned %d, expected %d",
+ oldpath, (longlong_t)oldsize, newpath,
+ (longlong_t)newsize, replacing, error, expected_error);
+ }
+
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+}
+
+/*
+ * Callback function which expands the physical size of the vdev.
+ */
+vdev_t *
+grow_vdev(vdev_t *vd, void *arg)
+{
+ spa_t *spa = vd->vdev_spa;
+ size_t *newsize = arg;
+ size_t fsize;
+ int fd;
+
+ ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
+ ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+ if ((fd = open(vd->vdev_path, O_RDWR)) == -1)
+ return (vd);
+
+ fsize = lseek(fd, 0, SEEK_END);
+ (void) ftruncate(fd, *newsize);
+
+ if (ztest_opts.zo_verbose >= 6) {
+ (void) printf("%s grew from %lu to %lu bytes\n",
+ vd->vdev_path, (ulong_t)fsize, (ulong_t)*newsize);
+ }
+ (void) close(fd);
+ return (NULL);
+}
+
+/*
+ * Callback function which expands a given vdev by calling vdev_online().
+ */
+/* ARGSUSED */
+vdev_t *
+online_vdev(vdev_t *vd, void *arg)
+{
+ spa_t *spa = vd->vdev_spa;
+ vdev_t *tvd = vd->vdev_top;
+ uint64_t guid = vd->vdev_guid;
+ uint64_t generation = spa->spa_config_generation + 1;
+ vdev_state_t newstate = VDEV_STATE_UNKNOWN;
+ int error;
+
+ ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
+ ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+ /* Calling vdev_online will initialize the new metaslabs */
+ spa_config_exit(spa, SCL_STATE, spa);
+ error = vdev_online(spa, guid, ZFS_ONLINE_EXPAND, &newstate);
+ spa_config_enter(spa, SCL_STATE, spa, RW_READER);
+
+ /*
+ * If vdev_online returned an error or the underlying vdev_open
+ * failed then we abort the expand. The only way to know that
+ * vdev_open fails is by checking the returned newstate.
+ */
+ if (error || newstate != VDEV_STATE_HEALTHY) {
+ if (ztest_opts.zo_verbose >= 5) {
+ (void) printf("Unable to expand vdev, state %llu, "
+ "error %d\n", (u_longlong_t)newstate, error);
+ }
+ return (vd);
+ }
+ ASSERT3U(newstate, ==, VDEV_STATE_HEALTHY);
+
+ /*
+ * Since we dropped the lock we need to ensure that we're
+ * still talking to the original vdev. It's possible this
+ * vdev may have been detached/replaced while we were
+ * trying to online it.
+ */
+ if (generation != spa->spa_config_generation) {
+ if (ztest_opts.zo_verbose >= 5) {
+ (void) printf("vdev configuration has changed, "
+ "guid %llu, state %llu, expected gen %llu, "
+ "got gen %llu\n",
+ (u_longlong_t)guid,
+ (u_longlong_t)tvd->vdev_state,
+ (u_longlong_t)generation,
+ (u_longlong_t)spa->spa_config_generation);
+ }
+ return (vd);
+ }
+ return (NULL);
+}
+
+/*
+ * Traverse the vdev tree calling the supplied function.
+ * We continue to walk the tree until we either have walked all
+ * children or we receive a non-NULL return from the callback.
+ * If a NULL callback is passed, then we just return back the first
+ * leaf vdev we encounter.
+ */
+vdev_t *
+vdev_walk_tree(vdev_t *vd, vdev_t *(*func)(vdev_t *, void *), void *arg)
+{
+ if (vd->vdev_ops->vdev_op_leaf) {
+ if (func == NULL)
+ return (vd);
+ else
+ return (func(vd, arg));
+ }
+
+ for (uint_t c = 0; c < vd->vdev_children; c++) {
+ vdev_t *cvd = vd->vdev_child[c];
+ if ((cvd = vdev_walk_tree(cvd, func, arg)) != NULL)
+ return (cvd);
+ }
+ return (NULL);
+}
+
+/*
+ * Verify that dynamic LUN growth works as expected.
+ */
+/* ARGSUSED */
+void
+ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa = ztest_spa;
+ vdev_t *vd, *tvd;
+ metaslab_class_t *mc;
+ metaslab_group_t *mg;
+ size_t psize, newsize;
+ uint64_t top;
+ uint64_t old_class_space, new_class_space, old_ms_count, new_ms_count;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ spa_config_enter(spa, SCL_STATE, spa, RW_READER);
+
+ top = ztest_random_vdev_top(spa, B_TRUE);
+
+ tvd = spa->spa_root_vdev->vdev_child[top];
+ mg = tvd->vdev_mg;
+ mc = mg->mg_class;
+ old_ms_count = tvd->vdev_ms_count;
+ old_class_space = metaslab_class_get_space(mc);
+
+ /*
+ * Determine the size of the first leaf vdev associated with
+ * our top-level device.
+ */
+ vd = vdev_walk_tree(tvd, NULL, NULL);
+ ASSERT3P(vd, !=, NULL);
+ ASSERT(vd->vdev_ops->vdev_op_leaf);
+
+ psize = vd->vdev_psize;
+
+ /*
+ * We only try to expand the vdev if it's healthy, less than 4x its
+ * original size, and it has a valid psize.
+ */
+ if (tvd->vdev_state != VDEV_STATE_HEALTHY ||
+ psize == 0 || psize >= 4 * ztest_opts.zo_vdev_size) {
+ spa_config_exit(spa, SCL_STATE, spa);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ return;
+ }
+ ASSERT(psize > 0);
+ newsize = psize + psize / 8;
+ ASSERT3U(newsize, >, psize);
+
+ if (ztest_opts.zo_verbose >= 6) {
+ (void) printf("Expanding LUN %s from %lu to %lu\n",
+ vd->vdev_path, (ulong_t)psize, (ulong_t)newsize);
+ }
+
+ /*
+ * Growing the vdev is a two step process:
+ * 1). expand the physical size (i.e. relabel)
+ * 2). online the vdev to create the new metaslabs
+ */
+ if (vdev_walk_tree(tvd, grow_vdev, &newsize) != NULL ||
+ vdev_walk_tree(tvd, online_vdev, NULL) != NULL ||
+ tvd->vdev_state != VDEV_STATE_HEALTHY) {
+ if (ztest_opts.zo_verbose >= 5) {
+ (void) printf("Could not expand LUN because "
+ "the vdev configuration changed.\n");
+ }
+ spa_config_exit(spa, SCL_STATE, spa);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ return;
+ }
+
+ spa_config_exit(spa, SCL_STATE, spa);
+
+ /*
+ * Expanding the LUN will update the config asynchronously,
+ * thus we must wait for the async thread to complete any
+ * pending tasks before proceeding.
+ */
+ for (;;) {
+ boolean_t done;
+ mutex_enter(&spa->spa_async_lock);
+ done = (spa->spa_async_thread == NULL && !spa->spa_async_tasks);
+ mutex_exit(&spa->spa_async_lock);
+ if (done)
+ break;
+ txg_wait_synced(spa_get_dsl(spa), 0);
+ (void) poll(NULL, 0, 100);
+ }
+
+ spa_config_enter(spa, SCL_STATE, spa, RW_READER);
+
+ tvd = spa->spa_root_vdev->vdev_child[top];
+ new_ms_count = tvd->vdev_ms_count;
+ new_class_space = metaslab_class_get_space(mc);
+
+ if (tvd->vdev_mg != mg || mg->mg_class != mc) {
+ if (ztest_opts.zo_verbose >= 5) {
+ (void) printf("Could not verify LUN expansion due to "
+ "intervening vdev offline or remove.\n");
+ }
+ spa_config_exit(spa, SCL_STATE, spa);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ return;
+ }
+
+ /*
+ * Make sure we were able to grow the vdev.
+ */
+ if (new_ms_count <= old_ms_count)
+ fatal(0, "LUN expansion failed: ms_count %llu <= %llu\n",
+ old_ms_count, new_ms_count);
+
+ /*
+ * Make sure we were able to grow the pool.
+ */
+ if (new_class_space <= old_class_space)
+ fatal(0, "LUN expansion failed: class_space %llu <= %llu\n",
+ old_class_space, new_class_space);
+
+ if (ztest_opts.zo_verbose >= 5) {
+ char oldnumbuf[6], newnumbuf[6];
+
+ nicenum(old_class_space, oldnumbuf);
+ nicenum(new_class_space, newnumbuf);
+ (void) printf("%s grew from %s to %s\n",
+ spa->spa_name, oldnumbuf, newnumbuf);
+ }
+
+ spa_config_exit(spa, SCL_STATE, spa);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+}
+
+/*
+ * Verify that dmu_objset_{create,destroy,open,close} work as expected.
+ */
+/* ARGSUSED */
+static void
+ztest_objset_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
+{
+ /*
+ * Create the objects common to all ztest datasets.
+ */
+ VERIFY(zap_create_claim(os, ZTEST_DIROBJ,
+ DMU_OT_ZAP_OTHER, DMU_OT_NONE, 0, tx) == 0);
+}
+
+static int
+ztest_dataset_create(char *dsname)
+{
+ uint64_t zilset = ztest_random(100);
+ int err = dmu_objset_create(dsname, DMU_OST_OTHER, 0,
+ ztest_objset_create_cb, NULL);
+
+ if (err || zilset < 80)
+ return (err);
+
+ if (ztest_opts.zo_verbose >= 6)
+ (void) printf("Setting dataset %s to sync always\n", dsname);
+ return (ztest_dsl_prop_set_uint64(dsname, ZFS_PROP_SYNC,
+ ZFS_SYNC_ALWAYS, B_FALSE));
+}
+
+/* ARGSUSED */
+static int
+ztest_objset_destroy_cb(const char *name, void *arg)
+{
+ objset_t *os;
+ dmu_object_info_t doi;
+ int error;
+
+ /*
+ * Verify that the dataset contains a directory object.
+ */
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, FTAG, &os));
+ error = dmu_object_info(os, ZTEST_DIROBJ, &doi);
+ if (error != ENOENT) {
+ /* We could have crashed in the middle of destroying it */
+ ASSERT0(error);
+ ASSERT3U(doi.doi_type, ==, DMU_OT_ZAP_OTHER);
+ ASSERT3S(doi.doi_physical_blocks_512, >=, 0);
+ }
+ dmu_objset_disown(os, FTAG);
+
+ /*
+ * Destroy the dataset.
+ */
+ if (strchr(name, '@') != NULL) {
+ VERIFY0(dsl_destroy_snapshot(name, B_FALSE));
+ } else {
+ VERIFY0(dsl_destroy_head(name));
+ }
+ return (0);
+}
+
+static boolean_t
+ztest_snapshot_create(char *osname, uint64_t id)
+{
+ char snapname[MAXNAMELEN];
+ int error;
+
+ (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id);
+
+ error = dmu_objset_snapshot_one(osname, snapname);
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ return (B_FALSE);
+ }
+ if (error != 0 && error != EEXIST) {
+ fatal(0, "ztest_snapshot_create(%s@%s) = %d", osname,
+ snapname, error);
+ }
+ return (B_TRUE);
+}
+
+static boolean_t
+ztest_snapshot_destroy(char *osname, uint64_t id)
+{
+ char snapname[MAXNAMELEN];
+ int error;
+
+ (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname,
+ (u_longlong_t)id);
+
+ error = dsl_destroy_snapshot(snapname, B_FALSE);
+ if (error != 0 && error != ENOENT)
+ fatal(0, "ztest_snapshot_destroy(%s) = %d", snapname, error);
+ return (B_TRUE);
+}
+
+/* ARGSUSED */
+void
+ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_ds_t zdtmp;
+ int iters;
+ int error;
+ objset_t *os, *os2;
+ char name[MAXNAMELEN];
+ zilog_t *zilog;
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ (void) snprintf(name, MAXNAMELEN, "%s/temp_%llu",
+ ztest_opts.zo_pool, (u_longlong_t)id);
+
+ /*
+ * If this dataset exists from a previous run, process its replay log
+ * half of the time. If we don't replay it, then dmu_objset_destroy()
+ * (invoked from ztest_objset_destroy_cb()) should just throw it away.
+ */
+ if (ztest_random(2) == 0 &&
+ dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os) == 0) {
+ ztest_zd_init(&zdtmp, NULL, os);
+ zil_replay(os, &zdtmp, ztest_replay_vector);
+ ztest_zd_fini(&zdtmp);
+ dmu_objset_disown(os, FTAG);
+ }
+
+ /*
+ * There may be an old instance of the dataset we're about to
+ * create lying around from a previous run. If so, destroy it
+ * and all of its snapshots.
+ */
+ (void) dmu_objset_find(name, ztest_objset_destroy_cb, NULL,
+ DS_FIND_CHILDREN | DS_FIND_SNAPSHOTS);
+
+ /*
+ * Verify that the destroyed dataset is no longer in the namespace.
+ */
+ VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
+ FTAG, &os));
+
+ /*
+ * Verify that we can create a new dataset.
+ */
+ error = ztest_dataset_create(name);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ (void) rw_unlock(&ztest_name_lock);
+ return;
+ }
+ fatal(0, "dmu_objset_create(%s) = %d", name, error);
+ }
+
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os));
+
+ ztest_zd_init(&zdtmp, NULL, os);
+
+ /*
+ * Open the intent log for it.
+ */
+ zilog = zil_open(os, ztest_get_data);
+
+ /*
+ * Put some objects in there, do a little I/O to them,
+ * and randomly take a couple of snapshots along the way.
+ */
+ iters = ztest_random(5);
+ for (int i = 0; i < iters; i++) {
+ ztest_dmu_object_alloc_free(&zdtmp, id);
+ if (ztest_random(iters) == 0)
+ (void) ztest_snapshot_create(name, i);
+ }
+
+ /*
+ * Verify that we cannot create an existing dataset.
+ */
+ VERIFY3U(EEXIST, ==,
+ dmu_objset_create(name, DMU_OST_OTHER, 0, NULL, NULL));
+
+ /*
+ * Verify that we can hold an objset that is also owned.
+ */
+ VERIFY3U(0, ==, dmu_objset_hold(name, FTAG, &os2));
+ dmu_objset_rele(os2, FTAG);
+
+ /*
+ * Verify that we cannot own an objset that is already owned.
+ */
+ VERIFY3U(EBUSY, ==,
+ dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os2));
+
+ zil_close(zilog);
+ dmu_objset_disown(os, FTAG);
+ ztest_zd_fini(&zdtmp);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Verify that dmu_snapshot_{create,destroy,open,close} work as expected.
+ */
+void
+ztest_dmu_snapshot_create_destroy(ztest_ds_t *zd, uint64_t id)
+{
+ (void) rw_rdlock(&ztest_name_lock);
+ (void) ztest_snapshot_destroy(zd->zd_name, id);
+ (void) ztest_snapshot_create(zd->zd_name, id);
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Cleanup non-standard snapshots and clones.
+ */
+void
+ztest_dsl_dataset_cleanup(char *osname, uint64_t id)
+{
+ char snap1name[MAXNAMELEN];
+ char clone1name[MAXNAMELEN];
+ char snap2name[MAXNAMELEN];
+ char clone2name[MAXNAMELEN];
+ char snap3name[MAXNAMELEN];
+ int error;
+
+ (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu", osname, id);
+ (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu", osname, id);
+ (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu", clone1name, id);
+ (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id);
+ (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id);
+
+ error = dsl_destroy_head(clone2name);
+ if (error && error != ENOENT)
+ fatal(0, "dsl_destroy_head(%s) = %d", clone2name, error);
+ error = dsl_destroy_snapshot(snap3name, B_FALSE);
+ if (error && error != ENOENT)
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap3name, error);
+ error = dsl_destroy_snapshot(snap2name, B_FALSE);
+ if (error && error != ENOENT)
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap2name, error);
+ error = dsl_destroy_head(clone1name);
+ if (error && error != ENOENT)
+ fatal(0, "dsl_destroy_head(%s) = %d", clone1name, error);
+ error = dsl_destroy_snapshot(snap1name, B_FALSE);
+ if (error && error != ENOENT)
+ fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error);
+}
+
+/*
+ * Verify dsl_dataset_promote handles EBUSY
+ */
+void
+ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os;
+ char snap1name[MAXNAMELEN];
+ char clone1name[MAXNAMELEN];
+ char snap2name[MAXNAMELEN];
+ char clone2name[MAXNAMELEN];
+ char snap3name[MAXNAMELEN];
+ char *osname = zd->zd_name;
+ int error;
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ ztest_dsl_dataset_cleanup(osname, id);
+
+ (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu", osname, id);
+ (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu", osname, id);
+ (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu", clone1name, id);
+ (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id);
+ (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id);
+
+ error = dmu_objset_snapshot_one(osname, strchr(snap1name, '@') + 1);
+ if (error && error != EEXIST) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ goto out;
+ }
+ fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error);
+ }
+
+ error = dmu_objset_clone(clone1name, snap1name);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ goto out;
+ }
+ fatal(0, "dmu_objset_create(%s) = %d", clone1name, error);
+ }
+
+ error = dmu_objset_snapshot_one(clone1name, strchr(snap2name, '@') + 1);
+ if (error && error != EEXIST) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ goto out;
+ }
+ fatal(0, "dmu_open_snapshot(%s) = %d", snap2name, error);
+ }
+
+ error = dmu_objset_snapshot_one(clone1name, strchr(snap3name, '@') + 1);
+ if (error && error != EEXIST) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ goto out;
+ }
+ fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
+ }
+
+ error = dmu_objset_clone(clone2name, snap3name);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc(FTAG);
+ goto out;
+ }
+ fatal(0, "dmu_objset_create(%s) = %d", clone2name, error);
+ }
+
+ error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, FTAG, &os);
+ if (error)
+ fatal(0, "dmu_objset_own(%s) = %d", snap2name, error);
+ error = dsl_dataset_promote(clone2name, NULL);
+ if (error != EBUSY)
+ fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name,
+ error);
+ dmu_objset_disown(os, FTAG);
+
+out:
+ ztest_dsl_dataset_cleanup(osname, id);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Verify that dmu_object_{alloc,free} work as expected.
+ */
+void
+ztest_dmu_object_alloc_free(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_od_t od[4];
+ int batchsize = sizeof (od) / sizeof (od[0]);
+
+ for (int b = 0; b < batchsize; b++)
+ ztest_od_init(&od[b], id, FTAG, b, DMU_OT_UINT64_OTHER, 0, 0);
+
+ /*
+ * Destroy the previous batch of objects, create a new batch,
+ * and do some I/O on the new objects.
+ */
+ if (ztest_object_init(zd, od, sizeof (od), B_TRUE) != 0)
+ return;
+
+ while (ztest_random(4 * batchsize) != 0)
+ ztest_io(zd, od[ztest_random(batchsize)].od_object,
+ ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
+}
+
+/*
+ * Verify that dmu_{read,write} work as expected.
+ */
+void
+ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[2];
+ dmu_tx_t *tx;
+ int i, freeit, error;
+ uint64_t n, s, txg;
+ bufwad_t *packbuf, *bigbuf, *pack, *bigH, *bigT;
+ uint64_t packobj, packoff, packsize, bigobj, bigoff, bigsize;
+ uint64_t chunksize = (1000 + ztest_random(1000)) * sizeof (uint64_t);
+ uint64_t regions = 997;
+ uint64_t stride = 123456789ULL;
+ uint64_t width = 40;
+ int free_percent = 5;
+
+ /*
+ * This test uses two objects, packobj and bigobj, that are always
+ * updated together (i.e. in the same tx) so that their contents are
+ * in sync and can be compared. Their contents relate to each other
+ * in a simple way: packobj is a dense array of 'bufwad' structures,
+ * while bigobj is a sparse array of the same bufwads. Specifically,
+ * for any index n, there are three bufwads that should be identical:
+ *
+ * packobj, at offset n * sizeof (bufwad_t)
+ * bigobj, at the head of the nth chunk
+ * bigobj, at the tail of the nth chunk
+ *
+ * The chunk size is arbitrary. It doesn't have to be a power of two,
+ * and it doesn't have any relation to the object blocksize.
+ * The only requirement is that it can hold at least two bufwads.
+ *
+ * Normally, we write the bufwad to each of these locations.
+ * However, free_percent of the time we instead write zeroes to
+ * packobj and perform a dmu_free_range() on bigobj. By comparing
+ * bigobj to packobj, we can verify that the DMU is correctly
+ * tracking which parts of an object are allocated and free,
+ * and that the contents of the allocated blocks are correct.
+ */
+
+ /*
+ * Read the directory info. If it's the first time, set things up.
+ */
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, chunksize);
+ ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ bigobj = od[0].od_object;
+ packobj = od[1].od_object;
+ chunksize = od[0].od_gen;
+ ASSERT(chunksize == od[1].od_gen);
+
+ /*
+ * Prefetch a random chunk of the big object.
+ * Our aim here is to get some async reads in flight
+ * for blocks that we may free below; the DMU should
+ * handle this race correctly.
+ */
+ n = ztest_random(regions) * stride + ztest_random(width);
+ s = 1 + ztest_random(2 * width - 1);
+ dmu_prefetch(os, bigobj, n * chunksize, s * chunksize);
+
+ /*
+ * Pick a random index and compute the offsets into packobj and bigobj.
+ */
+ n = ztest_random(regions) * stride + ztest_random(width);
+ s = 1 + ztest_random(width - 1);
+
+ packoff = n * sizeof (bufwad_t);
+ packsize = s * sizeof (bufwad_t);
+
+ bigoff = n * chunksize;
+ bigsize = s * chunksize;
+
+ packbuf = umem_alloc(packsize, UMEM_NOFAIL);
+ bigbuf = umem_alloc(bigsize, UMEM_NOFAIL);
+
+ /*
+ * free_percent of the time, free a range of bigobj rather than
+ * overwriting it.
+ */
+ freeit = (ztest_random(100) < free_percent);
+
+ /*
+ * Read the current contents of our objects.
+ */
+ error = dmu_read(os, packobj, packoff, packsize, packbuf,
+ DMU_READ_PREFETCH);
+ ASSERT0(error);
+ error = dmu_read(os, bigobj, bigoff, bigsize, bigbuf,
+ DMU_READ_PREFETCH);
+ ASSERT0(error);
+
+ /*
+ * Get a tx for the mods to both packobj and bigobj.
+ */
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_write(tx, packobj, packoff, packsize);
+
+ if (freeit)
+ dmu_tx_hold_free(tx, bigobj, bigoff, bigsize);
+ else
+ dmu_tx_hold_write(tx, bigobj, bigoff, bigsize);
+
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0) {
+ umem_free(packbuf, packsize);
+ umem_free(bigbuf, bigsize);
+ return;
+ }
+
+ dmu_object_set_checksum(os, bigobj,
+ (enum zio_checksum)ztest_random_dsl_prop(ZFS_PROP_CHECKSUM), tx);
+
+ dmu_object_set_compress(os, bigobj,
+ (enum zio_compress)ztest_random_dsl_prop(ZFS_PROP_COMPRESSION), tx);
+
+ /*
+ * For each index from n to n + s, verify that the existing bufwad
+ * in packobj matches the bufwads at the head and tail of the
+ * corresponding chunk in bigobj. Then update all three bufwads
+ * with the new values we want to write out.
+ */
+ for (i = 0; i < s; i++) {
+ /* LINTED */
+ pack = (bufwad_t *)((char *)packbuf + i * sizeof (bufwad_t));
+ /* LINTED */
+ bigH = (bufwad_t *)((char *)bigbuf + i * chunksize);
+ /* LINTED */
+ bigT = (bufwad_t *)((char *)bigH + chunksize) - 1;
+
+ ASSERT((uintptr_t)bigH - (uintptr_t)bigbuf < bigsize);
+ ASSERT((uintptr_t)bigT - (uintptr_t)bigbuf < bigsize);
+
+ if (pack->bw_txg > txg)
+ fatal(0, "future leak: got %llx, open txg is %llx",
+ pack->bw_txg, txg);
+
+ if (pack->bw_data != 0 && pack->bw_index != n + i)
+ fatal(0, "wrong index: got %llx, wanted %llx+%llx",
+ pack->bw_index, n, i);
+
+ if (bcmp(pack, bigH, sizeof (bufwad_t)) != 0)
+ fatal(0, "pack/bigH mismatch in %p/%p", pack, bigH);
+
+ if (bcmp(pack, bigT, sizeof (bufwad_t)) != 0)
+ fatal(0, "pack/bigT mismatch in %p/%p", pack, bigT);
+
+ if (freeit) {
+ bzero(pack, sizeof (bufwad_t));
+ } else {
+ pack->bw_index = n + i;
+ pack->bw_txg = txg;
+ pack->bw_data = 1 + ztest_random(-2ULL);
+ }
+ *bigH = *pack;
+ *bigT = *pack;
+ }
+
+ /*
+ * We've verified all the old bufwads, and made new ones.
+ * Now write them out.
+ */
+ dmu_write(os, packobj, packoff, packsize, packbuf, tx);
+
+ if (freeit) {
+ if (ztest_opts.zo_verbose >= 7) {
+ (void) printf("freeing offset %llx size %llx"
+ " txg %llx\n",
+ (u_longlong_t)bigoff,
+ (u_longlong_t)bigsize,
+ (u_longlong_t)txg);
+ }
+ VERIFY(0 == dmu_free_range(os, bigobj, bigoff, bigsize, tx));
+ } else {
+ if (ztest_opts.zo_verbose >= 7) {
+ (void) printf("writing offset %llx size %llx"
+ " txg %llx\n",
+ (u_longlong_t)bigoff,
+ (u_longlong_t)bigsize,
+ (u_longlong_t)txg);
+ }
+ dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx);
+ }
+
+ dmu_tx_commit(tx);
+
+ /*
+ * Sanity check the stuff we just wrote.
+ */
+ {
+ void *packcheck = umem_alloc(packsize, UMEM_NOFAIL);
+ void *bigcheck = umem_alloc(bigsize, UMEM_NOFAIL);
+
+ VERIFY(0 == dmu_read(os, packobj, packoff,
+ packsize, packcheck, DMU_READ_PREFETCH));
+ VERIFY(0 == dmu_read(os, bigobj, bigoff,
+ bigsize, bigcheck, DMU_READ_PREFETCH));
+
+ ASSERT(bcmp(packbuf, packcheck, packsize) == 0);
+ ASSERT(bcmp(bigbuf, bigcheck, bigsize) == 0);
+
+ umem_free(packcheck, packsize);
+ umem_free(bigcheck, bigsize);
+ }
+
+ umem_free(packbuf, packsize);
+ umem_free(bigbuf, bigsize);
+}
+
+void
+compare_and_update_pbbufs(uint64_t s, bufwad_t *packbuf, bufwad_t *bigbuf,
+ uint64_t bigsize, uint64_t n, uint64_t chunksize, uint64_t txg)
+{
+ uint64_t i;
+ bufwad_t *pack;
+ bufwad_t *bigH;
+ bufwad_t *bigT;
+
+ /*
+ * For each index from n to n + s, verify that the existing bufwad
+ * in packobj matches the bufwads at the head and tail of the
+ * corresponding chunk in bigobj. Then update all three bufwads
+ * with the new values we want to write out.
+ */
+ for (i = 0; i < s; i++) {
+ /* LINTED */
+ pack = (bufwad_t *)((char *)packbuf + i * sizeof (bufwad_t));
+ /* LINTED */
+ bigH = (bufwad_t *)((char *)bigbuf + i * chunksize);
+ /* LINTED */
+ bigT = (bufwad_t *)((char *)bigH + chunksize) - 1;
+
+ ASSERT((uintptr_t)bigH - (uintptr_t)bigbuf < bigsize);
+ ASSERT((uintptr_t)bigT - (uintptr_t)bigbuf < bigsize);
+
+ if (pack->bw_txg > txg)
+ fatal(0, "future leak: got %llx, open txg is %llx",
+ pack->bw_txg, txg);
+
+ if (pack->bw_data != 0 && pack->bw_index != n + i)
+ fatal(0, "wrong index: got %llx, wanted %llx+%llx",
+ pack->bw_index, n, i);
+
+ if (bcmp(pack, bigH, sizeof (bufwad_t)) != 0)
+ fatal(0, "pack/bigH mismatch in %p/%p", pack, bigH);
+
+ if (bcmp(pack, bigT, sizeof (bufwad_t)) != 0)
+ fatal(0, "pack/bigT mismatch in %p/%p", pack, bigT);
+
+ pack->bw_index = n + i;
+ pack->bw_txg = txg;
+ pack->bw_data = 1 + ztest_random(-2ULL);
+
+ *bigH = *pack;
+ *bigT = *pack;
+ }
+}
+
+void
+ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[2];
+ dmu_tx_t *tx;
+ uint64_t i;
+ int error;
+ uint64_t n, s, txg;
+ bufwad_t *packbuf, *bigbuf;
+ uint64_t packobj, packoff, packsize, bigobj, bigoff, bigsize;
+ uint64_t blocksize = ztest_random_blocksize();
+ uint64_t chunksize = blocksize;
+ uint64_t regions = 997;
+ uint64_t stride = 123456789ULL;
+ uint64_t width = 9;
+ dmu_buf_t *bonus_db;
+ arc_buf_t **bigbuf_arcbufs;
+ dmu_object_info_t doi;
+
+ /*
+ * This test uses two objects, packobj and bigobj, that are always
+ * updated together (i.e. in the same tx) so that their contents are
+ * in sync and can be compared. Their contents relate to each other
+ * in a simple way: packobj is a dense array of 'bufwad' structures,
+ * while bigobj is a sparse array of the same bufwads. Specifically,
+ * for any index n, there are three bufwads that should be identical:
+ *
+ * packobj, at offset n * sizeof (bufwad_t)
+ * bigobj, at the head of the nth chunk
+ * bigobj, at the tail of the nth chunk
+ *
+ * The chunk size is set equal to bigobj block size so that
+ * dmu_assign_arcbuf() can be tested for object updates.
+ */
+
+ /*
+ * Read the directory info. If it's the first time, set things up.
+ */
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
+ ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ bigobj = od[0].od_object;
+ packobj = od[1].od_object;
+ blocksize = od[0].od_blocksize;
+ chunksize = blocksize;
+ ASSERT(chunksize == od[1].od_gen);
+
+ VERIFY(dmu_object_info(os, bigobj, &doi) == 0);
+ VERIFY(ISP2(doi.doi_data_block_size));
+ VERIFY(chunksize == doi.doi_data_block_size);
+ VERIFY(chunksize >= 2 * sizeof (bufwad_t));
+
+ /*
+ * Pick a random index and compute the offsets into packobj and bigobj.
+ */
+ n = ztest_random(regions) * stride + ztest_random(width);
+ s = 1 + ztest_random(width - 1);
+
+ packoff = n * sizeof (bufwad_t);
+ packsize = s * sizeof (bufwad_t);
+
+ bigoff = n * chunksize;
+ bigsize = s * chunksize;
+
+ packbuf = umem_zalloc(packsize, UMEM_NOFAIL);
+ bigbuf = umem_zalloc(bigsize, UMEM_NOFAIL);
+
+ VERIFY3U(0, ==, dmu_bonus_hold(os, bigobj, FTAG, &bonus_db));
+
+ bigbuf_arcbufs = umem_zalloc(2 * s * sizeof (arc_buf_t *), UMEM_NOFAIL);
+
+ /*
+ * Iteration 0 test zcopy for DB_UNCACHED dbufs.
+ * Iteration 1 test zcopy to already referenced dbufs.
+ * Iteration 2 test zcopy to dirty dbuf in the same txg.
+ * Iteration 3 test zcopy to dbuf dirty in previous txg.
+ * Iteration 4 test zcopy when dbuf is no longer dirty.
+ * Iteration 5 test zcopy when it can't be done.
+ * Iteration 6 one more zcopy write.
+ */
+ for (i = 0; i < 7; i++) {
+ uint64_t j;
+ uint64_t off;
+
+ /*
+ * In iteration 5 (i == 5) use arcbufs
+ * that don't match bigobj blksz to test
+ * dmu_assign_arcbuf() when it can't directly
+ * assign an arcbuf to a dbuf.
+ */
+ for (j = 0; j < s; j++) {
+ if (i != 5) {
+ bigbuf_arcbufs[j] =
+ dmu_request_arcbuf(bonus_db, chunksize);
+ } else {
+ bigbuf_arcbufs[2 * j] =
+ dmu_request_arcbuf(bonus_db, chunksize / 2);
+ bigbuf_arcbufs[2 * j + 1] =
+ dmu_request_arcbuf(bonus_db, chunksize / 2);
+ }
+ }
+
+ /*
+ * Get a tx for the mods to both packobj and bigobj.
+ */
+ tx = dmu_tx_create(os);
+
+ dmu_tx_hold_write(tx, packobj, packoff, packsize);
+ dmu_tx_hold_write(tx, bigobj, bigoff, bigsize);
+
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0) {
+ umem_free(packbuf, packsize);
+ umem_free(bigbuf, bigsize);
+ for (j = 0; j < s; j++) {
+ if (i != 5) {
+ dmu_return_arcbuf(bigbuf_arcbufs[j]);
+ } else {
+ dmu_return_arcbuf(
+ bigbuf_arcbufs[2 * j]);
+ dmu_return_arcbuf(
+ bigbuf_arcbufs[2 * j + 1]);
+ }
+ }
+ umem_free(bigbuf_arcbufs, 2 * s * sizeof (arc_buf_t *));
+ dmu_buf_rele(bonus_db, FTAG);
+ return;
+ }
+
+ /*
+ * 50% of the time don't read objects in the 1st iteration to
+ * test dmu_assign_arcbuf() for the case when there're no
+ * existing dbufs for the specified offsets.
+ */
+ if (i != 0 || ztest_random(2) != 0) {
+ error = dmu_read(os, packobj, packoff,
+ packsize, packbuf, DMU_READ_PREFETCH);
+ ASSERT0(error);
+ error = dmu_read(os, bigobj, bigoff, bigsize,
+ bigbuf, DMU_READ_PREFETCH);
+ ASSERT0(error);
+ }
+ compare_and_update_pbbufs(s, packbuf, bigbuf, bigsize,
+ n, chunksize, txg);
+
+ /*
+ * We've verified all the old bufwads, and made new ones.
+ * Now write them out.
+ */
+ dmu_write(os, packobj, packoff, packsize, packbuf, tx);
+ if (ztest_opts.zo_verbose >= 7) {
+ (void) printf("writing offset %llx size %llx"
+ " txg %llx\n",
+ (u_longlong_t)bigoff,
+ (u_longlong_t)bigsize,
+ (u_longlong_t)txg);
+ }
+ for (off = bigoff, j = 0; j < s; j++, off += chunksize) {
+ dmu_buf_t *dbt;
+ if (i != 5) {
+ bcopy((caddr_t)bigbuf + (off - bigoff),
+ bigbuf_arcbufs[j]->b_data, chunksize);
+ } else {
+ bcopy((caddr_t)bigbuf + (off - bigoff),
+ bigbuf_arcbufs[2 * j]->b_data,
+ chunksize / 2);
+ bcopy((caddr_t)bigbuf + (off - bigoff) +
+ chunksize / 2,
+ bigbuf_arcbufs[2 * j + 1]->b_data,
+ chunksize / 2);
+ }
+
+ if (i == 1) {
+ VERIFY(dmu_buf_hold(os, bigobj, off,
+ FTAG, &dbt, DMU_READ_NO_PREFETCH) == 0);
+ }
+ if (i != 5) {
+ dmu_assign_arcbuf(bonus_db, off,
+ bigbuf_arcbufs[j], tx);
+ } else {
+ dmu_assign_arcbuf(bonus_db, off,
+ bigbuf_arcbufs[2 * j], tx);
+ dmu_assign_arcbuf(bonus_db,
+ off + chunksize / 2,
+ bigbuf_arcbufs[2 * j + 1], tx);
+ }
+ if (i == 1) {
+ dmu_buf_rele(dbt, FTAG);
+ }
+ }
+ dmu_tx_commit(tx);
+
+ /*
+ * Sanity check the stuff we just wrote.
+ */
+ {
+ void *packcheck = umem_alloc(packsize, UMEM_NOFAIL);
+ void *bigcheck = umem_alloc(bigsize, UMEM_NOFAIL);
+
+ VERIFY(0 == dmu_read(os, packobj, packoff,
+ packsize, packcheck, DMU_READ_PREFETCH));
+ VERIFY(0 == dmu_read(os, bigobj, bigoff,
+ bigsize, bigcheck, DMU_READ_PREFETCH));
+
+ ASSERT(bcmp(packbuf, packcheck, packsize) == 0);
+ ASSERT(bcmp(bigbuf, bigcheck, bigsize) == 0);
+
+ umem_free(packcheck, packsize);
+ umem_free(bigcheck, bigsize);
+ }
+ if (i == 2) {
+ txg_wait_open(dmu_objset_pool(os), 0);
+ } else if (i == 3) {
+ txg_wait_synced(dmu_objset_pool(os), 0);
+ }
+ }
+
+ dmu_buf_rele(bonus_db, FTAG);
+ umem_free(packbuf, packsize);
+ umem_free(bigbuf, bigsize);
+ umem_free(bigbuf_arcbufs, 2 * s * sizeof (arc_buf_t *));
+}
+
+/* ARGSUSED */
+void
+ztest_dmu_write_parallel(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_od_t od[1];
+ uint64_t offset = (1ULL << (ztest_random(20) + 43)) +
+ (ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
+
+ /*
+ * Have multiple threads write to large offsets in an object
+ * to verify that parallel writes to an object -- even to the
+ * same blocks within the object -- doesn't cause any trouble.
+ */
+ ztest_od_init(&od[0], ID_PARALLEL, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ while (ztest_random(10) != 0)
+ ztest_io(zd, od[0].od_object, offset);
+}
+
+void
+ztest_dmu_prealloc(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_od_t od[1];
+ uint64_t offset = (1ULL << (ztest_random(4) + SPA_MAXBLOCKSHIFT)) +
+ (ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
+ uint64_t count = ztest_random(20) + 1;
+ uint64_t blocksize = ztest_random_blocksize();
+ void *data;
+
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
+ return;
+
+ if (ztest_truncate(zd, od[0].od_object, offset, count * blocksize) != 0)
+ return;
+
+ ztest_prealloc(zd, od[0].od_object, offset, count * blocksize);
+
+ data = umem_zalloc(blocksize, UMEM_NOFAIL);
+
+ while (ztest_random(count) != 0) {
+ uint64_t randoff = offset + (ztest_random(count) * blocksize);
+ if (ztest_write(zd, od[0].od_object, randoff, blocksize,
+ data) != 0)
+ break;
+ while (ztest_random(4) != 0)
+ ztest_io(zd, od[0].od_object, randoff);
+ }
+
+ umem_free(data, blocksize);
+}
+
+/*
+ * Verify that zap_{create,destroy,add,remove,update} work as expected.
+ */
+#define ZTEST_ZAP_MIN_INTS 1
+#define ZTEST_ZAP_MAX_INTS 4
+#define ZTEST_ZAP_MAX_PROPS 1000
+
+void
+ztest_zap(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[1];
+ uint64_t object;
+ uint64_t txg, last_txg;
+ uint64_t value[ZTEST_ZAP_MAX_INTS];
+ uint64_t zl_ints, zl_intsize, prop;
+ int i, ints;
+ dmu_tx_t *tx;
+ char propname[100], txgname[100];
+ int error;
+ char *hc[2] = { "s.acl.h", ".s.open.h.hyLZlg" };
+
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
+ return;
+
+ object = od[0].od_object;
+
+ /*
+ * Generate a known hash collision, and verify that
+ * we can lookup and remove both entries.
+ */
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_zap(tx, object, B_TRUE, NULL);
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0)
+ return;
+ for (i = 0; i < 2; i++) {
+ value[i] = i;
+ VERIFY3U(0, ==, zap_add(os, object, hc[i], sizeof (uint64_t),
+ 1, &value[i], tx));
+ }
+ for (i = 0; i < 2; i++) {
+ VERIFY3U(EEXIST, ==, zap_add(os, object, hc[i],
+ sizeof (uint64_t), 1, &value[i], tx));
+ VERIFY3U(0, ==,
+ zap_length(os, object, hc[i], &zl_intsize, &zl_ints));
+ ASSERT3U(zl_intsize, ==, sizeof (uint64_t));
+ ASSERT3U(zl_ints, ==, 1);
+ }
+ for (i = 0; i < 2; i++) {
+ VERIFY3U(0, ==, zap_remove(os, object, hc[i], tx));
+ }
+ dmu_tx_commit(tx);
+
+ /*
+ * Generate a buch of random entries.
+ */
+ ints = MAX(ZTEST_ZAP_MIN_INTS, object % ZTEST_ZAP_MAX_INTS);
+
+ prop = ztest_random(ZTEST_ZAP_MAX_PROPS);
+ (void) sprintf(propname, "prop_%llu", (u_longlong_t)prop);
+ (void) sprintf(txgname, "txg_%llu", (u_longlong_t)prop);
+ bzero(value, sizeof (value));
+ last_txg = 0;
+
+ /*
+ * If these zap entries already exist, validate their contents.
+ */
+ error = zap_length(os, object, txgname, &zl_intsize, &zl_ints);
+ if (error == 0) {
+ ASSERT3U(zl_intsize, ==, sizeof (uint64_t));
+ ASSERT3U(zl_ints, ==, 1);
+
+ VERIFY(zap_lookup(os, object, txgname, zl_intsize,
+ zl_ints, &last_txg) == 0);
+
+ VERIFY(zap_length(os, object, propname, &zl_intsize,
+ &zl_ints) == 0);
+
+ ASSERT3U(zl_intsize, ==, sizeof (uint64_t));
+ ASSERT3U(zl_ints, ==, ints);
+
+ VERIFY(zap_lookup(os, object, propname, zl_intsize,
+ zl_ints, value) == 0);
+
+ for (i = 0; i < ints; i++) {
+ ASSERT3U(value[i], ==, last_txg + object + i);
+ }
+ } else {
+ ASSERT3U(error, ==, ENOENT);
+ }
+
+ /*
+ * Atomically update two entries in our zap object.
+ * The first is named txg_%llu, and contains the txg
+ * in which the property was last updated. The second
+ * is named prop_%llu, and the nth element of its value
+ * should be txg + object + n.
+ */
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_zap(tx, object, B_TRUE, NULL);
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0)
+ return;
+
+ if (last_txg > txg)
+ fatal(0, "zap future leak: old %llu new %llu", last_txg, txg);
+
+ for (i = 0; i < ints; i++)
+ value[i] = txg + object + i;
+
+ VERIFY3U(0, ==, zap_update(os, object, txgname, sizeof (uint64_t),
+ 1, &txg, tx));
+ VERIFY3U(0, ==, zap_update(os, object, propname, sizeof (uint64_t),
+ ints, value, tx));
+
+ dmu_tx_commit(tx);
+
+ /*
+ * Remove a random pair of entries.
+ */
+ prop = ztest_random(ZTEST_ZAP_MAX_PROPS);
+ (void) sprintf(propname, "prop_%llu", (u_longlong_t)prop);
+ (void) sprintf(txgname, "txg_%llu", (u_longlong_t)prop);
+
+ error = zap_length(os, object, txgname, &zl_intsize, &zl_ints);
+
+ if (error == ENOENT)
+ return;
+
+ ASSERT0(error);
+
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_zap(tx, object, B_TRUE, NULL);
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0)
+ return;
+ VERIFY3U(0, ==, zap_remove(os, object, txgname, tx));
+ VERIFY3U(0, ==, zap_remove(os, object, propname, tx));
+ dmu_tx_commit(tx);
+}
+
+/*
+ * Testcase to test the upgrading of a microzap to fatzap.
+ */
+void
+ztest_fzap(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[1];
+ uint64_t object, txg;
+
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
+ return;
+
+ object = od[0].od_object;
+
+ /*
+ * Add entries to this ZAP and make sure it spills over
+ * and gets upgraded to a fatzap. Also, since we are adding
+ * 2050 entries we should see ptrtbl growth and leaf-block split.
+ */
+ for (int i = 0; i < 2050; i++) {
+ char name[MAXNAMELEN];
+ uint64_t value = i;
+ dmu_tx_t *tx;
+ int error;
+
+ (void) snprintf(name, sizeof (name), "fzap-%llu-%llu",
+ id, value);
+
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_zap(tx, object, B_TRUE, name);
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0)
+ return;
+ error = zap_add(os, object, name, sizeof (uint64_t), 1,
+ &value, tx);
+ ASSERT(error == 0 || error == EEXIST);
+ dmu_tx_commit(tx);
+ }
+}
+
+/* ARGSUSED */
+void
+ztest_zap_parallel(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[1];
+ uint64_t txg, object, count, wsize, wc, zl_wsize, zl_wc;
+ dmu_tx_t *tx;
+ int i, namelen, error;
+ int micro = ztest_random(2);
+ char name[20], string_value[20];
+ void *data;
+
+ ztest_od_init(&od[0], ID_PARALLEL, FTAG, micro, DMU_OT_ZAP_OTHER, 0, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ object = od[0].od_object;
+
+ /*
+ * Generate a random name of the form 'xxx.....' where each
+ * x is a random printable character and the dots are dots.
+ * There are 94 such characters, and the name length goes from
+ * 6 to 20, so there are 94^3 * 15 = 12,458,760 possible names.
+ */
+ namelen = ztest_random(sizeof (name) - 5) + 5 + 1;
+
+ for (i = 0; i < 3; i++)
+ name[i] = '!' + ztest_random('~' - '!' + 1);
+ for (; i < namelen - 1; i++)
+ name[i] = '.';
+ name[i] = '\0';
+
+ if ((namelen & 1) || micro) {
+ wsize = sizeof (txg);
+ wc = 1;
+ data = &txg;
+ } else {
+ wsize = 1;
+ wc = namelen;
+ data = string_value;
+ }
+
+ count = -1ULL;
+ VERIFY0(zap_count(os, object, &count));
+ ASSERT(count != -1ULL);
+
+ /*
+ * Select an operation: length, lookup, add, update, remove.
+ */
+ i = ztest_random(5);
+
+ if (i >= 2) {
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_zap(tx, object, B_TRUE, NULL);
+ txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
+ if (txg == 0)
+ return;
+ bcopy(name, string_value, namelen);
+ } else {
+ tx = NULL;
+ txg = 0;
+ bzero(string_value, namelen);
+ }
+
+ switch (i) {
+
+ case 0:
+ error = zap_length(os, object, name, &zl_wsize, &zl_wc);
+ if (error == 0) {
+ ASSERT3U(wsize, ==, zl_wsize);
+ ASSERT3U(wc, ==, zl_wc);
+ } else {
+ ASSERT3U(error, ==, ENOENT);
+ }
+ break;
+
+ case 1:
+ error = zap_lookup(os, object, name, wsize, wc, data);
+ if (error == 0) {
+ if (data == string_value &&
+ bcmp(name, data, namelen) != 0)
+ fatal(0, "name '%s' != val '%s' len %d",
+ name, data, namelen);
+ } else {
+ ASSERT3U(error, ==, ENOENT);
+ }
+ break;
+
+ case 2:
+ error = zap_add(os, object, name, wsize, wc, data, tx);
+ ASSERT(error == 0 || error == EEXIST);
+ break;
+
+ case 3:
+ VERIFY(zap_update(os, object, name, wsize, wc, data, tx) == 0);
+ break;
+
+ case 4:
+ error = zap_remove(os, object, name, tx);
+ ASSERT(error == 0 || error == ENOENT);
+ break;
+ }
+
+ if (tx != NULL)
+ dmu_tx_commit(tx);
+}
+
+/*
+ * Commit callback data.
+ */
+typedef struct ztest_cb_data {
+ list_node_t zcd_node;
+ uint64_t zcd_txg;
+ int zcd_expected_err;
+ boolean_t zcd_added;
+ boolean_t zcd_called;
+ spa_t *zcd_spa;
+} ztest_cb_data_t;
+
+/* This is the actual commit callback function */
+static void
+ztest_commit_callback(void *arg, int error)
+{
+ ztest_cb_data_t *data = arg;
+ uint64_t synced_txg;
+
+ VERIFY(data != NULL);
+ VERIFY3S(data->zcd_expected_err, ==, error);
+ VERIFY(!data->zcd_called);
+
+ synced_txg = spa_last_synced_txg(data->zcd_spa);
+ if (data->zcd_txg > synced_txg)
+ fatal(0, "commit callback of txg %" PRIu64 " called prematurely"
+ ", last synced txg = %" PRIu64 "\n", data->zcd_txg,
+ synced_txg);
+
+ data->zcd_called = B_TRUE;
+
+ if (error == ECANCELED) {
+ ASSERT0(data->zcd_txg);
+ ASSERT(!data->zcd_added);
+
+ /*
+ * The private callback data should be destroyed here, but
+ * since we are going to check the zcd_called field after
+ * dmu_tx_abort(), we will destroy it there.
+ */
+ return;
+ }
+
+ /* Was this callback added to the global callback list? */
+ if (!data->zcd_added)
+ goto out;
+
+ ASSERT3U(data->zcd_txg, !=, 0);
+
+ /* Remove our callback from the list */
+ (void) mutex_lock(&zcl.zcl_callbacks_lock);
+ list_remove(&zcl.zcl_callbacks, data);
+ (void) mutex_unlock(&zcl.zcl_callbacks_lock);
+
+out:
+ umem_free(data, sizeof (ztest_cb_data_t));
+}
+
+/* Allocate and initialize callback data structure */
+static ztest_cb_data_t *
+ztest_create_cb_data(objset_t *os, uint64_t txg)
+{
+ ztest_cb_data_t *cb_data;
+
+ cb_data = umem_zalloc(sizeof (ztest_cb_data_t), UMEM_NOFAIL);
+
+ cb_data->zcd_txg = txg;
+ cb_data->zcd_spa = dmu_objset_spa(os);
+
+ return (cb_data);
+}
+
+/*
+ * If a number of txgs equal to this threshold have been created after a commit
+ * callback has been registered but not called, then we assume there is an
+ * implementation bug.
+ */
+#define ZTEST_COMMIT_CALLBACK_THRESH (TXG_CONCURRENT_STATES + 2)
+
+/*
+ * Commit callback test.
+ */
+void
+ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[1];
+ dmu_tx_t *tx;
+ ztest_cb_data_t *cb_data[3], *tmp_cb;
+ uint64_t old_txg, txg;
+ int i, error;
+
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ tx = dmu_tx_create(os);
+
+ cb_data[0] = ztest_create_cb_data(os, 0);
+ dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[0]);
+
+ dmu_tx_hold_write(tx, od[0].od_object, 0, sizeof (uint64_t));
+
+ /* Every once in a while, abort the transaction on purpose */
+ if (ztest_random(100) == 0)
+ error = -1;
+
+ if (!error)
+ error = dmu_tx_assign(tx, TXG_NOWAIT);
+
+ txg = error ? 0 : dmu_tx_get_txg(tx);
+
+ cb_data[0]->zcd_txg = txg;
+ cb_data[1] = ztest_create_cb_data(os, txg);
+ dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[1]);
+
+ if (error) {
+ /*
+ * It's not a strict requirement to call the registered
+ * callbacks from inside dmu_tx_abort(), but that's what
+ * it's supposed to happen in the current implementation
+ * so we will check for that.
+ */
+ for (i = 0; i < 2; i++) {
+ cb_data[i]->zcd_expected_err = ECANCELED;
+ VERIFY(!cb_data[i]->zcd_called);
+ }
+
+ dmu_tx_abort(tx);
+
+ for (i = 0; i < 2; i++) {
+ VERIFY(cb_data[i]->zcd_called);
+ umem_free(cb_data[i], sizeof (ztest_cb_data_t));
+ }
+
+ return;
+ }
+
+ cb_data[2] = ztest_create_cb_data(os, txg);
+ dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[2]);
+
+ /*
+ * Read existing data to make sure there isn't a future leak.
+ */
+ VERIFY(0 == dmu_read(os, od[0].od_object, 0, sizeof (uint64_t),
+ &old_txg, DMU_READ_PREFETCH));
+
+ if (old_txg > txg)
+ fatal(0, "future leak: got %" PRIu64 ", open txg is %" PRIu64,
+ old_txg, txg);
+
+ dmu_write(os, od[0].od_object, 0, sizeof (uint64_t), &txg, tx);
+
+ (void) mutex_lock(&zcl.zcl_callbacks_lock);
+
+ /*
+ * Since commit callbacks don't have any ordering requirement and since
+ * it is theoretically possible for a commit callback to be called
+ * after an arbitrary amount of time has elapsed since its txg has been
+ * synced, it is difficult to reliably determine whether a commit
+ * callback hasn't been called due to high load or due to a flawed
+ * implementation.
+ *
+ * In practice, we will assume that if after a certain number of txgs a
+ * commit callback hasn't been called, then most likely there's an
+ * implementation bug..
+ */
+ tmp_cb = list_head(&zcl.zcl_callbacks);
+ if (tmp_cb != NULL &&
+ tmp_cb->zcd_txg > txg - ZTEST_COMMIT_CALLBACK_THRESH) {
+ fatal(0, "Commit callback threshold exceeded, oldest txg: %"
+ PRIu64 ", open txg: %" PRIu64 "\n", tmp_cb->zcd_txg, txg);
+ }
+
+ /*
+ * Let's find the place to insert our callbacks.
+ *
+ * Even though the list is ordered by txg, it is possible for the
+ * insertion point to not be the end because our txg may already be
+ * quiescing at this point and other callbacks in the open txg
+ * (from other objsets) may have sneaked in.
+ */
+ tmp_cb = list_tail(&zcl.zcl_callbacks);
+ while (tmp_cb != NULL && tmp_cb->zcd_txg > txg)
+ tmp_cb = list_prev(&zcl.zcl_callbacks, tmp_cb);
+
+ /* Add the 3 callbacks to the list */
+ for (i = 0; i < 3; i++) {
+ if (tmp_cb == NULL)
+ list_insert_head(&zcl.zcl_callbacks, cb_data[i]);
+ else
+ list_insert_after(&zcl.zcl_callbacks, tmp_cb,
+ cb_data[i]);
+
+ cb_data[i]->zcd_added = B_TRUE;
+ VERIFY(!cb_data[i]->zcd_called);
+
+ tmp_cb = cb_data[i];
+ }
+
+ (void) mutex_unlock(&zcl.zcl_callbacks_lock);
+
+ dmu_tx_commit(tx);
+}
+
+/* ARGSUSED */
+void
+ztest_dsl_prop_get_set(ztest_ds_t *zd, uint64_t id)
+{
+ zfs_prop_t proplist[] = {
+ ZFS_PROP_CHECKSUM,
+ ZFS_PROP_COMPRESSION,
+ ZFS_PROP_COPIES,
+ ZFS_PROP_DEDUP
+ };
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ for (int p = 0; p < sizeof (proplist) / sizeof (proplist[0]); p++)
+ (void) ztest_dsl_prop_set_uint64(zd->zd_name, proplist[p],
+ ztest_random_dsl_prop(proplist[p]), (int)ztest_random(2));
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/* ARGSUSED */
+void
+ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id)
+{
+ nvlist_t *props = NULL;
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ (void) ztest_spa_prop_set_uint64(ZPOOL_PROP_DEDUPDITTO,
+ ZIO_DEDUPDITTO_MIN + ztest_random(ZIO_DEDUPDITTO_MIN));
+
+ VERIFY0(spa_prop_get(ztest_spa, &props));
+
+ if (ztest_opts.zo_verbose >= 6)
+ dump_nvlist(props, 4);
+
+ nvlist_free(props);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+static int
+user_release_one(const char *snapname, const char *holdname)
+{
+ nvlist_t *snaps, *holds;
+ int error;
+
+ snaps = fnvlist_alloc();
+ holds = fnvlist_alloc();
+ fnvlist_add_boolean(holds, holdname);
+ fnvlist_add_nvlist(snaps, snapname, holds);
+ fnvlist_free(holds);
+ error = dsl_dataset_user_release(snaps, NULL);
+ fnvlist_free(snaps);
+ return (error);
+}
+
+/*
+ * Test snapshot hold/release and deferred destroy.
+ */
+void
+ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
+{
+ int error;
+ objset_t *os = zd->zd_os;
+ objset_t *origin;
+ char snapname[100];
+ char fullname[100];
+ char clonename[100];
+ char tag[100];
+ char osname[MAXNAMELEN];
+ nvlist_t *holds;
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ dmu_objset_name(os, osname);
+
+ (void) snprintf(snapname, sizeof (snapname), "sh1_%llu", id);
+ (void) snprintf(fullname, sizeof (fullname), "%s@%s", osname, snapname);
+ (void) snprintf(clonename, sizeof (clonename),
+ "%s/ch1_%llu", osname, id);
+ (void) snprintf(tag, sizeof (tag), "tag_%llu", id);
+
+ /*
+ * Clean up from any previous run.
+ */
+ error = dsl_destroy_head(clonename);
+ if (error != ENOENT)
+ ASSERT0(error);
+ error = user_release_one(fullname, tag);
+ if (error != ESRCH && error != ENOENT)
+ ASSERT0(error);
+ error = dsl_destroy_snapshot(fullname, B_FALSE);
+ if (error != ENOENT)
+ ASSERT0(error);
+
+ /*
+ * Create snapshot, clone it, mark snap for deferred destroy,
+ * destroy clone, verify snap was also destroyed.
+ */
+ error = dmu_objset_snapshot_one(osname, snapname);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc("dmu_objset_snapshot");
+ goto out;
+ }
+ fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
+ }
+
+ error = dmu_objset_clone(clonename, fullname);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc("dmu_objset_clone");
+ goto out;
+ }
+ fatal(0, "dmu_objset_clone(%s) = %d", clonename, error);
+ }
+
+ error = dsl_destroy_snapshot(fullname, B_TRUE);
+ if (error) {
+ fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
+ fullname, error);
+ }
+
+ error = dsl_destroy_head(clonename);
+ if (error)
+ fatal(0, "dsl_destroy_head(%s) = %d", clonename, error);
+
+ error = dmu_objset_hold(fullname, FTAG, &origin);
+ if (error != ENOENT)
+ fatal(0, "dmu_objset_hold(%s) = %d", fullname, error);
+
+ /*
+ * Create snapshot, add temporary hold, verify that we can't
+ * destroy a held snapshot, mark for deferred destroy,
+ * release hold, verify snapshot was destroyed.
+ */
+ error = dmu_objset_snapshot_one(osname, snapname);
+ if (error) {
+ if (error == ENOSPC) {
+ ztest_record_enospc("dmu_objset_snapshot");
+ goto out;
+ }
+ fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
+ }
+
+ holds = fnvlist_alloc();
+ fnvlist_add_string(holds, fullname, tag);
+ error = dsl_dataset_user_hold(holds, 0, NULL);
+ fnvlist_free(holds);
+
+ if (error)
+ fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag);
+
+ error = dsl_destroy_snapshot(fullname, B_FALSE);
+ if (error != EBUSY) {
+ fatal(0, "dsl_destroy_snapshot(%s, B_FALSE) = %d",
+ fullname, error);
+ }
+
+ error = dsl_destroy_snapshot(fullname, B_TRUE);
+ if (error) {
+ fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
+ fullname, error);
+ }
+
+ error = user_release_one(fullname, tag);
+ if (error)
+ fatal(0, "user_release_one(%s)", fullname, tag);
+
+ VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT);
+
+out:
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Inject random faults into the on-disk data.
+ */
+/* ARGSUSED */
+void
+ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ int fd;
+ uint64_t offset;
+ uint64_t leaves;
+ uint64_t bad = 0x1990c0ffeedecadeULL;
+ uint64_t top, leaf;
+ char path0[MAXPATHLEN];
+ char pathrand[MAXPATHLEN];
+ size_t fsize;
+ int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */
+ int iters = 1000;
+ int maxfaults;
+ int mirror_save;
+ vdev_t *vd0 = NULL;
+ uint64_t guid0 = 0;
+ boolean_t islog = B_FALSE;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ maxfaults = MAXFAULTS();
+ leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
+ mirror_save = zs->zs_mirrors;
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+
+ ASSERT(leaves >= 1);
+
+ /*
+ * We need SCL_STATE here because we're going to look at vd0->vdev_tsd.
+ */
+ spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
+
+ if (ztest_random(2) == 0) {
+ /*
+ * Inject errors on a normal data device or slog device.
+ */
+ top = ztest_random_vdev_top(spa, B_TRUE);
+ leaf = ztest_random(leaves) + zs->zs_splits;
+
+ /*
+ * Generate paths to the first leaf in this top-level vdev,
+ * and to the random leaf we selected. We'll induce transient
+ * write failures and random online/offline activity on leaf 0,
+ * and we'll write random garbage to the randomly chosen leaf.
+ */
+ (void) snprintf(path0, sizeof (path0), ztest_dev_template,
+ ztest_opts.zo_dir, ztest_opts.zo_pool,
+ top * leaves + zs->zs_splits);
+ (void) snprintf(pathrand, sizeof (pathrand), ztest_dev_template,
+ ztest_opts.zo_dir, ztest_opts.zo_pool,
+ top * leaves + leaf);
+
+ vd0 = vdev_lookup_by_path(spa->spa_root_vdev, path0);
+ if (vd0 != NULL && vd0->vdev_top->vdev_islog)
+ islog = B_TRUE;
+
+ if (vd0 != NULL && maxfaults != 1) {
+ /*
+ * Make vd0 explicitly claim to be unreadable,
+ * or unwriteable, or reach behind its back
+ * and close the underlying fd. We can do this if
+ * maxfaults == 0 because we'll fail and reexecute,
+ * and we can do it if maxfaults >= 2 because we'll
+ * have enough redundancy. If maxfaults == 1, the
+ * combination of this with injection of random data
+ * corruption below exceeds the pool's fault tolerance.
+ */
+ vdev_file_t *vf = vd0->vdev_tsd;
+
+ if (vf != NULL && ztest_random(3) == 0) {
+ (void) close(vf->vf_vnode->v_fd);
+ vf->vf_vnode->v_fd = -1;
+ } else if (ztest_random(2) == 0) {
+ vd0->vdev_cant_read = B_TRUE;
+ } else {
+ vd0->vdev_cant_write = B_TRUE;
+ }
+ guid0 = vd0->vdev_guid;
+ }
+ } else {
+ /*
+ * Inject errors on an l2cache device.
+ */
+ spa_aux_vdev_t *sav = &spa->spa_l2cache;
+
+ if (sav->sav_count == 0) {
+ spa_config_exit(spa, SCL_STATE, FTAG);
+ return;
+ }
+ vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
+ guid0 = vd0->vdev_guid;
+ (void) strcpy(path0, vd0->vdev_path);
+ (void) strcpy(pathrand, vd0->vdev_path);
+
+ leaf = 0;
+ leaves = 1;
+ maxfaults = INT_MAX; /* no limit on cache devices */
+ }
+
+ spa_config_exit(spa, SCL_STATE, FTAG);
+
+ /*
+ * If we can tolerate two or more faults, or we're dealing
+ * with a slog, randomly online/offline vd0.
+ */
+ if ((maxfaults >= 2 || islog) && guid0 != 0) {
+ if (ztest_random(10) < 6) {
+ int flags = (ztest_random(2) == 0 ?
+ ZFS_OFFLINE_TEMPORARY : 0);
+
+ /*
+ * We have to grab the zs_name_lock as writer to
+ * prevent a race between offlining a slog and
+ * destroying a dataset. Offlining the slog will
+ * grab a reference on the dataset which may cause
+ * dmu_objset_destroy() to fail with EBUSY thus
+ * leaving the dataset in an inconsistent state.
+ */
+ if (islog)
+ (void) rw_wrlock(&ztest_name_lock);
+
+ VERIFY(vdev_offline(spa, guid0, flags) != EBUSY);
+
+ if (islog)
+ (void) rw_unlock(&ztest_name_lock);
+ } else {
+ /*
+ * Ideally we would like to be able to randomly
+ * call vdev_[on|off]line without holding locks
+ * to force unpredictable failures but the side
+ * effects of vdev_[on|off]line prevent us from
+ * doing so. We grab the ztest_vdev_lock here to
+ * prevent a race between injection testing and
+ * aux_vdev removal.
+ */
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ (void) vdev_online(spa, guid0, 0, NULL);
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ }
+ }
+
+ if (maxfaults == 0)
+ return;
+
+ /*
+ * We have at least single-fault tolerance, so inject data corruption.
+ */
+ fd = open(pathrand, O_RDWR);
+
+ if (fd == -1) /* we hit a gap in the device namespace */
+ return;
+
+ fsize = lseek(fd, 0, SEEK_END);
+
+ while (--iters != 0) {
+ offset = ztest_random(fsize / (leaves << bshift)) *
+ (leaves << bshift) + (leaf << bshift) +
+ (ztest_random(1ULL << (bshift - 1)) & -8ULL);
+
+ if (offset >= fsize)
+ continue;
+
+ VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+ if (mirror_save != zs->zs_mirrors) {
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+ (void) close(fd);
+ return;
+ }
+
+ if (pwrite(fd, &bad, sizeof (bad), offset) != sizeof (bad))
+ fatal(1, "can't inject bad word at 0x%llx in %s",
+ offset, pathrand);
+
+ VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
+
+ if (ztest_opts.zo_verbose >= 7)
+ (void) printf("injected bad word into %s,"
+ " offset 0x%llx\n", pathrand, (u_longlong_t)offset);
+ }
+
+ (void) close(fd);
+}
+
+/*
+ * Verify that DDT repair works as expected.
+ */
+void
+ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = ztest_spa;
+ objset_t *os = zd->zd_os;
+ ztest_od_t od[1];
+ uint64_t object, blocksize, txg, pattern, psize;
+ enum zio_checksum checksum = spa_dedup_checksum(spa);
+ dmu_buf_t *db;
+ dmu_tx_t *tx;
+ void *buf;
+ blkptr_t blk;
+ int copies = 2 * ZIO_DEDUPDITTO_MIN;
+
+ blocksize = ztest_random_blocksize();
+ blocksize = MIN(blocksize, 2048); /* because we write so many */
+
+ ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
+
+ if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
+ return;
+
+ /*
+ * Take the name lock as writer to prevent anyone else from changing
+ * the pool and dataset properies we need to maintain during this test.
+ */
+ (void) rw_wrlock(&ztest_name_lock);
+
+ if (ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_DEDUP, checksum,
+ B_FALSE) != 0 ||
+ ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_COPIES, 1,
+ B_FALSE) != 0) {
+ (void) rw_unlock(&ztest_name_lock);
+ return;
+ }
+
+ object = od[0].od_object;
+ blocksize = od[0].od_blocksize;
+ pattern = zs->zs_guid ^ dmu_objset_fsid_guid(os);
+
+ ASSERT(object != 0);
+
+ tx = dmu_tx_create(os);
+ dmu_tx_hold_write(tx, object, 0, copies * blocksize);
+ txg = ztest_tx_assign(tx, TXG_WAIT, FTAG);
+ if (txg == 0) {
+ (void) rw_unlock(&ztest_name_lock);
+ return;
+ }
+
+ /*
+ * Write all the copies of our block.
+ */
+ for (int i = 0; i < copies; i++) {
+ uint64_t offset = i * blocksize;
+ int error = dmu_buf_hold(os, object, offset, FTAG, &db,
+ DMU_READ_NO_PREFETCH);
+ if (error != 0) {
+ fatal(B_FALSE, "dmu_buf_hold(%p, %llu, %llu) = %u",
+ os, (long long)object, (long long) offset, error);
+ }
+ ASSERT(db->db_offset == offset);
+ ASSERT(db->db_size == blocksize);
+ ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) ||
+ ztest_pattern_match(db->db_data, db->db_size, 0ULL));
+ dmu_buf_will_fill(db, tx);
+ ztest_pattern_set(db->db_data, db->db_size, pattern);
+ dmu_buf_rele(db, FTAG);
+ }
+
+ dmu_tx_commit(tx);
+ txg_wait_synced(spa_get_dsl(spa), txg);
+
+ /*
+ * Find out what block we got.
+ */
+ VERIFY0(dmu_buf_hold(os, object, 0, FTAG, &db,
+ DMU_READ_NO_PREFETCH));
+ blk = *((dmu_buf_impl_t *)db)->db_blkptr;
+ dmu_buf_rele(db, FTAG);
+
+ /*
+ * Damage the block. Dedup-ditto will save us when we read it later.
+ */
+ psize = BP_GET_PSIZE(&blk);
+ buf = zio_buf_alloc(psize);
+ ztest_pattern_set(buf, psize, ~pattern);
+
+ (void) zio_wait(zio_rewrite(NULL, spa, 0, &blk,
+ buf, psize, NULL, NULL, ZIO_PRIORITY_SYNC_WRITE,
+ ZIO_FLAG_CANFAIL | ZIO_FLAG_INDUCE_DAMAGE, NULL));
+
+ zio_buf_free(buf, psize);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Scrub the pool.
+ */
+/* ARGSUSED */
+void
+ztest_scrub(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa = ztest_spa;
+
+ (void) spa_scan(spa, POOL_SCAN_SCRUB);
+ (void) poll(NULL, 0, 100); /* wait a moment, then force a restart */
+ (void) spa_scan(spa, POOL_SCAN_SCRUB);
+}
+
+/*
+ * Change the guid for the pool.
+ */
+/* ARGSUSED */
+void
+ztest_reguid(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa = ztest_spa;
+ uint64_t orig, load;
+ int error;
+
+ orig = spa_guid(spa);
+ load = spa_load_guid(spa);
+
+ (void) rw_wrlock(&ztest_name_lock);
+ error = spa_change_guid(spa);
+ (void) rw_unlock(&ztest_name_lock);
+
+ if (error != 0)
+ return;
+
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("Changed guid old %llu -> %llu\n",
+ (u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
+ }
+
+ VERIFY3U(orig, !=, spa_guid(spa));
+ VERIFY3U(load, ==, spa_load_guid(spa));
+}
+
+/*
+ * Rename the pool to a different name and then rename it back.
+ */
+/* ARGSUSED */
+void
+ztest_spa_rename(ztest_ds_t *zd, uint64_t id)
+{
+ char *oldname, *newname;
+ spa_t *spa;
+
+ (void) rw_wrlock(&ztest_name_lock);
+
+ oldname = ztest_opts.zo_pool;
+ newname = umem_alloc(strlen(oldname) + 5, UMEM_NOFAIL);
+ (void) strcpy(newname, oldname);
+ (void) strcat(newname, "_tmp");
+
+ /*
+ * Do the rename
+ */
+ VERIFY3U(0, ==, spa_rename(oldname, newname));
+
+ /*
+ * Try to open it under the old name, which shouldn't exist
+ */
+ VERIFY3U(ENOENT, ==, spa_open(oldname, &spa, FTAG));
+
+ /*
+ * Open it under the new name and make sure it's still the same spa_t.
+ */
+ VERIFY3U(0, ==, spa_open(newname, &spa, FTAG));
+
+ ASSERT(spa == ztest_spa);
+ spa_close(spa, FTAG);
+
+ /*
+ * Rename it back to the original
+ */
+ VERIFY3U(0, ==, spa_rename(newname, oldname));
+
+ /*
+ * Make sure it can still be opened
+ */
+ VERIFY3U(0, ==, spa_open(oldname, &spa, FTAG));
+
+ ASSERT(spa == ztest_spa);
+ spa_close(spa, FTAG);
+
+ umem_free(newname, strlen(newname) + 1);
+
+ (void) rw_unlock(&ztest_name_lock);
+}
+
+/*
+ * Verify pool integrity by running zdb.
+ */
+static void
+ztest_run_zdb(char *pool)
+{
+ int status;
+ char zdb[MAXPATHLEN + MAXNAMELEN + 20];
+ char zbuf[1024];
+ char *bin;
+ char *ztest;
+ char *isa;
+ int isalen;
+ FILE *fp;
+
+ strlcpy(zdb, "/usr/bin/ztest", sizeof(zdb));
+
+ /* zdb lives in /usr/sbin, while ztest lives in /usr/bin */
+ bin = strstr(zdb, "/usr/bin/");
+ ztest = strstr(bin, "/ztest");
+ isa = bin + 8;
+ isalen = ztest - isa;
+ isa = strdup(isa);
+ /* LINTED */
+ (void) sprintf(bin,
+ "/usr/sbin%.*s/zdb -bcc%s%s -U %s %s",
+ isalen,
+ isa,
+ ztest_opts.zo_verbose >= 3 ? "s" : "",
+ ztest_opts.zo_verbose >= 4 ? "v" : "",
+ spa_config_path,
+ pool);
+ free(isa);
+
+ if (ztest_opts.zo_verbose >= 5)
+ (void) printf("Executing %s\n", strstr(zdb, "zdb "));
+
+ fp = popen(zdb, "r");
+ assert(fp != NULL);
+
+ while (fgets(zbuf, sizeof (zbuf), fp) != NULL)
+ if (ztest_opts.zo_verbose >= 3)
+ (void) printf("%s", zbuf);
+
+ status = pclose(fp);
+
+ if (status == 0)
+ return;
+
+ ztest_dump_core = 0;
+ if (WIFEXITED(status))
+ fatal(0, "'%s' exit code %d", zdb, WEXITSTATUS(status));
+ else
+ fatal(0, "'%s' died with signal %d", zdb, WTERMSIG(status));
+}
+
+static void
+ztest_walk_pool_directory(char *header)
+{
+ spa_t *spa = NULL;
+
+ if (ztest_opts.zo_verbose >= 6)
+ (void) printf("%s\n", header);
+
+ mutex_enter(&spa_namespace_lock);
+ while ((spa = spa_next(spa)) != NULL)
+ if (ztest_opts.zo_verbose >= 6)
+ (void) printf("\t%s\n", spa_name(spa));
+ mutex_exit(&spa_namespace_lock);
+}
+
+static void
+ztest_spa_import_export(char *oldname, char *newname)
+{
+ nvlist_t *config, *newconfig;
+ uint64_t pool_guid;
+ spa_t *spa;
+ int error;
+
+ if (ztest_opts.zo_verbose >= 4) {
+ (void) printf("import/export: old = %s, new = %s\n",
+ oldname, newname);
+ }
+
+ /*
+ * Clean up from previous runs.
+ */
+ (void) spa_destroy(newname);
+
+ /*
+ * Get the pool's configuration and guid.
+ */
+ VERIFY3U(0, ==, spa_open(oldname, &spa, FTAG));
+
+ /*
+ * Kick off a scrub to tickle scrub/export races.
+ */
+ if (ztest_random(2) == 0)
+ (void) spa_scan(spa, POOL_SCAN_SCRUB);
+
+ pool_guid = spa_guid(spa);
+ spa_close(spa, FTAG);
+
+ ztest_walk_pool_directory("pools before export");
+
+ /*
+ * Export it.
+ */
+ VERIFY3U(0, ==, spa_export(oldname, &config, B_FALSE, B_FALSE));
+
+ ztest_walk_pool_directory("pools after export");
+
+ /*
+ * Try to import it.
+ */
+ newconfig = spa_tryimport(config);
+ ASSERT(newconfig != NULL);
+ nvlist_free(newconfig);
+
+ /*
+ * Import it under the new name.
+ */
+ error = spa_import(newname, config, NULL, 0);
+ if (error != 0) {
+ dump_nvlist(config, 0);
+ fatal(B_FALSE, "couldn't import pool %s as %s: error %u",
+ oldname, newname, error);
+ }
+
+ ztest_walk_pool_directory("pools after import");
+
+ /*
+ * Try to import it again -- should fail with EEXIST.
+ */
+ VERIFY3U(EEXIST, ==, spa_import(newname, config, NULL, 0));
+
+ /*
+ * Try to import it under a different name -- should fail with EEXIST.
+ */
+ VERIFY3U(EEXIST, ==, spa_import(oldname, config, NULL, 0));
+
+ /*
+ * Verify that the pool is no longer visible under the old name.
+ */
+ VERIFY3U(ENOENT, ==, spa_open(oldname, &spa, FTAG));
+
+ /*
+ * Verify that we can open and close the pool using the new name.
+ */
+ VERIFY3U(0, ==, spa_open(newname, &spa, FTAG));
+ ASSERT(pool_guid == spa_guid(spa));
+ spa_close(spa, FTAG);
+
+ nvlist_free(config);
+}
+
+static void
+ztest_resume(spa_t *spa)
+{
+ if (spa_suspended(spa) && ztest_opts.zo_verbose >= 6)
+ (void) printf("resuming from suspended state\n");
+ spa_vdev_state_enter(spa, SCL_NONE);
+ vdev_clear(spa, NULL);
+ (void) spa_vdev_state_exit(spa, NULL, 0);
+ (void) zio_resume(spa);
+}
+
+static void *
+ztest_resume_thread(void *arg)
+{
+ spa_t *spa = arg;
+
+ while (!ztest_exiting) {
+ if (spa_suspended(spa))
+ ztest_resume(spa);
+ (void) poll(NULL, 0, 100);
+ }
+ return (NULL);
+}
+
+static void *
+ztest_deadman_thread(void *arg)
+{
+ ztest_shared_t *zs = arg;
+ int grace = 300;
+ hrtime_t delta;
+
+ delta = (zs->zs_thread_stop - zs->zs_thread_start) / NANOSEC + grace;
+
+ (void) poll(NULL, 0, (int)(1000 * delta));
+
+ fatal(0, "failed to complete within %d seconds of deadline", grace);
+
+ return (NULL);
+}
+
+static void
+ztest_execute(int test, ztest_info_t *zi, uint64_t id)
+{
+ ztest_ds_t *zd = &ztest_ds[id % ztest_opts.zo_datasets];
+ ztest_shared_callstate_t *zc = ZTEST_GET_SHARED_CALLSTATE(test);
+ hrtime_t functime = gethrtime();
+
+ for (int i = 0; i < zi->zi_iters; i++)
+ zi->zi_func(zd, id);
+
+ functime = gethrtime() - functime;
+
+ atomic_add_64(&zc->zc_count, 1);
+ atomic_add_64(&zc->zc_time, functime);
+
+ if (ztest_opts.zo_verbose >= 4) {
+ Dl_info dli;
+ (void) dladdr((void *)zi->zi_func, &dli);
+ (void) printf("%6.2f sec in %s\n",
+ (double)functime / NANOSEC, dli.dli_sname);
+ }
+}
+
+static void *
+ztest_thread(void *arg)
+{
+ int rand;
+ uint64_t id = (uintptr_t)arg;
+ ztest_shared_t *zs = ztest_shared;
+ uint64_t call_next;
+ hrtime_t now;
+ ztest_info_t *zi;
+ ztest_shared_callstate_t *zc;
+
+ while ((now = gethrtime()) < zs->zs_thread_stop) {
+ /*
+ * See if it's time to force a crash.
+ */
+ if (now > zs->zs_thread_kill)
+ ztest_kill(zs);
+
+ /*
+ * If we're getting ENOSPC with some regularity, stop.
+ */
+ if (zs->zs_enospc_count > 10)
+ break;
+
+ /*
+ * Pick a random function to execute.
+ */
+ rand = ztest_random(ZTEST_FUNCS);
+ zi = &ztest_info[rand];
+ zc = ZTEST_GET_SHARED_CALLSTATE(rand);
+ call_next = zc->zc_next;
+
+ if (now >= call_next &&
+ atomic_cas_64(&zc->zc_next, call_next, call_next +
+ ztest_random(2 * zi->zi_interval[0] + 1)) == call_next) {
+ ztest_execute(rand, zi, id);
+ }
+ }
+
+ return (NULL);
+}
+
+static void
+ztest_dataset_name(char *dsname, char *pool, int d)
+{
+ (void) snprintf(dsname, MAXNAMELEN, "%s/ds_%d", pool, d);
+}
+
+static void
+ztest_dataset_destroy(int d)
+{
+ char name[MAXNAMELEN];
+
+ ztest_dataset_name(name, ztest_opts.zo_pool, d);
+
+ if (ztest_opts.zo_verbose >= 3)
+ (void) printf("Destroying %s to free up space\n", name);
+
+ /*
+ * Cleanup any non-standard clones and snapshots. In general,
+ * ztest thread t operates on dataset (t % zopt_datasets),
+ * so there may be more than one thing to clean up.
+ */
+ for (int t = d; t < ztest_opts.zo_threads;
+ t += ztest_opts.zo_datasets) {
+ ztest_dsl_dataset_cleanup(name, t);
+ }
+
+ (void) dmu_objset_find(name, ztest_objset_destroy_cb, NULL,
+ DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
+}
+
+static void
+ztest_dataset_dirobj_verify(ztest_ds_t *zd)
+{
+ uint64_t usedobjs, dirobjs, scratch;
+
+ /*
+ * ZTEST_DIROBJ is the object directory for the entire dataset.
+ * Therefore, the number of objects in use should equal the
+ * number of ZTEST_DIROBJ entries, +1 for ZTEST_DIROBJ itself.
+ * If not, we have an object leak.
+ *
+ * Note that we can only check this in ztest_dataset_open(),
+ * when the open-context and syncing-context values agree.
+ * That's because zap_count() returns the open-context value,
+ * while dmu_objset_space() returns the rootbp fill count.
+ */
+ VERIFY3U(0, ==, zap_count(zd->zd_os, ZTEST_DIROBJ, &dirobjs));
+ dmu_objset_space(zd->zd_os, &scratch, &scratch, &usedobjs, &scratch);
+ ASSERT3U(dirobjs + 1, ==, usedobjs);
+}
+
+static int
+ztest_dataset_open(int d)
+{
+ ztest_ds_t *zd = &ztest_ds[d];
+ uint64_t committed_seq = ZTEST_GET_SHARED_DS(d)->zd_seq;
+ objset_t *os;
+ zilog_t *zilog;
+ char name[MAXNAMELEN];
+ int error;
+
+ ztest_dataset_name(name, ztest_opts.zo_pool, d);
+
+ (void) rw_rdlock(&ztest_name_lock);
+
+ error = ztest_dataset_create(name);
+ if (error == ENOSPC) {
+ (void) rw_unlock(&ztest_name_lock);
+ ztest_record_enospc(FTAG);
+ return (error);
+ }
+ ASSERT(error == 0 || error == EEXIST);
+
+ VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os));
+ (void) rw_unlock(&ztest_name_lock);
+
+ ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os);
+
+ zilog = zd->zd_zilog;
+
+ if (zilog->zl_header->zh_claim_lr_seq != 0 &&
+ zilog->zl_header->zh_claim_lr_seq < committed_seq)
+ fatal(0, "missing log records: claimed %llu < committed %llu",
+ zilog->zl_header->zh_claim_lr_seq, committed_seq);
+
+ ztest_dataset_dirobj_verify(zd);
+
+ zil_replay(os, zd, ztest_replay_vector);
+
+ ztest_dataset_dirobj_verify(zd);
+
+ if (ztest_opts.zo_verbose >= 6)
+ (void) printf("%s replay %llu blocks, %llu records, seq %llu\n",
+ zd->zd_name,
+ (u_longlong_t)zilog->zl_parse_blk_count,
+ (u_longlong_t)zilog->zl_parse_lr_count,
+ (u_longlong_t)zilog->zl_replaying_seq);
+
+ zilog = zil_open(os, ztest_get_data);
+
+ if (zilog->zl_replaying_seq != 0 &&
+ zilog->zl_replaying_seq < committed_seq)
+ fatal(0, "missing log records: replayed %llu < committed %llu",
+ zilog->zl_replaying_seq, committed_seq);
+
+ return (0);
+}
+
+static void
+ztest_dataset_close(int d)
+{
+ ztest_ds_t *zd = &ztest_ds[d];
+
+ zil_close(zd->zd_zilog);
+ dmu_objset_disown(zd->zd_os, zd);
+
+ ztest_zd_fini(zd);
+}
+
+/*
+ * Kick off threads to run tests on all datasets in parallel.
+ */
+static void
+ztest_run(ztest_shared_t *zs)
+{
+ thread_t *tid;
+ spa_t *spa;
+ objset_t *os;
+ thread_t resume_tid;
+ int error;
+
+ ztest_exiting = B_FALSE;
+
+ /*
+ * Initialize parent/child shared state.
+ */
+ VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
+ VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
+
+ zs->zs_thread_start = gethrtime();
+ zs->zs_thread_stop =
+ zs->zs_thread_start + ztest_opts.zo_passtime * NANOSEC;
+ zs->zs_thread_stop = MIN(zs->zs_thread_stop, zs->zs_proc_stop);
+ zs->zs_thread_kill = zs->zs_thread_stop;
+ if (ztest_random(100) < ztest_opts.zo_killrate) {
+ zs->zs_thread_kill -=
+ ztest_random(ztest_opts.zo_passtime * NANOSEC);
+ }
+
+ (void) _mutex_init(&zcl.zcl_callbacks_lock, USYNC_THREAD, NULL);
+
+ list_create(&zcl.zcl_callbacks, sizeof (ztest_cb_data_t),
+ offsetof(ztest_cb_data_t, zcd_node));
+
+ /*
+ * Open our pool.
+ */
+ kernel_init(FREAD | FWRITE);
+ VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
+ spa->spa_debug = B_TRUE;
+ ztest_spa = spa;
+
+ VERIFY0(dmu_objset_own(ztest_opts.zo_pool,
+ DMU_OST_ANY, B_TRUE, FTAG, &os));
+ zs->zs_guid = dmu_objset_fsid_guid(os);
+ dmu_objset_disown(os, FTAG);
+
+ spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN;
+
+ /*
+ * We don't expect the pool to suspend unless maxfaults == 0,
+ * in which case ztest_fault_inject() temporarily takes away
+ * the only valid replica.
+ */
+ if (MAXFAULTS() == 0)
+ spa->spa_failmode = ZIO_FAILURE_MODE_WAIT;
+ else
+ spa->spa_failmode = ZIO_FAILURE_MODE_PANIC;
+
+ /*
+ * Create a thread to periodically resume suspended I/O.
+ */
+ VERIFY(thr_create(0, 0, ztest_resume_thread, spa, THR_BOUND,
+ &resume_tid) == 0);
+
+ /*
+ * Create a deadman thread to abort() if we hang.
+ */
+ VERIFY(thr_create(0, 0, ztest_deadman_thread, zs, THR_BOUND,
+ NULL) == 0);
+
+ /*
+ * Verify that we can safely inquire about about any object,
+ * whether it's allocated or not. To make it interesting,
+ * we probe a 5-wide window around each power of two.
+ * This hits all edge cases, including zero and the max.
+ */
+ for (int t = 0; t < 64; t++) {
+ for (int d = -5; d <= 5; d++) {
+ error = dmu_object_info(spa->spa_meta_objset,
+ (1ULL << t) + d, NULL);
+ ASSERT(error == 0 || error == ENOENT ||
+ error == EINVAL);
+ }
+ }
+
+ /*
+ * If we got any ENOSPC errors on the previous run, destroy something.
+ */
+ if (zs->zs_enospc_count != 0) {
+ int d = ztest_random(ztest_opts.zo_datasets);
+ ztest_dataset_destroy(d);
+ }
+ zs->zs_enospc_count = 0;
+
+ tid = umem_zalloc(ztest_opts.zo_threads * sizeof (thread_t),
+ UMEM_NOFAIL);
+
+ if (ztest_opts.zo_verbose >= 4)
+ (void) printf("starting main threads...\n");
+
+ /*
+ * Kick off all the tests that run in parallel.
+ */
+ for (int t = 0; t < ztest_opts.zo_threads; t++) {
+ if (t < ztest_opts.zo_datasets &&
+ ztest_dataset_open(t) != 0)
+ return;
+ VERIFY(thr_create(0, 0, ztest_thread, (void *)(uintptr_t)t,
+ THR_BOUND, &tid[t]) == 0);
+ }
+
+ /*
+ * Wait for all of the tests to complete. We go in reverse order
+ * so we don't close datasets while threads are still using them.
+ */
+ for (int t = ztest_opts.zo_threads - 1; t >= 0; t--) {
+ VERIFY(thr_join(tid[t], NULL, NULL) == 0);
+ if (t < ztest_opts.zo_datasets)
+ ztest_dataset_close(t);
+ }
+
+ txg_wait_synced(spa_get_dsl(spa), 0);
+
+ zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
+ zs->zs_space = metaslab_class_get_space(spa_normal_class(spa));
+
+ umem_free(tid, ztest_opts.zo_threads * sizeof (thread_t));
+
+ /* Kill the resume thread */
+ ztest_exiting = B_TRUE;
+ VERIFY(thr_join(resume_tid, NULL, NULL) == 0);
+ ztest_resume(spa);
+
+ /*
+ * Right before closing the pool, kick off a bunch of async I/O;
+ * spa_close() should wait for it to complete.
+ */
+ for (uint64_t object = 1; object < 50; object++)
+ dmu_prefetch(spa->spa_meta_objset, object, 0, 1ULL << 20);
+
+ spa_close(spa, FTAG);
+
+ /*
+ * Verify that we can loop over all pools.
+ */
+ mutex_enter(&spa_namespace_lock);
+ for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
+ if (ztest_opts.zo_verbose > 3)
+ (void) printf("spa_next: found %s\n", spa_name(spa));
+ mutex_exit(&spa_namespace_lock);
+
+ /*
+ * Verify that we can export the pool and reimport it under a
+ * different name.
+ */
+ if (ztest_random(2) == 0) {
+ char name[MAXNAMELEN];
+ (void) snprintf(name, MAXNAMELEN, "%s_import",
+ ztest_opts.zo_pool);
+ ztest_spa_import_export(ztest_opts.zo_pool, name);
+ ztest_spa_import_export(name, ztest_opts.zo_pool);
+ }
+
+ kernel_fini();
+
+ list_destroy(&zcl.zcl_callbacks);
+
+ (void) _mutex_destroy(&zcl.zcl_callbacks_lock);
+
+ (void) rwlock_destroy(&ztest_name_lock);
+ (void) _mutex_destroy(&ztest_vdev_lock);
+}
+
+static void
+ztest_freeze(void)
+{
+ ztest_ds_t *zd = &ztest_ds[0];
+ spa_t *spa;
+ int numloops = 0;
+
+ if (ztest_opts.zo_verbose >= 3)
+ (void) printf("testing spa_freeze()...\n");
+
+ kernel_init(FREAD | FWRITE);
+ VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
+ VERIFY3U(0, ==, ztest_dataset_open(0));
+ spa->spa_debug = B_TRUE;
+ ztest_spa = spa;
+
+ /*
+ * Force the first log block to be transactionally allocated.
+ * We have to do this before we freeze the pool -- otherwise
+ * the log chain won't be anchored.
+ */
+ while (BP_IS_HOLE(&zd->zd_zilog->zl_header->zh_log)) {
+ ztest_dmu_object_alloc_free(zd, 0);
+ zil_commit(zd->zd_zilog, 0);
+ }
+
+ txg_wait_synced(spa_get_dsl(spa), 0);
+
+ /*
+ * Freeze the pool. This stops spa_sync() from doing anything,
+ * so that the only way to record changes from now on is the ZIL.
+ */
+ spa_freeze(spa);
+
+ /*
+ * Run tests that generate log records but don't alter the pool config
+ * or depend on DSL sync tasks (snapshots, objset create/destroy, etc).
+ * We do a txg_wait_synced() after each iteration to force the txg
+ * to increase well beyond the last synced value in the uberblock.
+ * The ZIL should be OK with that.
+ */
+ while (ztest_random(10) != 0 &&
+ numloops++ < ztest_opts.zo_maxloops) {
+ ztest_dmu_write_parallel(zd, 0);
+ ztest_dmu_object_alloc_free(zd, 0);
+ txg_wait_synced(spa_get_dsl(spa), 0);
+ }
+
+ /*
+ * Commit all of the changes we just generated.
+ */
+ zil_commit(zd->zd_zilog, 0);
+ txg_wait_synced(spa_get_dsl(spa), 0);
+
+ /*
+ * Close our dataset and close the pool.
+ */
+ ztest_dataset_close(0);
+ spa_close(spa, FTAG);
+ kernel_fini();
+
+ /*
+ * Open and close the pool and dataset to induce log replay.
+ */
+ kernel_init(FREAD | FWRITE);
+ VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
+ ASSERT(spa_freeze_txg(spa) == UINT64_MAX);
+ VERIFY3U(0, ==, ztest_dataset_open(0));
+ ztest_dataset_close(0);
+
+ spa->spa_debug = B_TRUE;
+ ztest_spa = spa;
+ txg_wait_synced(spa_get_dsl(spa), 0);
+ ztest_reguid(NULL, 0);
+
+ spa_close(spa, FTAG);
+ kernel_fini();
+}
+
+void
+print_time(hrtime_t t, char *timebuf)
+{
+ hrtime_t s = t / NANOSEC;
+ hrtime_t m = s / 60;
+ hrtime_t h = m / 60;
+ hrtime_t d = h / 24;
+
+ s -= m * 60;
+ m -= h * 60;
+ h -= d * 24;
+
+ timebuf[0] = '\0';
+
+ if (d)
+ (void) sprintf(timebuf,
+ "%llud%02lluh%02llum%02llus", d, h, m, s);
+ else if (h)
+ (void) sprintf(timebuf, "%lluh%02llum%02llus", h, m, s);
+ else if (m)
+ (void) sprintf(timebuf, "%llum%02llus", m, s);
+ else
+ (void) sprintf(timebuf, "%llus", s);
+}
+
+static nvlist_t *
+make_random_props()
+{
+ nvlist_t *props;
+
+ VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
+ if (ztest_random(2) == 0)
+ return (props);
+ VERIFY(nvlist_add_uint64(props, "autoreplace", 1) == 0);
+
+ return (props);
+}
+
+/*
+ * Create a storage pool with the given name and initial vdev size.
+ * Then test spa_freeze() functionality.
+ */
+static void
+ztest_init(ztest_shared_t *zs)
+{
+ spa_t *spa;
+ nvlist_t *nvroot, *props;
+
+ VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
+ VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
+
+ kernel_init(FREAD | FWRITE);
+
+ /*
+ * Create the storage pool.
+ */
+ (void) spa_destroy(ztest_opts.zo_pool);
+ ztest_shared->zs_vdev_next_leaf = 0;
+ zs->zs_splits = 0;
+ zs->zs_mirrors = ztest_opts.zo_mirrors;
+ nvroot = make_vdev_root(NULL, NULL, NULL, ztest_opts.zo_vdev_size, 0,
+ 0, ztest_opts.zo_raidz, zs->zs_mirrors, 1);
+ props = make_random_props();
+ for (int i = 0; i < SPA_FEATURES; i++) {
+ char buf[1024];
+ (void) snprintf(buf, sizeof (buf), "feature@%s",
+ spa_feature_table[i].fi_uname);
+ VERIFY3U(0, ==, nvlist_add_uint64(props, buf, 0));
+ }
+ VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props, NULL));
+ nvlist_free(nvroot);
+
+ VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
+ zs->zs_metaslab_sz =
+ 1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift;
+
+ spa_close(spa, FTAG);
+
+ kernel_fini();
+
+ ztest_run_zdb(ztest_opts.zo_pool);
+
+ ztest_freeze();
+
+ ztest_run_zdb(ztest_opts.zo_pool);
+
+ (void) rwlock_destroy(&ztest_name_lock);
+ (void) _mutex_destroy(&ztest_vdev_lock);
+}
+
+static void
+setup_data_fd(void)
+{
+ static char ztest_name_data[] = "/tmp/ztest.data.XXXXXX";
+
+ ztest_fd_data = mkstemp(ztest_name_data);
+ ASSERT3S(ztest_fd_data, >=, 0);
+ (void) unlink(ztest_name_data);
+}
+
+
+static int
+shared_data_size(ztest_shared_hdr_t *hdr)
+{
+ int size;
+
+ size = hdr->zh_hdr_size;
+ size += hdr->zh_opts_size;
+ size += hdr->zh_size;
+ size += hdr->zh_stats_size * hdr->zh_stats_count;
+ size += hdr->zh_ds_size * hdr->zh_ds_count;
+
+ return (size);
+}
+
+static void
+setup_hdr(void)
+{
+ int size;
+ ztest_shared_hdr_t *hdr;
+
+ hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
+ PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
+ ASSERT(hdr != MAP_FAILED);
+
+ VERIFY3U(0, ==, ftruncate(ztest_fd_data, sizeof (ztest_shared_hdr_t)));
+
+ hdr->zh_hdr_size = sizeof (ztest_shared_hdr_t);
+ hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
+ hdr->zh_size = sizeof (ztest_shared_t);
+ hdr->zh_stats_size = sizeof (ztest_shared_callstate_t);
+ hdr->zh_stats_count = ZTEST_FUNCS;
+ hdr->zh_ds_size = sizeof (ztest_shared_ds_t);
+ hdr->zh_ds_count = ztest_opts.zo_datasets;
+
+ size = shared_data_size(hdr);
+ VERIFY3U(0, ==, ftruncate(ztest_fd_data, size));
+
+ (void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
+}
+
+static void
+setup_data(void)
+{
+ int size, offset;
+ ztest_shared_hdr_t *hdr;
+ uint8_t *buf;
+
+ hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
+ PROT_READ, MAP_SHARED, ztest_fd_data, 0);
+ ASSERT(hdr != MAP_FAILED);
+
+ size = shared_data_size(hdr);
+
+ (void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
+ hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
+ PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
+ ASSERT(hdr != MAP_FAILED);
+ buf = (uint8_t *)hdr;
+
+ offset = hdr->zh_hdr_size;
+ ztest_shared_opts = (void *)&buf[offset];
+ offset += hdr->zh_opts_size;
+ ztest_shared = (void *)&buf[offset];
+ offset += hdr->zh_size;
+ ztest_shared_callstate = (void *)&buf[offset];
+ offset += hdr->zh_stats_size * hdr->zh_stats_count;
+ ztest_shared_ds = (void *)&buf[offset];
+}
+
+static boolean_t
+exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
+{
+ pid_t pid;
+ int status;
+ char *cmdbuf = NULL;
+
+ pid = fork();
+
+ if (cmd == NULL) {
+ cmdbuf = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
+ (void) strlcpy(cmdbuf, getexecname(), MAXPATHLEN);
+ cmd = cmdbuf;
+ }
+
+ if (pid == -1)
+ fatal(1, "fork failed");
+
+ if (pid == 0) { /* child */
+ char *emptyargv[2] = { cmd, NULL };
+ char fd_data_str[12];
+
+ struct rlimit rl = { 1024, 1024 };
+ (void) setrlimit(RLIMIT_NOFILE, &rl);
+
+ (void) close(ztest_fd_rand);
+ VERIFY3U(11, >=,
+ snprintf(fd_data_str, 12, "%d", ztest_fd_data));
+ VERIFY0(setenv("ZTEST_FD_DATA", fd_data_str, 1));
+
+ (void) enable_extended_FILE_stdio(-1, -1);
+ if (libpath != NULL)
+ VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
+#ifdef illumos
+ (void) execv(cmd, emptyargv);
+#else
+ (void) execvp(cmd, emptyargv);
+#endif
+ ztest_dump_core = B_FALSE;
+ fatal(B_TRUE, "exec failed: %s", cmd);
+ }
+
+ if (cmdbuf != NULL) {
+ umem_free(cmdbuf, MAXPATHLEN);
+ cmd = NULL;
+ }
+
+ while (waitpid(pid, &status, 0) != pid)
+ continue;
+ if (statusp != NULL)
+ *statusp = status;
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ (void) fprintf(stderr, "child exited with code %d\n",
+ WEXITSTATUS(status));
+ exit(2);
+ }
+ return (B_FALSE);
+ } else if (WIFSIGNALED(status)) {
+ if (!ignorekill || WTERMSIG(status) != SIGKILL) {
+ (void) fprintf(stderr, "child died with signal %d\n",
+ WTERMSIG(status));
+ exit(3);
+ }
+ return (B_TRUE);
+ } else {
+ (void) fprintf(stderr, "something strange happened to child\n");
+ exit(4);
+ /* NOTREACHED */
+ }
+}
+
+static void
+ztest_run_init(void)
+{
+ ztest_shared_t *zs = ztest_shared;
+
+ ASSERT(ztest_opts.zo_init != 0);
+
+ /*
+ * Blow away any existing copy of zpool.cache
+ */
+ (void) remove(spa_config_path);
+
+ /*
+ * Create and initialize our storage pool.
+ */
+ for (int i = 1; i <= ztest_opts.zo_init; i++) {
+ bzero(zs, sizeof (ztest_shared_t));
+ if (ztest_opts.zo_verbose >= 3 &&
+ ztest_opts.zo_init != 1) {
+ (void) printf("ztest_init(), pass %d\n", i);
+ }
+ ztest_init(zs);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int kills = 0;
+ int iters = 0;
+ int older = 0;
+ int newer = 0;
+ ztest_shared_t *zs;
+ ztest_info_t *zi;
+ ztest_shared_callstate_t *zc;
+ char timebuf[100];
+ char numbuf[6];
+ spa_t *spa;
+ char *cmd;
+ boolean_t hasalt;
+ char *fd_data_str = getenv("ZTEST_FD_DATA");
+
+ (void) setvbuf(stdout, NULL, _IOLBF, 0);
+
+ dprintf_setup(&argc, argv);
+
+ ztest_fd_rand = open("/dev/urandom", O_RDONLY);
+ ASSERT3S(ztest_fd_rand, >=, 0);
+
+ if (!fd_data_str) {
+ process_options(argc, argv);
+
+ setup_data_fd();
+ setup_hdr();
+ setup_data();
+ bcopy(&ztest_opts, ztest_shared_opts,
+ sizeof (*ztest_shared_opts));
+ } else {
+ ztest_fd_data = atoi(fd_data_str);
+ setup_data();
+ bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
+ }
+ ASSERT3U(ztest_opts.zo_datasets, ==, ztest_shared_hdr->zh_ds_count);
+
+ /* Override location of zpool.cache */
+ VERIFY3U(asprintf((char **)&spa_config_path, "%s/zpool.cache",
+ ztest_opts.zo_dir), !=, -1);
+
+ ztest_ds = umem_alloc(ztest_opts.zo_datasets * sizeof (ztest_ds_t),
+ UMEM_NOFAIL);
+ zs = ztest_shared;
+
+ if (fd_data_str) {
+ metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
+ metaslab_df_alloc_threshold =
+ zs->zs_metaslab_df_alloc_threshold;
+
+ if (zs->zs_do_init)
+ ztest_run_init();
+ else
+ ztest_run(zs);
+ exit(0);
+ }
+
+ hasalt = (strlen(ztest_opts.zo_alt_ztest) != 0);
+
+ if (ztest_opts.zo_verbose >= 1) {
+ (void) printf("%llu vdevs, %d datasets, %d threads,"
+ " %llu seconds...\n",
+ (u_longlong_t)ztest_opts.zo_vdevs,
+ ztest_opts.zo_datasets,
+ ztest_opts.zo_threads,
+ (u_longlong_t)ztest_opts.zo_time);
+ }
+
+ cmd = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
+ (void) strlcpy(cmd, getexecname(), MAXNAMELEN);
+
+ zs->zs_do_init = B_TRUE;
+ if (strlen(ztest_opts.zo_alt_ztest) != 0) {
+ if (ztest_opts.zo_verbose >= 1) {
+ (void) printf("Executing older ztest for "
+ "initialization: %s\n", ztest_opts.zo_alt_ztest);
+ }
+ VERIFY(!exec_child(ztest_opts.zo_alt_ztest,
+ ztest_opts.zo_alt_libpath, B_FALSE, NULL));
+ } else {
+ VERIFY(!exec_child(NULL, NULL, B_FALSE, NULL));
+ }
+ zs->zs_do_init = B_FALSE;
+
+ zs->zs_proc_start = gethrtime();
+ zs->zs_proc_stop = zs->zs_proc_start + ztest_opts.zo_time * NANOSEC;
+
+ for (int f = 0; f < ZTEST_FUNCS; f++) {
+ zi = &ztest_info[f];
+ zc = ZTEST_GET_SHARED_CALLSTATE(f);
+ if (zs->zs_proc_start + zi->zi_interval[0] > zs->zs_proc_stop)
+ zc->zc_next = UINT64_MAX;
+ else
+ zc->zc_next = zs->zs_proc_start +
+ ztest_random(2 * zi->zi_interval[0] + 1);
+ }
+
+ /*
+ * Run the tests in a loop. These tests include fault injection
+ * to verify that self-healing data works, and forced crashes
+ * to verify that we never lose on-disk consistency.
+ */
+ while (gethrtime() < zs->zs_proc_stop) {
+ int status;
+ boolean_t killed;
+
+ /*
+ * Initialize the workload counters for each function.
+ */
+ for (int f = 0; f < ZTEST_FUNCS; f++) {
+ zc = ZTEST_GET_SHARED_CALLSTATE(f);
+ zc->zc_count = 0;
+ zc->zc_time = 0;
+ }
+
+ /* Set the allocation switch size */
+ zs->zs_metaslab_df_alloc_threshold =
+ ztest_random(zs->zs_metaslab_sz / 4) + 1;
+
+ if (!hasalt || ztest_random(2) == 0) {
+ if (hasalt && ztest_opts.zo_verbose >= 1) {
+ (void) printf("Executing newer ztest: %s\n",
+ cmd);
+ }
+ newer++;
+ killed = exec_child(cmd, NULL, B_TRUE, &status);
+ } else {
+ if (hasalt && ztest_opts.zo_verbose >= 1) {
+ (void) printf("Executing older ztest: %s\n",
+ ztest_opts.zo_alt_ztest);
+ }
+ older++;
+ killed = exec_child(ztest_opts.zo_alt_ztest,
+ ztest_opts.zo_alt_libpath, B_TRUE, &status);
+ }
+
+ if (killed)
+ kills++;
+ iters++;
+
+ if (ztest_opts.zo_verbose >= 1) {
+ hrtime_t now = gethrtime();
+
+ now = MIN(now, zs->zs_proc_stop);
+ print_time(zs->zs_proc_stop - now, timebuf);
+ nicenum(zs->zs_space, numbuf);
+
+ (void) printf("Pass %3d, %8s, %3llu ENOSPC, "
+ "%4.1f%% of %5s used, %3.0f%% done, %8s to go\n",
+ iters,
+ WIFEXITED(status) ? "Complete" : "SIGKILL",
+ (u_longlong_t)zs->zs_enospc_count,
+ 100.0 * zs->zs_alloc / zs->zs_space,
+ numbuf,
+ 100.0 * (now - zs->zs_proc_start) /
+ (ztest_opts.zo_time * NANOSEC), timebuf);
+ }
+
+ if (ztest_opts.zo_verbose >= 2) {
+ (void) printf("\nWorkload summary:\n\n");
+ (void) printf("%7s %9s %s\n",
+ "Calls", "Time", "Function");
+ (void) printf("%7s %9s %s\n",
+ "-----", "----", "--------");
+ for (int f = 0; f < ZTEST_FUNCS; f++) {
+ Dl_info dli;
+
+ zi = &ztest_info[f];
+ zc = ZTEST_GET_SHARED_CALLSTATE(f);
+ print_time(zc->zc_time, timebuf);
+ (void) dladdr((void *)zi->zi_func, &dli);
+ (void) printf("%7llu %9s %s\n",
+ (u_longlong_t)zc->zc_count, timebuf,
+ dli.dli_sname);
+ }
+ (void) printf("\n");
+ }
+
+ /*
+ * It's possible that we killed a child during a rename test,
+ * in which case we'll have a 'ztest_tmp' pool lying around
+ * instead of 'ztest'. Do a blind rename in case this happened.
+ */
+ kernel_init(FREAD);
+ if (spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0) {
+ spa_close(spa, FTAG);
+ } else {
+ char tmpname[MAXNAMELEN];
+ kernel_fini();
+ kernel_init(FREAD | FWRITE);
+ (void) snprintf(tmpname, sizeof (tmpname), "%s_tmp",
+ ztest_opts.zo_pool);
+ (void) spa_rename(tmpname, ztest_opts.zo_pool);
+ }
+ kernel_fini();
+
+ ztest_run_zdb(ztest_opts.zo_pool);
+ }
+
+ if (ztest_opts.zo_verbose >= 1) {
+ if (hasalt) {
+ (void) printf("%d runs of older ztest: %s\n", older,
+ ztest_opts.zo_alt_ztest);
+ (void) printf("%d runs of newer ztest: %s\n", newer,
+ cmd);
+ }
+ (void) printf("%d killed, %d completed, %.0f%% kill rate\n",
+ kills, iters - kills, (100.0 * kills) / MAX(1, iters));
+ }
+
+ umem_free(cmd, MAXNAMELEN);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/common/avl/avl.c b/cddl/contrib/opensolaris/common/avl/avl.c
new file mode 100644
index 0000000..dd39c12
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/avl/avl.c
@@ -0,0 +1,1030 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * AVL - generic AVL tree implementation for kernel use
+ *
+ * A complete description of AVL trees can be found in many CS textbooks.
+ *
+ * Here is a very brief overview. An AVL tree is a binary search tree that is
+ * almost perfectly balanced. By "almost" perfectly balanced, we mean that at
+ * any given node, the left and right subtrees are allowed to differ in height
+ * by at most 1 level.
+ *
+ * This relaxation from a perfectly balanced binary tree allows doing
+ * insertion and deletion relatively efficiently. Searching the tree is
+ * still a fast operation, roughly O(log(N)).
+ *
+ * The key to insertion and deletion is a set of tree maniuplations called
+ * rotations, which bring unbalanced subtrees back into the semi-balanced state.
+ *
+ * This implementation of AVL trees has the following peculiarities:
+ *
+ * - The AVL specific data structures are physically embedded as fields
+ * in the "using" data structures. To maintain generality the code
+ * must constantly translate between "avl_node_t *" and containing
+ * data structure "void *"s by adding/subracting the avl_offset.
+ *
+ * - Since the AVL data is always embedded in other structures, there is
+ * no locking or memory allocation in the AVL routines. This must be
+ * provided for by the enclosing data structure's semantics. Typically,
+ * avl_insert()/_add()/_remove()/avl_insert_here() require some kind of
+ * exclusive write lock. Other operations require a read lock.
+ *
+ * - The implementation uses iteration instead of explicit recursion,
+ * since it is intended to run on limited size kernel stacks. Since
+ * there is no recursion stack present to move "up" in the tree,
+ * there is an explicit "parent" link in the avl_node_t.
+ *
+ * - The left/right children pointers of a node are in an array.
+ * In the code, variables (instead of constants) are used to represent
+ * left and right indices. The implementation is written as if it only
+ * dealt with left handed manipulations. By changing the value assigned
+ * to "left", the code also works for right handed trees. The
+ * following variables/terms are frequently used:
+ *
+ * int left; // 0 when dealing with left children,
+ * // 1 for dealing with right children
+ *
+ * int left_heavy; // -1 when left subtree is taller at some node,
+ * // +1 when right subtree is taller
+ *
+ * int right; // will be the opposite of left (0 or 1)
+ * int right_heavy;// will be the opposite of left_heavy (-1 or 1)
+ *
+ * int direction; // 0 for "<" (ie. left child); 1 for ">" (right)
+ *
+ * Though it is a little more confusing to read the code, the approach
+ * allows using half as much code (and hence cache footprint) for tree
+ * manipulations and eliminates many conditional branches.
+ *
+ * - The avl_index_t is an opaque "cookie" used to find nodes at or
+ * adjacent to where a new value would be inserted in the tree. The value
+ * is a modified "avl_node_t *". The bottom bit (normally 0 for a
+ * pointer) is set to indicate if that the new node has a value greater
+ * than the value of the indicated "avl_node_t *".
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/debug.h>
+#include <sys/avl.h>
+#include <sys/cmn_err.h>
+
+/*
+ * Small arrays to translate between balance (or diff) values and child indeces.
+ *
+ * Code that deals with binary tree data structures will randomly use
+ * left and right children when examining a tree. C "if()" statements
+ * which evaluate randomly suffer from very poor hardware branch prediction.
+ * In this code we avoid some of the branch mispredictions by using the
+ * following translation arrays. They replace random branches with an
+ * additional memory reference. Since the translation arrays are both very
+ * small the data should remain efficiently in cache.
+ */
+static const int avl_child2balance[2] = {-1, 1};
+static const int avl_balance2child[] = {0, 0, 1};
+
+
+/*
+ * Walk from one node to the previous valued node (ie. an infix walk
+ * towards the left). At any given node we do one of 2 things:
+ *
+ * - If there is a left child, go to it, then to it's rightmost descendant.
+ *
+ * - otherwise we return thru parent nodes until we've come from a right child.
+ *
+ * Return Value:
+ * NULL - if at the end of the nodes
+ * otherwise next node
+ */
+void *
+avl_walk(avl_tree_t *tree, void *oldnode, int left)
+{
+ size_t off = tree->avl_offset;
+ avl_node_t *node = AVL_DATA2NODE(oldnode, off);
+ int right = 1 - left;
+ int was_child;
+
+
+ /*
+ * nowhere to walk to if tree is empty
+ */
+ if (node == NULL)
+ return (NULL);
+
+ /*
+ * Visit the previous valued node. There are two possibilities:
+ *
+ * If this node has a left child, go down one left, then all
+ * the way right.
+ */
+ if (node->avl_child[left] != NULL) {
+ for (node = node->avl_child[left];
+ node->avl_child[right] != NULL;
+ node = node->avl_child[right])
+ ;
+ /*
+ * Otherwise, return thru left children as far as we can.
+ */
+ } else {
+ for (;;) {
+ was_child = AVL_XCHILD(node);
+ node = AVL_XPARENT(node);
+ if (node == NULL)
+ return (NULL);
+ if (was_child == right)
+ break;
+ }
+ }
+
+ return (AVL_NODE2DATA(node, off));
+}
+
+/*
+ * Return the lowest valued node in a tree or NULL.
+ * (leftmost child from root of tree)
+ */
+void *
+avl_first(avl_tree_t *tree)
+{
+ avl_node_t *node;
+ avl_node_t *prev = NULL;
+ size_t off = tree->avl_offset;
+
+ for (node = tree->avl_root; node != NULL; node = node->avl_child[0])
+ prev = node;
+
+ if (prev != NULL)
+ return (AVL_NODE2DATA(prev, off));
+ return (NULL);
+}
+
+/*
+ * Return the highest valued node in a tree or NULL.
+ * (rightmost child from root of tree)
+ */
+void *
+avl_last(avl_tree_t *tree)
+{
+ avl_node_t *node;
+ avl_node_t *prev = NULL;
+ size_t off = tree->avl_offset;
+
+ for (node = tree->avl_root; node != NULL; node = node->avl_child[1])
+ prev = node;
+
+ if (prev != NULL)
+ return (AVL_NODE2DATA(prev, off));
+ return (NULL);
+}
+
+/*
+ * Access the node immediately before or after an insertion point.
+ *
+ * "avl_index_t" is a (avl_node_t *) with the bottom bit indicating a child
+ *
+ * Return value:
+ * NULL: no node in the given direction
+ * "void *" of the found tree node
+ */
+void *
+avl_nearest(avl_tree_t *tree, avl_index_t where, int direction)
+{
+ int child = AVL_INDEX2CHILD(where);
+ avl_node_t *node = AVL_INDEX2NODE(where);
+ void *data;
+ size_t off = tree->avl_offset;
+
+ if (node == NULL) {
+ ASSERT(tree->avl_root == NULL);
+ return (NULL);
+ }
+ data = AVL_NODE2DATA(node, off);
+ if (child != direction)
+ return (data);
+
+ return (avl_walk(tree, data, direction));
+}
+
+
+/*
+ * Search for the node which contains "value". The algorithm is a
+ * simple binary tree search.
+ *
+ * return value:
+ * NULL: the value is not in the AVL tree
+ * *where (if not NULL) is set to indicate the insertion point
+ * "void *" of the found tree node
+ */
+void *
+avl_find(avl_tree_t *tree, const void *value, avl_index_t *where)
+{
+ avl_node_t *node;
+ avl_node_t *prev = NULL;
+ int child = 0;
+ int diff;
+ size_t off = tree->avl_offset;
+
+ for (node = tree->avl_root; node != NULL;
+ node = node->avl_child[child]) {
+
+ prev = node;
+
+ diff = tree->avl_compar(value, AVL_NODE2DATA(node, off));
+ ASSERT(-1 <= diff && diff <= 1);
+ if (diff == 0) {
+#ifdef DEBUG
+ if (where != NULL)
+ *where = 0;
+#endif
+ return (AVL_NODE2DATA(node, off));
+ }
+ child = avl_balance2child[1 + diff];
+
+ }
+
+ if (where != NULL)
+ *where = AVL_MKINDEX(prev, child);
+
+ return (NULL);
+}
+
+
+/*
+ * Perform a rotation to restore balance at the subtree given by depth.
+ *
+ * This routine is used by both insertion and deletion. The return value
+ * indicates:
+ * 0 : subtree did not change height
+ * !0 : subtree was reduced in height
+ *
+ * The code is written as if handling left rotations, right rotations are
+ * symmetric and handled by swapping values of variables right/left[_heavy]
+ *
+ * On input balance is the "new" balance at "node". This value is either
+ * -2 or +2.
+ */
+static int
+avl_rotation(avl_tree_t *tree, avl_node_t *node, int balance)
+{
+ int left = !(balance < 0); /* when balance = -2, left will be 0 */
+ int right = 1 - left;
+ int left_heavy = balance >> 1;
+ int right_heavy = -left_heavy;
+ avl_node_t *parent = AVL_XPARENT(node);
+ avl_node_t *child = node->avl_child[left];
+ avl_node_t *cright;
+ avl_node_t *gchild;
+ avl_node_t *gright;
+ avl_node_t *gleft;
+ int which_child = AVL_XCHILD(node);
+ int child_bal = AVL_XBALANCE(child);
+
+ /* BEGIN CSTYLED */
+ /*
+ * case 1 : node is overly left heavy, the left child is balanced or
+ * also left heavy. This requires the following rotation.
+ *
+ * (node bal:-2)
+ * / \
+ * / \
+ * (child bal:0 or -1)
+ * / \
+ * / \
+ * cright
+ *
+ * becomes:
+ *
+ * (child bal:1 or 0)
+ * / \
+ * / \
+ * (node bal:-1 or 0)
+ * / \
+ * / \
+ * cright
+ *
+ * we detect this situation by noting that child's balance is not
+ * right_heavy.
+ */
+ /* END CSTYLED */
+ if (child_bal != right_heavy) {
+
+ /*
+ * compute new balance of nodes
+ *
+ * If child used to be left heavy (now balanced) we reduced
+ * the height of this sub-tree -- used in "return...;" below
+ */
+ child_bal += right_heavy; /* adjust towards right */
+
+ /*
+ * move "cright" to be node's left child
+ */
+ cright = child->avl_child[right];
+ node->avl_child[left] = cright;
+ if (cright != NULL) {
+ AVL_SETPARENT(cright, node);
+ AVL_SETCHILD(cright, left);
+ }
+
+ /*
+ * move node to be child's right child
+ */
+ child->avl_child[right] = node;
+ AVL_SETBALANCE(node, -child_bal);
+ AVL_SETCHILD(node, right);
+ AVL_SETPARENT(node, child);
+
+ /*
+ * update the pointer into this subtree
+ */
+ AVL_SETBALANCE(child, child_bal);
+ AVL_SETCHILD(child, which_child);
+ AVL_SETPARENT(child, parent);
+ if (parent != NULL)
+ parent->avl_child[which_child] = child;
+ else
+ tree->avl_root = child;
+
+ return (child_bal == 0);
+ }
+
+ /* BEGIN CSTYLED */
+ /*
+ * case 2 : When node is left heavy, but child is right heavy we use
+ * a different rotation.
+ *
+ * (node b:-2)
+ * / \
+ * / \
+ * / \
+ * (child b:+1)
+ * / \
+ * / \
+ * (gchild b: != 0)
+ * / \
+ * / \
+ * gleft gright
+ *
+ * becomes:
+ *
+ * (gchild b:0)
+ * / \
+ * / \
+ * / \
+ * (child b:?) (node b:?)
+ * / \ / \
+ * / \ / \
+ * gleft gright
+ *
+ * computing the new balances is more complicated. As an example:
+ * if gchild was right_heavy, then child is now left heavy
+ * else it is balanced
+ */
+ /* END CSTYLED */
+ gchild = child->avl_child[right];
+ gleft = gchild->avl_child[left];
+ gright = gchild->avl_child[right];
+
+ /*
+ * move gright to left child of node and
+ *
+ * move gleft to right child of node
+ */
+ node->avl_child[left] = gright;
+ if (gright != NULL) {
+ AVL_SETPARENT(gright, node);
+ AVL_SETCHILD(gright, left);
+ }
+
+ child->avl_child[right] = gleft;
+ if (gleft != NULL) {
+ AVL_SETPARENT(gleft, child);
+ AVL_SETCHILD(gleft, right);
+ }
+
+ /*
+ * move child to left child of gchild and
+ *
+ * move node to right child of gchild and
+ *
+ * fixup parent of all this to point to gchild
+ */
+ balance = AVL_XBALANCE(gchild);
+ gchild->avl_child[left] = child;
+ AVL_SETBALANCE(child, (balance == right_heavy ? left_heavy : 0));
+ AVL_SETPARENT(child, gchild);
+ AVL_SETCHILD(child, left);
+
+ gchild->avl_child[right] = node;
+ AVL_SETBALANCE(node, (balance == left_heavy ? right_heavy : 0));
+ AVL_SETPARENT(node, gchild);
+ AVL_SETCHILD(node, right);
+
+ AVL_SETBALANCE(gchild, 0);
+ AVL_SETPARENT(gchild, parent);
+ AVL_SETCHILD(gchild, which_child);
+ if (parent != NULL)
+ parent->avl_child[which_child] = gchild;
+ else
+ tree->avl_root = gchild;
+
+ return (1); /* the new tree is always shorter */
+}
+
+
+/*
+ * Insert a new node into an AVL tree at the specified (from avl_find()) place.
+ *
+ * Newly inserted nodes are always leaf nodes in the tree, since avl_find()
+ * searches out to the leaf positions. The avl_index_t indicates the node
+ * which will be the parent of the new node.
+ *
+ * After the node is inserted, a single rotation further up the tree may
+ * be necessary to maintain an acceptable AVL balance.
+ */
+void
+avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where)
+{
+ avl_node_t *node;
+ avl_node_t *parent = AVL_INDEX2NODE(where);
+ int old_balance;
+ int new_balance;
+ int which_child = AVL_INDEX2CHILD(where);
+ size_t off = tree->avl_offset;
+
+ ASSERT(tree);
+#ifdef _LP64
+ ASSERT(((uintptr_t)new_data & 0x7) == 0);
+#endif
+
+ node = AVL_DATA2NODE(new_data, off);
+
+ /*
+ * First, add the node to the tree at the indicated position.
+ */
+ ++tree->avl_numnodes;
+
+ node->avl_child[0] = NULL;
+ node->avl_child[1] = NULL;
+
+ AVL_SETCHILD(node, which_child);
+ AVL_SETBALANCE(node, 0);
+ AVL_SETPARENT(node, parent);
+ if (parent != NULL) {
+ ASSERT(parent->avl_child[which_child] == NULL);
+ parent->avl_child[which_child] = node;
+ } else {
+ ASSERT(tree->avl_root == NULL);
+ tree->avl_root = node;
+ }
+ /*
+ * Now, back up the tree modifying the balance of all nodes above the
+ * insertion point. If we get to a highly unbalanced ancestor, we
+ * need to do a rotation. If we back out of the tree we are done.
+ * If we brought any subtree into perfect balance (0), we are also done.
+ */
+ for (;;) {
+ node = parent;
+ if (node == NULL)
+ return;
+
+ /*
+ * Compute the new balance
+ */
+ old_balance = AVL_XBALANCE(node);
+ new_balance = old_balance + avl_child2balance[which_child];
+
+ /*
+ * If we introduced equal balance, then we are done immediately
+ */
+ if (new_balance == 0) {
+ AVL_SETBALANCE(node, 0);
+ return;
+ }
+
+ /*
+ * If both old and new are not zero we went
+ * from -1 to -2 balance, do a rotation.
+ */
+ if (old_balance != 0)
+ break;
+
+ AVL_SETBALANCE(node, new_balance);
+ parent = AVL_XPARENT(node);
+ which_child = AVL_XCHILD(node);
+ }
+
+ /*
+ * perform a rotation to fix the tree and return
+ */
+ (void) avl_rotation(tree, node, new_balance);
+}
+
+/*
+ * Insert "new_data" in "tree" in the given "direction" either after or
+ * before (AVL_AFTER, AVL_BEFORE) the data "here".
+ *
+ * Insertions can only be done at empty leaf points in the tree, therefore
+ * if the given child of the node is already present we move to either
+ * the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since
+ * every other node in the tree is a leaf, this always works.
+ *
+ * To help developers using this interface, we assert that the new node
+ * is correctly ordered at every step of the way in DEBUG kernels.
+ */
+void
+avl_insert_here(
+ avl_tree_t *tree,
+ void *new_data,
+ void *here,
+ int direction)
+{
+ avl_node_t *node;
+ int child = direction; /* rely on AVL_BEFORE == 0, AVL_AFTER == 1 */
+#ifdef DEBUG
+ int diff;
+#endif
+
+ ASSERT(tree != NULL);
+ ASSERT(new_data != NULL);
+ ASSERT(here != NULL);
+ ASSERT(direction == AVL_BEFORE || direction == AVL_AFTER);
+
+ /*
+ * If corresponding child of node is not NULL, go to the neighboring
+ * node and reverse the insertion direction.
+ */
+ node = AVL_DATA2NODE(here, tree->avl_offset);
+
+#ifdef DEBUG
+ diff = tree->avl_compar(new_data, here);
+ ASSERT(-1 <= diff && diff <= 1);
+ ASSERT(diff != 0);
+ ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+
+ if (node->avl_child[child] != NULL) {
+ node = node->avl_child[child];
+ child = 1 - child;
+ while (node->avl_child[child] != NULL) {
+#ifdef DEBUG
+ diff = tree->avl_compar(new_data,
+ AVL_NODE2DATA(node, tree->avl_offset));
+ ASSERT(-1 <= diff && diff <= 1);
+ ASSERT(diff != 0);
+ ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+ node = node->avl_child[child];
+ }
+#ifdef DEBUG
+ diff = tree->avl_compar(new_data,
+ AVL_NODE2DATA(node, tree->avl_offset));
+ ASSERT(-1 <= diff && diff <= 1);
+ ASSERT(diff != 0);
+ ASSERT(diff > 0 ? child == 1 : child == 0);
+#endif
+ }
+ ASSERT(node->avl_child[child] == NULL);
+
+ avl_insert(tree, new_data, AVL_MKINDEX(node, child));
+}
+
+/*
+ * Add a new node to an AVL tree.
+ */
+void
+avl_add(avl_tree_t *tree, void *new_node)
+{
+ avl_index_t where;
+
+ /*
+ * This is unfortunate. We want to call panic() here, even for
+ * non-DEBUG kernels. In userland, however, we can't depend on anything
+ * in libc or else the rtld build process gets confused. So, all we can
+ * do in userland is resort to a normal ASSERT().
+ */
+ if (avl_find(tree, new_node, &where) != NULL)
+#ifdef _KERNEL
+ panic("avl_find() succeeded inside avl_add()");
+#else
+ ASSERT(0);
+#endif
+ avl_insert(tree, new_node, where);
+}
+
+/*
+ * Delete a node from the AVL tree. Deletion is similar to insertion, but
+ * with 2 complications.
+ *
+ * First, we may be deleting an interior node. Consider the following subtree:
+ *
+ * d c c
+ * / \ / \ / \
+ * b e b e b e
+ * / \ / \ /
+ * a c a a
+ *
+ * When we are deleting node (d), we find and bring up an adjacent valued leaf
+ * node, say (c), to take the interior node's place. In the code this is
+ * handled by temporarily swapping (d) and (c) in the tree and then using
+ * common code to delete (d) from the leaf position.
+ *
+ * Secondly, an interior deletion from a deep tree may require more than one
+ * rotation to fix the balance. This is handled by moving up the tree through
+ * parents and applying rotations as needed. The return value from
+ * avl_rotation() is used to detect when a subtree did not change overall
+ * height due to a rotation.
+ */
+void
+avl_remove(avl_tree_t *tree, void *data)
+{
+ avl_node_t *delete;
+ avl_node_t *parent;
+ avl_node_t *node;
+ avl_node_t tmp;
+ int old_balance;
+ int new_balance;
+ int left;
+ int right;
+ int which_child;
+ size_t off = tree->avl_offset;
+
+ ASSERT(tree);
+
+ delete = AVL_DATA2NODE(data, off);
+
+ /*
+ * Deletion is easiest with a node that has at most 1 child.
+ * We swap a node with 2 children with a sequentially valued
+ * neighbor node. That node will have at most 1 child. Note this
+ * has no effect on the ordering of the remaining nodes.
+ *
+ * As an optimization, we choose the greater neighbor if the tree
+ * is right heavy, otherwise the left neighbor. This reduces the
+ * number of rotations needed.
+ */
+ if (delete->avl_child[0] != NULL && delete->avl_child[1] != NULL) {
+
+ /*
+ * choose node to swap from whichever side is taller
+ */
+ old_balance = AVL_XBALANCE(delete);
+ left = avl_balance2child[old_balance + 1];
+ right = 1 - left;
+
+ /*
+ * get to the previous value'd node
+ * (down 1 left, as far as possible right)
+ */
+ for (node = delete->avl_child[left];
+ node->avl_child[right] != NULL;
+ node = node->avl_child[right])
+ ;
+
+ /*
+ * create a temp placeholder for 'node'
+ * move 'node' to delete's spot in the tree
+ */
+ tmp = *node;
+
+ *node = *delete;
+ if (node->avl_child[left] == node)
+ node->avl_child[left] = &tmp;
+
+ parent = AVL_XPARENT(node);
+ if (parent != NULL)
+ parent->avl_child[AVL_XCHILD(node)] = node;
+ else
+ tree->avl_root = node;
+ AVL_SETPARENT(node->avl_child[left], node);
+ AVL_SETPARENT(node->avl_child[right], node);
+
+ /*
+ * Put tmp where node used to be (just temporary).
+ * It always has a parent and at most 1 child.
+ */
+ delete = &tmp;
+ parent = AVL_XPARENT(delete);
+ parent->avl_child[AVL_XCHILD(delete)] = delete;
+ which_child = (delete->avl_child[1] != 0);
+ if (delete->avl_child[which_child] != NULL)
+ AVL_SETPARENT(delete->avl_child[which_child], delete);
+ }
+
+
+ /*
+ * Here we know "delete" is at least partially a leaf node. It can
+ * be easily removed from the tree.
+ */
+ ASSERT(tree->avl_numnodes > 0);
+ --tree->avl_numnodes;
+ parent = AVL_XPARENT(delete);
+ which_child = AVL_XCHILD(delete);
+ if (delete->avl_child[0] != NULL)
+ node = delete->avl_child[0];
+ else
+ node = delete->avl_child[1];
+
+ /*
+ * Connect parent directly to node (leaving out delete).
+ */
+ if (node != NULL) {
+ AVL_SETPARENT(node, parent);
+ AVL_SETCHILD(node, which_child);
+ }
+ if (parent == NULL) {
+ tree->avl_root = node;
+ return;
+ }
+ parent->avl_child[which_child] = node;
+
+
+ /*
+ * Since the subtree is now shorter, begin adjusting parent balances
+ * and performing any needed rotations.
+ */
+ do {
+
+ /*
+ * Move up the tree and adjust the balance
+ *
+ * Capture the parent and which_child values for the next
+ * iteration before any rotations occur.
+ */
+ node = parent;
+ old_balance = AVL_XBALANCE(node);
+ new_balance = old_balance - avl_child2balance[which_child];
+ parent = AVL_XPARENT(node);
+ which_child = AVL_XCHILD(node);
+
+ /*
+ * If a node was in perfect balance but isn't anymore then
+ * we can stop, since the height didn't change above this point
+ * due to a deletion.
+ */
+ if (old_balance == 0) {
+ AVL_SETBALANCE(node, new_balance);
+ break;
+ }
+
+ /*
+ * If the new balance is zero, we don't need to rotate
+ * else
+ * need a rotation to fix the balance.
+ * If the rotation doesn't change the height
+ * of the sub-tree we have finished adjusting.
+ */
+ if (new_balance == 0)
+ AVL_SETBALANCE(node, new_balance);
+ else if (!avl_rotation(tree, node, new_balance))
+ break;
+ } while (parent != NULL);
+}
+
+#define AVL_REINSERT(tree, obj) \
+ avl_remove((tree), (obj)); \
+ avl_add((tree), (obj))
+
+boolean_t
+avl_update_lt(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) ||
+ (t->avl_compar(obj, neighbor) <= 0));
+
+ neighbor = AVL_PREV(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+boolean_t
+avl_update_gt(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) ||
+ (t->avl_compar(obj, neighbor) >= 0));
+
+ neighbor = AVL_NEXT(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+boolean_t
+avl_update(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ neighbor = AVL_PREV(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ neighbor = AVL_NEXT(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * initialize a new AVL tree
+ */
+void
+avl_create(avl_tree_t *tree, int (*compar) (const void *, const void *),
+ size_t size, size_t offset)
+{
+ ASSERT(tree);
+ ASSERT(compar);
+ ASSERT(size > 0);
+ ASSERT(size >= offset + sizeof (avl_node_t));
+#ifdef _LP64
+ ASSERT((offset & 0x7) == 0);
+#endif
+
+ tree->avl_compar = compar;
+ tree->avl_root = NULL;
+ tree->avl_numnodes = 0;
+ tree->avl_size = size;
+ tree->avl_offset = offset;
+}
+
+/*
+ * Delete a tree.
+ */
+/* ARGSUSED */
+void
+avl_destroy(avl_tree_t *tree)
+{
+ ASSERT(tree);
+ ASSERT(tree->avl_numnodes == 0);
+ ASSERT(tree->avl_root == NULL);
+}
+
+
+/*
+ * Return the number of nodes in an AVL tree.
+ */
+ulong_t
+avl_numnodes(avl_tree_t *tree)
+{
+ ASSERT(tree);
+ return (tree->avl_numnodes);
+}
+
+boolean_t
+avl_is_empty(avl_tree_t *tree)
+{
+ ASSERT(tree);
+ return (tree->avl_numnodes == 0);
+}
+
+#define CHILDBIT (1L)
+
+/*
+ * Post-order tree walk used to visit all tree nodes and destroy the tree
+ * in post order. This is used for destroying a tree w/o paying any cost
+ * for rebalancing it.
+ *
+ * example:
+ *
+ * void *cookie = NULL;
+ * my_data_t *node;
+ *
+ * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL)
+ * free(node);
+ * avl_destroy(tree);
+ *
+ * The cookie is really an avl_node_t to the current node's parent and
+ * an indication of which child you looked at last.
+ *
+ * On input, a cookie value of CHILDBIT indicates the tree is done.
+ */
+void *
+avl_destroy_nodes(avl_tree_t *tree, void **cookie)
+{
+ avl_node_t *node;
+ avl_node_t *parent;
+ int child;
+ void *first;
+ size_t off = tree->avl_offset;
+
+ /*
+ * Initial calls go to the first node or it's right descendant.
+ */
+ if (*cookie == NULL) {
+ first = avl_first(tree);
+
+ /*
+ * deal with an empty tree
+ */
+ if (first == NULL) {
+ *cookie = (void *)CHILDBIT;
+ return (NULL);
+ }
+
+ node = AVL_DATA2NODE(first, off);
+ parent = AVL_XPARENT(node);
+ goto check_right_side;
+ }
+
+ /*
+ * If there is no parent to return to we are done.
+ */
+ parent = (avl_node_t *)((uintptr_t)(*cookie) & ~CHILDBIT);
+ if (parent == NULL) {
+ if (tree->avl_root != NULL) {
+ ASSERT(tree->avl_numnodes == 1);
+ tree->avl_root = NULL;
+ tree->avl_numnodes = 0;
+ }
+ return (NULL);
+ }
+
+ /*
+ * Remove the child pointer we just visited from the parent and tree.
+ */
+ child = (uintptr_t)(*cookie) & CHILDBIT;
+ parent->avl_child[child] = NULL;
+ ASSERT(tree->avl_numnodes > 1);
+ --tree->avl_numnodes;
+
+ /*
+ * If we just did a right child or there isn't one, go up to parent.
+ */
+ if (child == 1 || parent->avl_child[1] == NULL) {
+ node = parent;
+ parent = AVL_XPARENT(parent);
+ goto done;
+ }
+
+ /*
+ * Do parent's right child, then leftmost descendent.
+ */
+ node = parent->avl_child[1];
+ while (node->avl_child[0] != NULL) {
+ parent = node;
+ node = node->avl_child[0];
+ }
+
+ /*
+ * If here, we moved to a left child. It may have one
+ * child on the right (when balance == +1).
+ */
+check_right_side:
+ if (node->avl_child[1] != NULL) {
+ ASSERT(AVL_XBALANCE(node) == 1);
+ parent = node;
+ node = node->avl_child[1];
+ ASSERT(node->avl_child[0] == NULL &&
+ node->avl_child[1] == NULL);
+ } else {
+ ASSERT(AVL_XBALANCE(node) <= 0);
+ }
+
+done:
+ if (parent == NULL) {
+ *cookie = (void *)CHILDBIT;
+ ASSERT(node == tree->avl_root);
+ } else {
+ *cookie = (void *)((uintptr_t)parent | AVL_XCHILD(node));
+ }
+
+ return (AVL_NODE2DATA(node, off));
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c
new file mode 100644
index 0000000..a4f3df3
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c
@@ -0,0 +1,1366 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sysmacros.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <ctf_impl.h>
+
+/*
+ * This static string is used as the template for initially populating a
+ * dynamic container's string table. We always store \0 in the first byte,
+ * and we use the generic string "PARENT" to mark this container's parent
+ * if one is associated with the container using ctf_import().
+ */
+static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
+
+/*
+ * To create an empty CTF container, we just declare a zeroed header and call
+ * ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
+ * and initialize the dynamic members. We set dtstrlen to 1 to reserve the
+ * first byte of the string table for a \0 byte, and we start assigning type
+ * IDs at 1 because type ID 0 is used as a sentinel.
+ */
+ctf_file_t *
+ctf_create(int *errp)
+{
+ static const ctf_header_t hdr = { { CTF_MAGIC, CTF_VERSION, 0 } };
+
+ const ulong_t hashlen = 128;
+ ctf_dtdef_t **hash = ctf_alloc(hashlen * sizeof (ctf_dtdef_t *));
+ ctf_sect_t cts;
+ ctf_file_t *fp;
+
+ if (hash == NULL)
+ return (ctf_set_open_errno(errp, EAGAIN));
+
+ cts.cts_name = _CTF_SECTION;
+ cts.cts_type = SHT_PROGBITS;
+ cts.cts_flags = 0;
+ cts.cts_data = &hdr;
+ cts.cts_size = sizeof (hdr);
+ cts.cts_entsize = 1;
+ cts.cts_offset = 0;
+
+ if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) == NULL) {
+ ctf_free(hash, hashlen * sizeof (ctf_dtdef_t *));
+ return (NULL);
+ }
+
+ fp->ctf_flags |= LCTF_RDWR;
+ fp->ctf_dthashlen = hashlen;
+ bzero(hash, hashlen * sizeof (ctf_dtdef_t *));
+ fp->ctf_dthash = hash;
+ fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE);
+ fp->ctf_dtnextid = 1;
+ fp->ctf_dtoldid = 0;
+
+ return (fp);
+}
+
+static uchar_t *
+ctf_copy_smembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
+{
+ ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ ctf_member_t ctm;
+
+ for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if (dmd->dmd_name) {
+ ctm.ctm_name = soff;
+ soff += strlen(dmd->dmd_name) + 1;
+ } else
+ ctm.ctm_name = 0;
+
+ ctm.ctm_type = (ushort_t)dmd->dmd_type;
+ ctm.ctm_offset = (ushort_t)dmd->dmd_offset;
+
+ bcopy(&ctm, t, sizeof (ctm));
+ t += sizeof (ctm);
+ }
+
+ return (t);
+}
+
+static uchar_t *
+ctf_copy_lmembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
+{
+ ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ ctf_lmember_t ctlm;
+
+ for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if (dmd->dmd_name) {
+ ctlm.ctlm_name = soff;
+ soff += strlen(dmd->dmd_name) + 1;
+ } else
+ ctlm.ctlm_name = 0;
+
+ ctlm.ctlm_type = (ushort_t)dmd->dmd_type;
+ ctlm.ctlm_pad = 0;
+ ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
+ ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
+
+ bcopy(&ctlm, t, sizeof (ctlm));
+ t += sizeof (ctlm);
+ }
+
+ return (t);
+}
+
+static uchar_t *
+ctf_copy_emembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
+{
+ ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ ctf_enum_t cte;
+
+ for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
+ cte.cte_name = soff;
+ cte.cte_value = dmd->dmd_value;
+ soff += strlen(dmd->dmd_name) + 1;
+ bcopy(&cte, t, sizeof (cte));
+ t += sizeof (cte);
+ }
+
+ return (t);
+}
+
+static uchar_t *
+ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
+{
+ ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ size_t len;
+
+ for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if (dmd->dmd_name == NULL)
+ continue; /* skip anonymous members */
+ len = strlen(dmd->dmd_name) + 1;
+ bcopy(dmd->dmd_name, s, len);
+ s += len;
+ }
+
+ return (s);
+}
+
+/*
+ * If the specified CTF container is writable and has been modified, reload
+ * this container with the updated type definitions. In order to make this
+ * code and the rest of libctf as simple as possible, we perform updates by
+ * taking the dynamic type definitions and creating an in-memory CTF file
+ * containing the definitions, and then call ctf_bufopen() on it. This not
+ * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest
+ * of the library code with different lookup paths for static and dynamic
+ * type definitions. We are therefore optimizing greatly for lookup over
+ * update, which we assume will be an uncommon operation. We perform one
+ * extra trick here for the benefit of callers and to keep our code simple:
+ * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
+ * constant for the caller, so after ctf_bufopen() returns, we use bcopy to
+ * swap the interior of the old and new ctf_file_t's, and then free the old.
+ */
+int
+ctf_update(ctf_file_t *fp)
+{
+ ctf_file_t ofp, *nfp;
+ ctf_header_t hdr;
+ ctf_dtdef_t *dtd;
+ ctf_sect_t cts;
+
+ uchar_t *s, *s0, *t;
+ size_t size;
+ void *buf;
+ int err;
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (!(fp->ctf_flags & LCTF_DIRTY))
+ return (0); /* no update required */
+
+ /*
+ * Fill in an initial CTF header. We will leave the label, object,
+ * and function sections empty and only output a header, type section,
+ * and string table. The type section begins at a 4-byte aligned
+ * boundary past the CTF header itself (at relative offset zero).
+ */
+ bzero(&hdr, sizeof (hdr));
+ hdr.cth_magic = CTF_MAGIC;
+ hdr.cth_version = CTF_VERSION;
+
+ if (fp->ctf_flags & LCTF_CHILD)
+ hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */
+
+ /*
+ * Iterate through the dynamic type definition list and compute the
+ * size of the CTF type section we will need to generate.
+ */
+ for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs);
+ dtd != NULL; dtd = ctf_list_next(dtd)) {
+
+ uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
+ uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
+
+ if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
+ size += sizeof (ctf_stype_t);
+ else
+ size += sizeof (ctf_type_t);
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ size += sizeof (uint_t);
+ break;
+ case CTF_K_ARRAY:
+ size += sizeof (ctf_array_t);
+ break;
+ case CTF_K_FUNCTION:
+ size += sizeof (ushort_t) * (vlen + (vlen & 1));
+ break;
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
+ size += sizeof (ctf_member_t) * vlen;
+ else
+ size += sizeof (ctf_lmember_t) * vlen;
+ break;
+ case CTF_K_ENUM:
+ size += sizeof (ctf_enum_t) * vlen;
+ break;
+ }
+ }
+
+ /*
+ * Fill in the string table offset and size, compute the size of the
+ * entire CTF buffer we need, and then allocate a new buffer and
+ * bcopy the finished header to the start of the buffer.
+ */
+ hdr.cth_stroff = hdr.cth_typeoff + size;
+ hdr.cth_strlen = fp->ctf_dtstrlen;
+ size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
+
+ if ((buf = ctf_data_alloc(size)) == MAP_FAILED)
+ return (ctf_set_errno(fp, EAGAIN));
+
+ bcopy(&hdr, buf, sizeof (ctf_header_t));
+ t = (uchar_t *)buf + sizeof (ctf_header_t);
+ s = s0 = (uchar_t *)buf + sizeof (ctf_header_t) + hdr.cth_stroff;
+
+ bcopy(_CTF_STRTAB_TEMPLATE, s, sizeof (_CTF_STRTAB_TEMPLATE));
+ s += sizeof (_CTF_STRTAB_TEMPLATE);
+
+ /*
+ * We now take a final lap through the dynamic type definition list and
+ * copy the appropriate type records and strings to the output buffer.
+ */
+ for (dtd = ctf_list_next(&fp->ctf_dtdefs);
+ dtd != NULL; dtd = ctf_list_next(dtd)) {
+
+ uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
+ uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
+
+ ctf_array_t cta;
+ uint_t encoding;
+ size_t len;
+
+ if (dtd->dtd_name != NULL) {
+ dtd->dtd_data.ctt_name = (uint_t)(s - s0);
+ len = strlen(dtd->dtd_name) + 1;
+ bcopy(dtd->dtd_name, s, len);
+ s += len;
+ } else
+ dtd->dtd_data.ctt_name = 0;
+
+ if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
+ len = sizeof (ctf_stype_t);
+ else
+ len = sizeof (ctf_type_t);
+
+ bcopy(&dtd->dtd_data, t, len);
+ t += len;
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ if (kind == CTF_K_INTEGER) {
+ encoding = CTF_INT_DATA(
+ dtd->dtd_u.dtu_enc.cte_format,
+ dtd->dtd_u.dtu_enc.cte_offset,
+ dtd->dtd_u.dtu_enc.cte_bits);
+ } else {
+ encoding = CTF_FP_DATA(
+ dtd->dtd_u.dtu_enc.cte_format,
+ dtd->dtd_u.dtu_enc.cte_offset,
+ dtd->dtd_u.dtu_enc.cte_bits);
+ }
+ bcopy(&encoding, t, sizeof (encoding));
+ t += sizeof (encoding);
+ break;
+
+ case CTF_K_ARRAY:
+ cta.cta_contents = (ushort_t)
+ dtd->dtd_u.dtu_arr.ctr_contents;
+ cta.cta_index = (ushort_t)
+ dtd->dtd_u.dtu_arr.ctr_index;
+ cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
+ bcopy(&cta, t, sizeof (cta));
+ t += sizeof (cta);
+ break;
+
+ case CTF_K_FUNCTION: {
+ ushort_t *argv = (ushort_t *)(uintptr_t)t;
+ uint_t argc;
+
+ for (argc = 0; argc < vlen; argc++)
+ *argv++ = (ushort_t)dtd->dtd_u.dtu_argv[argc];
+
+ if (vlen & 1)
+ *argv++ = 0; /* pad to 4-byte boundary */
+
+ t = (uchar_t *)argv;
+ break;
+ }
+
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
+ t = ctf_copy_smembers(dtd, (uint_t)(s - s0), t);
+ else
+ t = ctf_copy_lmembers(dtd, (uint_t)(s - s0), t);
+ s = ctf_copy_membnames(dtd, s);
+ break;
+
+ case CTF_K_ENUM:
+ t = ctf_copy_emembers(dtd, (uint_t)(s - s0), t);
+ s = ctf_copy_membnames(dtd, s);
+ break;
+ }
+ }
+
+ /*
+ * Finally, we are ready to ctf_bufopen() the new container. If this
+ * is successful, we then switch nfp and fp and free the old container.
+ */
+ ctf_data_protect(buf, size);
+ cts.cts_name = _CTF_SECTION;
+ cts.cts_type = SHT_PROGBITS;
+ cts.cts_flags = 0;
+ cts.cts_data = buf;
+ cts.cts_size = size;
+ cts.cts_entsize = 1;
+ cts.cts_offset = 0;
+
+ if ((nfp = ctf_bufopen(&cts, NULL, NULL, &err)) == NULL) {
+ ctf_data_free(buf, size);
+ return (ctf_set_errno(fp, err));
+ }
+
+ (void) ctf_setmodel(nfp, ctf_getmodel(fp));
+ (void) ctf_import(nfp, fp->ctf_parent);
+
+ nfp->ctf_refcnt = fp->ctf_refcnt;
+ nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
+ nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */
+ nfp->ctf_dthash = fp->ctf_dthash;
+ nfp->ctf_dthashlen = fp->ctf_dthashlen;
+ nfp->ctf_dtdefs = fp->ctf_dtdefs;
+ nfp->ctf_dtstrlen = fp->ctf_dtstrlen;
+ nfp->ctf_dtnextid = fp->ctf_dtnextid;
+ nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
+ nfp->ctf_specific = fp->ctf_specific;
+
+ fp->ctf_dthash = NULL;
+ fp->ctf_dthashlen = 0;
+ bzero(&fp->ctf_dtdefs, sizeof (ctf_list_t));
+
+ bcopy(fp, &ofp, sizeof (ctf_file_t));
+ bcopy(nfp, fp, sizeof (ctf_file_t));
+ bcopy(&ofp, nfp, sizeof (ctf_file_t));
+
+ /*
+ * Initialize the ctf_lookup_by_name top-level dictionary. We keep an
+ * array of type name prefixes and the corresponding ctf_hash to use.
+ * NOTE: This code must be kept in sync with the code in ctf_bufopen().
+ */
+ fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
+ fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
+ fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
+ fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
+
+ nfp->ctf_refcnt = 1; /* force nfp to be freed */
+ ctf_close(nfp);
+
+ return (0);
+}
+
+void
+ctf_dtd_insert(ctf_file_t *fp, ctf_dtdef_t *dtd)
+{
+ ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
+
+ dtd->dtd_hash = fp->ctf_dthash[h];
+ fp->ctf_dthash[h] = dtd;
+ ctf_list_append(&fp->ctf_dtdefs, dtd);
+}
+
+void
+ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
+{
+ ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
+ ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
+ ctf_dmdef_t *dmd, *nmd;
+ size_t len;
+
+ for (p = *q; p != NULL; p = p->dtd_hash) {
+ if (p != dtd)
+ q = &p->dtd_hash;
+ else
+ break;
+ }
+
+ if (p != NULL)
+ *q = p->dtd_hash;
+
+ switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ case CTF_K_ENUM:
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = nmd) {
+ if (dmd->dmd_name != NULL) {
+ len = strlen(dmd->dmd_name) + 1;
+ ctf_free(dmd->dmd_name, len);
+ fp->ctf_dtstrlen -= len;
+ }
+ nmd = ctf_list_next(dmd);
+ ctf_free(dmd, sizeof (ctf_dmdef_t));
+ }
+ break;
+ case CTF_K_FUNCTION:
+ ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
+ CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
+ break;
+ }
+
+ if (dtd->dtd_name) {
+ len = strlen(dtd->dtd_name) + 1;
+ ctf_free(dtd->dtd_name, len);
+ fp->ctf_dtstrlen -= len;
+ }
+
+ ctf_list_delete(&fp->ctf_dtdefs, dtd);
+ ctf_free(dtd, sizeof (ctf_dtdef_t));
+}
+
+ctf_dtdef_t *
+ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
+{
+ ulong_t h = type & (fp->ctf_dthashlen - 1);
+ ctf_dtdef_t *dtd;
+
+ if (fp->ctf_dthash == NULL)
+ return (NULL);
+
+ for (dtd = fp->ctf_dthash[h]; dtd != NULL; dtd = dtd->dtd_hash) {
+ if (dtd->dtd_type == type)
+ break;
+ }
+
+ return (dtd);
+}
+
+/*
+ * Discard all of the dynamic type definitions that have been added to the
+ * container since the last call to ctf_update(). We locate such types by
+ * scanning the list and deleting elements that have type IDs greater than
+ * ctf_dtoldid, which is set by ctf_update(), above.
+ */
+int
+ctf_discard(ctf_file_t *fp)
+{
+ ctf_dtdef_t *dtd, *ntd;
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (!(fp->ctf_flags & LCTF_DIRTY))
+ return (0); /* no update required */
+
+ for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
+ if (dtd->dtd_type <= fp->ctf_dtoldid)
+ continue; /* skip types that have been committed */
+
+ ntd = ctf_list_next(dtd);
+ ctf_dtd_delete(fp, dtd);
+ }
+
+ fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
+ fp->ctf_flags &= ~LCTF_DIRTY;
+
+ return (0);
+}
+
+static ctf_id_t
+ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+ char *s = NULL;
+
+ if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
+ return (ctf_set_errno(fp, ECTF_FULL));
+
+ if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL)
+ return (ctf_set_errno(fp, EAGAIN));
+
+ if (name != NULL && (s = ctf_strdup(name)) == NULL) {
+ ctf_free(dtd, sizeof (ctf_dtdef_t));
+ return (ctf_set_errno(fp, EAGAIN));
+ }
+
+ type = fp->ctf_dtnextid++;
+ type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD));
+
+ bzero(dtd, sizeof (ctf_dtdef_t));
+ dtd->dtd_name = s;
+ dtd->dtd_type = type;
+
+ if (s != NULL)
+ fp->ctf_dtstrlen += strlen(s) + 1;
+
+ ctf_dtd_insert(fp, dtd);
+ fp->ctf_flags |= LCTF_DIRTY;
+
+ *rp = dtd;
+ return (type);
+}
+
+/*
+ * When encoding integer sizes, we want to convert a byte count in the range
+ * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
+ * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
+ */
+static size_t
+clp2(size_t x)
+{
+ x--;
+
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+
+ return (x + 1);
+}
+
+static ctf_id_t
+ctf_add_encoded(ctf_file_t *fp, uint_t flag,
+ const char *name, const ctf_encoding_t *ep, uint_t kind)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (ep == NULL)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
+ dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY);
+ dtd->dtd_u.dtu_enc = *ep;
+
+ return (type);
+}
+
+static ctf_id_t
+ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
+ dtd->dtd_data.ctt_type = (ushort_t)ref;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_integer(ctf_file_t *fp, uint_t flag,
+ const char *name, const ctf_encoding_t *ep)
+{
+ return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER));
+}
+
+ctf_id_t
+ctf_add_float(ctf_file_t *fp, uint_t flag,
+ const char *name, const ctf_encoding_t *ep)
+{
+ return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT));
+}
+
+ctf_id_t
+ctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
+{
+ return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));
+}
+
+ctf_id_t
+ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (arp == NULL)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
+ dtd->dtd_data.ctt_size = 0;
+ dtd->dtd_u.dtu_arr = *arp;
+
+ return (type);
+}
+
+int
+ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
+{
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ fp->ctf_flags |= LCTF_DIRTY;
+ dtd->dtd_u.dtu_arr = *arp;
+
+ return (0);
+}
+
+ctf_id_t
+ctf_add_function(ctf_file_t *fp, uint_t flag,
+ const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+ uint_t vlen;
+ ctf_id_t *vdat = NULL;
+
+ if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
+ (ctc->ctc_argc != 0 && argv == NULL))
+ return (ctf_set_errno(fp, EINVAL));
+
+ vlen = ctc->ctc_argc;
+ if (ctc->ctc_flags & CTF_FUNC_VARARG)
+ vlen++; /* add trailing zero to indicate varargs (see below) */
+
+ if (vlen > CTF_MAX_VLEN)
+ return (ctf_set_errno(fp, EOVERFLOW));
+
+ if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
+ return (ctf_set_errno(fp, EAGAIN));
+
+ if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) {
+ ctf_free(vdat, sizeof (ctf_id_t) * vlen);
+ return (CTF_ERR); /* errno is set for us */
+ }
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
+ dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
+
+ bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
+ if (ctc->ctc_flags & CTF_FUNC_VARARG)
+ vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
+ dtd->dtd_u.dtu_argv = vdat;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name)
+{
+ ctf_hash_t *hp = &fp->ctf_structs;
+ ctf_helem_t *hep = NULL;
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0);
+ dtd->dtd_data.ctt_size = 0;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name)
+{
+ ctf_hash_t *hp = &fp->ctf_unions;
+ ctf_helem_t *hep = NULL;
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
+ dtd->dtd_data.ctt_size = 0;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
+{
+ ctf_hash_t *hp = &fp->ctf_enums;
+ ctf_helem_t *hep = NULL;
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
+ dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
+{
+ ctf_hash_t *hp;
+ ctf_helem_t *hep;
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ switch (kind) {
+ case CTF_K_STRUCT:
+ hp = &fp->ctf_structs;
+ break;
+ case CTF_K_UNION:
+ hp = &fp->ctf_unions;
+ break;
+ case CTF_K_ENUM:
+ hp = &fp->ctf_enums;
+ break;
+ default:
+ return (ctf_set_errno(fp, ECTF_NOTSUE));
+ }
+
+ /*
+ * If the type is already defined or exists as a forward tag, just
+ * return the ctf_id_t of the existing definition.
+ */
+ if (name != NULL && (hep = ctf_hash_lookup(hp,
+ fp, name, strlen(name))) != NULL)
+ return (hep->h_type);
+
+ if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0);
+ dtd->dtd_data.ctt_type = kind;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
+{
+ ctf_dtdef_t *dtd;
+ ctf_id_t type;
+
+ if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
+ dtd->dtd_data.ctt_type = (ushort_t)ref;
+
+ return (type);
+}
+
+ctf_id_t
+ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
+{
+ return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));
+}
+
+ctf_id_t
+ctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
+{
+ return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST));
+}
+
+ctf_id_t
+ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
+{
+ return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT));
+}
+
+int
+ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
+{
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, enid);
+ ctf_dmdef_t *dmd;
+
+ uint_t kind, vlen, root;
+ char *s;
+
+ if (name == NULL)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (dtd == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
+ root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
+ vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
+
+ if (kind != CTF_K_ENUM)
+ return (ctf_set_errno(fp, ECTF_NOTENUM));
+
+ if (vlen == CTF_MAX_VLEN)
+ return (ctf_set_errno(fp, ECTF_DTFULL));
+
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if (strcmp(dmd->dmd_name, name) == 0)
+ return (ctf_set_errno(fp, ECTF_DUPMEMBER));
+ }
+
+ if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
+ return (ctf_set_errno(fp, EAGAIN));
+
+ if ((s = ctf_strdup(name)) == NULL) {
+ ctf_free(dmd, sizeof (ctf_dmdef_t));
+ return (ctf_set_errno(fp, EAGAIN));
+ }
+
+ dmd->dmd_name = s;
+ dmd->dmd_type = CTF_ERR;
+ dmd->dmd_offset = 0;
+ dmd->dmd_value = value;
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
+ ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
+
+ fp->ctf_dtstrlen += strlen(s) + 1;
+ fp->ctf_flags |= LCTF_DIRTY;
+
+ return (0);
+}
+
+int
+ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
+{
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, souid);
+ ctf_dmdef_t *dmd;
+
+ ssize_t msize, malign, ssize;
+ uint_t kind, vlen, root;
+ char *s = NULL;
+
+ if (!(fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(fp, ECTF_RDONLY));
+
+ if (dtd == NULL)
+ return (ctf_set_errno(fp, ECTF_BADID));
+
+ kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
+ root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
+ vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
+ return (ctf_set_errno(fp, ECTF_NOTSOU));
+
+ if (vlen == CTF_MAX_VLEN)
+ return (ctf_set_errno(fp, ECTF_DTFULL));
+
+ if (name != NULL) {
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if (dmd->dmd_name != NULL &&
+ strcmp(dmd->dmd_name, name) == 0)
+ return (ctf_set_errno(fp, ECTF_DUPMEMBER));
+ }
+ }
+
+ if ((msize = ctf_type_size(fp, type)) == CTF_ERR ||
+ (malign = ctf_type_align(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
+ return (ctf_set_errno(fp, EAGAIN));
+
+ if (name != NULL && (s = ctf_strdup(name)) == NULL) {
+ ctf_free(dmd, sizeof (ctf_dmdef_t));
+ return (ctf_set_errno(fp, EAGAIN));
+ }
+
+ dmd->dmd_name = s;
+ dmd->dmd_type = type;
+ dmd->dmd_value = -1;
+
+ if (kind == CTF_K_STRUCT && vlen != 0) {
+ ctf_dmdef_t *lmd = ctf_list_prev(&dtd->dtd_u.dtu_members);
+ ctf_id_t ltype = ctf_type_resolve(fp, lmd->dmd_type);
+ size_t off = lmd->dmd_offset;
+
+ ctf_encoding_t linfo;
+ ssize_t lsize;
+
+ if (ctf_type_encoding(fp, ltype, &linfo) != CTF_ERR)
+ off += linfo.cte_bits;
+ else if ((lsize = ctf_type_size(fp, ltype)) != CTF_ERR)
+ off += lsize * NBBY;
+
+ /*
+ * Round up the offset of the end of the last member to the
+ * next byte boundary, convert 'off' to bytes, and then round
+ * it up again to the next multiple of the alignment required
+ * by the new member. Finally, convert back to bits and store
+ * the result in dmd_offset. Technically we could do more
+ * efficient packing if the new member is a bit-field, but
+ * we're the "compiler" and ANSI says we can do as we choose.
+ */
+ off = roundup(off, NBBY) / NBBY;
+ off = roundup(off, MAX(malign, 1));
+ dmd->dmd_offset = off * NBBY;
+ ssize = off + msize;
+ } else {
+ dmd->dmd_offset = 0;
+ ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
+ ssize = MAX(ssize, msize);
+ }
+
+ if (ssize > CTF_MAX_SIZE) {
+ dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
+ dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
+ dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
+ } else
+ dtd->dtd_data.ctt_size = (ushort_t)ssize;
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
+ ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
+
+ if (s != NULL)
+ fp->ctf_dtstrlen += strlen(s) + 1;
+
+ fp->ctf_flags |= LCTF_DIRTY;
+ return (0);
+}
+
+static int
+enumcmp(const char *name, int value, void *arg)
+{
+ ctf_bundle_t *ctb = arg;
+ int bvalue;
+
+ return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type,
+ name, &bvalue) == CTF_ERR || value != bvalue);
+}
+
+static int
+enumadd(const char *name, int value, void *arg)
+{
+ ctf_bundle_t *ctb = arg;
+
+ return (ctf_add_enumerator(ctb->ctb_file, ctb->ctb_type,
+ name, value) == CTF_ERR);
+}
+
+/*ARGSUSED*/
+static int
+membcmp(const char *name, ctf_id_t type, ulong_t offset, void *arg)
+{
+ ctf_bundle_t *ctb = arg;
+ ctf_membinfo_t ctm;
+
+ return (ctf_member_info(ctb->ctb_file, ctb->ctb_type,
+ name, &ctm) == CTF_ERR || ctm.ctm_offset != offset);
+}
+
+static int
+membadd(const char *name, ctf_id_t type, ulong_t offset, void *arg)
+{
+ ctf_bundle_t *ctb = arg;
+ ctf_dmdef_t *dmd;
+ char *s = NULL;
+
+ if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
+ return (ctf_set_errno(ctb->ctb_file, EAGAIN));
+
+ if (name != NULL && (s = ctf_strdup(name)) == NULL) {
+ ctf_free(dmd, sizeof (ctf_dmdef_t));
+ return (ctf_set_errno(ctb->ctb_file, EAGAIN));
+ }
+
+ /*
+ * For now, dmd_type is copied as the src_fp's type; it is reset to an
+ * equivalent dst_fp type by a final loop in ctf_add_type(), below.
+ */
+ dmd->dmd_name = s;
+ dmd->dmd_type = type;
+ dmd->dmd_offset = offset;
+ dmd->dmd_value = -1;
+
+ ctf_list_append(&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
+
+ if (s != NULL)
+ ctb->ctb_file->ctf_dtstrlen += strlen(s) + 1;
+
+ ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
+ return (0);
+}
+
+/*
+ * The ctf_add_type routine is used to copy a type from a source CTF container
+ * to a dynamic destination container. This routine operates recursively by
+ * following the source type's links and embedded member types. If the
+ * destination container already contains a named type which has the same
+ * attributes, then we succeed and return this type but no changes occur.
+ */
+ctf_id_t
+ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
+{
+ ctf_id_t dst_type = CTF_ERR;
+ uint_t dst_kind = CTF_K_UNKNOWN;
+
+ const ctf_type_t *tp;
+ const char *name;
+ uint_t kind, flag, vlen;
+
+ ctf_bundle_t src, dst;
+ ctf_encoding_t src_en, dst_en;
+ ctf_arinfo_t src_ar, dst_ar;
+
+ ctf_dtdef_t *dtd;
+ ctf_funcinfo_t ctc;
+ ssize_t size;
+
+ ctf_hash_t *hp;
+ ctf_helem_t *hep;
+
+ if (!(dst_fp->ctf_flags & LCTF_RDWR))
+ return (ctf_set_errno(dst_fp, ECTF_RDONLY));
+
+ if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
+ return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
+
+ name = ctf_strptr(src_fp, tp->ctt_name);
+ kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
+ flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
+ vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
+
+ switch (kind) {
+ case CTF_K_STRUCT:
+ hp = &dst_fp->ctf_structs;
+ break;
+ case CTF_K_UNION:
+ hp = &dst_fp->ctf_unions;
+ break;
+ case CTF_K_ENUM:
+ hp = &dst_fp->ctf_enums;
+ break;
+ default:
+ hp = &dst_fp->ctf_names;
+ break;
+ }
+
+ /*
+ * If the source type has a name and is a root type (visible at the
+ * top-level scope), lookup the name in the destination container and
+ * verify that it is of the same kind before we do anything else.
+ */
+ if ((flag & CTF_ADD_ROOT) && name[0] != '\0' &&
+ (hep = ctf_hash_lookup(hp, dst_fp, name, strlen(name))) != NULL) {
+ dst_type = (ctf_id_t)hep->h_type;
+ dst_kind = ctf_type_kind(dst_fp, dst_type);
+ }
+
+ /*
+ * If an identically named dst_type exists, fail with ECTF_CONFLICT
+ * unless dst_type is a forward declaration and src_type is a struct,
+ * union, or enum (i.e. the definition of the previous forward decl).
+ */
+ if (dst_type != CTF_ERR && dst_kind != kind && (
+ dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM &&
+ kind != CTF_K_STRUCT && kind != CTF_K_UNION)))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+
+ /*
+ * If the non-empty name was not found in the appropriate hash, search
+ * the list of pending dynamic definitions that are not yet committed.
+ * If a matching name and kind are found, assume this is the type that
+ * we are looking for. This is necessary to permit ctf_add_type() to
+ * operate recursively on entities such as a struct that contains a
+ * pointer member that refers to the same struct type.
+ */
+ if (dst_type == CTF_ERR && name[0] != '\0') {
+ for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL &&
+ dtd->dtd_type > dst_fp->ctf_dtoldid;
+ dtd = ctf_list_prev(dtd)) {
+ if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) == kind &&
+ dtd->dtd_name != NULL &&
+ strcmp(dtd->dtd_name, name) == 0)
+ return (dtd->dtd_type);
+ }
+ }
+
+ src.ctb_file = src_fp;
+ src.ctb_type = src_type;
+ src.ctb_dtd = NULL;
+
+ dst.ctb_file = dst_fp;
+ dst.ctb_type = dst_type;
+ dst.ctb_dtd = NULL;
+
+ /*
+ * Now perform kind-specific processing. If dst_type is CTF_ERR, then
+ * we add a new type with the same properties as src_type to dst_fp.
+ * If dst_type is not CTF_ERR, then we verify that dst_type has the
+ * same attributes as src_type. We recurse for embedded references.
+ */
+ switch (kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ if (ctf_type_encoding(src_fp, src_type, &src_en) != 0)
+ return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
+
+ if (dst_type != CTF_ERR) {
+ if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (bcmp(&src_en, &dst_en, sizeof (ctf_encoding_t)))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+
+ } else if (kind == CTF_K_INTEGER) {
+ dst_type = ctf_add_integer(dst_fp, flag, name, &src_en);
+ } else
+ dst_type = ctf_add_float(dst_fp, flag, name, &src_en);
+ break;
+
+ case CTF_K_POINTER:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ src_type = ctf_type_reference(src_fp, src_type);
+ src_type = ctf_add_type(dst_fp, src_fp, src_type);
+
+ if (src_type == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind);
+ break;
+
+ case CTF_K_ARRAY:
+ if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR)
+ return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
+
+ src_ar.ctr_contents =
+ ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents);
+ src_ar.ctr_index =
+ ctf_add_type(dst_fp, src_fp, src_ar.ctr_index);
+ src_ar.ctr_nelems = src_ar.ctr_nelems;
+
+ if (src_ar.ctr_contents == CTF_ERR ||
+ src_ar.ctr_index == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (dst_type != CTF_ERR) {
+ if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (bcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+ } else
+ dst_type = ctf_add_array(dst_fp, flag, &src_ar);
+ break;
+
+ case CTF_K_FUNCTION:
+ ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type);
+ ctc.ctc_argc = 0;
+ ctc.ctc_flags = 0;
+
+ if (ctc.ctc_return == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL);
+ break;
+
+ case CTF_K_STRUCT:
+ case CTF_K_UNION: {
+ ctf_dmdef_t *dmd;
+ int errs = 0;
+
+ /*
+ * Technically to match a struct or union we need to check both
+ * ways (src members vs. dst, dst members vs. src) but we make
+ * this more optimal by only checking src vs. dst and comparing
+ * the total size of the structure (which we must do anyway)
+ * which covers the possibility of dst members not in src.
+ * This optimization can be defeated for unions, but is so
+ * pathological as to render it irrelevant for our purposes.
+ */
+ if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
+ if (ctf_type_size(src_fp, src_type) !=
+ ctf_type_size(dst_fp, dst_type))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+
+ if (ctf_member_iter(src_fp, src_type, membcmp, &dst))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+
+ break;
+ }
+
+ /*
+ * Unlike the other cases, copying structs and unions is done
+ * manually so as to avoid repeated lookups in ctf_add_member
+ * and to ensure the exact same member offsets as in src_type.
+ */
+ dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
+ if (dst_type == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ dst.ctb_type = dst_type;
+ dst.ctb_dtd = dtd;
+
+ if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
+ errs++; /* increment errs and fail at bottom of case */
+
+ if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
+ dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
+ dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
+ dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
+ } else
+ dtd->dtd_data.ctt_size = (ushort_t)size;
+
+ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
+
+ /*
+ * Make a final pass through the members changing each dmd_type
+ * (a src_fp type) to an equivalent type in dst_fp. We pass
+ * through all members, leaving any that fail set to CTF_ERR.
+ */
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = ctf_list_next(dmd)) {
+ if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
+ dmd->dmd_type)) == CTF_ERR)
+ errs++;
+ }
+
+ if (errs)
+ return (CTF_ERR); /* errno is set for us */
+ break;
+ }
+
+ case CTF_K_ENUM:
+ if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
+ if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
+ ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
+ return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
+ } else {
+ dst_type = ctf_add_enum(dst_fp, flag, name);
+ if ((dst.ctb_type = dst_type) == CTF_ERR ||
+ ctf_enum_iter(src_fp, src_type, enumadd, &dst))
+ return (CTF_ERR); /* errno is set for us */
+ }
+ break;
+
+ case CTF_K_FORWARD:
+ if (dst_type == CTF_ERR) {
+ dst_type = ctf_add_forward(dst_fp,
+ flag, name, CTF_K_STRUCT); /* assume STRUCT */
+ }
+ break;
+
+ case CTF_K_TYPEDEF:
+ src_type = ctf_type_reference(src_fp, src_type);
+ src_type = ctf_add_type(dst_fp, src_fp, src_type);
+
+ if (src_type == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ /*
+ * If dst_type is not CTF_ERR at this point, we should check if
+ * ctf_type_reference(dst_fp, dst_type) != src_type and if so
+ * fail with ECTF_CONFLICT. However, this causes problems with
+ * <sys/types.h> typedefs that vary based on things like if
+ * _ILP32x then pid_t is int otherwise long. We therefore omit
+ * this check and assume that if the identically named typedef
+ * already exists in dst_fp, it is correct or equivalent.
+ */
+ if (dst_type == CTF_ERR) {
+ dst_type = ctf_add_typedef(dst_fp, flag,
+ name, src_type);
+ }
+ break;
+
+ default:
+ return (ctf_set_errno(dst_fp, ECTF_CORRUPT));
+ }
+
+ return (dst_type);
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_decl.c b/cddl/contrib/opensolaris/common/ctf/ctf_decl.c
new file mode 100644
index 0000000..6bf5700
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_decl.c
@@ -0,0 +1,184 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * CTF Declaration Stack
+ *
+ * In order to implement ctf_type_name(), we must convert a type graph back
+ * into a C type declaration. Unfortunately, a type graph represents a storage
+ * class ordering of the type whereas a type declaration must obey the C rules
+ * for operator precedence, and the two orderings are frequently in conflict.
+ * For example, consider these CTF type graphs and their C declarations:
+ *
+ * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
+ * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
+ *
+ * In each case, parentheses are used to raise operator * to higher lexical
+ * precedence, so the string form of the C declaration cannot be constructed by
+ * walking the type graph links and forming the string from left to right.
+ *
+ * The functions in this file build a set of stacks from the type graph nodes
+ * corresponding to the C operator precedence levels in the appropriate order.
+ * The code in ctf_type_name() can then iterate over the levels and nodes in
+ * lexical precedence order and construct the final C declaration string.
+ */
+
+#include <ctf_impl.h>
+
+void
+ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len)
+{
+ int i;
+
+ bzero(cd, sizeof (ctf_decl_t));
+
+ for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
+ cd->cd_order[i] = CTF_PREC_BASE - 1;
+
+ cd->cd_qualp = CTF_PREC_BASE;
+ cd->cd_ordp = CTF_PREC_BASE;
+
+ cd->cd_buf = buf;
+ cd->cd_ptr = buf;
+ cd->cd_end = buf + len;
+}
+
+void
+ctf_decl_fini(ctf_decl_t *cd)
+{
+ ctf_decl_node_t *cdp, *ndp;
+ int i;
+
+ for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) {
+ for (cdp = ctf_list_next(&cd->cd_nodes[i]);
+ cdp != NULL; cdp = ndp) {
+ ndp = ctf_list_next(cdp);
+ ctf_free(cdp, sizeof (ctf_decl_node_t));
+ }
+ }
+}
+
+void
+ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_decl_node_t *cdp;
+ ctf_decl_prec_t prec;
+ uint_t kind, n = 1;
+ int is_qual = 0;
+
+ const ctf_type_t *tp;
+ ctf_arinfo_t ar;
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) {
+ cd->cd_err = fp->ctf_errno;
+ return;
+ }
+
+ switch (kind = LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_ARRAY:
+ (void) ctf_array_info(fp, type, &ar);
+ ctf_decl_push(cd, fp, ar.ctr_contents);
+ n = ar.ctr_nelems;
+ prec = CTF_PREC_ARRAY;
+ break;
+
+ case CTF_K_TYPEDEF:
+ if (ctf_strptr(fp, tp->ctt_name)[0] == '\0') {
+ ctf_decl_push(cd, fp, tp->ctt_type);
+ return;
+ }
+ prec = CTF_PREC_BASE;
+ break;
+
+ case CTF_K_FUNCTION:
+ ctf_decl_push(cd, fp, tp->ctt_type);
+ prec = CTF_PREC_FUNCTION;
+ break;
+
+ case CTF_K_POINTER:
+ ctf_decl_push(cd, fp, tp->ctt_type);
+ prec = CTF_PREC_POINTER;
+ break;
+
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ ctf_decl_push(cd, fp, tp->ctt_type);
+ prec = cd->cd_qualp;
+ is_qual++;
+ break;
+
+ default:
+ prec = CTF_PREC_BASE;
+ }
+
+ if ((cdp = ctf_alloc(sizeof (ctf_decl_node_t))) == NULL) {
+ cd->cd_err = EAGAIN;
+ return;
+ }
+
+ cdp->cd_type = type;
+ cdp->cd_kind = kind;
+ cdp->cd_n = n;
+
+ if (ctf_list_next(&cd->cd_nodes[prec]) == NULL)
+ cd->cd_order[prec] = cd->cd_ordp++;
+
+ /*
+ * Reset cd_qualp to the highest precedence level that we've seen so
+ * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
+ */
+ if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
+ cd->cd_qualp = prec;
+
+ /*
+ * C array declarators are ordered inside out so prepend them. Also by
+ * convention qualifiers of base types precede the type specifier (e.g.
+ * const int vs. int const) even though the two forms are equivalent.
+ */
+ if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
+ ctf_list_prepend(&cd->cd_nodes[prec], cdp);
+ else
+ ctf_list_append(&cd->cd_nodes[prec], cdp);
+}
+
+/*PRINTFLIKE2*/
+void
+ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...)
+{
+ size_t len = (size_t)(cd->cd_end - cd->cd_ptr);
+ va_list ap;
+ size_t n;
+
+ va_start(ap, format);
+ n = vsnprintf(cd->cd_ptr, len, format, ap);
+ va_end(ap);
+
+ cd->cd_ptr += MIN(n, len);
+ cd->cd_len += n;
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_error.c b/cddl/contrib/opensolaris/common/ctf/ctf_error.c
new file mode 100644
index 0000000..888c6c8
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_error.c
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+
+static const char *const _ctf_errlist[] = {
+ "File is not in CTF or ELF format", /* ECTF_FMT */
+ "File uses more recent ELF version than libctf", /* ECTF_ELFVERS */
+ "File uses more recent CTF version than libctf", /* ECTF_CTFVERS */
+ "File is a different endian-ness than libctf", /* ECTF_ENDIAN */
+ "Symbol table uses invalid entry size", /* ECTF_SYMTAB */
+ "Symbol table data buffer is not valid", /* ECTF_SYMBAD */
+ "String table data buffer is not valid", /* ECTF_STRBAD */
+ "File data structure corruption detected", /* ECTF_CORRUPT */
+ "File does not contain CTF data", /* ECTF_NOCTFDATA */
+ "Buffer does not contain CTF data", /* ECTF_NOCTFBUF */
+ "Symbol table information is not available", /* ECTF_NOSYMTAB */
+ "Type information is in parent and unavailable", /* ECTF_NOPARENT */
+ "Cannot import types with different data model", /* ECTF_DMODEL */
+ "Failed to mmap a needed data section", /* ECTF_MMAP */
+ "Decompression package SUNWzlib not installed", /* ECTF_ZMISSING */
+ "Failed to initialize decompression library", /* ECTF_ZINIT */
+ "Failed to allocate decompression buffer", /* ECTF_ZALLOC */
+ "Failed to decompress CTF data", /* ECTF_DECOMPRESS */
+ "External string table is not available", /* ECTF_STRTAB */
+ "String name offset is corrupt", /* ECTF_BADNAME */
+ "Invalid type identifier", /* ECTF_BADID */
+ "Type is not a struct or union", /* ECTF_NOTSOU */
+ "Type is not an enum", /* ECTF_NOTENUM */
+ "Type is not a struct, union, or enum", /* ECTF_NOTSUE */
+ "Type is not an integer or float", /* ECTF_NOTINTFP */
+ "Type is not an array", /* ECTF_NOTARRAY */
+ "Type does not reference another type", /* ECTF_NOTREF */
+ "Input buffer is too small for type name", /* ECTF_NAMELEN */
+ "No type information available for that name", /* ECTF_NOTYPE */
+ "Syntax error in type name", /* ECTF_SYNTAX */
+ "Symbol table entry is not a function", /* ECTF_NOTFUNC */
+ "No function information available for symbol", /* ECTF_NOFUNCDAT */
+ "Symbol table entry is not a data object", /* ECTF_NOTDATA */
+ "No type information available for symbol", /* ECTF_NOTYPEDAT */
+ "No label information available for that name", /* ECTF_NOLABEL */
+ "File does not contain any labels", /* ECTF_NOLABELDATA */
+ "Feature not supported", /* ECTF_NOTSUP */
+ "Invalid enum element name", /* ECTF_NOENUMNAM */
+ "Invalid member name", /* ECTF_NOMEMBNAM */
+ "CTF container is read-only", /* ECTF_RDONLY */
+ "Limit on number of dynamic type members reached", /* ECTF_DTFULL */
+ "Limit on number of dynamic types reached", /* ECTF_FULL */
+ "Duplicate member name definition", /* ECTF_DUPMEMBER */
+ "Conflicting type is already defined", /* ECTF_CONFLICT */
+};
+
+static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]);
+
+const char *
+ctf_errmsg(int error)
+{
+ const char *str;
+
+ if (error >= ECTF_BASE && (error - ECTF_BASE) < _ctf_nerr)
+ str = _ctf_errlist[error - ECTF_BASE];
+ else
+ str = ctf_strerror(error);
+
+ return (str ? str : "Unknown error");
+}
+
+int
+ctf_errno(ctf_file_t *fp)
+{
+ return (fp->ctf_errno);
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_hash.c b/cddl/contrib/opensolaris/common/ctf/ctf_hash.c
new file mode 100644
index 0000000..b10a761
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_hash.c
@@ -0,0 +1,178 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+
+static const ushort_t _CTF_EMPTY[1] = { 0 };
+
+int
+ctf_hash_create(ctf_hash_t *hp, ulong_t nelems)
+{
+ if (nelems > USHRT_MAX)
+ return (EOVERFLOW);
+
+ /*
+ * If the hash table is going to be empty, don't bother allocating any
+ * memory and make the only bucket point to a zero so lookups fail.
+ */
+ if (nelems == 0) {
+ bzero(hp, sizeof (ctf_hash_t));
+ hp->h_buckets = (ushort_t *)_CTF_EMPTY;
+ hp->h_nbuckets = 1;
+ return (0);
+ }
+
+ hp->h_nbuckets = 211; /* use a prime number of hash buckets */
+ hp->h_nelems = nelems + 1; /* we use index zero as a sentinel */
+ hp->h_free = 1; /* first free element is index 1 */
+
+ hp->h_buckets = ctf_alloc(sizeof (ushort_t) * hp->h_nbuckets);
+ hp->h_chains = ctf_alloc(sizeof (ctf_helem_t) * hp->h_nelems);
+
+ if (hp->h_buckets == NULL || hp->h_chains == NULL) {
+ ctf_hash_destroy(hp);
+ return (EAGAIN);
+ }
+
+ bzero(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets);
+ bzero(hp->h_chains, sizeof (ctf_helem_t) * hp->h_nelems);
+
+ return (0);
+}
+
+uint_t
+ctf_hash_size(const ctf_hash_t *hp)
+{
+ return (hp->h_nelems ? hp->h_nelems - 1 : 0);
+}
+
+static ulong_t
+ctf_hash_compute(const char *key, size_t len)
+{
+ ulong_t g, h = 0;
+ const char *p, *q = key + len;
+ size_t n = 0;
+
+ for (p = key; p < q; p++, n++) {
+ h = (h << 4) + *p;
+
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ return (h);
+}
+
+int
+ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
+{
+ ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];
+ const char *str = ctsp->cts_strs + CTF_NAME_OFFSET(name);
+ ctf_helem_t *hep = &hp->h_chains[hp->h_free];
+ ulong_t h;
+
+ if (type == 0)
+ return (EINVAL);
+
+ if (hp->h_free >= hp->h_nelems)
+ return (EOVERFLOW);
+
+ if (ctsp->cts_strs == NULL)
+ return (ECTF_STRTAB);
+
+ if (ctsp->cts_len <= CTF_NAME_OFFSET(name))
+ return (ECTF_BADNAME);
+
+ if (str[0] == '\0')
+ return (0); /* just ignore empty strings on behalf of caller */
+
+ hep->h_name = name;
+ hep->h_type = type;
+ h = ctf_hash_compute(str, strlen(str)) % hp->h_nbuckets;
+ hep->h_next = hp->h_buckets[h];
+ hp->h_buckets[h] = hp->h_free++;
+
+ return (0);
+}
+
+/*
+ * Wrapper for ctf_hash_lookup/ctf_hash_insert: if the key is already in the
+ * hash, override the previous definition with this new official definition.
+ * If the key is not present, then call ctf_hash_insert() and hash it in.
+ */
+int
+ctf_hash_define(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
+{
+ const char *str = ctf_strptr(fp, name);
+ ctf_helem_t *hep = ctf_hash_lookup(hp, fp, str, strlen(str));
+
+ if (hep == NULL)
+ return (ctf_hash_insert(hp, fp, type, name));
+
+ hep->h_type = type;
+ return (0);
+}
+
+ctf_helem_t *
+ctf_hash_lookup(ctf_hash_t *hp, ctf_file_t *fp, const char *key, size_t len)
+{
+ ctf_helem_t *hep;
+ ctf_strs_t *ctsp;
+ const char *str;
+ ushort_t i;
+
+ ulong_t h = ctf_hash_compute(key, len) % hp->h_nbuckets;
+
+ for (i = hp->h_buckets[h]; i != 0; i = hep->h_next) {
+ hep = &hp->h_chains[i];
+ ctsp = &fp->ctf_str[CTF_NAME_STID(hep->h_name)];
+ str = ctsp->cts_strs + CTF_NAME_OFFSET(hep->h_name);
+
+ if (strncmp(key, str, len) == 0 && str[len] == '\0')
+ return (hep);
+ }
+
+ return (NULL);
+}
+
+void
+ctf_hash_destroy(ctf_hash_t *hp)
+{
+ if (hp->h_buckets != NULL && hp->h_nbuckets != 1) {
+ ctf_free(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets);
+ hp->h_buckets = NULL;
+ }
+
+ if (hp->h_chains != NULL) {
+ ctf_free(hp->h_chains, sizeof (ctf_helem_t) * hp->h_nelems);
+ hp->h_chains = NULL;
+ }
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_impl.h b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
new file mode 100644
index 0000000..9999080
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
@@ -0,0 +1,336 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CTF_IMPL_H
+#define _CTF_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/sysmacros.h>
+#include <sys/ctf_api.h>
+
+#ifdef _KERNEL
+
+#include <sys/systm.h>
+#include <sys/cmn_err.h>
+#include <sys/varargs.h>
+
+#define isspace(c) \
+ ((c) == ' ' || (c) == '\t' || (c) == '\n' || \
+ (c) == '\r' || (c) == '\f' || (c) == '\v')
+
+#define MAP_FAILED ((void *)-1)
+
+#else /* _KERNEL */
+
+#include <strings.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <limits.h>
+#include <ctype.h>
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ctf_helem {
+ uint_t h_name; /* reference to name in string table */
+ ushort_t h_type; /* corresponding type ID number */
+ ushort_t h_next; /* index of next element in hash chain */
+} ctf_helem_t;
+
+typedef struct ctf_hash {
+ ushort_t *h_buckets; /* hash bucket array (chain indices) */
+ ctf_helem_t *h_chains; /* hash chains buffer */
+ ushort_t h_nbuckets; /* number of elements in bucket array */
+ ushort_t h_nelems; /* number of elements in hash table */
+ uint_t h_free; /* index of next free hash element */
+} ctf_hash_t;
+
+typedef struct ctf_strs {
+ const char *cts_strs; /* base address of string table */
+ size_t cts_len; /* size of string table in bytes */
+} ctf_strs_t;
+
+typedef struct ctf_dmodel {
+ const char *ctd_name; /* data model name */
+ int ctd_code; /* data model code */
+ size_t ctd_pointer; /* size of void * in bytes */
+ size_t ctd_char; /* size of char in bytes */
+ size_t ctd_short; /* size of short in bytes */
+ size_t ctd_int; /* size of int in bytes */
+ size_t ctd_long; /* size of long in bytes */
+} ctf_dmodel_t;
+
+typedef struct ctf_lookup {
+ const char *ctl_prefix; /* string prefix for this lookup */
+ size_t ctl_len; /* length of prefix string in bytes */
+ ctf_hash_t *ctl_hash; /* pointer to hash table for lookup */
+} ctf_lookup_t;
+
+typedef struct ctf_fileops {
+ ushort_t (*ctfo_get_kind)(ushort_t);
+ ushort_t (*ctfo_get_root)(ushort_t);
+ ushort_t (*ctfo_get_vlen)(ushort_t);
+} ctf_fileops_t;
+
+typedef struct ctf_list {
+ struct ctf_list *l_prev; /* previous pointer or tail pointer */
+ struct ctf_list *l_next; /* next pointer or head pointer */
+} ctf_list_t;
+
+typedef enum {
+ CTF_PREC_BASE,
+ CTF_PREC_POINTER,
+ CTF_PREC_ARRAY,
+ CTF_PREC_FUNCTION,
+ CTF_PREC_MAX
+} ctf_decl_prec_t;
+
+typedef struct ctf_decl_node {
+ ctf_list_t cd_list; /* linked list pointers */
+ ctf_id_t cd_type; /* type identifier */
+ uint_t cd_kind; /* type kind */
+ uint_t cd_n; /* type dimension if array */
+} ctf_decl_node_t;
+
+typedef struct ctf_decl {
+ ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */
+ int cd_order[CTF_PREC_MAX]; /* storage order of decls */
+ ctf_decl_prec_t cd_qualp; /* qualifier precision */
+ ctf_decl_prec_t cd_ordp; /* ordered precision */
+ char *cd_buf; /* buffer for output */
+ char *cd_ptr; /* buffer location */
+ char *cd_end; /* buffer limit */
+ size_t cd_len; /* buffer space required */
+ int cd_err; /* saved error value */
+} ctf_decl_t;
+
+typedef struct ctf_dmdef {
+ ctf_list_t dmd_list; /* list forward/back pointers */
+ char *dmd_name; /* name of this member */
+ ctf_id_t dmd_type; /* type of this member (for sou) */
+ ulong_t dmd_offset; /* offset of this member in bits (for sou) */
+ int dmd_value; /* value of this member (for enum) */
+} ctf_dmdef_t;
+
+typedef struct ctf_dtdef {
+ ctf_list_t dtd_list; /* list forward/back pointers */
+ struct ctf_dtdef *dtd_hash; /* hash chain pointer for ctf_dthash */
+ char *dtd_name; /* name associated with definition (if any) */
+ ctf_id_t dtd_type; /* type identifier for this definition */
+ ctf_type_t dtd_data; /* type node (see <sys/ctf.h>) */
+ union {
+ ctf_list_t dtu_members; /* struct, union, or enum */
+ ctf_arinfo_t dtu_arr; /* array */
+ ctf_encoding_t dtu_enc; /* integer or float */
+ ctf_id_t *dtu_argv; /* function */
+ } dtd_u;
+} ctf_dtdef_t;
+
+typedef struct ctf_bundle {
+ ctf_file_t *ctb_file; /* CTF container handle */
+ ctf_id_t ctb_type; /* CTF type identifier */
+ ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any) */
+} ctf_bundle_t;
+
+/*
+ * The ctf_file is the structure used to represent a CTF container to library
+ * clients, who see it only as an opaque pointer. Modifications can therefore
+ * be made freely to this structure without regard to client versioning. The
+ * ctf_file_t typedef appears in <sys/ctf_api.h> and declares a forward tag.
+ *
+ * NOTE: ctf_update() requires that everything inside of ctf_file either be an
+ * immediate value, a pointer to dynamically allocated data *outside* of the
+ * ctf_file itself, or a pointer to statically allocated data. If you add a
+ * pointer to ctf_file that points to something within the ctf_file itself,
+ * you must make corresponding changes to ctf_update().
+ */
+struct ctf_file {
+ const ctf_fileops_t *ctf_fileops; /* version-specific file operations */
+ ctf_sect_t ctf_data; /* CTF data from object file */
+ ctf_sect_t ctf_symtab; /* symbol table from object file */
+ ctf_sect_t ctf_strtab; /* string table from object file */
+ ctf_hash_t ctf_structs; /* hash table of struct types */
+ ctf_hash_t ctf_unions; /* hash table of union types */
+ ctf_hash_t ctf_enums; /* hash table of enum types */
+ ctf_hash_t ctf_names; /* hash table of remaining type names */
+ ctf_lookup_t ctf_lookups[5]; /* pointers to hashes for name lookup */
+ ctf_strs_t ctf_str[2]; /* array of string table base and bounds */
+ const uchar_t *ctf_base; /* base of CTF header + uncompressed buffer */
+ const uchar_t *ctf_buf; /* uncompressed CTF data buffer */
+ size_t ctf_size; /* size of CTF header + uncompressed data */
+ uint_t *ctf_sxlate; /* translation table for symtab entries */
+ ulong_t ctf_nsyms; /* number of entries in symtab xlate table */
+ uint_t *ctf_txlate; /* translation table for type IDs */
+ ushort_t *ctf_ptrtab; /* translation table for pointer-to lookups */
+ ulong_t ctf_typemax; /* maximum valid type ID number */
+ const ctf_dmodel_t *ctf_dmodel; /* data model pointer (see above) */
+ struct ctf_file *ctf_parent; /* parent CTF container (if any) */
+ const char *ctf_parlabel; /* label in parent container (if any) */
+ const char *ctf_parname; /* basename of parent (if any) */
+ uint_t ctf_refcnt; /* reference count (for parent links) */
+ uint_t ctf_flags; /* libctf flags (see below) */
+ int ctf_errno; /* error code for most recent error */
+ int ctf_version; /* CTF data version */
+ ctf_dtdef_t **ctf_dthash; /* hash of dynamic type definitions */
+ ulong_t ctf_dthashlen; /* size of dynamic type hash bucket array */
+ ctf_list_t ctf_dtdefs; /* list of dynamic type definitions */
+ size_t ctf_dtstrlen; /* total length of dynamic type strings */
+ ulong_t ctf_dtnextid; /* next dynamic type id to assign */
+ ulong_t ctf_dtoldid; /* oldest id that has been committed */
+ void *ctf_specific; /* data for ctf_get/setspecific */
+};
+
+#define LCTF_INDEX_TO_TYPEPTR(fp, i) \
+ ((ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)]))
+
+#define LCTF_INFO_KIND(fp, info) ((fp)->ctf_fileops->ctfo_get_kind(info))
+#define LCTF_INFO_ROOT(fp, info) ((fp)->ctf_fileops->ctfo_get_root(info))
+#define LCTF_INFO_VLEN(fp, info) ((fp)->ctf_fileops->ctfo_get_vlen(info))
+
+#define LCTF_MMAP 0x0001 /* libctf should munmap buffers on close */
+#define LCTF_CHILD 0x0002 /* CTF container is a child */
+#define LCTF_RDWR 0x0004 /* CTF container is writable */
+#define LCTF_DIRTY 0x0008 /* CTF container has been modified */
+
+#define ECTF_BASE 1000 /* base value for libctf errnos */
+
+enum {
+ ECTF_FMT = ECTF_BASE, /* file is not in CTF or ELF format */
+ ECTF_ELFVERS, /* ELF version is more recent than libctf */
+ ECTF_CTFVERS, /* CTF version is more recent than libctf */
+ ECTF_ENDIAN, /* data is different endian-ness than lib */
+ ECTF_SYMTAB, /* symbol table uses invalid entry size */
+ ECTF_SYMBAD, /* symbol table data buffer invalid */
+ ECTF_STRBAD, /* string table data buffer invalid */
+ ECTF_CORRUPT, /* file data corruption detected */
+ ECTF_NOCTFDATA, /* ELF file does not contain CTF data */
+ ECTF_NOCTFBUF, /* buffer does not contain CTF data */
+ ECTF_NOSYMTAB, /* symbol table data is not available */
+ ECTF_NOPARENT, /* parent CTF container is not available */
+ ECTF_DMODEL, /* data model mismatch */
+ ECTF_MMAP, /* failed to mmap a data section */
+ ECTF_ZMISSING, /* decompression library not installed */
+ ECTF_ZINIT, /* failed to initialize decompression library */
+ ECTF_ZALLOC, /* failed to allocate decompression buffer */
+ ECTF_DECOMPRESS, /* failed to decompress CTF data */
+ ECTF_STRTAB, /* string table for this string is missing */
+ ECTF_BADNAME, /* string offset is corrupt w.r.t. strtab */
+ ECTF_BADID, /* invalid type ID number */
+ ECTF_NOTSOU, /* type is not a struct or union */
+ ECTF_NOTENUM, /* type is not an enum */
+ ECTF_NOTSUE, /* type is not a struct, union, or enum */
+ ECTF_NOTINTFP, /* type is not an integer or float */
+ ECTF_NOTARRAY, /* type is not an array */
+ ECTF_NOTREF, /* type does not reference another type */
+ ECTF_NAMELEN, /* buffer is too small to hold type name */
+ ECTF_NOTYPE, /* no type found corresponding to name */
+ ECTF_SYNTAX, /* syntax error in type name */
+ ECTF_NOTFUNC, /* symtab entry does not refer to a function */
+ ECTF_NOFUNCDAT, /* no func info available for function */
+ ECTF_NOTDATA, /* symtab entry does not refer to a data obj */
+ ECTF_NOTYPEDAT, /* no type info available for object */
+ ECTF_NOLABEL, /* no label found corresponding to name */
+ ECTF_NOLABELDATA, /* file does not contain any labels */
+ ECTF_NOTSUP, /* feature not supported */
+ ECTF_NOENUMNAM, /* enum element name not found */
+ ECTF_NOMEMBNAM, /* member name not found */
+ ECTF_RDONLY, /* CTF container is read-only */
+ ECTF_DTFULL, /* CTF type is full (no more members allowed) */
+ ECTF_FULL, /* CTF container is full */
+ ECTF_DUPMEMBER, /* duplicate member name definition */
+ ECTF_CONFLICT /* conflicting type definition present */
+};
+
+extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,
+ ssize_t *, ssize_t *);
+
+extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);
+
+extern int ctf_hash_create(ctf_hash_t *, ulong_t);
+extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
+extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
+extern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *,
+ const char *, size_t);
+extern uint_t ctf_hash_size(const ctf_hash_t *);
+extern void ctf_hash_destroy(ctf_hash_t *);
+
+#define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
+#define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
+
+extern void ctf_list_append(ctf_list_t *, void *);
+extern void ctf_list_prepend(ctf_list_t *, void *);
+extern void ctf_list_delete(ctf_list_t *, void *);
+
+extern void ctf_dtd_insert(ctf_file_t *, ctf_dtdef_t *);
+extern void ctf_dtd_delete(ctf_file_t *, ctf_dtdef_t *);
+extern ctf_dtdef_t *ctf_dtd_lookup(ctf_file_t *, ctf_id_t);
+
+extern void ctf_decl_init(ctf_decl_t *, char *, size_t);
+extern void ctf_decl_fini(ctf_decl_t *);
+extern void ctf_decl_push(ctf_decl_t *, ctf_file_t *, ctf_id_t);
+extern void ctf_decl_sprintf(ctf_decl_t *, const char *, ...);
+
+extern const char *ctf_strraw(ctf_file_t *, uint_t);
+extern const char *ctf_strptr(ctf_file_t *, uint_t);
+
+extern ctf_file_t *ctf_set_open_errno(int *, int);
+extern long ctf_set_errno(ctf_file_t *, int);
+
+extern const void *ctf_sect_mmap(ctf_sect_t *, int);
+extern void ctf_sect_munmap(const ctf_sect_t *);
+
+extern void *ctf_data_alloc(size_t);
+extern void ctf_data_free(void *, size_t);
+extern void ctf_data_protect(void *, size_t);
+
+extern void *ctf_alloc(size_t);
+extern void ctf_free(void *, size_t);
+
+extern char *ctf_strdup(const char *);
+extern const char *ctf_strerror(int);
+extern void ctf_dprintf(const char *, ...);
+
+extern void *ctf_zopen(int *);
+
+extern const char _CTF_SECTION[]; /* name of CTF ELF section */
+extern const char _CTF_NULLSTR[]; /* empty string */
+
+extern int _libctf_version; /* library client version */
+extern int _libctf_debug; /* debugging messages enabled */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CTF_IMPL_H */
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_labels.c b/cddl/contrib/opensolaris/common/ctf/ctf_labels.c
new file mode 100644
index 0000000..ddcb1d3
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_labels.c
@@ -0,0 +1,153 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+
+static int
+extract_label_info(ctf_file_t *fp, const ctf_lblent_t **ctl, uint_t *num_labels)
+{
+ const ctf_header_t *h;
+
+ /*
+ * Labels are only supported in V2 or later
+ */
+ if (fp->ctf_version < CTF_VERSION_2)
+ return (ctf_set_errno(fp, ECTF_NOTSUP));
+
+ h = (const ctf_header_t *)fp->ctf_data.cts_data;
+
+ /* LINTED - pointer alignment */
+ *ctl = (const ctf_lblent_t *)(fp->ctf_buf + h->cth_lbloff);
+ *num_labels = (h->cth_objtoff - h->cth_lbloff) / sizeof (ctf_lblent_t);
+
+ return (0);
+}
+
+/*
+ * Returns the topmost label, or NULL if any errors are encountered
+ */
+const char *
+ctf_label_topmost(ctf_file_t *fp)
+{
+ const ctf_lblent_t *ctlp;
+ const char *s;
+ uint_t num_labels;
+
+ if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)
+ return (NULL); /* errno is set */
+
+ if (num_labels == 0) {
+ (void) ctf_set_errno(fp, ECTF_NOLABELDATA);
+ return (NULL);
+ }
+
+ if ((s = ctf_strraw(fp, (ctlp + num_labels - 1)->ctl_label)) == NULL)
+ (void) ctf_set_errno(fp, ECTF_CORRUPT);
+
+ return (s);
+}
+
+/*
+ * Iterate over all labels. We pass the label string and the lblinfo_t struct
+ * to the specified callback function.
+ */
+int
+ctf_label_iter(ctf_file_t *fp, ctf_label_f *func, void *arg)
+{
+ const ctf_lblent_t *ctlp;
+ uint_t i, num_labels;
+ ctf_lblinfo_t linfo;
+ const char *lname;
+ int rc;
+
+ if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)
+ return (CTF_ERR); /* errno is set */
+
+ if (num_labels == 0)
+ return (ctf_set_errno(fp, ECTF_NOLABELDATA));
+
+ for (i = 0; i < num_labels; i++, ctlp++) {
+ if ((lname = ctf_strraw(fp, ctlp->ctl_label)) == NULL) {
+ ctf_dprintf("failed to decode label %u with "
+ "typeidx %u\n", ctlp->ctl_label, ctlp->ctl_typeidx);
+ return (ctf_set_errno(fp, ECTF_CORRUPT));
+ }
+
+ linfo.ctb_typeidx = ctlp->ctl_typeidx;
+ if ((rc = func(lname, &linfo, arg)) != 0)
+ return (rc);
+ }
+
+ return (0);
+}
+
+typedef struct linfo_cb_arg {
+ const char *lca_name; /* Label we want to retrieve info for */
+ ctf_lblinfo_t *lca_info; /* Where to store the info about the label */
+} linfo_cb_arg_t;
+
+static int
+label_info_cb(const char *lname, const ctf_lblinfo_t *linfo, void *arg)
+{
+ /*
+ * If lname matches the label we are looking for, copy the
+ * lblinfo_t struct for the caller.
+ */
+ if (strcmp(lname, ((linfo_cb_arg_t *)arg)->lca_name) == 0) {
+ /*
+ * Allow caller not to allocate storage to test if label exists
+ */
+ if (((linfo_cb_arg_t *)arg)->lca_info != NULL)
+ bcopy(linfo, ((linfo_cb_arg_t *)arg)->lca_info,
+ sizeof (ctf_lblinfo_t));
+ return (1); /* Indicate we found a match */
+ }
+
+ return (0);
+}
+
+/*
+ * Retrieve information about the label with name "lname"
+ */
+int
+ctf_label_info(ctf_file_t *fp, const char *lname, ctf_lblinfo_t *linfo)
+{
+ linfo_cb_arg_t cb_arg;
+ int rc;
+
+ cb_arg.lca_name = lname;
+ cb_arg.lca_info = linfo;
+
+ if ((rc = ctf_label_iter(fp, label_info_cb, &cb_arg)) == CTF_ERR)
+ return (rc);
+
+ if (rc != 1)
+ return (ctf_set_errno(fp, ECTF_NOLABEL));
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c b/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c
new file mode 100644
index 0000000..f8fa724
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_lookup.c
@@ -0,0 +1,313 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sysmacros.h>
+#include <ctf_impl.h>
+
+/*
+ * Compare the given input string and length against a table of known C storage
+ * qualifier keywords. We just ignore these in ctf_lookup_by_name, below. To
+ * do this quickly, we use a pre-computed Perfect Hash Function similar to the
+ * technique originally described in the classic paper:
+ *
+ * R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
+ * Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.
+ *
+ * For an input string S of length N, we use hash H = S[N - 1] + N - 105, which
+ * for the current set of qualifiers yields a unique H in the range [0 .. 20].
+ * The hash can be modified when the keyword set changes as necessary. We also
+ * store the length of each keyword and check it prior to the final strcmp().
+ */
+static int
+isqualifier(const char *s, size_t len)
+{
+ static const struct qual {
+ const char *q_name;
+ size_t q_len;
+ } qhash[] = {
+ { "static", 6 }, { "", 0 }, { "", 0 }, { "", 0 },
+ { "volatile", 8 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 },
+ { "", 0 }, { "auto", 4 }, { "extern", 6 }, { "", 0 }, { "", 0 },
+ { "", 0 }, { "", 0 }, { "const", 5 }, { "register", 8 },
+ { "", 0 }, { "restrict", 8 }, { "_Restrict", 9 }
+ };
+
+ int h = s[len - 1] + (int)len - 105;
+ const struct qual *qp = &qhash[h];
+
+ return (h >= 0 && h < sizeof (qhash) / sizeof (qhash[0]) &&
+ len == qp->q_len && strncmp(qp->q_name, s, qp->q_len) == 0);
+}
+
+/*
+ * Attempt to convert the given C type name into the corresponding CTF type ID.
+ * It is not possible to do complete and proper conversion of type names
+ * without implementing a more full-fledged parser, which is necessary to
+ * handle things like types that are function pointers to functions that
+ * have arguments that are function pointers, and fun stuff like that.
+ * Instead, this function implements a very simple conversion algorithm that
+ * finds the things that we actually care about: structs, unions, enums,
+ * integers, floats, typedefs, and pointers to any of these named types.
+ */
+ctf_id_t
+ctf_lookup_by_name(ctf_file_t *fp, const char *name)
+{
+ static const char delimiters[] = " \t\n\r\v\f*";
+
+ const ctf_lookup_t *lp;
+ const ctf_helem_t *hp;
+ const char *p, *q, *end;
+ ctf_id_t type = 0;
+ ctf_id_t ntype, ptype;
+
+ if (name == NULL)
+ return (ctf_set_errno(fp, EINVAL));
+
+ for (p = name, end = name + strlen(name); *p != '\0'; p = q) {
+ while (isspace(*p))
+ p++; /* skip leading ws */
+
+ if (p == end)
+ break;
+
+ if ((q = strpbrk(p + 1, delimiters)) == NULL)
+ q = end; /* compare until end */
+
+ if (*p == '*') {
+ /*
+ * Find a pointer to type by looking in fp->ctf_ptrtab.
+ * If we can't find a pointer to the given type, see if
+ * we can compute a pointer to the type resulting from
+ * resolving the type down to its base type and use
+ * that instead. This helps with cases where the CTF
+ * data includes "struct foo *" but not "foo_t *" and
+ * the user tries to access "foo_t *" in the debugger.
+ */
+ ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)];
+ if (ntype == 0) {
+ ntype = ctf_type_resolve(fp, type);
+ if (ntype == CTF_ERR || (ntype = fp->ctf_ptrtab[
+ CTF_TYPE_TO_INDEX(ntype)]) == 0) {
+ (void) ctf_set_errno(fp, ECTF_NOTYPE);
+ goto err;
+ }
+ }
+
+ type = CTF_INDEX_TO_TYPE(ntype,
+ (fp->ctf_flags & LCTF_CHILD));
+
+ q = p + 1;
+ continue;
+ }
+
+ if (isqualifier(p, (size_t)(q - p)))
+ continue; /* skip qualifier keyword */
+
+ for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++) {
+ if (lp->ctl_prefix[0] == '\0' ||
+ strncmp(p, lp->ctl_prefix, (size_t)(q - p)) == 0) {
+ for (p += lp->ctl_len; isspace(*p); p++)
+ continue; /* skip prefix and next ws */
+
+ if ((q = strchr(p, '*')) == NULL)
+ q = end; /* compare until end */
+
+ while (isspace(q[-1]))
+ q--; /* exclude trailing ws */
+
+ if ((hp = ctf_hash_lookup(lp->ctl_hash, fp, p,
+ (size_t)(q - p))) == NULL) {
+ (void) ctf_set_errno(fp, ECTF_NOTYPE);
+ goto err;
+ }
+
+ type = hp->h_type;
+ break;
+ }
+ }
+
+ if (lp->ctl_prefix == NULL) {
+ (void) ctf_set_errno(fp, ECTF_NOTYPE);
+ goto err;
+ }
+ }
+
+ if (*p != '\0' || type == 0)
+ return (ctf_set_errno(fp, ECTF_SYNTAX));
+
+ return (type);
+
+err:
+ if (fp->ctf_parent != NULL &&
+ (ptype = ctf_lookup_by_name(fp->ctf_parent, name)) != CTF_ERR)
+ return (ptype);
+
+ return (CTF_ERR);
+}
+
+/*
+ * Given a symbol table index, return the type of the data object described
+ * by the corresponding entry in the symbol table.
+ */
+ctf_id_t
+ctf_lookup_by_symbol(ctf_file_t *fp, ulong_t symidx)
+{
+ const ctf_sect_t *sp = &fp->ctf_symtab;
+ ctf_id_t type;
+
+ if (sp->cts_data == NULL)
+ return (ctf_set_errno(fp, ECTF_NOSYMTAB));
+
+ if (symidx >= fp->ctf_nsyms)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if (sp->cts_entsize == sizeof (Elf32_Sym)) {
+ const Elf32_Sym *symp = (Elf32_Sym *)sp->cts_data + symidx;
+ if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT)
+ return (ctf_set_errno(fp, ECTF_NOTDATA));
+ } else {
+ const Elf64_Sym *symp = (Elf64_Sym *)sp->cts_data + symidx;
+ if (ELF64_ST_TYPE(symp->st_info) != STT_OBJECT)
+ return (ctf_set_errno(fp, ECTF_NOTDATA));
+ }
+
+ if (fp->ctf_sxlate[symidx] == -1u)
+ return (ctf_set_errno(fp, ECTF_NOTYPEDAT));
+
+ type = *(ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
+ if (type == 0)
+ return (ctf_set_errno(fp, ECTF_NOTYPEDAT));
+
+ return (type);
+}
+
+/*
+ * Return the pointer to the internal CTF type data corresponding to the
+ * given type ID. If the ID is invalid, the function returns NULL.
+ * This function is not exported outside of the library.
+ */
+const ctf_type_t *
+ctf_lookup_by_id(ctf_file_t **fpp, ctf_id_t type)
+{
+ ctf_file_t *fp = *fpp; /* caller passes in starting CTF container */
+
+ if ((fp->ctf_flags & LCTF_CHILD) && CTF_TYPE_ISPARENT(type) &&
+ (fp = fp->ctf_parent) == NULL) {
+ (void) ctf_set_errno(*fpp, ECTF_NOPARENT);
+ return (NULL);
+ }
+
+ type = CTF_TYPE_TO_INDEX(type);
+ if (type > 0 && type <= fp->ctf_typemax) {
+ *fpp = fp; /* function returns ending CTF container */
+ return (LCTF_INDEX_TO_TYPEPTR(fp, type));
+ }
+
+ (void) ctf_set_errno(fp, ECTF_BADID);
+ return (NULL);
+}
+
+/*
+ * Given a symbol table index, return the info for the function described
+ * by the corresponding entry in the symbol table.
+ */
+int
+ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip)
+{
+ const ctf_sect_t *sp = &fp->ctf_symtab;
+ const ushort_t *dp;
+ ushort_t info, kind, n;
+
+ if (sp->cts_data == NULL)
+ return (ctf_set_errno(fp, ECTF_NOSYMTAB));
+
+ if (symidx >= fp->ctf_nsyms)
+ return (ctf_set_errno(fp, EINVAL));
+
+ if (sp->cts_entsize == sizeof (Elf32_Sym)) {
+ const Elf32_Sym *symp = (Elf32_Sym *)sp->cts_data + symidx;
+ if (ELF32_ST_TYPE(symp->st_info) != STT_FUNC)
+ return (ctf_set_errno(fp, ECTF_NOTFUNC));
+ } else {
+ const Elf64_Sym *symp = (Elf64_Sym *)sp->cts_data + symidx;
+ if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC)
+ return (ctf_set_errno(fp, ECTF_NOTFUNC));
+ }
+
+ if (fp->ctf_sxlate[symidx] == -1u)
+ return (ctf_set_errno(fp, ECTF_NOFUNCDAT));
+
+ dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
+
+ info = *dp++;
+ kind = LCTF_INFO_KIND(fp, info);
+ n = LCTF_INFO_VLEN(fp, info);
+
+ if (kind == CTF_K_UNKNOWN && n == 0)
+ return (ctf_set_errno(fp, ECTF_NOFUNCDAT));
+
+ if (kind != CTF_K_FUNCTION)
+ return (ctf_set_errno(fp, ECTF_CORRUPT));
+
+ fip->ctc_return = *dp++;
+ fip->ctc_argc = n;
+ fip->ctc_flags = 0;
+
+ if (n != 0 && dp[n - 1] == 0) {
+ fip->ctc_flags |= CTF_FUNC_VARARG;
+ fip->ctc_argc--;
+ }
+
+ return (0);
+}
+
+/*
+ * Given a symbol table index, return the arguments for the function described
+ * by the corresponding entry in the symbol table.
+ */
+int
+ctf_func_args(ctf_file_t *fp, ulong_t symidx, uint_t argc, ctf_id_t *argv)
+{
+ const ushort_t *dp;
+ ctf_funcinfo_t f;
+
+ if (ctf_func_info(fp, symidx, &f) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ /*
+ * The argument data is two ushort_t's past the translation table
+ * offset: one for the function info, and one for the return type.
+ */
+ dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]) + 2;
+
+ for (argc = MIN(argc, f.ctc_argc); argc != 0; argc--)
+ *argv++ = *dp++;
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_open.c b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
new file mode 100644
index 0000000..e49a4cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
@@ -0,0 +1,954 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+#include <sys/mman.h>
+#include <sys/zmod.h>
+
+static const ctf_dmodel_t _libctf_models[] = {
+ { "ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4 },
+ { "LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8 },
+ { NULL, 0, 0, 0, 0, 0, 0 }
+};
+
+const char _CTF_SECTION[] = ".SUNW_ctf";
+const char _CTF_NULLSTR[] = "";
+
+int _libctf_version = CTF_VERSION; /* library client version */
+int _libctf_debug = 0; /* debugging messages enabled */
+
+static ushort_t
+get_kind_v1(ushort_t info)
+{
+ return (CTF_INFO_KIND_V1(info));
+}
+
+static ushort_t
+get_kind_v2(ushort_t info)
+{
+ return (CTF_INFO_KIND(info));
+}
+
+static ushort_t
+get_root_v1(ushort_t info)
+{
+ return (CTF_INFO_ISROOT_V1(info));
+}
+
+static ushort_t
+get_root_v2(ushort_t info)
+{
+ return (CTF_INFO_ISROOT(info));
+}
+
+static ushort_t
+get_vlen_v1(ushort_t info)
+{
+ return (CTF_INFO_VLEN_V1(info));
+}
+
+static ushort_t
+get_vlen_v2(ushort_t info)
+{
+ return (CTF_INFO_VLEN(info));
+}
+
+static const ctf_fileops_t ctf_fileops[] = {
+ { NULL, NULL },
+ { get_kind_v1, get_root_v1, get_vlen_v1 },
+ { get_kind_v2, get_root_v2, get_vlen_v2 },
+};
+
+/*
+ * Convert a 32-bit ELF symbol into GElf (Elf64) and return a pointer to it.
+ */
+static Elf64_Sym *
+sym_to_gelf(const Elf32_Sym *src, Elf64_Sym *dst)
+{
+ dst->st_name = src->st_name;
+ dst->st_value = src->st_value;
+ dst->st_size = src->st_size;
+ dst->st_info = src->st_info;
+ dst->st_other = src->st_other;
+ dst->st_shndx = src->st_shndx;
+
+ return (dst);
+}
+
+/*
+ * Initialize the symtab translation table by filling each entry with the
+ * offset of the CTF type or function data corresponding to each STT_FUNC or
+ * STT_OBJECT entry in the symbol table.
+ */
+static int
+init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
+ const ctf_sect_t *sp, const ctf_sect_t *strp)
+{
+ const uchar_t *symp = sp->cts_data;
+ uint_t *xp = fp->ctf_sxlate;
+ uint_t *xend = xp + fp->ctf_nsyms;
+
+ uint_t objtoff = hp->cth_objtoff;
+ uint_t funcoff = hp->cth_funcoff;
+
+ ushort_t info, vlen;
+ Elf64_Sym sym, *gsp;
+ const char *name;
+
+ /*
+ * The CTF data object and function type sections are ordered to match
+ * the relative order of the respective symbol types in the symtab.
+ * If no type information is available for a symbol table entry, a
+ * pad is inserted in the CTF section. As a further optimization,
+ * anonymous or undefined symbols are omitted from the CTF data.
+ */
+ for (; xp < xend; xp++, symp += sp->cts_entsize) {
+ if (sp->cts_entsize == sizeof (Elf32_Sym))
+ gsp = sym_to_gelf((Elf32_Sym *)(uintptr_t)symp, &sym);
+ else
+ gsp = (Elf64_Sym *)(uintptr_t)symp;
+
+ if (gsp->st_name < strp->cts_size)
+ name = (const char *)strp->cts_data + gsp->st_name;
+ else
+ name = _CTF_NULLSTR;
+
+ if (gsp->st_name == 0 || gsp->st_shndx == SHN_UNDEF ||
+ strcmp(name, "_START_") == 0 ||
+ strcmp(name, "_END_") == 0) {
+ *xp = -1u;
+ continue;
+ }
+
+ switch (ELF64_ST_TYPE(gsp->st_info)) {
+ case STT_OBJECT:
+ if (objtoff >= hp->cth_funcoff ||
+ (gsp->st_shndx == SHN_ABS && gsp->st_value == 0)) {
+ *xp = -1u;
+ break;
+ }
+
+ *xp = objtoff;
+ objtoff += sizeof (ushort_t);
+ break;
+
+ case STT_FUNC:
+ if (funcoff >= hp->cth_typeoff) {
+ *xp = -1u;
+ break;
+ }
+
+ *xp = funcoff;
+
+ info = *(ushort_t *)((uintptr_t)fp->ctf_buf + funcoff);
+ vlen = LCTF_INFO_VLEN(fp, info);
+
+ /*
+ * If we encounter a zero pad at the end, just skip it.
+ * Otherwise skip over the function and its return type
+ * (+2) and the argument list (vlen).
+ */
+ if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN &&
+ vlen == 0)
+ funcoff += sizeof (ushort_t); /* skip pad */
+ else
+ funcoff += sizeof (ushort_t) * (vlen + 2);
+ break;
+
+ default:
+ *xp = -1u;
+ break;
+ }
+ }
+
+ ctf_dprintf("loaded %lu symtab entries\n", fp->ctf_nsyms);
+ return (0);
+}
+
+/*
+ * Initialize the type ID translation table with the byte offset of each type,
+ * and initialize the hash tables of each named type.
+ */
+static int
+init_types(ctf_file_t *fp, const ctf_header_t *cth)
+{
+ /* LINTED - pointer alignment */
+ const ctf_type_t *tbuf = (ctf_type_t *)(fp->ctf_buf + cth->cth_typeoff);
+ /* LINTED - pointer alignment */
+ const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff);
+
+ ulong_t pop[CTF_K_MAX + 1] = { 0 };
+ const ctf_type_t *tp;
+ ctf_hash_t *hp;
+ ushort_t id, dst;
+ uint_t *xp;
+
+ /*
+ * We initially determine whether the container is a child or a parent
+ * based on the value of cth_parname. To support containers that pre-
+ * date cth_parname, we also scan the types themselves for references
+ * to values in the range reserved for child types in our first pass.
+ */
+ int child = cth->cth_parname != 0;
+ int nlstructs = 0, nlunions = 0;
+ int err;
+
+ /*
+ * We make two passes through the entire type section. In this first
+ * pass, we count the number of each type and the total number of types.
+ */
+ for (tp = tbuf; tp < tend; fp->ctf_typemax++) {
+ ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
+ ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
+ ssize_t size, increment;
+
+ size_t vbytes;
+ uint_t n;
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ vbytes = sizeof (uint_t);
+ break;
+ case CTF_K_ARRAY:
+ vbytes = sizeof (ctf_array_t);
+ break;
+ case CTF_K_FUNCTION:
+ vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+ break;
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (fp->ctf_version == CTF_VERSION_1 ||
+ size < CTF_LSTRUCT_THRESH) {
+ ctf_member_t *mp = (ctf_member_t *)
+ ((uintptr_t)tp + increment);
+
+ vbytes = sizeof (ctf_member_t) * vlen;
+ for (n = vlen; n != 0; n--, mp++)
+ child |= CTF_TYPE_ISCHILD(mp->ctm_type);
+ } else {
+ ctf_lmember_t *lmp = (ctf_lmember_t *)
+ ((uintptr_t)tp + increment);
+
+ vbytes = sizeof (ctf_lmember_t) * vlen;
+ for (n = vlen; n != 0; n--, lmp++)
+ child |=
+ CTF_TYPE_ISCHILD(lmp->ctlm_type);
+ }
+ break;
+ case CTF_K_ENUM:
+ vbytes = sizeof (ctf_enum_t) * vlen;
+ break;
+ case CTF_K_FORWARD:
+ /*
+ * For forward declarations, ctt_type is the CTF_K_*
+ * kind for the tag, so bump that population count too.
+ * If ctt_type is unknown, treat the tag as a struct.
+ */
+ if (tp->ctt_type == CTF_K_UNKNOWN ||
+ tp->ctt_type >= CTF_K_MAX)
+ pop[CTF_K_STRUCT]++;
+ else
+ pop[tp->ctt_type]++;
+ /*FALLTHRU*/
+ case CTF_K_UNKNOWN:
+ vbytes = 0;
+ break;
+ case CTF_K_POINTER:
+ case CTF_K_TYPEDEF:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ child |= CTF_TYPE_ISCHILD(tp->ctt_type);
+ vbytes = 0;
+ break;
+ default:
+ ctf_dprintf("detected invalid CTF kind -- %u\n", kind);
+ return (ECTF_CORRUPT);
+ }
+ tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+ pop[kind]++;
+ }
+
+ /*
+ * If we detected a reference to a child type ID, then we know this
+ * container is a child and may have a parent's types imported later.
+ */
+ if (child) {
+ ctf_dprintf("CTF container %p is a child\n", (void *)fp);
+ fp->ctf_flags |= LCTF_CHILD;
+ } else
+ ctf_dprintf("CTF container %p is a parent\n", (void *)fp);
+
+ /*
+ * Now that we've counted up the number of each type, we can allocate
+ * the hash tables, type translation table, and pointer table.
+ */
+ if ((err = ctf_hash_create(&fp->ctf_structs, pop[CTF_K_STRUCT])) != 0)
+ return (err);
+
+ if ((err = ctf_hash_create(&fp->ctf_unions, pop[CTF_K_UNION])) != 0)
+ return (err);
+
+ if ((err = ctf_hash_create(&fp->ctf_enums, pop[CTF_K_ENUM])) != 0)
+ return (err);
+
+ if ((err = ctf_hash_create(&fp->ctf_names,
+ pop[CTF_K_INTEGER] + pop[CTF_K_FLOAT] + pop[CTF_K_FUNCTION] +
+ pop[CTF_K_TYPEDEF] + pop[CTF_K_POINTER] + pop[CTF_K_VOLATILE] +
+ pop[CTF_K_CONST] + pop[CTF_K_RESTRICT])) != 0)
+ return (err);
+
+ fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));
+ fp->ctf_ptrtab = ctf_alloc(sizeof (ushort_t) * (fp->ctf_typemax + 1));
+
+ if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
+ return (EAGAIN); /* memory allocation failed */
+
+ xp = fp->ctf_txlate;
+ *xp++ = 0; /* type id 0 is used as a sentinel value */
+
+ bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1));
+ bzero(fp->ctf_ptrtab, sizeof (ushort_t) * (fp->ctf_typemax + 1));
+
+ /*
+ * In the second pass through the types, we fill in each entry of the
+ * type and pointer tables and add names to the appropriate hashes.
+ */
+ for (id = 1, tp = tbuf; tp < tend; xp++, id++) {
+ ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
+ ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
+ ssize_t size, increment;
+
+ const char *name;
+ size_t vbytes;
+ ctf_helem_t *hep;
+ ctf_encoding_t cte;
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+ name = ctf_strptr(fp, tp->ctt_name);
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ /*
+ * Only insert a new integer base type definition if
+ * this type name has not been defined yet. We re-use
+ * the names with different encodings for bit-fields.
+ */
+ if ((hep = ctf_hash_lookup(&fp->ctf_names, fp,
+ name, strlen(name))) == NULL) {
+ err = ctf_hash_insert(&fp->ctf_names, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+ } else if (ctf_type_encoding(fp, hep->h_type,
+ &cte) == 0 && cte.cte_bits == 0) {
+ /*
+ * Work-around SOS8 stabs bug: replace existing
+ * intrinsic w/ same name if it was zero bits.
+ */
+ hep->h_type = CTF_INDEX_TO_TYPE(id, child);
+ }
+ vbytes = sizeof (uint_t);
+ break;
+
+ case CTF_K_ARRAY:
+ vbytes = sizeof (ctf_array_t);
+ break;
+
+ case CTF_K_FUNCTION:
+ err = ctf_hash_insert(&fp->ctf_names, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+ vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+ break;
+
+ case CTF_K_STRUCT:
+ err = ctf_hash_define(&fp->ctf_structs, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+
+ if (fp->ctf_version == CTF_VERSION_1 ||
+ size < CTF_LSTRUCT_THRESH)
+ vbytes = sizeof (ctf_member_t) * vlen;
+ else {
+ vbytes = sizeof (ctf_lmember_t) * vlen;
+ nlstructs++;
+ }
+ break;
+
+ case CTF_K_UNION:
+ err = ctf_hash_define(&fp->ctf_unions, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+
+ if (fp->ctf_version == CTF_VERSION_1 ||
+ size < CTF_LSTRUCT_THRESH)
+ vbytes = sizeof (ctf_member_t) * vlen;
+ else {
+ vbytes = sizeof (ctf_lmember_t) * vlen;
+ nlunions++;
+ }
+ break;
+
+ case CTF_K_ENUM:
+ err = ctf_hash_define(&fp->ctf_enums, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+
+ vbytes = sizeof (ctf_enum_t) * vlen;
+ break;
+
+ case CTF_K_TYPEDEF:
+ err = ctf_hash_insert(&fp->ctf_names, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+ vbytes = 0;
+ break;
+
+ case CTF_K_FORWARD:
+ /*
+ * Only insert forward tags into the given hash if the
+ * type or tag name is not already present.
+ */
+ switch (tp->ctt_type) {
+ case CTF_K_STRUCT:
+ hp = &fp->ctf_structs;
+ break;
+ case CTF_K_UNION:
+ hp = &fp->ctf_unions;
+ break;
+ case CTF_K_ENUM:
+ hp = &fp->ctf_enums;
+ break;
+ default:
+ hp = &fp->ctf_structs;
+ }
+
+ if (ctf_hash_lookup(hp, fp,
+ name, strlen(name)) == NULL) {
+ err = ctf_hash_insert(hp, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+ }
+ vbytes = 0;
+ break;
+
+ case CTF_K_POINTER:
+ /*
+ * If the type referenced by the pointer is in this CTF
+ * container, then store the index of the pointer type
+ * in fp->ctf_ptrtab[ index of referenced type ].
+ */
+ if (CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
+ CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
+ fp->ctf_ptrtab[
+ CTF_TYPE_TO_INDEX(tp->ctt_type)] = id;
+ /*FALLTHRU*/
+
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ err = ctf_hash_insert(&fp->ctf_names, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
+ /*FALLTHRU*/
+
+ default:
+ vbytes = 0;
+ break;
+ }
+
+ *xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf);
+ tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+ }
+
+ ctf_dprintf("%lu total types processed\n", fp->ctf_typemax);
+ ctf_dprintf("%u enum names hashed\n", ctf_hash_size(&fp->ctf_enums));
+ ctf_dprintf("%u struct names hashed (%d long)\n",
+ ctf_hash_size(&fp->ctf_structs), nlstructs);
+ ctf_dprintf("%u union names hashed (%d long)\n",
+ ctf_hash_size(&fp->ctf_unions), nlunions);
+ ctf_dprintf("%u base type names hashed\n",
+ ctf_hash_size(&fp->ctf_names));
+
+ /*
+ * Make an additional pass through the pointer table to find pointers
+ * that point to anonymous typedef nodes. If we find one, modify the
+ * pointer table so that the pointer is also known to point to the
+ * node that is referenced by the anonymous typedef node.
+ */
+ for (id = 1; id <= fp->ctf_typemax; id++) {
+ if ((dst = fp->ctf_ptrtab[id]) != 0) {
+ tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF &&
+ strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 &&
+ CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
+ CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
+ fp->ctf_ptrtab[
+ CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst;
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Decode the specified CTF buffer and optional symbol table and create a new
+ * CTF container representing the symbolic debugging information. This code
+ * can be used directly by the debugger, or it can be used as the engine for
+ * ctf_fdopen() or ctf_open(), below.
+ */
+ctf_file_t *
+ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
+ const ctf_sect_t *strsect, int *errp)
+{
+ const ctf_preamble_t *pp;
+ ctf_header_t hp;
+ ctf_file_t *fp;
+ void *buf, *base;
+ size_t size, hdrsz;
+ int err;
+
+ if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))
+ return (ctf_set_open_errno(errp, EINVAL));
+
+ if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
+ symsect->cts_entsize != sizeof (Elf64_Sym))
+ return (ctf_set_open_errno(errp, ECTF_SYMTAB));
+
+ if (symsect != NULL && symsect->cts_data == NULL)
+ return (ctf_set_open_errno(errp, ECTF_SYMBAD));
+
+ if (strsect != NULL && strsect->cts_data == NULL)
+ return (ctf_set_open_errno(errp, ECTF_STRBAD));
+
+ if (ctfsect->cts_size < sizeof (ctf_preamble_t))
+ return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
+
+ pp = (const ctf_preamble_t *)ctfsect->cts_data;
+
+ ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n",
+ pp->ctp_magic, pp->ctp_version);
+
+ /*
+ * Validate each part of the CTF header (either V1 or V2).
+ * First, we validate the preamble (common to all versions). At that
+ * point, we know specific header version, and can validate the
+ * version-specific parts including section offsets and alignments.
+ */
+ if (pp->ctp_magic != CTF_MAGIC)
+ return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
+
+ if (pp->ctp_version == CTF_VERSION_2) {
+ if (ctfsect->cts_size < sizeof (ctf_header_t))
+ return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
+
+ bcopy(ctfsect->cts_data, &hp, sizeof (hp));
+ hdrsz = sizeof (ctf_header_t);
+
+ } else if (pp->ctp_version == CTF_VERSION_1) {
+ const ctf_header_v1_t *h1p =
+ (const ctf_header_v1_t *)ctfsect->cts_data;
+
+ if (ctfsect->cts_size < sizeof (ctf_header_v1_t))
+ return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
+
+ bzero(&hp, sizeof (hp));
+ hp.cth_preamble = h1p->cth_preamble;
+ hp.cth_objtoff = h1p->cth_objtoff;
+ hp.cth_funcoff = h1p->cth_funcoff;
+ hp.cth_typeoff = h1p->cth_typeoff;
+ hp.cth_stroff = h1p->cth_stroff;
+ hp.cth_strlen = h1p->cth_strlen;
+
+ hdrsz = sizeof (ctf_header_v1_t);
+ } else
+ return (ctf_set_open_errno(errp, ECTF_CTFVERS));
+
+ size = hp.cth_stroff + hp.cth_strlen;
+
+ ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size);
+
+ if (hp.cth_lbloff > size || hp.cth_objtoff > size ||
+ hp.cth_funcoff > size || hp.cth_typeoff > size ||
+ hp.cth_stroff > size)
+ return (ctf_set_open_errno(errp, ECTF_CORRUPT));
+
+ if (hp.cth_lbloff > hp.cth_objtoff ||
+ hp.cth_objtoff > hp.cth_funcoff ||
+ hp.cth_funcoff > hp.cth_typeoff ||
+ hp.cth_typeoff > hp.cth_stroff)
+ return (ctf_set_open_errno(errp, ECTF_CORRUPT));
+
+ if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) ||
+ (hp.cth_funcoff & 1) || (hp.cth_typeoff & 3))
+ return (ctf_set_open_errno(errp, ECTF_CORRUPT));
+
+ /*
+ * Once everything is determined to be valid, attempt to decompress
+ * the CTF data buffer if it is compressed. Otherwise we just put
+ * the data section's buffer pointer into ctf_buf, below.
+ */
+ if (hp.cth_flags & CTF_F_COMPRESS) {
+ size_t srclen, dstlen;
+ const void *src;
+ int rc = Z_OK;
+
+ if (ctf_zopen(errp) == NULL)
+ return (NULL); /* errp is set for us */
+
+ if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED)
+ return (ctf_set_open_errno(errp, ECTF_ZALLOC));
+
+ bcopy(ctfsect->cts_data, base, hdrsz);
+ ((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS;
+ buf = (uchar_t *)base + hdrsz;
+
+ src = (uchar_t *)ctfsect->cts_data + hdrsz;
+ srclen = ctfsect->cts_size - hdrsz;
+ dstlen = size;
+
+ if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) {
+ ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc));
+ ctf_data_free(base, size + hdrsz);
+ return (ctf_set_open_errno(errp, ECTF_DECOMPRESS));
+ }
+
+ if (dstlen != size) {
+ ctf_dprintf("zlib inflate short -- got %lu of %lu "
+ "bytes\n", (ulong_t)dstlen, (ulong_t)size);
+ ctf_data_free(base, size + hdrsz);
+ return (ctf_set_open_errno(errp, ECTF_CORRUPT));
+ }
+
+ ctf_data_protect(base, size + hdrsz);
+
+ } else {
+ base = (void *)ctfsect->cts_data;
+ buf = (uchar_t *)base + hdrsz;
+ }
+
+ /*
+ * Once we have uncompressed and validated the CTF data buffer, we can
+ * proceed with allocating a ctf_file_t and initializing it.
+ */
+ if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL)
+ return (ctf_set_open_errno(errp, EAGAIN));
+
+ bzero(fp, sizeof (ctf_file_t));
+ fp->ctf_version = hp.cth_version;
+ fp->ctf_fileops = &ctf_fileops[hp.cth_version];
+ bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t));
+
+ if (symsect != NULL) {
+ bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t));
+ bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t));
+ }
+
+ if (fp->ctf_data.cts_name != NULL)
+ fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name);
+ if (fp->ctf_symtab.cts_name != NULL)
+ fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name);
+ if (fp->ctf_strtab.cts_name != NULL)
+ fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name);
+
+ if (fp->ctf_data.cts_name == NULL)
+ fp->ctf_data.cts_name = _CTF_NULLSTR;
+ if (fp->ctf_symtab.cts_name == NULL)
+ fp->ctf_symtab.cts_name = _CTF_NULLSTR;
+ if (fp->ctf_strtab.cts_name == NULL)
+ fp->ctf_strtab.cts_name = _CTF_NULLSTR;
+
+ fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff;
+ fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen;
+
+ if (strsect != NULL) {
+ fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
+ fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
+ }
+
+ fp->ctf_base = base;
+ fp->ctf_buf = buf;
+ fp->ctf_size = size + hdrsz;
+
+ /*
+ * If we have a parent container name and label, store the relocated
+ * string pointers in the CTF container for easy access later.
+ */
+ if (hp.cth_parlabel != 0)
+ fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel);
+ if (hp.cth_parname != 0)
+ fp->ctf_parname = ctf_strptr(fp, hp.cth_parname);
+
+ ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n",
+ fp->ctf_parname ? fp->ctf_parname : "<NULL>",
+ fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");
+
+ /*
+ * If we have a symbol table section, allocate and initialize
+ * the symtab translation table, pointed to by ctf_sxlate.
+ */
+ if (symsect != NULL) {
+ fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;
+ fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t));
+
+ if (fp->ctf_sxlate == NULL) {
+ (void) ctf_set_open_errno(errp, EAGAIN);
+ goto bad;
+ }
+
+ if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) {
+ (void) ctf_set_open_errno(errp, err);
+ goto bad;
+ }
+ }
+
+ if ((err = init_types(fp, &hp)) != 0) {
+ (void) ctf_set_open_errno(errp, err);
+ goto bad;
+ }
+
+ /*
+ * Initialize the ctf_lookup_by_name top-level dictionary. We keep an
+ * array of type name prefixes and the corresponding ctf_hash to use.
+ * NOTE: This code must be kept in sync with the code in ctf_update().
+ */
+ fp->ctf_lookups[0].ctl_prefix = "struct";
+ fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix);
+ fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
+ fp->ctf_lookups[1].ctl_prefix = "union";
+ fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix);
+ fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
+ fp->ctf_lookups[2].ctl_prefix = "enum";
+ fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix);
+ fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
+ fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
+ fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix);
+ fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
+ fp->ctf_lookups[4].ctl_prefix = NULL;
+ fp->ctf_lookups[4].ctl_len = 0;
+ fp->ctf_lookups[4].ctl_hash = NULL;
+
+ if (symsect != NULL) {
+ if (symsect->cts_entsize == sizeof (Elf64_Sym))
+ (void) ctf_setmodel(fp, CTF_MODEL_LP64);
+ else
+ (void) ctf_setmodel(fp, CTF_MODEL_ILP32);
+ } else
+ (void) ctf_setmodel(fp, CTF_MODEL_NATIVE);
+
+ fp->ctf_refcnt = 1;
+ return (fp);
+
+bad:
+ ctf_close(fp);
+ return (NULL);
+}
+
+/*
+ * Close the specified CTF container and free associated data structures. Note
+ * that ctf_close() is a reference counted operation: if the specified file is
+ * the parent of other active containers, its reference count will be greater
+ * than one and it will be freed later when no active children exist.
+ */
+void
+ctf_close(ctf_file_t *fp)
+{
+ ctf_dtdef_t *dtd, *ntd;
+
+ if (fp == NULL)
+ return; /* allow ctf_close(NULL) to simplify caller code */
+
+ ctf_dprintf("ctf_close(%p) refcnt=%u\n", (void *)fp, fp->ctf_refcnt);
+
+ if (fp->ctf_refcnt > 1) {
+ fp->ctf_refcnt--;
+ return;
+ }
+
+ if (fp->ctf_parent != NULL)
+ ctf_close(fp->ctf_parent);
+
+ for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
+ ntd = ctf_list_next(dtd);
+ ctf_dtd_delete(fp, dtd);
+ }
+
+ ctf_free(fp->ctf_dthash, fp->ctf_dthashlen * sizeof (ctf_dtdef_t *));
+
+ if (fp->ctf_flags & LCTF_MMAP) {
+ if (fp->ctf_data.cts_data != NULL)
+ ctf_sect_munmap(&fp->ctf_data);
+ if (fp->ctf_symtab.cts_data != NULL)
+ ctf_sect_munmap(&fp->ctf_symtab);
+ if (fp->ctf_strtab.cts_data != NULL)
+ ctf_sect_munmap(&fp->ctf_strtab);
+ }
+
+ if (fp->ctf_data.cts_name != _CTF_NULLSTR &&
+ fp->ctf_data.cts_name != NULL) {
+ ctf_free((char *)fp->ctf_data.cts_name,
+ strlen(fp->ctf_data.cts_name) + 1);
+ }
+
+ if (fp->ctf_symtab.cts_name != _CTF_NULLSTR &&
+ fp->ctf_symtab.cts_name != NULL) {
+ ctf_free((char *)fp->ctf_symtab.cts_name,
+ strlen(fp->ctf_symtab.cts_name) + 1);
+ }
+
+ if (fp->ctf_strtab.cts_name != _CTF_NULLSTR &&
+ fp->ctf_strtab.cts_name != NULL) {
+ ctf_free((char *)fp->ctf_strtab.cts_name,
+ strlen(fp->ctf_strtab.cts_name) + 1);
+ }
+
+ if (fp->ctf_base != fp->ctf_data.cts_data && fp->ctf_base != NULL)
+ ctf_data_free((void *)fp->ctf_base, fp->ctf_size);
+
+ if (fp->ctf_sxlate != NULL)
+ ctf_free(fp->ctf_sxlate, sizeof (uint_t) * fp->ctf_nsyms);
+
+ if (fp->ctf_txlate != NULL) {
+ ctf_free(fp->ctf_txlate,
+ sizeof (uint_t) * (fp->ctf_typemax + 1));
+ }
+
+ if (fp->ctf_ptrtab != NULL) {
+ ctf_free(fp->ctf_ptrtab,
+ sizeof (ushort_t) * (fp->ctf_typemax + 1));
+ }
+
+ ctf_hash_destroy(&fp->ctf_structs);
+ ctf_hash_destroy(&fp->ctf_unions);
+ ctf_hash_destroy(&fp->ctf_enums);
+ ctf_hash_destroy(&fp->ctf_names);
+
+ ctf_free(fp, sizeof (ctf_file_t));
+}
+
+/*
+ * Return the CTF handle for the parent CTF container, if one exists.
+ * Otherwise return NULL to indicate this container has no imported parent.
+ */
+ctf_file_t *
+ctf_parent_file(ctf_file_t *fp)
+{
+ return (fp->ctf_parent);
+}
+
+/*
+ * Return the name of the parent CTF container, if one exists. Otherwise
+ * return NULL to indicate this container is a root container.
+ */
+const char *
+ctf_parent_name(ctf_file_t *fp)
+{
+ return (fp->ctf_parname);
+}
+
+/*
+ * Import the types from the specified parent container by storing a pointer
+ * to it in ctf_parent and incrementing its reference count. Only one parent
+ * is allowed: if a parent already exists, it is replaced by the new parent.
+ */
+int
+ctf_import(ctf_file_t *fp, ctf_file_t *pfp)
+{
+ if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
+ return (ctf_set_errno(fp, EINVAL));
+
+ if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
+ return (ctf_set_errno(fp, ECTF_DMODEL));
+
+ if (fp->ctf_parent != NULL)
+ ctf_close(fp->ctf_parent);
+
+ if (pfp != NULL) {
+ fp->ctf_flags |= LCTF_CHILD;
+ pfp->ctf_refcnt++;
+ }
+
+ fp->ctf_parent = pfp;
+ return (0);
+}
+
+/*
+ * Set the data model constant for the CTF container.
+ */
+int
+ctf_setmodel(ctf_file_t *fp, int model)
+{
+ const ctf_dmodel_t *dp;
+
+ for (dp = _libctf_models; dp->ctd_name != NULL; dp++) {
+ if (dp->ctd_code == model) {
+ fp->ctf_dmodel = dp;
+ return (0);
+ }
+ }
+
+ return (ctf_set_errno(fp, EINVAL));
+}
+
+/*
+ * Return the data model constant for the CTF container.
+ */
+int
+ctf_getmodel(ctf_file_t *fp)
+{
+ return (fp->ctf_dmodel->ctd_code);
+}
+
+void
+ctf_setspecific(ctf_file_t *fp, void *data)
+{
+ fp->ctf_specific = data;
+}
+
+void *
+ctf_getspecific(ctf_file_t *fp)
+{
+ return (fp->ctf_specific);
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_types.c b/cddl/contrib/opensolaris/common/ctf/ctf_types.c
new file mode 100644
index 0000000..290c518
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_types.c
@@ -0,0 +1,845 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+
+ssize_t
+ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
+ ssize_t *incrementp)
+{
+ ssize_t size, increment;
+
+ if (fp->ctf_version > CTF_VERSION_1 &&
+ tp->ctt_size == CTF_LSIZE_SENT) {
+ size = CTF_TYPE_LSIZE(tp);
+ increment = sizeof (ctf_type_t);
+ } else {
+ size = tp->ctt_size;
+ increment = sizeof (ctf_stype_t);
+ }
+
+ if (sizep)
+ *sizep = size;
+ if (incrementp)
+ *incrementp = increment;
+
+ return (size);
+}
+
+/*
+ * Iterate over the members of a STRUCT or UNION. We pass the name, member
+ * type, and offset of each member to the specified callback function.
+ */
+int
+ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ ssize_t size, increment;
+ uint_t kind, n;
+ int rc;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+ kind = LCTF_INFO_KIND(fp, tp->ctt_info);
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
+ return (ctf_set_errno(ofp, ECTF_NOTSOU));
+
+ if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
+ const ctf_member_t *mp = (const ctf_member_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
+ const char *name = ctf_strptr(fp, mp->ctm_name);
+ if ((rc = func(name, mp->ctm_type, mp->ctm_offset,
+ arg)) != 0)
+ return (rc);
+ }
+
+ } else {
+ const ctf_lmember_t *lmp = (const ctf_lmember_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
+ const char *name = ctf_strptr(fp, lmp->ctlm_name);
+ if ((rc = func(name, lmp->ctlm_type,
+ (ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0)
+ return (rc);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Iterate over the members of an ENUM. We pass the string name and associated
+ * integer value of each enum element to the specified callback function.
+ */
+int
+ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ const ctf_enum_t *ep;
+ ssize_t increment;
+ uint_t n;
+ int rc;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM)
+ return (ctf_set_errno(ofp, ECTF_NOTENUM));
+
+ (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
+
+ ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
+ const char *name = ctf_strptr(fp, ep->cte_name);
+ if ((rc = func(name, ep->cte_value, arg)) != 0)
+ return (rc);
+ }
+
+ return (0);
+}
+
+/*
+ * Iterate over every root (user-visible) type in the given CTF container.
+ * We pass the type ID of each type to the specified callback function.
+ */
+int
+ctf_type_iter(ctf_file_t *fp, ctf_type_f *func, void *arg)
+{
+ ctf_id_t id, max = fp->ctf_typemax;
+ int rc, child = (fp->ctf_flags & LCTF_CHILD);
+
+ for (id = 1; id <= max; id++) {
+ const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
+ if (CTF_INFO_ISROOT(tp->ctt_info) &&
+ (rc = func(CTF_INDEX_TO_TYPE(id, child), arg)) != 0)
+ return (rc);
+ }
+
+ return (0);
+}
+
+/*
+ * Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
+ * RESTRICT nodes until we reach a "base" type node. This is useful when
+ * we want to follow a type ID to a node that has members or a size. To guard
+ * against infinite loops, we implement simplified cycle detection and check
+ * each link against itself, the previous node, and the topmost node.
+ */
+ctf_id_t
+ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_id_t prev = type, otype = type;
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+
+ while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) {
+ switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_TYPEDEF:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ if (tp->ctt_type == type || tp->ctt_type == otype ||
+ tp->ctt_type == prev) {
+ ctf_dprintf("type %ld cycle detected\n", otype);
+ return (ctf_set_errno(ofp, ECTF_CORRUPT));
+ }
+ prev = type;
+ type = tp->ctt_type;
+ break;
+ default:
+ return (type);
+ }
+ }
+
+ return (CTF_ERR); /* errno is set for us */
+}
+
+/*
+ * Lookup the given type ID and print a string name for it into buf. Return
+ * the actual number of bytes (not including \0) needed to format the name.
+ */
+ssize_t
+ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
+{
+ ctf_decl_t cd;
+ ctf_decl_node_t *cdp;
+ ctf_decl_prec_t prec, lp, rp;
+ int ptr, arr;
+ uint_t k;
+
+ if (fp == NULL && type == CTF_ERR)
+ return (-1); /* simplify caller code by permitting CTF_ERR */
+
+ ctf_decl_init(&cd, buf, len);
+ ctf_decl_push(&cd, fp, type);
+
+ if (cd.cd_err != 0) {
+ ctf_decl_fini(&cd);
+ return (ctf_set_errno(fp, cd.cd_err));
+ }
+
+ /*
+ * If the type graph's order conflicts with lexical precedence order
+ * for pointers or arrays, then we need to surround the declarations at
+ * the corresponding lexical precedence with parentheses. This can
+ * result in either a parenthesized pointer (*) as in int (*)() or
+ * int (*)[], or in a parenthesized pointer and array as in int (*[])().
+ */
+ ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
+ arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
+
+ rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
+ lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
+
+ k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
+
+ for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
+ for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
+ cdp != NULL; cdp = ctf_list_next(cdp)) {
+
+ ctf_file_t *rfp = fp;
+ const ctf_type_t *tp =
+ ctf_lookup_by_id(&rfp, cdp->cd_type);
+ const char *name = ctf_strptr(rfp, tp->ctt_name);
+
+ if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
+ ctf_decl_sprintf(&cd, " ");
+
+ if (lp == prec) {
+ ctf_decl_sprintf(&cd, "(");
+ lp = -1;
+ }
+
+ switch (cdp->cd_kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ case CTF_K_TYPEDEF:
+ ctf_decl_sprintf(&cd, "%s", name);
+ break;
+ case CTF_K_POINTER:
+ ctf_decl_sprintf(&cd, "*");
+ break;
+ case CTF_K_ARRAY:
+ ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
+ break;
+ case CTF_K_FUNCTION:
+ ctf_decl_sprintf(&cd, "()");
+ break;
+ case CTF_K_STRUCT:
+ case CTF_K_FORWARD:
+ ctf_decl_sprintf(&cd, "struct %s", name);
+ break;
+ case CTF_K_UNION:
+ ctf_decl_sprintf(&cd, "union %s", name);
+ break;
+ case CTF_K_ENUM:
+ ctf_decl_sprintf(&cd, "enum %s", name);
+ break;
+ case CTF_K_VOLATILE:
+ ctf_decl_sprintf(&cd, "volatile");
+ break;
+ case CTF_K_CONST:
+ ctf_decl_sprintf(&cd, "const");
+ break;
+ case CTF_K_RESTRICT:
+ ctf_decl_sprintf(&cd, "restrict");
+ break;
+ }
+
+ k = cdp->cd_kind;
+ }
+
+ if (rp == prec)
+ ctf_decl_sprintf(&cd, ")");
+ }
+
+ if (cd.cd_len >= len)
+ (void) ctf_set_errno(fp, ECTF_NAMELEN);
+
+ ctf_decl_fini(&cd);
+ return (cd.cd_len);
+}
+
+/*
+ * Lookup the given type ID and print a string name for it into buf. If buf
+ * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
+ */
+char *
+ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
+{
+ ssize_t rv = ctf_type_lname(fp, type, buf, len);
+ return (rv >= 0 && rv < len ? buf : NULL);
+}
+
+/*
+ * Resolve the type down to a base type node, and then return the size
+ * of the type storage in bytes.
+ */
+ssize_t
+ctf_type_size(ctf_file_t *fp, ctf_id_t type)
+{
+ const ctf_type_t *tp;
+ ssize_t size;
+ ctf_arinfo_t ar;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (-1); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (-1); /* errno is set for us */
+
+ switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_POINTER:
+ return (fp->ctf_dmodel->ctd_pointer);
+
+ case CTF_K_FUNCTION:
+ return (0); /* function size is only known by symtab */
+
+ case CTF_K_ENUM:
+ return (fp->ctf_dmodel->ctd_int);
+
+ case CTF_K_ARRAY:
+ /*
+ * Array size is not directly returned by stabs data. Instead,
+ * it defines the element type and requires the user to perform
+ * the multiplication. If ctf_get_ctt_size() returns zero, the
+ * current version of ctfconvert does not compute member sizes
+ * and we compute the size here on its behalf.
+ */
+ if ((size = ctf_get_ctt_size(fp, tp, NULL, NULL)) > 0)
+ return (size);
+
+ if (ctf_array_info(fp, type, &ar) == CTF_ERR ||
+ (size = ctf_type_size(fp, ar.ctr_contents)) == CTF_ERR)
+ return (-1); /* errno is set for us */
+
+ return (size * ar.ctr_nelems);
+
+ default:
+ return (ctf_get_ctt_size(fp, tp, NULL, NULL));
+ }
+}
+
+/*
+ * Resolve the type down to a base type node, and then return the alignment
+ * needed for the type storage in bytes.
+ */
+ssize_t
+ctf_type_align(ctf_file_t *fp, ctf_id_t type)
+{
+ const ctf_type_t *tp;
+ ctf_arinfo_t r;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (-1); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (-1); /* errno is set for us */
+
+ switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_POINTER:
+ case CTF_K_FUNCTION:
+ return (fp->ctf_dmodel->ctd_pointer);
+
+ case CTF_K_ARRAY:
+ if (ctf_array_info(fp, type, &r) == CTF_ERR)
+ return (-1); /* errno is set for us */
+ return (ctf_type_align(fp, r.ctr_contents));
+
+ case CTF_K_STRUCT:
+ case CTF_K_UNION: {
+ uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info);
+ ssize_t size, increment;
+ size_t align = 0;
+ const void *vmp;
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+ vmp = (uchar_t *)tp + increment;
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT)
+ n = MIN(n, 1); /* only use first member for structs */
+
+ if (fp->ctf_version == CTF_VERSION_1 ||
+ size < CTF_LSTRUCT_THRESH) {
+ const ctf_member_t *mp = vmp;
+ for (; n != 0; n--, mp++) {
+ ssize_t am = ctf_type_align(fp, mp->ctm_type);
+ align = MAX(align, am);
+ }
+ } else {
+ const ctf_lmember_t *lmp = vmp;
+ for (; n != 0; n--, lmp++) {
+ ssize_t am = ctf_type_align(fp, lmp->ctlm_type);
+ align = MAX(align, am);
+ }
+ }
+
+ return (align);
+ }
+
+ case CTF_K_ENUM:
+ return (fp->ctf_dmodel->ctd_int);
+
+ default:
+ return (ctf_get_ctt_size(fp, tp, NULL, NULL));
+ }
+}
+
+/*
+ * Return the kind (CTF_K_* constant) for the specified type ID.
+ */
+int
+ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
+{
+ const ctf_type_t *tp;
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ return (LCTF_INFO_KIND(fp, tp->ctt_info));
+}
+
+/*
+ * If the type is one that directly references another type (such as POINTER),
+ * then return the ID of the type to which it refers.
+ */
+ctf_id_t
+ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_POINTER:
+ case CTF_K_TYPEDEF:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ return (tp->ctt_type);
+ default:
+ return (ctf_set_errno(ofp, ECTF_NOTREF));
+ }
+}
+
+/*
+ * Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
+ * pointer to the given type, see if we can compute a pointer to the type
+ * resulting from resolving the type down to its base type and use that
+ * instead. This helps with cases where the CTF data includes "struct foo *"
+ * but not "foo_t *" and the user accesses "foo_t *" in the debugger.
+ */
+ctf_id_t
+ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_file_t *ofp = fp;
+ ctf_id_t ntype;
+
+ if (ctf_lookup_by_id(&fp, type) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
+ return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (ctf_set_errno(ofp, ECTF_NOTYPE));
+
+ if (ctf_lookup_by_id(&fp, type) == NULL)
+ return (ctf_set_errno(ofp, ECTF_NOTYPE));
+
+ if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
+ return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
+
+ return (ctf_set_errno(ofp, ECTF_NOTYPE));
+}
+
+/*
+ * Return the encoding for the specified INTEGER or FLOAT.
+ */
+int
+ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ ssize_t increment;
+ uint_t data;
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
+
+ switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
+ case CTF_K_INTEGER:
+ data = *(const uint_t *)((uintptr_t)tp + increment);
+ ep->cte_format = CTF_INT_ENCODING(data);
+ ep->cte_offset = CTF_INT_OFFSET(data);
+ ep->cte_bits = CTF_INT_BITS(data);
+ break;
+ case CTF_K_FLOAT:
+ data = *(const uint_t *)((uintptr_t)tp + increment);
+ ep->cte_format = CTF_FP_ENCODING(data);
+ ep->cte_offset = CTF_FP_OFFSET(data);
+ ep->cte_bits = CTF_FP_BITS(data);
+ break;
+ default:
+ return (ctf_set_errno(ofp, ECTF_NOTINTFP));
+ }
+
+ return (0);
+}
+
+int
+ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
+{
+ int rval;
+
+ if (ltype < rtype)
+ rval = -1;
+ else if (ltype > rtype)
+ rval = 1;
+ else
+ rval = 0;
+
+ if (lfp == rfp)
+ return (rval);
+
+ if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
+ lfp = lfp->ctf_parent;
+
+ if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
+ rfp = rfp->ctf_parent;
+
+ if (lfp < rfp)
+ return (-1);
+
+ if (lfp > rfp)
+ return (1);
+
+ return (rval);
+}
+
+/*
+ * Return a boolean value indicating if two types are compatible integers or
+ * floating-pointer values. This function returns true if the two types are
+ * the same, or if they have the same ASCII name and encoding properties.
+ * This function could be extended to test for compatibility for other kinds.
+ */
+int
+ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
+ ctf_file_t *rfp, ctf_id_t rtype)
+{
+ const ctf_type_t *ltp, *rtp;
+ ctf_encoding_t le, re;
+ ctf_arinfo_t la, ra;
+ uint_t lkind, rkind;
+
+ if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)
+ return (1);
+
+ ltype = ctf_type_resolve(lfp, ltype);
+ lkind = ctf_type_kind(lfp, ltype);
+
+ rtype = ctf_type_resolve(rfp, rtype);
+ rkind = ctf_type_kind(rfp, rtype);
+
+ if (lkind != rkind ||
+ (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
+ (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
+ strcmp(ctf_strptr(lfp, ltp->ctt_name),
+ ctf_strptr(rfp, rtp->ctt_name)) != 0)
+ return (0);
+
+ switch (lkind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ return (ctf_type_encoding(lfp, ltype, &le) == 0 &&
+ ctf_type_encoding(rfp, rtype, &re) == 0 &&
+ bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);
+ case CTF_K_POINTER:
+ return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),
+ rfp, ctf_type_reference(rfp, rtype)));
+ case CTF_K_ARRAY:
+ return (ctf_array_info(lfp, ltype, &la) == 0 &&
+ ctf_array_info(rfp, rtype, &ra) == 0 &&
+ la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(
+ lfp, la.ctr_contents, rfp, ra.ctr_contents) &&
+ ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));
+ case CTF_K_ENUM:
+ case CTF_K_FORWARD:
+ return (1); /* no other checks required for these type kinds */
+ default:
+ return (0); /* should not get here since we did a resolve */
+ }
+}
+
+/*
+ * Return the type and offset for a given member of a STRUCT or UNION.
+ */
+int
+ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
+ ctf_membinfo_t *mip)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ ssize_t size, increment;
+ uint_t kind, n;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+ kind = LCTF_INFO_KIND(fp, tp->ctt_info);
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
+ return (ctf_set_errno(ofp, ECTF_NOTSOU));
+
+ if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
+ const ctf_member_t *mp = (const ctf_member_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
+ if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
+ mip->ctm_type = mp->ctm_type;
+ mip->ctm_offset = mp->ctm_offset;
+ return (0);
+ }
+ }
+ } else {
+ const ctf_lmember_t *lmp = (const ctf_lmember_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
+ if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
+ mip->ctm_type = lmp->ctlm_type;
+ mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
+ return (0);
+ }
+ }
+ }
+
+ return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
+}
+
+/*
+ * Return the array type, index, and size information for the specified ARRAY.
+ */
+int
+ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ const ctf_array_t *ap;
+ ssize_t increment;
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
+ return (ctf_set_errno(ofp, ECTF_NOTARRAY));
+
+ (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
+
+ ap = (const ctf_array_t *)((uintptr_t)tp + increment);
+ arp->ctr_contents = ap->cta_contents;
+ arp->ctr_index = ap->cta_index;
+ arp->ctr_nelems = ap->cta_nelems;
+
+ return (0);
+}
+
+/*
+ * Convert the specified value to the corresponding enum member name, if a
+ * matching name can be found. Otherwise NULL is returned.
+ */
+const char *
+ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ const ctf_enum_t *ep;
+ ssize_t increment;
+ uint_t n;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (NULL); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (NULL); /* errno is set for us */
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
+ (void) ctf_set_errno(ofp, ECTF_NOTENUM);
+ return (NULL);
+ }
+
+ (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
+
+ ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
+ if (ep->cte_value == value)
+ return (ctf_strptr(fp, ep->cte_name));
+ }
+
+ (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
+ return (NULL);
+}
+
+/*
+ * Convert the specified enum tag name to the corresponding value, if a
+ * matching name can be found. Otherwise CTF_ERR is returned.
+ */
+int
+ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
+{
+ ctf_file_t *ofp = fp;
+ const ctf_type_t *tp;
+ const ctf_enum_t *ep;
+ ssize_t size, increment;
+ uint_t n;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
+ (void) ctf_set_errno(ofp, ECTF_NOTENUM);
+ return (CTF_ERR);
+ }
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+
+ ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
+ if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
+ if (valp != NULL)
+ *valp = ep->cte_value;
+ return (0);
+ }
+ }
+
+ (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
+ return (CTF_ERR);
+}
+
+/*
+ * Recursively visit the members of any type. This function is used as the
+ * engine for ctf_type_visit, below. We resolve the input type, recursively
+ * invoke ourself for each type member if the type is a struct or union, and
+ * then invoke the callback function on the current type. If any callback
+ * returns non-zero, we abort and percolate the error code back up to the top.
+ */
+static int
+ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
+ const char *name, ulong_t offset, int depth)
+{
+ ctf_id_t otype = type;
+ const ctf_type_t *tp;
+ ssize_t size, increment;
+ uint_t kind, n;
+ int rc;
+
+ if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
+ return (CTF_ERR); /* errno is set for us */
+
+ if ((rc = func(name, otype, offset, depth, arg)) != 0)
+ return (rc);
+
+ kind = LCTF_INFO_KIND(fp, tp->ctt_info);
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
+ return (0);
+
+ (void) ctf_get_ctt_size(fp, tp, &size, &increment);
+
+ if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
+ const ctf_member_t *mp = (const ctf_member_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
+ if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
+ func, arg, ctf_strptr(fp, mp->ctm_name),
+ offset + mp->ctm_offset, depth + 1)) != 0)
+ return (rc);
+ }
+
+ } else {
+ const ctf_lmember_t *lmp = (const ctf_lmember_t *)
+ ((uintptr_t)tp + increment);
+
+ for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
+ if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
+ func, arg, ctf_strptr(fp, lmp->ctlm_name),
+ offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
+ depth + 1)) != 0)
+ return (rc);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Recursively visit the members of any type. We pass the name, member
+ * type, and offset of each member to the specified callback function.
+ */
+int
+ctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
+{
+ return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));
+}
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_util.c b/cddl/contrib/opensolaris/common/ctf/ctf_util.c
new file mode 100644
index 0000000..740d403
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_util.c
@@ -0,0 +1,152 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+
+/*
+ * Simple doubly-linked list append routine. This implementation assumes that
+ * each list element contains an embedded ctf_list_t as the first member.
+ * An additional ctf_list_t is used to store the head (l_next) and tail
+ * (l_prev) pointers. The current head and tail list elements have their
+ * previous and next pointers set to NULL, respectively.
+ */
+void
+ctf_list_append(ctf_list_t *lp, void *new)
+{
+ ctf_list_t *p = lp->l_prev; /* p = tail list element */
+ ctf_list_t *q = new; /* q = new list element */
+
+ lp->l_prev = q;
+ q->l_prev = p;
+ q->l_next = NULL;
+
+ if (p != NULL)
+ p->l_next = q;
+ else
+ lp->l_next = q;
+}
+
+/*
+ * Prepend the specified existing element to the given ctf_list_t. The
+ * existing pointer should be pointing at a struct with embedded ctf_list_t.
+ */
+void
+ctf_list_prepend(ctf_list_t *lp, void *new)
+{
+ ctf_list_t *p = new; /* p = new list element */
+ ctf_list_t *q = lp->l_next; /* q = head list element */
+
+ lp->l_next = p;
+ p->l_prev = NULL;
+ p->l_next = q;
+
+ if (q != NULL)
+ q->l_prev = p;
+ else
+ lp->l_prev = p;
+}
+
+/*
+ * Delete the specified existing element from the given ctf_list_t. The
+ * existing pointer should be pointing at a struct with embedded ctf_list_t.
+ */
+void
+ctf_list_delete(ctf_list_t *lp, void *existing)
+{
+ ctf_list_t *p = existing;
+
+ if (p->l_prev != NULL)
+ p->l_prev->l_next = p->l_next;
+ else
+ lp->l_next = p->l_next;
+
+ if (p->l_next != NULL)
+ p->l_next->l_prev = p->l_prev;
+ else
+ lp->l_prev = p->l_prev;
+}
+
+/*
+ * Convert an encoded CTF string name into a pointer to a C string by looking
+ * up the appropriate string table buffer and then adding the offset.
+ */
+const char *
+ctf_strraw(ctf_file_t *fp, uint_t name)
+{
+ ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];
+
+ if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET(name) < ctsp->cts_len)
+ return (ctsp->cts_strs + CTF_NAME_OFFSET(name));
+
+ /* string table not loaded or corrupt offset */
+ return (NULL);
+}
+
+const char *
+ctf_strptr(ctf_file_t *fp, uint_t name)
+{
+ const char *s = ctf_strraw(fp, name);
+ return (s != NULL ? s : "(?)");
+}
+
+/*
+ * Same strdup(3C), but use ctf_alloc() to do the memory allocation.
+ */
+char *
+ctf_strdup(const char *s1)
+{
+ char *s2 = ctf_alloc(strlen(s1) + 1);
+
+ if (s2 != NULL)
+ (void) strcpy(s2, s1);
+
+ return (s2);
+}
+
+/*
+ * Store the specified error code into errp if it is non-NULL, and then
+ * return NULL for the benefit of the caller.
+ */
+ctf_file_t *
+ctf_set_open_errno(int *errp, int error)
+{
+ if (errp != NULL)
+ *errp = error;
+ return (NULL);
+}
+
+/*
+ * Store the specified error code into the CTF container, and then return
+ * CTF_ERR for the benefit of the caller.
+ */
+long
+ctf_set_errno(ctf_file_t *fp, int err)
+{
+ fp->ctf_errno = err;
+ return (CTF_ERR);
+}
diff --git a/cddl/contrib/opensolaris/head/atomic.h b/cddl/contrib/opensolaris/head/atomic.h
new file mode 100644
index 0000000..00c9476
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/atomic.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ATOMIC_H
+#define _ATOMIC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/atomic.h>
+
+#endif /* _ATOMIC_H */
diff --git a/cddl/contrib/opensolaris/head/libintl.h b/cddl/contrib/opensolaris/head/libintl.h
new file mode 100644
index 0000000..e649668
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/libintl.h
@@ -0,0 +1,125 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#ifndef _LIBINTL_H
+#define _LIBINTL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/isa_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * wchar_t is a built-in type in standard C++ and as such is not
+ * defined here when using standard C++. However, the GNU compiler
+ * fixincludes utility nonetheless creates its own version of this
+ * header for use by gcc and g++. In that version it adds a redundant
+ * guard for __cplusplus. To avoid the creation of a gcc/g++ specific
+ * header we need to include the following magic comment:
+ *
+ * we must use the C++ compiler's type
+ *
+ * The above comment should not be removed or changed until GNU
+ * gcc/fixinc/inclhack.def is updated to bypass this header.
+ */
+#if !defined(__cplusplus) || (__cplusplus < 199711L && !defined(__GNUG__))
+#ifndef _WCHAR_T
+#define _WCHAR_T
+#if defined(_LP64)
+typedef int wchar_t;
+#else
+typedef long wchar_t;
+#endif
+#endif /* !_WCHAR_T */
+#endif /* !defined(__cplusplus) ... */
+
+#define TEXTDOMAINMAX 256
+
+#define __GNU_GETTEXT_SUPPORTED_REVISION(m) \
+ ((((m) == 0) || ((m) == 1)) ? 1 : -1)
+
+#ifdef __STDC__
+extern char *dcgettext(const char *, const char *, const int);
+extern char *dgettext(const char *, const char *);
+extern char *gettext(const char *);
+extern char *textdomain(const char *);
+extern char *bindtextdomain(const char *, const char *);
+
+/*
+ * LI18NUX 2000 Globalization Specification Version 1.0
+ * with Amendment 2
+ */
+extern char *dcngettext(const char *, const char *,
+ const char *, unsigned long int, int);
+extern char *dngettext(const char *, const char *,
+ const char *, unsigned long int);
+extern char *ngettext(const char *, const char *, unsigned long int);
+extern char *bind_textdomain_codeset(const char *, const char *);
+
+/* Word handling functions --- requires dynamic linking */
+/* Warning: these are experimental and subject to change. */
+extern int wdinit(void);
+extern int wdchkind(wchar_t);
+extern int wdbindf(wchar_t, wchar_t, int);
+extern wchar_t *wddelim(wchar_t, wchar_t, int);
+extern wchar_t mcfiller(void);
+extern int mcwrap(void);
+
+#else
+extern char *dcgettext();
+extern char *dgettext();
+extern char *gettext();
+extern char *textdomain();
+extern char *bindtextdomain();
+
+/*
+ * LI18NUX 2000 Globalization Specification Version 1.0
+ * with Amendment 2
+ */
+extern char *dcngettext();
+extern char *dngettext();
+extern char *ngettext();
+extern char *bind_textdomain_codeset();
+
+/* Word handling functions --- requires dynamic linking */
+/* Warning: these are experimental and subject to change. */
+extern int wdinit();
+extern int wdchkind();
+extern int wdbindf();
+extern wchar_t *wddelim();
+extern wchar_t mcfiller();
+extern int mcwrap();
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBINTL_H */
diff --git a/cddl/contrib/opensolaris/head/nlist.h b/cddl/contrib/opensolaris/head/nlist.h
new file mode 100644
index 0000000..ea1bd203
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/nlist.h
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+
+#ifndef _NLIST_H
+#define _NLIST_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8.2.4 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct nlist {
+ char *n_name; /* symbol name */
+ long n_value; /* value of symbol */
+ short n_scnum; /* section number */
+ unsigned short n_type; /* type and derived type */
+ char n_sclass; /* storage class */
+ char n_numaux; /* number of aux. entries */
+};
+
+#if defined(__STDC__)
+extern int nlist(const char *, struct nlist *);
+#else /* __STDC__ */
+extern int nlist();
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NLIST_H */
diff --git a/cddl/contrib/opensolaris/head/note.h b/cddl/contrib/opensolaris/head/note.h
new file mode 100644
index 0000000..6c73867
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/note.h
@@ -0,0 +1,55 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1994 by Sun Microsystems, Inc.
+ */
+
+/*
+ * note.h: interface for annotating source with info for tools
+ *
+ * NOTE is the default interface, but if the identifier NOTE is in use for
+ * some other purpose, you may prepare a similar header file using your own
+ * identifier, mapping that identifier to _NOTE. Also, exported header
+ * files should *not* use NOTE, since the name may already be in use in
+ * a program's namespace. Rather, exported header files should include
+ * sys/note.h directly and use _NOTE. For consistency, all kernel source
+ * should use _NOTE.
+ */
+
+#ifndef _NOTE_H
+#define _NOTE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/note.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NOTE _NOTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NOTE_H */
diff --git a/cddl/contrib/opensolaris/head/stdio_ext.h b/cddl/contrib/opensolaris/head/stdio_ext.h
new file mode 100644
index 0000000..839e05f
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/stdio_ext.h
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _STDIO_EXT_H
+#define _STDIO_EXT_H
+
+#define enable_extended_FILE_stdio(x,y) (0)
+
+#endif
diff --git a/cddl/contrib/opensolaris/head/storclass.h b/cddl/contrib/opensolaris/head/storclass.h
new file mode 100644
index 0000000..3cbfb8e
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/storclass.h
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+
+#ifndef _STORCLASS_H
+#define _STORCLASS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.6 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * STORAGE CLASSES
+ */
+
+#define C_EFCN -1 /* physical end of function */
+#define C_NULL 0
+#define C_AUTO 1 /* automatic variable */
+#define C_EXT 2 /* external symbol */
+#define C_STAT 3 /* static */
+#define C_REG 4 /* register variable */
+#define C_EXTDEF 5 /* external definition */
+#define C_LABEL 6 /* label */
+#define C_ULABEL 7 /* undefined label */
+#define C_MOS 8 /* member of structure */
+#define C_ARG 9 /* function argument */
+#define C_STRTAG 10 /* structure tag */
+#define C_MOU 11 /* member of union */
+#define C_UNTAG 12 /* union tag */
+#define C_TPDEF 13 /* type definition */
+#define C_USTATIC 14 /* undefined static */
+#define C_ENTAG 15 /* enumeration tag */
+#define C_MOE 16 /* member of enumeration */
+#define C_REGPARM 17 /* register parameter */
+#define C_FIELD 18 /* bit field */
+#define C_BLOCK 100 /* ".bb" or ".eb" */
+#define C_FCN 101 /* ".bf" or ".ef" */
+#define C_EOS 102 /* end of structure */
+#define C_FILE 103 /* file name */
+
+/*
+ * The following storage class is a "dummy" used only by STS
+ * for line number entries reformatted as symbol table entries
+ */
+
+#define C_LINE 104
+#define C_ALIAS 105 /* duplicate tag */
+#define C_HIDDEN 106 /* special storage class for external */
+ /* symbols in dmert public libraries */
+#define C_SHADOW 107 /* shadow symbol */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STORCLASS_H */
diff --git a/cddl/contrib/opensolaris/head/syms.h b/cddl/contrib/opensolaris/head/syms.h
new file mode 100644
index 0000000..d18dda2
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/syms.h
@@ -0,0 +1,230 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+
+#ifndef _SYMS_H
+#define _SYMS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.8 */
+
+/* Storage Classes are defined in storclass.h */
+#include <storclass.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Number of characters in a symbol name */
+#define SYMNMLEN 8
+/* Number of characters in a file name */
+#define FILNMLEN 14
+/* Number of array dimensions in auxiliary entry */
+#define DIMNUM 4
+
+struct syment
+{
+ union
+ {
+ char _n_name[SYMNMLEN]; /* old COFF version */
+ struct
+ {
+ long _n_zeroes; /* new == 0 */
+ long _n_offset; /* offset into string table */
+ } _n_n;
+ char *_n_nptr[2]; /* allows for overlaying */
+ } _n;
+ unsigned long n_value; /* value of symbol */
+ short n_scnum; /* section number */
+ unsigned short n_type; /* type and derived type */
+ char n_sclass; /* storage class */
+ char n_numaux; /* number of aux. entries */
+};
+
+#define n_name _n._n_name
+#define n_nptr _n._n_nptr[1]
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+/*
+ * Relocatable symbols have a section number of the
+ * section in which they are defined. Otherwise, section
+ * numbers have the following meanings:
+ */
+ /* undefined symbol */
+#define N_UNDEF 0
+ /* value of symbol is absolute */
+#define N_ABS -1
+ /* special debugging symbol -- value of symbol is meaningless */
+#define N_DEBUG -2
+ /* indicates symbol needs transfer vector (preload) */
+#define N_TV (unsigned short)-3
+
+ /* indicates symbol needs transfer vector (postload) */
+
+#define P_TV (unsigned short)-4
+
+/*
+ * The fundamental type of a symbol packed into the low
+ * 4 bits of the word.
+ */
+
+#define _EF ".ef"
+
+#define T_NULL 0
+#define T_ARG 1 /* function argument (only used by compiler) */
+#define T_CHAR 2 /* character */
+#define T_SHORT 3 /* short integer */
+#define T_INT 4 /* integer */
+#define T_LONG 5 /* long integer */
+#define T_FLOAT 6 /* floating point */
+#define T_DOUBLE 7 /* double word */
+#define T_STRUCT 8 /* structure */
+#define T_UNION 9 /* union */
+#define T_ENUM 10 /* enumeration */
+#define T_MOE 11 /* member of enumeration */
+#define T_UCHAR 12 /* unsigned character */
+#define T_USHORT 13 /* unsigned short */
+#define T_UINT 14 /* unsigned integer */
+#define T_ULONG 15 /* unsigned long */
+
+/*
+ * derived types are:
+ */
+
+#define DT_NON 0 /* no derived type */
+#define DT_PTR 1 /* pointer */
+#define DT_FCN 2 /* function */
+#define DT_ARY 3 /* array */
+
+/*
+ * type packing constants
+ */
+
+#define N_BTMASK 017
+#define N_TMASK 060
+#define N_TMASK1 0300
+#define N_TMASK2 0360
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+/*
+ * MACROS
+ */
+
+ /* Basic Type of x */
+
+#define BTYPE(x) ((x) & N_BTMASK)
+
+ /* Is x a pointer ? */
+
+#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
+
+ /* Is x a function ? */
+
+#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
+
+ /* Is x an array ? */
+
+#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
+
+ /* Is x a structure, union, or enumeration TAG? */
+
+#define ISTAG(x) ((x) == C_STRTAG || (x) == C_UNTAG || (x) == C_ENTAG)
+
+#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(DT_PTR<<N_BTSHFT)|(x&N_BTMASK))
+
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+
+/*
+ * AUXILIARY ENTRY FORMAT
+ */
+
+union auxent
+{
+ struct
+ {
+ long x_tagndx; /* str, un, or enum tag indx */
+ union
+ {
+ struct
+ {
+ unsigned short x_lnno; /* declaration line */
+ /* number */
+ unsigned short x_size; /* str, union, array */
+ /* size */
+ } x_lnsz;
+ long x_fsize; /* size of function */
+ } x_misc;
+ union
+ {
+ struct /* if ISFCN, tag, or .bb */
+ {
+ long x_lnnoptr; /* ptr to fcn line # */
+ long x_endndx; /* entry ndx past */
+ /* block end */
+ } x_fcn;
+ struct /* if ISARY, up to 4 dimen. */
+ {
+ unsigned short x_dimen[DIMNUM];
+ } x_ary;
+ } x_fcnary;
+ unsigned short x_tvndx; /* tv index */
+ } x_sym;
+ struct
+ {
+ char x_fname[FILNMLEN];
+ } x_file;
+ struct
+ {
+ long x_scnlen; /* section length */
+ unsigned short x_nreloc; /* number of reloc entries */
+ unsigned short x_nlinno; /* number of line numbers */
+ } x_scn;
+
+ struct
+ {
+ long x_tvfill; /* tv fill value */
+ unsigned short x_tvlen; /* length of .tv */
+ unsigned short x_tvran[2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+};
+
+#define SYMENT struct syment
+#define SYMESZ 18 /* sizeof(SYMENT) */
+
+#define AUXENT union auxent
+#define AUXESZ 18 /* sizeof(AUXENT) */
+
+/* Defines for "special" symbols */
+
+#define _ETEXT "etext"
+#define _EDATA "edata"
+#define _END "end"
+#define _START "_start"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYMS_H */
diff --git a/cddl/contrib/opensolaris/head/synch.h b/cddl/contrib/opensolaris/head/synch.h
new file mode 100644
index 0000000..89efe9c
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/synch.h
@@ -0,0 +1,277 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _SYNCH_H
+#define _SYNCH_H
+
+/*
+ * synch.h:
+ * definitions needed to use the thread synchronization interface
+ */
+
+#ifndef _ASM
+#include <sys/machlock.h>
+#include <sys/time_impl.h>
+#include <sys/synch.h>
+#endif /* _ASM */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ASM
+
+/*
+ * Semaphores
+ */
+typedef struct _sema {
+ /* this structure must be the same as sem_t in <semaphore.h> */
+ uint32_t count; /* semaphore count */
+ uint16_t type;
+ uint16_t magic;
+ upad64_t pad1[3]; /* reserved for a mutex_t */
+ upad64_t pad2[2]; /* reserved for a cond_t */
+} sema_t;
+
+/*
+ * POSIX.1c Note:
+ * POSIX.1c requires that <pthread.h> define the structures pthread_mutex_t
+ * and pthread_cond_t. These structures are identical to mutex_t (lwp_mutex_t)
+ * and cond_t (lwp_cond_t) which are defined in <synch.h>. A nested included
+ * of <synch.h> (to allow a "#typedef mutex_t pthread_mutex_t") would pull in
+ * non-posix symbols/constants violating the namespace restrictions. Hence,
+ * pthread_mutex_t/pthread_cond_t have been redefined in <pthread.h> (actually
+ * in <sys/types.h>). Any modifications done to mutex_t/lwp_mutex_t or
+ * cond_t/lwp_cond_t should also be done to pthread_mutex_t/pthread_cond_t.
+ */
+typedef lwp_mutex_t mutex_t;
+typedef lwp_cond_t cond_t;
+
+/*
+ * Readers/writer locks
+ *
+ * NOTE: The layout of this structure should be kept in sync with the layout
+ * of the correponding structure of pthread_rwlock_t in sys/types.h.
+ * Also, there is an identical structure for lwp_rwlock_t in <sys/synch.h>.
+ * Because we have to deal with C++, we cannot redefine this one as that one.
+ */
+typedef struct _rwlock {
+ int32_t readers; /* rwstate word */
+ uint16_t type;
+ uint16_t magic;
+ mutex_t mutex; /* used with process-shared rwlocks */
+ cond_t readercv; /* used only to indicate ownership */
+ cond_t writercv; /* used only to indicate ownership */
+} rwlock_t;
+
+#ifdef __STDC__
+int _lwp_mutex_lock(lwp_mutex_t *);
+int _lwp_mutex_unlock(lwp_mutex_t *);
+int _lwp_mutex_trylock(lwp_mutex_t *);
+int _lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *);
+int _lwp_cond_timedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *);
+int _lwp_cond_reltimedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *);
+int _lwp_cond_signal(lwp_cond_t *);
+int _lwp_cond_broadcast(lwp_cond_t *);
+int _lwp_sema_init(lwp_sema_t *, int);
+int _lwp_sema_wait(lwp_sema_t *);
+int _lwp_sema_trywait(lwp_sema_t *);
+int _lwp_sema_post(lwp_sema_t *);
+int cond_init(cond_t *, int, void *);
+int cond_destroy(cond_t *);
+int cond_wait(cond_t *, mutex_t *);
+int cond_timedwait(cond_t *, mutex_t *, const timespec_t *);
+int cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
+int cond_signal(cond_t *);
+int cond_broadcast(cond_t *);
+int mutex_init(mutex_t *, int, void *);
+int mutex_destroy(mutex_t *);
+int mutex_consistent(mutex_t *);
+int mutex_lock(mutex_t *);
+int mutex_trylock(mutex_t *);
+int mutex_unlock(mutex_t *);
+int rwlock_init(rwlock_t *, int, void *);
+int rwlock_destroy(rwlock_t *);
+int rw_rdlock(rwlock_t *);
+int rw_wrlock(rwlock_t *);
+int rw_unlock(rwlock_t *);
+int rw_tryrdlock(rwlock_t *);
+int rw_trywrlock(rwlock_t *);
+int sema_init(sema_t *, unsigned int, int, void *);
+int sema_destroy(sema_t *);
+int sema_wait(sema_t *);
+int sema_timedwait(sema_t *, const timespec_t *);
+int sema_reltimedwait(sema_t *, const timespec_t *);
+int sema_post(sema_t *);
+int sema_trywait(sema_t *);
+
+#else /* __STDC__ */
+
+int _lwp_mutex_lock();
+int _lwp_mutex_unlock();
+int _lwp_mutex_trylock();
+int _lwp_cond_wait();
+int _lwp_cond_timedwait();
+int _lwp_cond_reltimedwait();
+int _lwp_cond_signal();
+int _lwp_cond_broadcast();
+int _lwp_sema_init();
+int _lwp_sema_wait();
+int _lwp_sema_trywait();
+int _lwp_sema_post();
+int cond_init();
+int cond_destroy();
+int cond_wait();
+int cond_timedwait();
+int cond_reltimedwait();
+int cond_signal();
+int cond_broadcast();
+int mutex_init();
+int mutex_destroy();
+int mutex_consistent();
+int mutex_lock();
+int mutex_trylock();
+int mutex_unlock();
+int rwlock_init();
+int rwlock_destroy();
+int rw_rdlock();
+int rw_wrlock();
+int rw_unlock();
+int rw_tryrdlock();
+int rw_trywrlock();
+int sema_init();
+int sema_destroy();
+int sema_wait();
+int sema_timedwait();
+int sema_reltimedwait();
+int sema_post();
+int sema_trywait();
+
+#endif /* __STDC__ */
+
+#endif /* _ASM */
+
+/* "Magic numbers" tagging synchronization object types */
+#define MUTEX_MAGIC _MUTEX_MAGIC
+#define SEMA_MAGIC _SEMA_MAGIC
+#define COND_MAGIC _COND_MAGIC
+#define RWL_MAGIC _RWL_MAGIC
+
+/*
+ * POSIX.1c Note:
+ * DEFAULTMUTEX is defined same as PTHREAD_MUTEX_INITIALIZER in <pthread.h>.
+ * DEFAULTCV is defined same as PTHREAD_COND_INITIALIZER in <pthread.h>.
+ * DEFAULTRWLOCK is defined same as PTHREAD_RWLOCK_INITIALIZER in <pthread.h>.
+ * Any changes to these macros should be reflected in <pthread.h>
+ */
+#define DEFAULTMUTEX \
+ {{0, 0, 0, {USYNC_THREAD}, MUTEX_MAGIC}, \
+ {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
+#define SHAREDMUTEX \
+ {{0, 0, 0, {USYNC_PROCESS}, MUTEX_MAGIC}, \
+ {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
+#define RECURSIVEMUTEX \
+ {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE}, MUTEX_MAGIC}, \
+ {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
+#define ERRORCHECKMUTEX \
+ {{0, 0, 0, {USYNC_THREAD|LOCK_ERRORCHECK}, MUTEX_MAGIC}, \
+ {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
+#define RECURSIVE_ERRORCHECKMUTEX \
+ {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE|LOCK_ERRORCHECK}, \
+ MUTEX_MAGIC}, {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
+#define DEFAULTCV \
+ {{{0, 0, 0, 0}, USYNC_THREAD, COND_MAGIC}, 0}
+#define SHAREDCV \
+ {{{0, 0, 0, 0}, USYNC_PROCESS, COND_MAGIC}, 0}
+#define DEFAULTSEMA \
+ {0, USYNC_THREAD, SEMA_MAGIC, {0, 0, 0}, {0, 0}}
+#define SHAREDSEMA \
+ {0, USYNC_PROCESS, SEMA_MAGIC, {0, 0, 0}, {0, 0}}
+#define DEFAULTRWLOCK \
+ {0, USYNC_THREAD, RWL_MAGIC, DEFAULTMUTEX, DEFAULTCV, DEFAULTCV}
+#define SHAREDRWLOCK \
+ {0, USYNC_PROCESS, RWL_MAGIC, SHAREDMUTEX, SHAREDCV, SHAREDCV}
+
+/*
+ * Tests on lock states.
+ */
+#define SEMA_HELD(x) _sema_held(x)
+#define RW_READ_HELD(x) _rw_read_held(x)
+#define RW_WRITE_HELD(x) _rw_write_held(x)
+#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x))
+#define MUTEX_HELD(x) _mutex_held(x)
+
+/*
+ * The following definitions are for assertions which can be checked
+ * statically by tools like lock_lint. You can also define your own
+ * run-time test for each. If you don't, we define them to 1 so that
+ * such assertions simply pass.
+ */
+#ifndef NO_LOCKS_HELD
+#define NO_LOCKS_HELD 1
+#endif
+#ifndef NO_COMPETING_THREADS
+#define NO_COMPETING_THREADS 1
+#endif
+
+#ifndef _ASM
+
+#ifdef __STDC__
+
+/*
+ * The *_held() functions apply equally well to Solaris threads
+ * and to Posix threads synchronization objects, but the formal
+ * type declarations are different, so we just declare the argument
+ * to each *_held() function to be a void *, expecting that they will
+ * be called with the proper type of argument in each case.
+ */
+int _sema_held(void *); /* sema_t or sem_t */
+int _rw_read_held(void *); /* rwlock_t or pthread_rwlock_t */
+int _rw_write_held(void *); /* rwlock_t or pthread_rwlock_t */
+int _mutex_held(void *); /* mutex_t or pthread_mutex_t */
+
+#else /* __STDC__ */
+
+int _sema_held();
+int _rw_read_held();
+int _rw_write_held();
+int _mutex_held();
+
+#endif /* __STDC__ */
+
+/* Pause API */
+#ifdef __STDC__
+void smt_pause(void);
+#else /* __STDC__ */
+void smt_pause();
+#endif /* __STDC__ */
+
+#endif /* _ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYNCH_H */
diff --git a/cddl/contrib/opensolaris/head/thread.h b/cddl/contrib/opensolaris/head/thread.h
new file mode 100644
index 0000000..d813a25
--- /dev/null
+++ b/cddl/contrib/opensolaris/head/thread.h
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _THREAD_H
+#define _THREAD_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <pthread.h>
+#include <pthread_np.h>
+#include <assert.h>
+
+/*
+ * Compatibility thread stuff needed for Solaris -> Linux port
+ */
+
+typedef pthread_t thread_t;
+typedef pthread_mutex_t mutex_t;
+typedef pthread_cond_t cond_t;
+typedef pthread_rwlock_t rwlock_t;
+
+#define USYNC_THREAD 0
+
+#define thr_self() (unsigned long)pthread_self()
+#define thr_equal(a,b) pthread_equal(a,b)
+#define thr_join(t,d,s) pthread_join(t,s)
+#define thr_exit(r) pthread_exit(r)
+#define _mutex_init(l,f,a) pthread_mutex_init(l,NULL)
+#define _mutex_destroy(l) pthread_mutex_destroy(l)
+#define mutex_lock(l) pthread_mutex_lock(l)
+#define mutex_trylock(l) pthread_mutex_trylock(l)
+#define mutex_unlock(l) pthread_mutex_unlock(l)
+#define rwlock_init(l,f,a) pthread_rwlock_init(l,NULL)
+#define rwlock_destroy(l) pthread_rwlock_destroy(l)
+#define rw_rdlock(l) pthread_rwlock_rdlock(l)
+#define rw_wrlock(l) pthread_rwlock_wrlock(l)
+#define rw_tryrdlock(l) pthread_rwlock_tryrdlock(l)
+#define rw_trywrlock(l) pthread_rwlock_trywrlock(l)
+#define rw_unlock(l) pthread_rwlock_unlock(l)
+#define cond_init(l,f,a) pthread_cond_init(l,NULL)
+#define cond_destroy(l) pthread_cond_destroy(l)
+#define cond_wait(l,m) pthread_cond_wait(l,m)
+#define cond_signal(l) pthread_cond_signal(l)
+#define cond_broadcast(l) pthread_cond_broadcast(l)
+
+#define THR_BOUND 0x00000001 /* = PTHREAD_SCOPE_SYSTEM */
+#define THR_NEW_LWP 0x00000002
+#define THR_DETACHED 0x00000040 /* = PTHREAD_CREATE_DETACHED */
+#define THR_SUSPENDED 0x00000080
+#define THR_DAEMON 0x00000100
+
+static __inline int
+thr_create(void *stack_base, size_t stack_size, void *(*start_func) (void*),
+ void *arg, long flags, thread_t *new_thread_ID)
+{
+ pthread_t dummy;
+ int ret;
+
+ assert(stack_base == NULL);
+ assert(stack_size == 0);
+ assert((flags & ~THR_BOUND & ~THR_DETACHED) == 0);
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ if (flags & THR_DETACHED)
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (new_thread_ID == NULL)
+ new_thread_ID = &dummy;
+
+ /* This function ignores the THR_BOUND flag, since NPTL doesn't seem to support PTHREAD_SCOPE_PROCESS */
+
+ ret = pthread_create(new_thread_ID, &attr, start_func, arg);
+
+ pthread_attr_destroy(&attr);
+
+ return (ret);
+}
+
+#endif /* _THREAD_H */
diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c
new file mode 100644
index 0000000..6cd0036
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf_lib.c
@@ -0,0 +1,500 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/zmod.h>
+#include <ctf_impl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#if defined(sun)
+#include <dlfcn.h>
+#else
+#include <zlib.h>
+#endif
+#include <gelf.h>
+
+#if defined(sun)
+#ifdef _LP64
+static const char *_libctf_zlib = "/usr/lib/64/libz.so";
+#else
+static const char *_libctf_zlib = "/usr/lib/libz.so";
+#endif
+#endif
+
+static struct {
+ int (*z_uncompress)(uchar_t *, ulong_t *, const uchar_t *, ulong_t);
+ const char *(*z_error)(int);
+ void *z_dlp;
+} zlib;
+
+static size_t _PAGESIZE;
+static size_t _PAGEMASK;
+
+#if defined(sun)
+#pragma init(_libctf_init)
+#else
+void _libctf_init(void) __attribute__ ((constructor));
+#endif
+void
+_libctf_init(void)
+{
+#if defined(sun)
+ const char *p = getenv("LIBCTF_DECOMPRESSOR");
+
+ if (p != NULL)
+ _libctf_zlib = p; /* use alternate decompression library */
+#endif
+
+ _libctf_debug = getenv("LIBCTF_DEBUG") != NULL;
+
+ _PAGESIZE = getpagesize();
+ _PAGEMASK = ~(_PAGESIZE - 1);
+}
+
+/*
+ * Attempt to dlopen the decompression library and locate the symbols of
+ * interest that we will need to call. This information in cached so
+ * that multiple calls to ctf_bufopen() do not need to reopen the library.
+ */
+void *
+ctf_zopen(int *errp)
+{
+#if defined(sun)
+ ctf_dprintf("decompressing CTF data using %s\n", _libctf_zlib);
+
+ if (zlib.z_dlp != NULL)
+ return (zlib.z_dlp); /* library is already loaded */
+
+ if (access(_libctf_zlib, R_OK) == -1)
+ return (ctf_set_open_errno(errp, ECTF_ZMISSING));
+
+ if ((zlib.z_dlp = dlopen(_libctf_zlib, RTLD_LAZY | RTLD_LOCAL)) == NULL)
+ return (ctf_set_open_errno(errp, ECTF_ZINIT));
+
+ zlib.z_uncompress = (int (*)(uchar_t *, ulong_t *, const uchar_t *, ulong_t)) dlsym(zlib.z_dlp, "uncompress");
+ zlib.z_error = (const char *(*)(int)) dlsym(zlib.z_dlp, "zError");
+
+ if (zlib.z_uncompress == NULL || zlib.z_error == NULL) {
+ (void) dlclose(zlib.z_dlp);
+ bzero(&zlib, sizeof (zlib));
+ return (ctf_set_open_errno(errp, ECTF_ZINIT));
+ }
+#else
+ zlib.z_uncompress = uncompress;
+ zlib.z_error = zError;
+
+ /* Dummy return variable as 'no error' */
+ zlib.z_dlp = (void *) (uintptr_t) 1;
+#endif
+
+ return (zlib.z_dlp);
+}
+
+/*
+ * The ctf_bufopen() routine calls these subroutines, defined by <sys/zmod.h>,
+ * which we then patch through to the functions in the decompression library.
+ */
+int
+z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
+{
+ return (zlib.z_uncompress(dst, (ulong_t *)dstlen, src, srclen));
+}
+
+const char *
+z_strerror(int err)
+{
+ return (zlib.z_error(err));
+}
+
+/*
+ * Convert a 32-bit ELF file header into GElf.
+ */
+static void
+ehdr_to_gelf(const Elf32_Ehdr *src, GElf_Ehdr *dst)
+{
+ bcopy(src->e_ident, dst->e_ident, EI_NIDENT);
+ dst->e_type = src->e_type;
+ dst->e_machine = src->e_machine;
+ dst->e_version = src->e_version;
+ dst->e_entry = (Elf64_Addr)src->e_entry;
+ dst->e_phoff = (Elf64_Off)src->e_phoff;
+ dst->e_shoff = (Elf64_Off)src->e_shoff;
+ dst->e_flags = src->e_flags;
+ dst->e_ehsize = src->e_ehsize;
+ dst->e_phentsize = src->e_phentsize;
+ dst->e_phnum = src->e_phnum;
+ dst->e_shentsize = src->e_shentsize;
+ dst->e_shnum = src->e_shnum;
+ dst->e_shstrndx = src->e_shstrndx;
+}
+
+/*
+ * Convert a 32-bit ELF section header into GElf.
+ */
+static void
+shdr_to_gelf(const Elf32_Shdr *src, GElf_Shdr *dst)
+{
+ dst->sh_name = src->sh_name;
+ dst->sh_type = src->sh_type;
+ dst->sh_flags = src->sh_flags;
+ dst->sh_addr = src->sh_addr;
+ dst->sh_offset = src->sh_offset;
+ dst->sh_size = src->sh_size;
+ dst->sh_link = src->sh_link;
+ dst->sh_info = src->sh_info;
+ dst->sh_addralign = src->sh_addralign;
+ dst->sh_entsize = src->sh_entsize;
+}
+
+/*
+ * In order to mmap a section from the ELF file, we must round down sh_offset
+ * to the previous page boundary, and mmap the surrounding page. We store
+ * the pointer to the start of the actual section data back into sp->cts_data.
+ */
+const void *
+ctf_sect_mmap(ctf_sect_t *sp, int fd)
+{
+ size_t pageoff = sp->cts_offset & ~_PAGEMASK;
+
+ caddr_t base = mmap64(NULL, sp->cts_size + pageoff, PROT_READ,
+ MAP_PRIVATE, fd, sp->cts_offset & _PAGEMASK);
+
+ if (base != MAP_FAILED)
+ sp->cts_data = base + pageoff;
+
+ return (base);
+}
+
+/*
+ * Since sp->cts_data has the adjusted offset, we have to again round down
+ * to get the actual mmap address and round up to get the size.
+ */
+void
+ctf_sect_munmap(const ctf_sect_t *sp)
+{
+ uintptr_t addr = (uintptr_t)sp->cts_data;
+ uintptr_t pageoff = addr & ~_PAGEMASK;
+
+ (void) munmap((void *)(addr - pageoff), sp->cts_size + pageoff);
+}
+
+/*
+ * Open the specified file descriptor and return a pointer to a CTF container.
+ * The file can be either an ELF file or raw CTF file. The caller is
+ * responsible for closing the file descriptor when it is no longer needed.
+ */
+ctf_file_t *
+ctf_fdopen(int fd, int *errp)
+{
+ ctf_sect_t ctfsect, symsect, strsect;
+ ctf_file_t *fp = NULL;
+
+ struct stat64 st;
+ ssize_t nbytes;
+
+ union {
+ ctf_preamble_t ctf;
+ Elf32_Ehdr e32;
+ GElf_Ehdr e64;
+ } hdr;
+
+ bzero(&ctfsect, sizeof (ctf_sect_t));
+ bzero(&symsect, sizeof (ctf_sect_t));
+ bzero(&strsect, sizeof (ctf_sect_t));
+ bzero(&hdr.ctf, sizeof (hdr));
+
+ if (fstat64(fd, &st) == -1)
+ return (ctf_set_open_errno(errp, errno));
+
+ if ((nbytes = pread64(fd, &hdr.ctf, sizeof (hdr), 0)) <= 0)
+ return (ctf_set_open_errno(errp, nbytes < 0? errno : ECTF_FMT));
+
+ /*
+ * If we have read enough bytes to form a CTF header and the magic
+ * string matches, attempt to interpret the file as raw CTF.
+ */
+ if (nbytes >= (ssize_t) sizeof (ctf_preamble_t) &&
+ hdr.ctf.ctp_magic == CTF_MAGIC) {
+ if (hdr.ctf.ctp_version > CTF_VERSION)
+ return (ctf_set_open_errno(errp, ECTF_CTFVERS));
+
+ ctfsect.cts_data = mmap64(NULL, st.st_size, PROT_READ,
+ MAP_PRIVATE, fd, 0);
+
+ if (ctfsect.cts_data == MAP_FAILED)
+ return (ctf_set_open_errno(errp, errno));
+
+ ctfsect.cts_name = _CTF_SECTION;
+ ctfsect.cts_type = SHT_PROGBITS;
+ ctfsect.cts_flags = SHF_ALLOC;
+ ctfsect.cts_size = (size_t)st.st_size;
+ ctfsect.cts_entsize = 1;
+ ctfsect.cts_offset = 0;
+
+ if ((fp = ctf_bufopen(&ctfsect, NULL, NULL, errp)) == NULL)
+ ctf_sect_munmap(&ctfsect);
+
+ return (fp);
+ }
+
+ /*
+ * If we have read enough bytes to form an ELF header and the magic
+ * string matches, attempt to interpret the file as an ELF file. We
+ * do our own largefile ELF processing, and convert everything to
+ * GElf structures so that clients can operate on any data model.
+ */
+ if (nbytes >= (ssize_t) sizeof (Elf32_Ehdr) &&
+ bcmp(&hdr.e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0) {
+#ifdef _BIG_ENDIAN
+ uchar_t order = ELFDATA2MSB;
+#else
+ uchar_t order = ELFDATA2LSB;
+#endif
+ GElf_Half i, n;
+ GElf_Shdr *sp;
+
+ void *strs_map;
+ size_t strs_mapsz;
+ char *strs;
+
+ if (hdr.e32.e_ident[EI_DATA] != order)
+ return (ctf_set_open_errno(errp, ECTF_ENDIAN));
+ if (hdr.e32.e_version != EV_CURRENT)
+ return (ctf_set_open_errno(errp, ECTF_ELFVERS));
+
+ if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS64) {
+ if (nbytes < (ssize_t) sizeof (GElf_Ehdr))
+ return (ctf_set_open_errno(errp, ECTF_FMT));
+ } else {
+ Elf32_Ehdr e32 = hdr.e32;
+ ehdr_to_gelf(&e32, &hdr.e64);
+ }
+
+ if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
+ return (ctf_set_open_errno(errp, ECTF_CORRUPT));
+
+ n = hdr.e64.e_shnum;
+ nbytes = sizeof (GElf_Shdr) * n;
+
+ if ((sp = malloc(nbytes)) == NULL)
+ return (ctf_set_open_errno(errp, errno));
+
+ /*
+ * Read in and convert to GElf the array of Shdr structures
+ * from e_shoff so we can locate sections of interest.
+ */
+ if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
+ Elf32_Shdr *sp32;
+
+ nbytes = sizeof (Elf32_Shdr) * n;
+
+ if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
+ sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
+ free(sp);
+ return (ctf_set_open_errno(errp, errno));
+ }
+
+ for (i = 0; i < n; i++)
+ shdr_to_gelf(&sp32[i], &sp[i]);
+
+ free(sp32);
+
+ } else if (pread64(fd, sp, nbytes, hdr.e64.e_shoff) != nbytes) {
+ free(sp);
+ return (ctf_set_open_errno(errp, errno));
+ }
+
+ /*
+ * Now mmap the section header strings section so that we can
+ * perform string comparison on the section names.
+ */
+ strs_mapsz = sp[hdr.e64.e_shstrndx].sh_size +
+ (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+
+ strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
+ fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
+
+ strs = (char *)strs_map +
+ (sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
+
+ if (strs_map == MAP_FAILED) {
+ free(sp);
+ return (ctf_set_open_errno(errp, ECTF_MMAP));
+ }
+
+ /*
+ * Iterate over the section header array looking for the CTF
+ * section and symbol table. The strtab is linked to symtab.
+ */
+ for (i = 0; i < n; i++) {
+ const GElf_Shdr *shp = &sp[i];
+ const GElf_Shdr *lhp = &sp[shp->sh_link];
+
+ if (shp->sh_link >= hdr.e64.e_shnum)
+ continue; /* corrupt sh_link field */
+
+ if (shp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size ||
+ lhp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size)
+ continue; /* corrupt sh_name field */
+
+ if (shp->sh_type == SHT_PROGBITS &&
+ strcmp(strs + shp->sh_name, _CTF_SECTION) == 0) {
+ ctfsect.cts_name = strs + shp->sh_name;
+ ctfsect.cts_type = shp->sh_type;
+ ctfsect.cts_flags = shp->sh_flags;
+ ctfsect.cts_size = shp->sh_size;
+ ctfsect.cts_entsize = shp->sh_entsize;
+ ctfsect.cts_offset = (off64_t)shp->sh_offset;
+
+ } else if (shp->sh_type == SHT_SYMTAB) {
+ symsect.cts_name = strs + shp->sh_name;
+ symsect.cts_type = shp->sh_type;
+ symsect.cts_flags = shp->sh_flags;
+ symsect.cts_size = shp->sh_size;
+ symsect.cts_entsize = shp->sh_entsize;
+ symsect.cts_offset = (off64_t)shp->sh_offset;
+
+ strsect.cts_name = strs + lhp->sh_name;
+ strsect.cts_type = lhp->sh_type;
+ strsect.cts_flags = lhp->sh_flags;
+ strsect.cts_size = lhp->sh_size;
+ strsect.cts_entsize = lhp->sh_entsize;
+ strsect.cts_offset = (off64_t)lhp->sh_offset;
+ }
+ }
+
+ free(sp); /* free section header array */
+
+ if (ctfsect.cts_type == SHT_NULL) {
+ (void) munmap(strs_map, strs_mapsz);
+ return (ctf_set_open_errno(errp, ECTF_NOCTFDATA));
+ }
+
+ /*
+ * Now mmap the CTF data, symtab, and strtab sections and
+ * call ctf_bufopen() to do the rest of the work.
+ */
+ if (ctf_sect_mmap(&ctfsect, fd) == MAP_FAILED) {
+ (void) munmap(strs_map, strs_mapsz);
+ return (ctf_set_open_errno(errp, ECTF_MMAP));
+ }
+
+ if (symsect.cts_type != SHT_NULL &&
+ strsect.cts_type != SHT_NULL) {
+ if (ctf_sect_mmap(&symsect, fd) == MAP_FAILED ||
+ ctf_sect_mmap(&strsect, fd) == MAP_FAILED) {
+ (void) ctf_set_open_errno(errp, ECTF_MMAP);
+ goto bad; /* unmap all and abort */
+ }
+ fp = ctf_bufopen(&ctfsect, &symsect, &strsect, errp);
+ } else
+ fp = ctf_bufopen(&ctfsect, NULL, NULL, errp);
+bad:
+ if (fp == NULL) {
+ ctf_sect_munmap(&ctfsect);
+ ctf_sect_munmap(&symsect);
+ ctf_sect_munmap(&strsect);
+ } else
+ fp->ctf_flags |= LCTF_MMAP;
+
+ (void) munmap(strs_map, strs_mapsz);
+ return (fp);
+ }
+
+ return (ctf_set_open_errno(errp, ECTF_FMT));
+}
+
+/*
+ * Open the specified file and return a pointer to a CTF container. The file
+ * can be either an ELF file or raw CTF file. This is just a convenient
+ * wrapper around ctf_fdopen() for callers.
+ */
+ctf_file_t *
+ctf_open(const char *filename, int *errp)
+{
+ ctf_file_t *fp;
+ int fd;
+
+ if ((fd = open64(filename, O_RDONLY)) == -1) {
+ if (errp != NULL)
+ *errp = errno;
+ return (NULL);
+ }
+
+ fp = ctf_fdopen(fd, errp);
+ (void) close(fd);
+ return (fp);
+}
+
+/*
+ * Write the uncompressed CTF data stream to the specified file descriptor.
+ * This is useful for saving the results of dynamic CTF containers.
+ */
+int
+ctf_write(ctf_file_t *fp, int fd)
+{
+ const uchar_t *buf = fp->ctf_base;
+ ssize_t resid = fp->ctf_size;
+ ssize_t len;
+
+ while (resid != 0) {
+ if ((len = write(fd, buf, resid)) <= 0)
+ return (ctf_set_errno(fp, errno));
+ resid -= len;
+ buf += len;
+ }
+
+ return (0);
+}
+
+/*
+ * Set the CTF library client version to the specified version. If version is
+ * zero, we just return the default library version number.
+ */
+int
+ctf_version(int version)
+{
+ if (version < 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (version > 0) {
+ if (version > CTF_VERSION) {
+ errno = ENOTSUP;
+ return (-1);
+ }
+ ctf_dprintf("ctf_version: client using version %d\n", version);
+ _libctf_version = version;
+ }
+
+ return (_libctf_version);
+}
diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf_subr.c b/cddl/contrib/opensolaris/lib/libctf/common/ctf_subr.c
new file mode 100644
index 0000000..e9f5ad7
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf_subr.c
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctf_impl.h>
+#include <sys/mman.h>
+#include <stdarg.h>
+
+void *
+ctf_data_alloc(size_t size)
+{
+ return (mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0));
+}
+
+void
+ctf_data_free(void *buf, size_t size)
+{
+ (void) munmap(buf, size);
+}
+
+void
+ctf_data_protect(void *buf, size_t size)
+{
+ (void) mprotect(buf, size, PROT_READ);
+}
+
+void *
+ctf_alloc(size_t size)
+{
+ return (malloc(size));
+}
+
+/*ARGSUSED*/
+void
+ctf_free(void *buf, __unused size_t size)
+{
+ free(buf);
+}
+
+const char *
+ctf_strerror(int err)
+{
+ return ((const char *) strerror(err));
+}
+
+/*PRINTFLIKE1*/
+void
+ctf_dprintf(const char *format, ...)
+{
+ if (_libctf_debug) {
+ va_list alist;
+
+ va_start(alist, format);
+ (void) fputs("libctf DEBUG: ", stderr);
+ (void) vfprintf(stderr, format, alist);
+ va_end(alist);
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libctf/common/libctf.h b/cddl/contrib/opensolaris/lib/libctf/common/libctf.h
new file mode 100644
index 0000000..3fd6931
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libctf/common/libctf.h
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This header file defines the interfaces available from the CTF debugger
+ * library, libctf. This library provides functions that a debugger can
+ * use to operate on data in the Compact ANSI-C Type Format (CTF). This
+ * is NOT a public interface, although it may eventually become one in
+ * the fullness of time after we gain more experience with the interfaces.
+ *
+ * In the meantime, be aware that any program linked with libctf in this
+ * release of Solaris is almost guaranteed to break in the next release.
+ *
+ * In short, do not user this header file or libctf for any purpose.
+ */
+
+#ifndef _LIBCTF_H
+#define _LIBCTF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/ctf_api.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This flag can be used to enable debug messages.
+ */
+extern int _libctf_debug;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBCTF_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
new file mode 100644
index 0000000..3b4a38c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
@@ -0,0 +1,361 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <link.h>
+#include <sys/dtrace.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <libelf.h>
+#include <gelf.h>
+
+/*
+ * In Solaris 10 GA, the only mechanism for communicating helper information
+ * is through the DTrace helper pseudo-device node in /devices; there is
+ * no /dev link. Because of this, USDT providers and helper actions don't
+ * work inside of non-global zones. This issue was addressed by adding
+ * the /dev and having this initialization code use that /dev link. If the
+ * /dev link doesn't exist it falls back to looking for the /devices node
+ * as this code may be embedded in a binary which runs on Solaris 10 GA.
+ *
+ * Users may set the following environment variable to affect the way
+ * helper initialization takes place:
+ *
+ * DTRACE_DOF_INIT_DEBUG enable debugging output
+ * DTRACE_DOF_INIT_DISABLE disable helper loading
+ * DTRACE_DOF_INIT_DEVNAME set the path to the helper node
+ */
+
+static const char *devnamep = "/dev/dtrace/helper";
+#if defined(sun)
+static const char *olddevname = "/devices/pseudo/dtrace@0:helper";
+#endif
+
+static const char *modname; /* Name of this load object */
+static int gen; /* DOF helper generation */
+#if defined(sun)
+extern dof_hdr_t __SUNW_dof; /* DOF defined in the .SUNW_dof section */
+#endif
+static boolean_t dof_init_debug = B_FALSE; /* From DTRACE_DOF_INIT_DEBUG */
+
+static void
+dprintf(int debug, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (debug && !dof_init_debug)
+ return;
+
+ va_start(ap, fmt);
+
+ if (modname == NULL)
+ (void) fprintf(stderr, "dtrace DOF: ");
+ else
+ (void) fprintf(stderr, "dtrace DOF %s: ", modname);
+
+ (void) vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", strerror(errno));
+
+ va_end(ap);
+}
+
+#if !defined(sun)
+static void
+fixsymbol(Elf *e, Elf_Data *data, size_t idx, int nprobes, char *buf,
+ dof_sec_t *sec, int *fixedprobes, char *dofstrtab)
+{
+ GElf_Sym sym;
+ char *s;
+ unsigned char *funcname;
+ dof_probe_t *prb;
+ int j = 0;
+ int ndx;
+
+ while (gelf_getsym(data, j++, &sym) != NULL) {
+ prb = (dof_probe_t *)(void *)(buf + sec->dofs_offset);
+
+ for (ndx = nprobes; ndx; ndx--, prb += 1) {
+ funcname = dofstrtab + prb->dofpr_func;
+ s = elf_strptr(e, idx, sym.st_name);
+ if (strcmp(s, funcname) == 0) {
+ dprintf(1, "fixing %s() symbol\n", s);
+ prb->dofpr_addr = sym.st_value;
+ (*fixedprobes)++;
+ }
+ }
+ if (*fixedprobes == nprobes)
+ break;
+ }
+}
+#endif
+
+#if defined(sun)
+#pragma init(dtrace_dof_init)
+#else
+static void dtrace_dof_init(void) __attribute__ ((constructor));
+#endif
+
+static void
+dtrace_dof_init(void)
+{
+#if defined(sun)
+ dof_hdr_t *dof = &__SUNW_dof;
+#else
+ dof_hdr_t *dof = NULL;
+#endif
+#ifdef _LP64
+ Elf64_Ehdr *elf;
+#else
+ Elf32_Ehdr *elf;
+#endif
+ dof_helper_t dh;
+ Link_map *lmp;
+#if defined(sun)
+ Lmid_t lmid;
+#else
+ u_long lmid = 0;
+ dof_sec_t *sec;
+ size_t i;
+#endif
+ int fd;
+ const char *p;
+#if !defined(sun)
+ Elf *e;
+ Elf_Scn *scn = NULL;
+ Elf_Data *symtabdata = NULL, *dynsymdata = NULL;
+ GElf_Shdr shdr;
+ int efd, nprobes;
+ char *s;
+ size_t shstridx, symtabidx = 0, dynsymidx = 0;
+ unsigned char *dofstrtab = NULL;
+ unsigned char *buf;
+ int fixedprobes = 0;
+#endif
+
+ if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
+ return;
+
+ if (getenv("DTRACE_DOF_INIT_DEBUG") != NULL)
+ dof_init_debug = B_TRUE;
+
+ if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lmp) == -1 || lmp == NULL) {
+ dprintf(1, "couldn't discover module name or address\n");
+ return;
+ }
+
+#if defined(sun)
+ if (dlinfo(RTLD_SELF, RTLD_DI_LMID, &lmid) == -1) {
+ dprintf(1, "couldn't discover link map ID\n");
+ return;
+ }
+#endif
+
+
+ if ((modname = strrchr(lmp->l_name, '/')) == NULL)
+ modname = lmp->l_name;
+ else
+ modname++;
+#if !defined(sun)
+ elf_version(EV_CURRENT);
+ if ((efd = open(lmp->l_name, O_RDONLY, 0)) < 0) {
+ dprintf(1, "couldn't open file for reading\n");
+ return;
+ }
+ if ((e = elf_begin(efd, ELF_C_READ, NULL)) == NULL) {
+ dprintf(1, "elf_begin failed\n");
+ close(efd);
+ return;
+ }
+ elf_getshdrstrndx(e, &shstridx);
+ dof = NULL;
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+ gelf_getshdr(scn, &shdr);
+ if (shdr.sh_type == SHT_SYMTAB) {
+ symtabidx = shdr.sh_link;
+ symtabdata = elf_getdata(scn, NULL);
+ } else if (shdr.sh_type == SHT_DYNSYM) {
+ dynsymidx = shdr.sh_link;
+ dynsymdata = elf_getdata(scn, NULL);
+ } else if (shdr.sh_type == SHT_PROGBITS) {
+ s = elf_strptr(e, shstridx, shdr.sh_name);
+ if (s && strcmp(s, ".SUNW_dof") == 0) {
+ dof = elf_getdata(scn, NULL)->d_buf;
+ }
+ }
+ }
+ if (dof == NULL) {
+ dprintf(1, "SUNW_dof section not found\n");
+ elf_end(e);
+ close(efd);
+ return;
+ }
+#endif
+
+ if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
+ dof->dofh_ident[DOF_ID_MAG1] != DOF_MAG_MAG1 ||
+ dof->dofh_ident[DOF_ID_MAG2] != DOF_MAG_MAG2 ||
+ dof->dofh_ident[DOF_ID_MAG3] != DOF_MAG_MAG3) {
+ dprintf(0, ".SUNW_dof section corrupt\n");
+ return;
+ }
+
+ elf = (void *)lmp->l_addr;
+
+ dh.dofhp_dof = (uintptr_t)dof;
+ dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_addr : 0;
+
+ if (lmid == 0) {
+ (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod),
+ "%s", modname);
+ } else {
+ (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod),
+ "LM%lu`%s", lmid, modname);
+ }
+
+ if ((p = getenv("DTRACE_DOF_INIT_DEVNAME")) != NULL)
+ devnamep = p;
+
+ if ((fd = open64(devnamep, O_RDWR)) < 0) {
+ dprintf(1, "failed to open helper device %s", devnamep);
+#if defined(sun)
+ /*
+ * If the device path wasn't explicitly set, try again with
+ * the old device path.
+ */
+ if (p != NULL)
+ return;
+
+ devnamep = olddevname;
+
+ if ((fd = open64(devnamep, O_RDWR)) < 0) {
+ dprintf(1, "failed to open helper device %s", devnamep);
+ return;
+ }
+#else
+ return;
+#endif
+ }
+#if !defined(sun)
+ /*
+ * We need to fix the base address of each probe since this wasn't
+ * done by ld(1). (ld(1) needs to grow support for parsing the
+ * SUNW_dof section).
+ *
+ * The complexity of this is not that great. The first for loop
+ * iterates over the sections inside the DOF file. There are usually
+ * 10 sections here. We asume the STRTAB section comes first and the
+ * PROBES section comes after. Since we are only interested in fixing
+ * data inside the PROBES section we quit the for loop after processing
+ * the PROBES section. It's usually the case that the first section
+ * is the STRTAB section and the second section is the PROBES section,
+ * so this for loop is not meaningful when doing complexity analysis.
+ *
+ * After finding the probes section, we iterate over the symbols
+ * in the symtab section. When we find a symbol name that matches
+ * the probe function name, we fix it. If we have fixed all the
+ * probes, we exit all the loops and we are done.
+ * The number of probes is given by the variable 'nprobes' and this
+ * depends entirely on the user, but some optimizations were done.
+ *
+ * We are assuming the number of probes is less than the number of
+ * symbols (libc can have 4k symbols, for example).
+ */
+ sec = (dof_sec_t *)(dof + 1);
+ buf = (char *)dof;
+ for (i = 0; i < dof->dofh_secnum; i++, sec++) {
+ if (sec->dofs_type == DOF_SECT_STRTAB)
+ dofstrtab = (unsigned char *)(buf + sec->dofs_offset);
+ else if (sec->dofs_type == DOF_SECT_PROBES && dofstrtab)
+ break;
+
+ }
+ nprobes = sec->dofs_size / sec->dofs_entsize;
+ fixsymbol(e, symtabdata, symtabidx, nprobes, buf, sec, &fixedprobes,
+ dofstrtab);
+ if (fixedprobes != nprobes) {
+ /*
+ * If we haven't fixed all the probes using the
+ * symtab section, look inside the dynsym
+ * section.
+ */
+ fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, sec,
+ &fixedprobes, dofstrtab);
+ }
+ if (fixedprobes != nprobes) {
+ fprintf(stderr, "WARNING: number of probes "
+ "fixed does not match the number of "
+ "defined probes (%d != %d, "
+ "respectively)\n", fixedprobes, nprobes);
+ fprintf(stderr, "WARNING: some probes might "
+ "not fire or your program might crash\n");
+ }
+#endif
+ if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
+ dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
+ else {
+ dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof);
+#if !defined(sun)
+ gen = dh.gen;
+#endif
+ }
+
+ (void) close(fd);
+#if !defined(sun)
+ elf_end(e);
+ (void) close(efd);
+#endif
+}
+
+#if defined(sun)
+#pragma fini(dtrace_dof_fini)
+#else
+static void dtrace_dof_fini(void) __attribute__ ((destructor));
+#endif
+
+static void
+dtrace_dof_fini(void)
+{
+ int fd;
+
+ if ((fd = open64(devnamep, O_RDWR)) < 0) {
+ dprintf(1, "failed to open helper device %s", devnamep);
+ return;
+ }
+
+ if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, &gen)) == -1)
+ dprintf(1, "DTrace ioctl failed to remove DOF (%d)\n", gen);
+ else
+ dprintf(1, "DTrace ioctl removed DOF (%d)\n", gen);
+
+ (void) close(fd);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
new file mode 100644
index 0000000..42b6645
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
@@ -0,0 +1,1966 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dt_impl.h>
+#include <assert.h>
+#if defined(sun)
+#include <alloca.h>
+#else
+#include <sys/sysctl.h>
+#include <libproc_compat.h>
+#endif
+#include <limits.h>
+
+#define DTRACE_AHASHSIZE 32779 /* big 'ol prime */
+
+/*
+ * Because qsort(3C) does not allow an argument to be passed to a comparison
+ * function, the variables that affect comparison must regrettably be global;
+ * they are protected by a global static lock, dt_qsort_lock.
+ */
+static pthread_mutex_t dt_qsort_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static int dt_revsort;
+static int dt_keysort;
+static int dt_keypos;
+
+#define DT_LESSTHAN (dt_revsort == 0 ? -1 : 1)
+#define DT_GREATERTHAN (dt_revsort == 0 ? 1 : -1)
+
+static void
+dt_aggregate_count(int64_t *existing, int64_t *new, size_t size)
+{
+ uint_t i;
+
+ for (i = 0; i < size / sizeof (int64_t); i++)
+ existing[i] = existing[i] + new[i];
+}
+
+static int
+dt_aggregate_countcmp(int64_t *lhs, int64_t *rhs)
+{
+ int64_t lvar = *lhs;
+ int64_t rvar = *rhs;
+
+ if (lvar < rvar)
+ return (DT_LESSTHAN);
+
+ if (lvar > rvar)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static void
+dt_aggregate_min(int64_t *existing, int64_t *new, size_t size)
+{
+ if (*new < *existing)
+ *existing = *new;
+}
+
+/*ARGSUSED*/
+static void
+dt_aggregate_max(int64_t *existing, int64_t *new, size_t size)
+{
+ if (*new > *existing)
+ *existing = *new;
+}
+
+static int
+dt_aggregate_averagecmp(int64_t *lhs, int64_t *rhs)
+{
+ int64_t lavg = lhs[0] ? (lhs[1] / lhs[0]) : 0;
+ int64_t ravg = rhs[0] ? (rhs[1] / rhs[0]) : 0;
+
+ if (lavg < ravg)
+ return (DT_LESSTHAN);
+
+ if (lavg > ravg)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static int
+dt_aggregate_stddevcmp(int64_t *lhs, int64_t *rhs)
+{
+ uint64_t lsd = dt_stddev((uint64_t *)lhs, 1);
+ uint64_t rsd = dt_stddev((uint64_t *)rhs, 1);
+
+ if (lsd < rsd)
+ return (DT_LESSTHAN);
+
+ if (lsd > rsd)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static void
+dt_aggregate_lquantize(int64_t *existing, int64_t *new, size_t size)
+{
+ int64_t arg = *existing++;
+ uint16_t levels = DTRACE_LQUANTIZE_LEVELS(arg);
+ int i;
+
+ for (i = 0; i <= levels + 1; i++)
+ existing[i] = existing[i] + new[i + 1];
+}
+
+static long double
+dt_aggregate_lquantizedsum(int64_t *lquanta)
+{
+ int64_t arg = *lquanta++;
+ int32_t base = DTRACE_LQUANTIZE_BASE(arg);
+ uint16_t step = DTRACE_LQUANTIZE_STEP(arg);
+ uint16_t levels = DTRACE_LQUANTIZE_LEVELS(arg), i;
+ long double total = (long double)lquanta[0] * (long double)(base - 1);
+
+ for (i = 0; i < levels; base += step, i++)
+ total += (long double)lquanta[i + 1] * (long double)base;
+
+ return (total + (long double)lquanta[levels + 1] *
+ (long double)(base + 1));
+}
+
+static int64_t
+dt_aggregate_lquantizedzero(int64_t *lquanta)
+{
+ int64_t arg = *lquanta++;
+ int32_t base = DTRACE_LQUANTIZE_BASE(arg);
+ uint16_t step = DTRACE_LQUANTIZE_STEP(arg);
+ uint16_t levels = DTRACE_LQUANTIZE_LEVELS(arg), i;
+
+ if (base - 1 == 0)
+ return (lquanta[0]);
+
+ for (i = 0; i < levels; base += step, i++) {
+ if (base != 0)
+ continue;
+
+ return (lquanta[i + 1]);
+ }
+
+ if (base + 1 == 0)
+ return (lquanta[levels + 1]);
+
+ return (0);
+}
+
+static int
+dt_aggregate_lquantizedcmp(int64_t *lhs, int64_t *rhs)
+{
+ long double lsum = dt_aggregate_lquantizedsum(lhs);
+ long double rsum = dt_aggregate_lquantizedsum(rhs);
+ int64_t lzero, rzero;
+
+ if (lsum < rsum)
+ return (DT_LESSTHAN);
+
+ if (lsum > rsum)
+ return (DT_GREATERTHAN);
+
+ /*
+ * If they're both equal, then we will compare based on the weights at
+ * zero. If the weights at zero are equal (or if zero is not within
+ * the range of the linear quantization), then this will be judged a
+ * tie and will be resolved based on the key comparison.
+ */
+ lzero = dt_aggregate_lquantizedzero(lhs);
+ rzero = dt_aggregate_lquantizedzero(rhs);
+
+ if (lzero < rzero)
+ return (DT_LESSTHAN);
+
+ if (lzero > rzero)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static void
+dt_aggregate_llquantize(int64_t *existing, int64_t *new, size_t size)
+{
+ int i;
+
+ for (i = 1; i < size / sizeof (int64_t); i++)
+ existing[i] = existing[i] + new[i];
+}
+
+static long double
+dt_aggregate_llquantizedsum(int64_t *llquanta)
+{
+ int64_t arg = *llquanta++;
+ uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+ uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
+ uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
+ uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+ int bin = 0, order;
+ int64_t value = 1, next, step;
+ long double total;
+
+ assert(nsteps >= factor);
+ assert(nsteps % factor == 0);
+
+ for (order = 0; order < low; order++)
+ value *= factor;
+
+ total = (long double)llquanta[bin++] * (long double)(value - 1);
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+
+ while (order <= high) {
+ assert(value < next);
+ total += (long double)llquanta[bin++] * (long double)(value);
+
+ if ((value += step) != next)
+ continue;
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+ order++;
+ }
+
+ return (total + (long double)llquanta[bin] * (long double)value);
+}
+
+static int
+dt_aggregate_llquantizedcmp(int64_t *lhs, int64_t *rhs)
+{
+ long double lsum = dt_aggregate_llquantizedsum(lhs);
+ long double rsum = dt_aggregate_llquantizedsum(rhs);
+ int64_t lzero, rzero;
+
+ if (lsum < rsum)
+ return (DT_LESSTHAN);
+
+ if (lsum > rsum)
+ return (DT_GREATERTHAN);
+
+ /*
+ * If they're both equal, then we will compare based on the weights at
+ * zero. If the weights at zero are equal, then this will be judged a
+ * tie and will be resolved based on the key comparison.
+ */
+ lzero = lhs[1];
+ rzero = rhs[1];
+
+ if (lzero < rzero)
+ return (DT_LESSTHAN);
+
+ if (lzero > rzero)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static int
+dt_aggregate_quantizedcmp(int64_t *lhs, int64_t *rhs)
+{
+ int nbuckets = DTRACE_QUANTIZE_NBUCKETS;
+ long double ltotal = 0, rtotal = 0;
+ int64_t lzero, rzero;
+ uint_t i;
+
+ for (i = 0; i < nbuckets; i++) {
+ int64_t bucketval = DTRACE_QUANTIZE_BUCKETVAL(i);
+
+ if (bucketval == 0) {
+ lzero = lhs[i];
+ rzero = rhs[i];
+ }
+
+ ltotal += (long double)bucketval * (long double)lhs[i];
+ rtotal += (long double)bucketval * (long double)rhs[i];
+ }
+
+ if (ltotal < rtotal)
+ return (DT_LESSTHAN);
+
+ if (ltotal > rtotal)
+ return (DT_GREATERTHAN);
+
+ /*
+ * If they're both equal, then we will compare based on the weights at
+ * zero. If the weights at zero are equal, then this will be judged a
+ * tie and will be resolved based on the key comparison.
+ */
+ if (lzero < rzero)
+ return (DT_LESSTHAN);
+
+ if (lzero > rzero)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static void
+dt_aggregate_usym(dtrace_hdl_t *dtp, uint64_t *data)
+{
+ uint64_t pid = data[0];
+ uint64_t *pc = &data[1];
+ struct ps_prochandle *P;
+ GElf_Sym sym;
+
+ if (dtp->dt_vector != NULL)
+ return;
+
+ if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0)) == NULL)
+ return;
+
+ dt_proc_lock(dtp, P);
+
+ if (Plookup_by_addr(P, *pc, NULL, 0, &sym) == 0)
+ *pc = sym.st_value;
+
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+}
+
+static void
+dt_aggregate_umod(dtrace_hdl_t *dtp, uint64_t *data)
+{
+ uint64_t pid = data[0];
+ uint64_t *pc = &data[1];
+ struct ps_prochandle *P;
+ const prmap_t *map;
+
+ if (dtp->dt_vector != NULL)
+ return;
+
+ if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0)) == NULL)
+ return;
+
+ dt_proc_lock(dtp, P);
+
+ if ((map = Paddr_to_map(P, *pc)) != NULL)
+ *pc = map->pr_vaddr;
+
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+}
+
+static void
+dt_aggregate_sym(dtrace_hdl_t *dtp, uint64_t *data)
+{
+ GElf_Sym sym;
+ uint64_t *pc = data;
+
+ if (dtrace_lookup_by_addr(dtp, *pc, &sym, NULL) == 0)
+ *pc = sym.st_value;
+}
+
+static void
+dt_aggregate_mod(dtrace_hdl_t *dtp, uint64_t *data)
+{
+ uint64_t *pc = data;
+ dt_module_t *dmp;
+
+ if (dtp->dt_vector != NULL) {
+ /*
+ * We don't have a way of just getting the module for a
+ * vectored open, and it doesn't seem to be worth defining
+ * one. This means that use of mod() won't get true
+ * aggregation in the postmortem case (some modules may
+ * appear more than once in aggregation output). It seems
+ * unlikely that anyone will ever notice or care...
+ */
+ return;
+ }
+
+ for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;
+ dmp = dt_list_next(dmp)) {
+ if (*pc - dmp->dm_text_va < dmp->dm_text_size) {
+ *pc = dmp->dm_text_va;
+ return;
+ }
+ }
+}
+
+static dtrace_aggvarid_t
+dt_aggregate_aggvarid(dt_ahashent_t *ent)
+{
+ dtrace_aggdesc_t *agg = ent->dtahe_data.dtada_desc;
+ caddr_t data = ent->dtahe_data.dtada_data;
+ dtrace_recdesc_t *rec = agg->dtagd_rec;
+
+ /*
+ * First, we'll check the variable ID in the aggdesc. If it's valid,
+ * we'll return it. If not, we'll use the compiler-generated ID
+ * present as the first record.
+ */
+ if (agg->dtagd_varid != DTRACE_AGGVARIDNONE)
+ return (agg->dtagd_varid);
+
+ agg->dtagd_varid = *((dtrace_aggvarid_t *)(uintptr_t)(data +
+ rec->dtrd_offset));
+
+ return (agg->dtagd_varid);
+}
+
+
+static int
+dt_aggregate_snap_cpu(dtrace_hdl_t *dtp, processorid_t cpu)
+{
+ dtrace_epid_t id;
+ uint64_t hashval;
+ size_t offs, roffs, size, ndx;
+ int i, j, rval;
+ caddr_t addr, data;
+ dtrace_recdesc_t *rec;
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dtrace_aggdesc_t *agg;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ dt_ahashent_t *h;
+ dtrace_bufdesc_t b = agp->dtat_buf, *buf = &b;
+ dtrace_aggdata_t *aggdata;
+ int flags = agp->dtat_flags;
+
+ buf->dtbd_cpu = cpu;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_AGGSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_AGGSNAP, &buf) == -1) {
+#endif
+ if (errno == ENOENT) {
+ /*
+ * If that failed with ENOENT, it may be because the
+ * CPU was unconfigured. This is okay; we'll just
+ * do nothing but return success.
+ */
+ return (0);
+ }
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if (buf->dtbd_drops != 0) {
+ if (dt_handle_cpudrop(dtp, cpu,
+ DTRACEDROP_AGGREGATION, buf->dtbd_drops) == -1)
+ return (-1);
+ }
+
+ if (buf->dtbd_size == 0)
+ return (0);
+
+ if (hash->dtah_hash == NULL) {
+ size_t size;
+
+ hash->dtah_size = DTRACE_AHASHSIZE;
+ size = hash->dtah_size * sizeof (dt_ahashent_t *);
+
+ if ((hash->dtah_hash = malloc(size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ bzero(hash->dtah_hash, size);
+ }
+
+ for (offs = 0; offs < buf->dtbd_size; ) {
+ /*
+ * We're guaranteed to have an ID.
+ */
+ id = *((dtrace_epid_t *)((uintptr_t)buf->dtbd_data +
+ (uintptr_t)offs));
+
+ if (id == DTRACE_AGGIDNONE) {
+ /*
+ * This is filler to assure proper alignment of the
+ * next record; we simply ignore it.
+ */
+ offs += sizeof (id);
+ continue;
+ }
+
+ if ((rval = dt_aggid_lookup(dtp, id, &agg)) != 0)
+ return (rval);
+
+ addr = buf->dtbd_data + offs;
+ size = agg->dtagd_size;
+ hashval = 0;
+
+ for (j = 0; j < agg->dtagd_nrecs - 1; j++) {
+ rec = &agg->dtagd_rec[j];
+ roffs = rec->dtrd_offset;
+
+ switch (rec->dtrd_action) {
+ case DTRACEACT_USYM:
+ dt_aggregate_usym(dtp,
+ /* LINTED - alignment */
+ (uint64_t *)&addr[roffs]);
+ break;
+
+ case DTRACEACT_UMOD:
+ dt_aggregate_umod(dtp,
+ /* LINTED - alignment */
+ (uint64_t *)&addr[roffs]);
+ break;
+
+ case DTRACEACT_SYM:
+ /* LINTED - alignment */
+ dt_aggregate_sym(dtp, (uint64_t *)&addr[roffs]);
+ break;
+
+ case DTRACEACT_MOD:
+ /* LINTED - alignment */
+ dt_aggregate_mod(dtp, (uint64_t *)&addr[roffs]);
+ break;
+
+ default:
+ break;
+ }
+
+ for (i = 0; i < rec->dtrd_size; i++)
+ hashval += addr[roffs + i];
+ }
+
+ ndx = hashval % hash->dtah_size;
+
+ for (h = hash->dtah_hash[ndx]; h != NULL; h = h->dtahe_next) {
+ if (h->dtahe_hashval != hashval)
+ continue;
+
+ if (h->dtahe_size != size)
+ continue;
+
+ aggdata = &h->dtahe_data;
+ data = aggdata->dtada_data;
+
+ for (j = 0; j < agg->dtagd_nrecs - 1; j++) {
+ rec = &agg->dtagd_rec[j];
+ roffs = rec->dtrd_offset;
+
+ for (i = 0; i < rec->dtrd_size; i++)
+ if (addr[roffs + i] != data[roffs + i])
+ goto hashnext;
+ }
+
+ /*
+ * We found it. Now we need to apply the aggregating
+ * action on the data here.
+ */
+ rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1];
+ roffs = rec->dtrd_offset;
+ /* LINTED - alignment */
+ h->dtahe_aggregate((int64_t *)&data[roffs],
+ /* LINTED - alignment */
+ (int64_t *)&addr[roffs], rec->dtrd_size);
+
+ /*
+ * If we're keeping per CPU data, apply the aggregating
+ * action there as well.
+ */
+ if (aggdata->dtada_percpu != NULL) {
+ data = aggdata->dtada_percpu[cpu];
+
+ /* LINTED - alignment */
+ h->dtahe_aggregate((int64_t *)data,
+ /* LINTED - alignment */
+ (int64_t *)&addr[roffs], rec->dtrd_size);
+ }
+
+ goto bufnext;
+hashnext:
+ continue;
+ }
+
+ /*
+ * If we're here, we couldn't find an entry for this record.
+ */
+ if ((h = malloc(sizeof (dt_ahashent_t))) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ bzero(h, sizeof (dt_ahashent_t));
+ aggdata = &h->dtahe_data;
+
+ if ((aggdata->dtada_data = malloc(size)) == NULL) {
+ free(h);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bcopy(addr, aggdata->dtada_data, size);
+ aggdata->dtada_size = size;
+ aggdata->dtada_desc = agg;
+ aggdata->dtada_handle = dtp;
+ (void) dt_epid_lookup(dtp, agg->dtagd_epid,
+ &aggdata->dtada_edesc, &aggdata->dtada_pdesc);
+ aggdata->dtada_normal = 1;
+
+ h->dtahe_hashval = hashval;
+ h->dtahe_size = size;
+ (void) dt_aggregate_aggvarid(h);
+
+ rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1];
+
+ if (flags & DTRACE_A_PERCPU) {
+ int max_cpus = agp->dtat_maxcpu;
+ caddr_t *percpu = malloc(max_cpus * sizeof (caddr_t));
+
+ if (percpu == NULL) {
+ free(aggdata->dtada_data);
+ free(h);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ for (j = 0; j < max_cpus; j++) {
+ percpu[j] = malloc(rec->dtrd_size);
+
+ if (percpu[j] == NULL) {
+ while (--j >= 0)
+ free(percpu[j]);
+
+ free(aggdata->dtada_data);
+ free(h);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ if (j == cpu) {
+ bcopy(&addr[rec->dtrd_offset],
+ percpu[j], rec->dtrd_size);
+ } else {
+ bzero(percpu[j], rec->dtrd_size);
+ }
+ }
+
+ aggdata->dtada_percpu = percpu;
+ }
+
+ switch (rec->dtrd_action) {
+ case DTRACEAGG_MIN:
+ h->dtahe_aggregate = dt_aggregate_min;
+ break;
+
+ case DTRACEAGG_MAX:
+ h->dtahe_aggregate = dt_aggregate_max;
+ break;
+
+ case DTRACEAGG_LQUANTIZE:
+ h->dtahe_aggregate = dt_aggregate_lquantize;
+ break;
+
+ case DTRACEAGG_LLQUANTIZE:
+ h->dtahe_aggregate = dt_aggregate_llquantize;
+ break;
+
+ case DTRACEAGG_COUNT:
+ case DTRACEAGG_SUM:
+ case DTRACEAGG_AVG:
+ case DTRACEAGG_STDDEV:
+ case DTRACEAGG_QUANTIZE:
+ h->dtahe_aggregate = dt_aggregate_count;
+ break;
+
+ default:
+ return (dt_set_errno(dtp, EDT_BADAGG));
+ }
+
+ if (hash->dtah_hash[ndx] != NULL)
+ hash->dtah_hash[ndx]->dtahe_prev = h;
+
+ h->dtahe_next = hash->dtah_hash[ndx];
+ hash->dtah_hash[ndx] = h;
+
+ if (hash->dtah_all != NULL)
+ hash->dtah_all->dtahe_prevall = h;
+
+ h->dtahe_nextall = hash->dtah_all;
+ hash->dtah_all = h;
+bufnext:
+ offs += agg->dtagd_size;
+ }
+
+ return (0);
+}
+
+int
+dtrace_aggregate_snap(dtrace_hdl_t *dtp)
+{
+ int i, rval;
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ hrtime_t now = gethrtime();
+ dtrace_optval_t interval = dtp->dt_options[DTRACEOPT_AGGRATE];
+
+ if (dtp->dt_lastagg != 0) {
+ if (now - dtp->dt_lastagg < interval)
+ return (0);
+
+ dtp->dt_lastagg += interval;
+ } else {
+ dtp->dt_lastagg = now;
+ }
+
+ if (!dtp->dt_active)
+ return (dt_set_errno(dtp, EINVAL));
+
+ if (agp->dtat_buf.dtbd_size == 0)
+ return (0);
+
+ for (i = 0; i < agp->dtat_ncpus; i++) {
+ if ((rval = dt_aggregate_snap_cpu(dtp, agp->dtat_cpus[i])))
+ return (rval);
+ }
+
+ return (0);
+}
+
+static int
+dt_aggregate_hashcmp(const void *lhs, const void *rhs)
+{
+ dt_ahashent_t *lh = *((dt_ahashent_t **)lhs);
+ dt_ahashent_t *rh = *((dt_ahashent_t **)rhs);
+ dtrace_aggdesc_t *lagg = lh->dtahe_data.dtada_desc;
+ dtrace_aggdesc_t *ragg = rh->dtahe_data.dtada_desc;
+
+ if (lagg->dtagd_nrecs < ragg->dtagd_nrecs)
+ return (DT_LESSTHAN);
+
+ if (lagg->dtagd_nrecs > ragg->dtagd_nrecs)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static int
+dt_aggregate_varcmp(const void *lhs, const void *rhs)
+{
+ dt_ahashent_t *lh = *((dt_ahashent_t **)lhs);
+ dt_ahashent_t *rh = *((dt_ahashent_t **)rhs);
+ dtrace_aggvarid_t lid, rid;
+
+ lid = dt_aggregate_aggvarid(lh);
+ rid = dt_aggregate_aggvarid(rh);
+
+ if (lid < rid)
+ return (DT_LESSTHAN);
+
+ if (lid > rid)
+ return (DT_GREATERTHAN);
+
+ return (0);
+}
+
+static int
+dt_aggregate_keycmp(const void *lhs, const void *rhs)
+{
+ dt_ahashent_t *lh = *((dt_ahashent_t **)lhs);
+ dt_ahashent_t *rh = *((dt_ahashent_t **)rhs);
+ dtrace_aggdesc_t *lagg = lh->dtahe_data.dtada_desc;
+ dtrace_aggdesc_t *ragg = rh->dtahe_data.dtada_desc;
+ dtrace_recdesc_t *lrec, *rrec;
+ char *ldata, *rdata;
+ int rval, i, j, keypos, nrecs;
+
+ if ((rval = dt_aggregate_hashcmp(lhs, rhs)) != 0)
+ return (rval);
+
+ nrecs = lagg->dtagd_nrecs - 1;
+ assert(nrecs == ragg->dtagd_nrecs - 1);
+
+ keypos = dt_keypos + 1 >= nrecs ? 0 : dt_keypos;
+
+ for (i = 1; i < nrecs; i++) {
+ uint64_t lval, rval;
+ int ndx = i + keypos;
+
+ if (ndx >= nrecs)
+ ndx = ndx - nrecs + 1;
+
+ lrec = &lagg->dtagd_rec[ndx];
+ rrec = &ragg->dtagd_rec[ndx];
+
+ ldata = lh->dtahe_data.dtada_data + lrec->dtrd_offset;
+ rdata = rh->dtahe_data.dtada_data + rrec->dtrd_offset;
+
+ if (lrec->dtrd_size < rrec->dtrd_size)
+ return (DT_LESSTHAN);
+
+ if (lrec->dtrd_size > rrec->dtrd_size)
+ return (DT_GREATERTHAN);
+
+ switch (lrec->dtrd_size) {
+ case sizeof (uint64_t):
+ /* LINTED - alignment */
+ lval = *((uint64_t *)ldata);
+ /* LINTED - alignment */
+ rval = *((uint64_t *)rdata);
+ break;
+
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ lval = *((uint32_t *)ldata);
+ /* LINTED - alignment */
+ rval = *((uint32_t *)rdata);
+ break;
+
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ lval = *((uint16_t *)ldata);
+ /* LINTED - alignment */
+ rval = *((uint16_t *)rdata);
+ break;
+
+ case sizeof (uint8_t):
+ lval = *((uint8_t *)ldata);
+ rval = *((uint8_t *)rdata);
+ break;
+
+ default:
+ switch (lrec->dtrd_action) {
+ case DTRACEACT_UMOD:
+ case DTRACEACT_UADDR:
+ case DTRACEACT_USYM:
+ for (j = 0; j < 2; j++) {
+ /* LINTED - alignment */
+ lval = ((uint64_t *)ldata)[j];
+ /* LINTED - alignment */
+ rval = ((uint64_t *)rdata)[j];
+
+ if (lval < rval)
+ return (DT_LESSTHAN);
+
+ if (lval > rval)
+ return (DT_GREATERTHAN);
+ }
+
+ break;
+
+ default:
+ for (j = 0; j < lrec->dtrd_size; j++) {
+ lval = ((uint8_t *)ldata)[j];
+ rval = ((uint8_t *)rdata)[j];
+
+ if (lval < rval)
+ return (DT_LESSTHAN);
+
+ if (lval > rval)
+ return (DT_GREATERTHAN);
+ }
+ }
+
+ continue;
+ }
+
+ if (lval < rval)
+ return (DT_LESSTHAN);
+
+ if (lval > rval)
+ return (DT_GREATERTHAN);
+ }
+
+ return (0);
+}
+
+static int
+dt_aggregate_valcmp(const void *lhs, const void *rhs)
+{
+ dt_ahashent_t *lh = *((dt_ahashent_t **)lhs);
+ dt_ahashent_t *rh = *((dt_ahashent_t **)rhs);
+ dtrace_aggdesc_t *lagg = lh->dtahe_data.dtada_desc;
+ dtrace_aggdesc_t *ragg = rh->dtahe_data.dtada_desc;
+ caddr_t ldata = lh->dtahe_data.dtada_data;
+ caddr_t rdata = rh->dtahe_data.dtada_data;
+ dtrace_recdesc_t *lrec, *rrec;
+ int64_t *laddr, *raddr;
+ int rval, i;
+
+ if ((rval = dt_aggregate_hashcmp(lhs, rhs)) != 0)
+ return (rval);
+
+ if (lagg->dtagd_nrecs > ragg->dtagd_nrecs)
+ return (DT_GREATERTHAN);
+
+ if (lagg->dtagd_nrecs < ragg->dtagd_nrecs)
+ return (DT_LESSTHAN);
+
+ for (i = 0; i < lagg->dtagd_nrecs; i++) {
+ lrec = &lagg->dtagd_rec[i];
+ rrec = &ragg->dtagd_rec[i];
+
+ if (lrec->dtrd_offset < rrec->dtrd_offset)
+ return (DT_LESSTHAN);
+
+ if (lrec->dtrd_offset > rrec->dtrd_offset)
+ return (DT_GREATERTHAN);
+
+ if (lrec->dtrd_action < rrec->dtrd_action)
+ return (DT_LESSTHAN);
+
+ if (lrec->dtrd_action > rrec->dtrd_action)
+ return (DT_GREATERTHAN);
+ }
+
+ laddr = (int64_t *)(uintptr_t)(ldata + lrec->dtrd_offset);
+ raddr = (int64_t *)(uintptr_t)(rdata + rrec->dtrd_offset);
+
+ switch (lrec->dtrd_action) {
+ case DTRACEAGG_AVG:
+ rval = dt_aggregate_averagecmp(laddr, raddr);
+ break;
+
+ case DTRACEAGG_STDDEV:
+ rval = dt_aggregate_stddevcmp(laddr, raddr);
+ break;
+
+ case DTRACEAGG_QUANTIZE:
+ rval = dt_aggregate_quantizedcmp(laddr, raddr);
+ break;
+
+ case DTRACEAGG_LQUANTIZE:
+ rval = dt_aggregate_lquantizedcmp(laddr, raddr);
+ break;
+
+ case DTRACEAGG_LLQUANTIZE:
+ rval = dt_aggregate_llquantizedcmp(laddr, raddr);
+ break;
+
+ case DTRACEAGG_COUNT:
+ case DTRACEAGG_SUM:
+ case DTRACEAGG_MIN:
+ case DTRACEAGG_MAX:
+ rval = dt_aggregate_countcmp(laddr, raddr);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ return (rval);
+}
+
+static int
+dt_aggregate_valkeycmp(const void *lhs, const void *rhs)
+{
+ int rval;
+
+ if ((rval = dt_aggregate_valcmp(lhs, rhs)) != 0)
+ return (rval);
+
+ /*
+ * If we're here, the values for the two aggregation elements are
+ * equal. We already know that the key layout is the same for the two
+ * elements; we must now compare the keys themselves as a tie-breaker.
+ */
+ return (dt_aggregate_keycmp(lhs, rhs));
+}
+
+static int
+dt_aggregate_keyvarcmp(const void *lhs, const void *rhs)
+{
+ int rval;
+
+ if ((rval = dt_aggregate_keycmp(lhs, rhs)) != 0)
+ return (rval);
+
+ return (dt_aggregate_varcmp(lhs, rhs));
+}
+
+static int
+dt_aggregate_varkeycmp(const void *lhs, const void *rhs)
+{
+ int rval;
+
+ if ((rval = dt_aggregate_varcmp(lhs, rhs)) != 0)
+ return (rval);
+
+ return (dt_aggregate_keycmp(lhs, rhs));
+}
+
+static int
+dt_aggregate_valvarcmp(const void *lhs, const void *rhs)
+{
+ int rval;
+
+ if ((rval = dt_aggregate_valkeycmp(lhs, rhs)) != 0)
+ return (rval);
+
+ return (dt_aggregate_varcmp(lhs, rhs));
+}
+
+static int
+dt_aggregate_varvalcmp(const void *lhs, const void *rhs)
+{
+ int rval;
+
+ if ((rval = dt_aggregate_varcmp(lhs, rhs)) != 0)
+ return (rval);
+
+ return (dt_aggregate_valkeycmp(lhs, rhs));
+}
+
+static int
+dt_aggregate_keyvarrevcmp(const void *lhs, const void *rhs)
+{
+ return (dt_aggregate_keyvarcmp(rhs, lhs));
+}
+
+static int
+dt_aggregate_varkeyrevcmp(const void *lhs, const void *rhs)
+{
+ return (dt_aggregate_varkeycmp(rhs, lhs));
+}
+
+static int
+dt_aggregate_valvarrevcmp(const void *lhs, const void *rhs)
+{
+ return (dt_aggregate_valvarcmp(rhs, lhs));
+}
+
+static int
+dt_aggregate_varvalrevcmp(const void *lhs, const void *rhs)
+{
+ return (dt_aggregate_varvalcmp(rhs, lhs));
+}
+
+static int
+dt_aggregate_bundlecmp(const void *lhs, const void *rhs)
+{
+ dt_ahashent_t **lh = *((dt_ahashent_t ***)lhs);
+ dt_ahashent_t **rh = *((dt_ahashent_t ***)rhs);
+ int i, rval;
+
+ if (dt_keysort) {
+ /*
+ * If we're sorting on keys, we need to scan until we find the
+ * last entry -- that's the representative key. (The order of
+ * the bundle is values followed by key to accommodate the
+ * default behavior of sorting by value.) If the keys are
+ * equal, we'll fall into the value comparison loop, below.
+ */
+ for (i = 0; lh[i + 1] != NULL; i++)
+ continue;
+
+ assert(i != 0);
+ assert(rh[i + 1] == NULL);
+
+ if ((rval = dt_aggregate_keycmp(&lh[i], &rh[i])) != 0)
+ return (rval);
+ }
+
+ for (i = 0; ; i++) {
+ if (lh[i + 1] == NULL) {
+ /*
+ * All of the values are equal; if we're sorting on
+ * keys, then we're only here because the keys were
+ * found to be equal and these records are therefore
+ * equal. If we're not sorting on keys, we'll use the
+ * key comparison from the representative key as the
+ * tie-breaker.
+ */
+ if (dt_keysort)
+ return (0);
+
+ assert(i != 0);
+ assert(rh[i + 1] == NULL);
+ return (dt_aggregate_keycmp(&lh[i], &rh[i]));
+ } else {
+ if ((rval = dt_aggregate_valcmp(&lh[i], &rh[i])) != 0)
+ return (rval);
+ }
+ }
+}
+
+int
+dt_aggregate_go(dtrace_hdl_t *dtp)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dtrace_optval_t size, cpu;
+ dtrace_bufdesc_t *buf = &agp->dtat_buf;
+ int rval, i;
+
+ assert(agp->dtat_maxcpu == 0);
+ assert(agp->dtat_ncpu == 0);
+ assert(agp->dtat_cpus == NULL);
+
+ agp->dtat_maxcpu = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
+ agp->dtat_ncpu = dt_sysconf(dtp, _SC_NPROCESSORS_MAX);
+ agp->dtat_cpus = malloc(agp->dtat_ncpu * sizeof (processorid_t));
+
+ if (agp->dtat_cpus == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ /*
+ * Use the aggregation buffer size as reloaded from the kernel.
+ */
+ size = dtp->dt_options[DTRACEOPT_AGGSIZE];
+
+ rval = dtrace_getopt(dtp, "aggsize", &size);
+ assert(rval == 0);
+
+ if (size == 0 || size == DTRACEOPT_UNSET)
+ return (0);
+
+ buf = &agp->dtat_buf;
+ buf->dtbd_size = size;
+
+ if ((buf->dtbd_data = malloc(buf->dtbd_size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ /*
+ * Now query for the CPUs enabled.
+ */
+ rval = dtrace_getopt(dtp, "cpu", &cpu);
+ assert(rval == 0 && cpu != DTRACEOPT_UNSET);
+
+ if (cpu != DTRACE_CPUALL) {
+ assert(cpu < agp->dtat_ncpu);
+ agp->dtat_cpus[agp->dtat_ncpus++] = (processorid_t)cpu;
+
+ return (0);
+ }
+
+ agp->dtat_ncpus = 0;
+ for (i = 0; i < agp->dtat_maxcpu; i++) {
+ if (dt_status(dtp, i) == -1)
+ continue;
+
+ agp->dtat_cpus[agp->dtat_ncpus++] = i;
+ }
+
+ return (0);
+}
+
+static int
+dt_aggwalk_rval(dtrace_hdl_t *dtp, dt_ahashent_t *h, int rval)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dtrace_aggdata_t *data;
+ dtrace_aggdesc_t *aggdesc;
+ dtrace_recdesc_t *rec;
+ int i;
+
+ switch (rval) {
+ case DTRACE_AGGWALK_NEXT:
+ break;
+
+ case DTRACE_AGGWALK_CLEAR: {
+ uint32_t size, offs = 0;
+
+ aggdesc = h->dtahe_data.dtada_desc;
+ rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1];
+ size = rec->dtrd_size;
+ data = &h->dtahe_data;
+
+ if (rec->dtrd_action == DTRACEAGG_LQUANTIZE) {
+ offs = sizeof (uint64_t);
+ size -= sizeof (uint64_t);
+ }
+
+ bzero(&data->dtada_data[rec->dtrd_offset] + offs, size);
+
+ if (data->dtada_percpu == NULL)
+ break;
+
+ for (i = 0; i < dtp->dt_aggregate.dtat_maxcpu; i++)
+ bzero(data->dtada_percpu[i] + offs, size);
+ break;
+ }
+
+ case DTRACE_AGGWALK_ERROR:
+ /*
+ * We assume that errno is already set in this case.
+ */
+ return (dt_set_errno(dtp, errno));
+
+ case DTRACE_AGGWALK_ABORT:
+ return (dt_set_errno(dtp, EDT_DIRABORT));
+
+ case DTRACE_AGGWALK_DENORMALIZE:
+ h->dtahe_data.dtada_normal = 1;
+ return (0);
+
+ case DTRACE_AGGWALK_NORMALIZE:
+ if (h->dtahe_data.dtada_normal == 0) {
+ h->dtahe_data.dtada_normal = 1;
+ return (dt_set_errno(dtp, EDT_BADRVAL));
+ }
+
+ return (0);
+
+ case DTRACE_AGGWALK_REMOVE: {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data;
+ int max_cpus = agp->dtat_maxcpu;
+
+ /*
+ * First, remove this hash entry from its hash chain.
+ */
+ if (h->dtahe_prev != NULL) {
+ h->dtahe_prev->dtahe_next = h->dtahe_next;
+ } else {
+ dt_ahash_t *hash = &agp->dtat_hash;
+ size_t ndx = h->dtahe_hashval % hash->dtah_size;
+
+ assert(hash->dtah_hash[ndx] == h);
+ hash->dtah_hash[ndx] = h->dtahe_next;
+ }
+
+ if (h->dtahe_next != NULL)
+ h->dtahe_next->dtahe_prev = h->dtahe_prev;
+
+ /*
+ * Now remove it from the list of all hash entries.
+ */
+ if (h->dtahe_prevall != NULL) {
+ h->dtahe_prevall->dtahe_nextall = h->dtahe_nextall;
+ } else {
+ dt_ahash_t *hash = &agp->dtat_hash;
+
+ assert(hash->dtah_all == h);
+ hash->dtah_all = h->dtahe_nextall;
+ }
+
+ if (h->dtahe_nextall != NULL)
+ h->dtahe_nextall->dtahe_prevall = h->dtahe_prevall;
+
+ /*
+ * We're unlinked. We can safely destroy the data.
+ */
+ if (aggdata->dtada_percpu != NULL) {
+ for (i = 0; i < max_cpus; i++)
+ free(aggdata->dtada_percpu[i]);
+ free(aggdata->dtada_percpu);
+ }
+
+ free(aggdata->dtada_data);
+ free(h);
+
+ return (0);
+ }
+
+ default:
+ return (dt_set_errno(dtp, EDT_BADRVAL));
+ }
+
+ return (0);
+}
+
+void
+dt_aggregate_qsort(dtrace_hdl_t *dtp, void *base, size_t nel, size_t width,
+ int (*compar)(const void *, const void *))
+{
+ int rev = dt_revsort, key = dt_keysort, keypos = dt_keypos;
+ dtrace_optval_t keyposopt = dtp->dt_options[DTRACEOPT_AGGSORTKEYPOS];
+
+ dt_revsort = (dtp->dt_options[DTRACEOPT_AGGSORTREV] != DTRACEOPT_UNSET);
+ dt_keysort = (dtp->dt_options[DTRACEOPT_AGGSORTKEY] != DTRACEOPT_UNSET);
+
+ if (keyposopt != DTRACEOPT_UNSET && keyposopt <= INT_MAX) {
+ dt_keypos = (int)keyposopt;
+ } else {
+ dt_keypos = 0;
+ }
+
+ if (compar == NULL) {
+ if (!dt_keysort) {
+ compar = dt_aggregate_varvalcmp;
+ } else {
+ compar = dt_aggregate_varkeycmp;
+ }
+ }
+
+ qsort(base, nel, width, compar);
+
+ dt_revsort = rev;
+ dt_keysort = key;
+ dt_keypos = keypos;
+}
+
+int
+dtrace_aggregate_walk(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg)
+{
+ dt_ahashent_t *h, *next;
+ dt_ahash_t *hash = &dtp->dt_aggregate.dtat_hash;
+
+ for (h = hash->dtah_all; h != NULL; h = next) {
+ /*
+ * dt_aggwalk_rval() can potentially remove the current hash
+ * entry; we need to load the next hash entry before calling
+ * into it.
+ */
+ next = h->dtahe_nextall;
+
+ if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1)
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+dt_aggregate_walk_sorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg,
+ int (*sfunc)(const void *, const void *))
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahashent_t *h, **sorted;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ size_t i, nentries = 0;
+
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall)
+ nentries++;
+
+ sorted = dt_alloc(dtp, nentries * sizeof (dt_ahashent_t *));
+
+ if (sorted == NULL)
+ return (-1);
+
+ for (h = hash->dtah_all, i = 0; h != NULL; h = h->dtahe_nextall)
+ sorted[i++] = h;
+
+ (void) pthread_mutex_lock(&dt_qsort_lock);
+
+ if (sfunc == NULL) {
+ dt_aggregate_qsort(dtp, sorted, nentries,
+ sizeof (dt_ahashent_t *), NULL);
+ } else {
+ /*
+ * If we've been explicitly passed a sorting function,
+ * we'll use that -- ignoring the values of the "aggsortrev",
+ * "aggsortkey" and "aggsortkeypos" options.
+ */
+ qsort(sorted, nentries, sizeof (dt_ahashent_t *), sfunc);
+ }
+
+ (void) pthread_mutex_unlock(&dt_qsort_lock);
+
+ for (i = 0; i < nentries; i++) {
+ h = sorted[i];
+
+ if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1) {
+ dt_free(dtp, sorted);
+ return (-1);
+ }
+ }
+
+ dt_free(dtp, sorted);
+ return (0);
+}
+
+int
+dtrace_aggregate_walk_sorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func, arg, NULL));
+}
+
+int
+dtrace_aggregate_walk_keysorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_varkeycmp));
+}
+
+int
+dtrace_aggregate_walk_valsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_varvalcmp));
+}
+
+int
+dtrace_aggregate_walk_keyvarsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_keyvarcmp));
+}
+
+int
+dtrace_aggregate_walk_valvarsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_valvarcmp));
+}
+
+int
+dtrace_aggregate_walk_keyrevsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_varkeyrevcmp));
+}
+
+int
+dtrace_aggregate_walk_valrevsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_varvalrevcmp));
+}
+
+int
+dtrace_aggregate_walk_keyvarrevsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_keyvarrevcmp));
+}
+
+int
+dtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *dtp,
+ dtrace_aggregate_f *func, void *arg)
+{
+ return (dt_aggregate_walk_sorted(dtp, func,
+ arg, dt_aggregate_valvarrevcmp));
+}
+
+int
+dtrace_aggregate_walk_joined(dtrace_hdl_t *dtp, dtrace_aggvarid_t *aggvars,
+ int naggvars, dtrace_aggregate_walk_joined_f *func, void *arg)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahashent_t *h, **sorted = NULL, ***bundle, **nbundle;
+ const dtrace_aggdata_t **data;
+ dt_ahashent_t *zaggdata = NULL;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ size_t nentries = 0, nbundles = 0, start, zsize = 0, bundlesize;
+ dtrace_aggvarid_t max = 0, aggvar;
+ int rval = -1, *map, *remap = NULL;
+ int i, j;
+ dtrace_optval_t sortpos = dtp->dt_options[DTRACEOPT_AGGSORTPOS];
+
+ /*
+ * If the sorting position is greater than the number of aggregation
+ * variable IDs, we silently set it to 0.
+ */
+ if (sortpos == DTRACEOPT_UNSET || sortpos >= naggvars)
+ sortpos = 0;
+
+ /*
+ * First we need to translate the specified aggregation variable IDs
+ * into a linear map that will allow us to translate an aggregation
+ * variable ID into its position in the specified aggvars.
+ */
+ for (i = 0; i < naggvars; i++) {
+ if (aggvars[i] == DTRACE_AGGVARIDNONE || aggvars[i] < 0)
+ return (dt_set_errno(dtp, EDT_BADAGGVAR));
+
+ if (aggvars[i] > max)
+ max = aggvars[i];
+ }
+
+ if ((map = dt_zalloc(dtp, (max + 1) * sizeof (int))) == NULL)
+ return (-1);
+
+ zaggdata = dt_zalloc(dtp, naggvars * sizeof (dt_ahashent_t));
+
+ if (zaggdata == NULL)
+ goto out;
+
+ for (i = 0; i < naggvars; i++) {
+ int ndx = i + sortpos;
+
+ if (ndx >= naggvars)
+ ndx -= naggvars;
+
+ aggvar = aggvars[ndx];
+ assert(aggvar <= max);
+
+ if (map[aggvar]) {
+ /*
+ * We have an aggregation variable that is present
+ * more than once in the array of aggregation
+ * variables. While it's unclear why one might want
+ * to do this, it's legal. To support this construct,
+ * we will allocate a remap that will indicate the
+ * position from which this aggregation variable
+ * should be pulled. (That is, where the remap will
+ * map from one position to another.)
+ */
+ if (remap == NULL) {
+ remap = dt_zalloc(dtp, naggvars * sizeof (int));
+
+ if (remap == NULL)
+ goto out;
+ }
+
+ /*
+ * Given that the variable is already present, assert
+ * that following through the mapping and adjusting
+ * for the sort position yields the same aggregation
+ * variable ID.
+ */
+ assert(aggvars[(map[aggvar] - 1 + sortpos) %
+ naggvars] == aggvars[ndx]);
+
+ remap[i] = map[aggvar];
+ continue;
+ }
+
+ map[aggvar] = i + 1;
+ }
+
+ /*
+ * We need to take two passes over the data to size our allocation, so
+ * we'll use the first pass to also fill in the zero-filled data to be
+ * used to properly format a zero-valued aggregation.
+ */
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggvarid_t id;
+ int ndx;
+
+ if ((id = dt_aggregate_aggvarid(h)) > max || !(ndx = map[id]))
+ continue;
+
+ if (zaggdata[ndx - 1].dtahe_size == 0) {
+ zaggdata[ndx - 1].dtahe_size = h->dtahe_size;
+ zaggdata[ndx - 1].dtahe_data = h->dtahe_data;
+ }
+
+ nentries++;
+ }
+
+ if (nentries == 0) {
+ /*
+ * We couldn't find any entries; there is nothing else to do.
+ */
+ rval = 0;
+ goto out;
+ }
+
+ /*
+ * Before we sort the data, we're going to look for any holes in our
+ * zero-filled data. This will occur if an aggregation variable that
+ * we are being asked to print has not yet been assigned the result of
+ * any aggregating action for _any_ tuple. The issue becomes that we
+ * would like a zero value to be printed for all columns for this
+ * aggregation, but without any record description, we don't know the
+ * aggregating action that corresponds to the aggregation variable. To
+ * try to find a match, we're simply going to lookup aggregation IDs
+ * (which are guaranteed to be contiguous and to start from 1), looking
+ * for the specified aggregation variable ID. If we find a match,
+ * we'll use that. If we iterate over all aggregation IDs and don't
+ * find a match, then we must be an anonymous enabling. (Anonymous
+ * enablings can't currently derive either aggregation variable IDs or
+ * aggregation variable names given only an aggregation ID.) In this
+ * obscure case (anonymous enabling, multiple aggregation printa() with
+ * some aggregations not represented for any tuple), our defined
+ * behavior is that the zero will be printed in the format of the first
+ * aggregation variable that contains any non-zero value.
+ */
+ for (i = 0; i < naggvars; i++) {
+ if (zaggdata[i].dtahe_size == 0) {
+ dtrace_aggvarid_t aggvar;
+
+ aggvar = aggvars[(i - sortpos + naggvars) % naggvars];
+ assert(zaggdata[i].dtahe_data.dtada_data == NULL);
+
+ for (j = DTRACE_AGGIDNONE + 1; ; j++) {
+ dtrace_aggdesc_t *agg;
+ dtrace_aggdata_t *aggdata;
+
+ if (dt_aggid_lookup(dtp, j, &agg) != 0)
+ break;
+
+ if (agg->dtagd_varid != aggvar)
+ continue;
+
+ /*
+ * We have our description -- now we need to
+ * cons up the zaggdata entry for it.
+ */
+ aggdata = &zaggdata[i].dtahe_data;
+ aggdata->dtada_size = agg->dtagd_size;
+ aggdata->dtada_desc = agg;
+ aggdata->dtada_handle = dtp;
+ (void) dt_epid_lookup(dtp, agg->dtagd_epid,
+ &aggdata->dtada_edesc,
+ &aggdata->dtada_pdesc);
+ aggdata->dtada_normal = 1;
+ zaggdata[i].dtahe_hashval = 0;
+ zaggdata[i].dtahe_size = agg->dtagd_size;
+ break;
+ }
+
+ if (zaggdata[i].dtahe_size == 0) {
+ caddr_t data;
+
+ /*
+ * We couldn't find this aggregation, meaning
+ * that we have never seen it before for any
+ * tuple _and_ this is an anonymous enabling.
+ * That is, we're in the obscure case outlined
+ * above. In this case, our defined behavior
+ * is to format the data in the format of the
+ * first non-zero aggregation -- of which, of
+ * course, we know there to be at least one
+ * (or nentries would have been zero).
+ */
+ for (j = 0; j < naggvars; j++) {
+ if (zaggdata[j].dtahe_size != 0)
+ break;
+ }
+
+ assert(j < naggvars);
+ zaggdata[i] = zaggdata[j];
+
+ data = zaggdata[i].dtahe_data.dtada_data;
+ assert(data != NULL);
+ }
+ }
+ }
+
+ /*
+ * Now we need to allocate our zero-filled data for use for
+ * aggregations that don't have a value corresponding to a given key.
+ */
+ for (i = 0; i < naggvars; i++) {
+ dtrace_aggdata_t *aggdata = &zaggdata[i].dtahe_data;
+ dtrace_aggdesc_t *aggdesc = aggdata->dtada_desc;
+ dtrace_recdesc_t *rec;
+ uint64_t larg;
+ caddr_t zdata;
+
+ zsize = zaggdata[i].dtahe_size;
+ assert(zsize != 0);
+
+ if ((zdata = dt_zalloc(dtp, zsize)) == NULL) {
+ /*
+ * If we failed to allocated some zero-filled data, we
+ * need to zero out the remaining dtada_data pointers
+ * to prevent the wrong data from being freed below.
+ */
+ for (j = i; j < naggvars; j++)
+ zaggdata[j].dtahe_data.dtada_data = NULL;
+ goto out;
+ }
+
+ aggvar = aggvars[(i - sortpos + naggvars) % naggvars];
+
+ /*
+ * First, the easy bit. To maintain compatibility with
+ * consumers that pull the compiler-generated ID out of the
+ * data, we put that ID at the top of the zero-filled data.
+ */
+ rec = &aggdesc->dtagd_rec[0];
+ /* LINTED - alignment */
+ *((dtrace_aggvarid_t *)(zdata + rec->dtrd_offset)) = aggvar;
+
+ rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1];
+
+ /*
+ * Now for the more complicated part. If (and only if) this
+ * is an lquantize() aggregating action, zero-filled data is
+ * not equivalent to an empty record: we must also get the
+ * parameters for the lquantize().
+ */
+ if (rec->dtrd_action == DTRACEAGG_LQUANTIZE) {
+ if (aggdata->dtada_data != NULL) {
+ /*
+ * The easier case here is if we actually have
+ * some prototype data -- in which case we
+ * manually dig it out of the aggregation
+ * record.
+ */
+ /* LINTED - alignment */
+ larg = *((uint64_t *)(aggdata->dtada_data +
+ rec->dtrd_offset));
+ } else {
+ /*
+ * We don't have any prototype data. As a
+ * result, we know that we _do_ have the
+ * compiler-generated information. (If this
+ * were an anonymous enabling, all of our
+ * zero-filled data would have prototype data
+ * -- either directly or indirectly.) So as
+ * gross as it is, we'll grovel around in the
+ * compiler-generated information to find the
+ * lquantize() parameters.
+ */
+ dtrace_stmtdesc_t *sdp;
+ dt_ident_t *aid;
+ dt_idsig_t *isp;
+
+ sdp = (dtrace_stmtdesc_t *)(uintptr_t)
+ aggdesc->dtagd_rec[0].dtrd_uarg;
+ aid = sdp->dtsd_aggdata;
+ isp = (dt_idsig_t *)aid->di_data;
+ assert(isp->dis_auxinfo != 0);
+ larg = isp->dis_auxinfo;
+ }
+
+ /* LINTED - alignment */
+ *((uint64_t *)(zdata + rec->dtrd_offset)) = larg;
+ }
+
+ aggdata->dtada_data = zdata;
+ }
+
+ /*
+ * Now that we've dealt with setting up our zero-filled data, we can
+ * allocate our sorted array, and take another pass over the data to
+ * fill it.
+ */
+ sorted = dt_alloc(dtp, nentries * sizeof (dt_ahashent_t *));
+
+ if (sorted == NULL)
+ goto out;
+
+ for (h = hash->dtah_all, i = 0; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggvarid_t id;
+
+ if ((id = dt_aggregate_aggvarid(h)) > max || !map[id])
+ continue;
+
+ sorted[i++] = h;
+ }
+
+ assert(i == nentries);
+
+ /*
+ * We've loaded our array; now we need to sort by value to allow us
+ * to create bundles of like value. We're going to acquire the
+ * dt_qsort_lock here, and hold it across all of our subsequent
+ * comparison and sorting.
+ */
+ (void) pthread_mutex_lock(&dt_qsort_lock);
+
+ qsort(sorted, nentries, sizeof (dt_ahashent_t *),
+ dt_aggregate_keyvarcmp);
+
+ /*
+ * Now we need to go through and create bundles. Because the number
+ * of bundles is bounded by the size of the sorted array, we're going
+ * to reuse the underlying storage. And note that "bundle" is an
+ * array of pointers to arrays of pointers to dt_ahashent_t -- making
+ * its type (regrettably) "dt_ahashent_t ***". (Regrettable because
+ * '*' -- like '_' and 'X' -- should never appear in triplicate in
+ * an ideal world.)
+ */
+ bundle = (dt_ahashent_t ***)sorted;
+
+ for (i = 1, start = 0; i <= nentries; i++) {
+ if (i < nentries &&
+ dt_aggregate_keycmp(&sorted[i], &sorted[i - 1]) == 0)
+ continue;
+
+ /*
+ * We have a bundle boundary. Everything from start to
+ * (i - 1) belongs in one bundle.
+ */
+ assert(i - start <= naggvars);
+ bundlesize = (naggvars + 2) * sizeof (dt_ahashent_t *);
+
+ if ((nbundle = dt_zalloc(dtp, bundlesize)) == NULL) {
+ (void) pthread_mutex_unlock(&dt_qsort_lock);
+ goto out;
+ }
+
+ for (j = start; j < i; j++) {
+ dtrace_aggvarid_t id = dt_aggregate_aggvarid(sorted[j]);
+
+ assert(id <= max);
+ assert(map[id] != 0);
+ assert(map[id] - 1 < naggvars);
+ assert(nbundle[map[id] - 1] == NULL);
+ nbundle[map[id] - 1] = sorted[j];
+
+ if (nbundle[naggvars] == NULL)
+ nbundle[naggvars] = sorted[j];
+ }
+
+ for (j = 0; j < naggvars; j++) {
+ if (nbundle[j] != NULL)
+ continue;
+
+ /*
+ * Before we assume that this aggregation variable
+ * isn't present (and fall back to using the
+ * zero-filled data allocated earlier), check the
+ * remap. If we have a remapping, we'll drop it in
+ * here. Note that we might be remapping an
+ * aggregation variable that isn't present for this
+ * key; in this case, the aggregation data that we
+ * copy will point to the zeroed data.
+ */
+ if (remap != NULL && remap[j]) {
+ assert(remap[j] - 1 < j);
+ assert(nbundle[remap[j] - 1] != NULL);
+ nbundle[j] = nbundle[remap[j] - 1];
+ } else {
+ nbundle[j] = &zaggdata[j];
+ }
+ }
+
+ bundle[nbundles++] = nbundle;
+ start = i;
+ }
+
+ /*
+ * Now we need to re-sort based on the first value.
+ */
+ dt_aggregate_qsort(dtp, bundle, nbundles, sizeof (dt_ahashent_t **),
+ dt_aggregate_bundlecmp);
+
+ (void) pthread_mutex_unlock(&dt_qsort_lock);
+
+ /*
+ * We're done! Now we just need to go back over the sorted bundles,
+ * calling the function.
+ */
+ data = alloca((naggvars + 1) * sizeof (dtrace_aggdata_t *));
+
+ for (i = 0; i < nbundles; i++) {
+ for (j = 0; j < naggvars; j++)
+ data[j + 1] = NULL;
+
+ for (j = 0; j < naggvars; j++) {
+ int ndx = j - sortpos;
+
+ if (ndx < 0)
+ ndx += naggvars;
+
+ assert(bundle[i][ndx] != NULL);
+ data[j + 1] = &bundle[i][ndx]->dtahe_data;
+ }
+
+ for (j = 0; j < naggvars; j++)
+ assert(data[j + 1] != NULL);
+
+ /*
+ * The representative key is the last element in the bundle.
+ * Assert that we have one, and then set it to be the first
+ * element of data.
+ */
+ assert(bundle[i][j] != NULL);
+ data[0] = &bundle[i][j]->dtahe_data;
+
+ if ((rval = func(data, naggvars + 1, arg)) == -1)
+ goto out;
+ }
+
+ rval = 0;
+out:
+ for (i = 0; i < nbundles; i++)
+ dt_free(dtp, bundle[i]);
+
+ if (zaggdata != NULL) {
+ for (i = 0; i < naggvars; i++)
+ dt_free(dtp, zaggdata[i].dtahe_data.dtada_data);
+ }
+
+ dt_free(dtp, zaggdata);
+ dt_free(dtp, sorted);
+ dt_free(dtp, remap);
+ dt_free(dtp, map);
+
+ return (rval);
+}
+
+int
+dtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp,
+ dtrace_aggregate_walk_f *func)
+{
+ dt_print_aggdata_t pd;
+
+ pd.dtpa_dtp = dtp;
+ pd.dtpa_fp = fp;
+ pd.dtpa_allunprint = 1;
+
+ if (func == NULL)
+ func = dtrace_aggregate_walk_sorted;
+
+ if ((*func)(dtp, dt_print_agg, &pd) == -1)
+ return (dt_set_errno(dtp, dtp->dt_errno));
+
+ return (0);
+}
+
+void
+dtrace_aggregate_clear(dtrace_hdl_t *dtp)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ dt_ahashent_t *h;
+ dtrace_aggdata_t *data;
+ dtrace_aggdesc_t *aggdesc;
+ dtrace_recdesc_t *rec;
+ int i, max_cpus = agp->dtat_maxcpu;
+
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ aggdesc = h->dtahe_data.dtada_desc;
+ rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1];
+ data = &h->dtahe_data;
+
+ bzero(&data->dtada_data[rec->dtrd_offset], rec->dtrd_size);
+
+ if (data->dtada_percpu == NULL)
+ continue;
+
+ for (i = 0; i < max_cpus; i++)
+ bzero(data->dtada_percpu[i], rec->dtrd_size);
+ }
+}
+
+void
+dt_aggregate_destroy(dtrace_hdl_t *dtp)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ dt_ahashent_t *h, *next;
+ dtrace_aggdata_t *aggdata;
+ int i, max_cpus = agp->dtat_maxcpu;
+
+ if (hash->dtah_hash == NULL) {
+ assert(hash->dtah_all == NULL);
+ } else {
+ free(hash->dtah_hash);
+
+ for (h = hash->dtah_all; h != NULL; h = next) {
+ next = h->dtahe_nextall;
+
+ aggdata = &h->dtahe_data;
+
+ if (aggdata->dtada_percpu != NULL) {
+ for (i = 0; i < max_cpus; i++)
+ free(aggdata->dtada_percpu[i]);
+ free(aggdata->dtada_percpu);
+ }
+
+ free(aggdata->dtada_data);
+ free(h);
+ }
+
+ hash->dtah_hash = NULL;
+ hash->dtah_all = NULL;
+ hash->dtah_size = 0;
+ }
+
+ free(agp->dtat_buf.dtbd_data);
+ free(agp->dtat_cpus);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
new file mode 100644
index 0000000..457b8fd
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
@@ -0,0 +1,501 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <dt_impl.h>
+#include <dt_parser.h>
+#include <dt_as.h>
+
+void
+dt_irlist_create(dt_irlist_t *dlp)
+{
+ bzero(dlp, sizeof (dt_irlist_t));
+ dlp->dl_label = 1;
+}
+
+void
+dt_irlist_destroy(dt_irlist_t *dlp)
+{
+ dt_irnode_t *dip, *nip;
+
+ for (dip = dlp->dl_list; dip != NULL; dip = nip) {
+ nip = dip->di_next;
+ free(dip);
+ }
+}
+
+void
+dt_irlist_append(dt_irlist_t *dlp, dt_irnode_t *dip)
+{
+ if (dlp->dl_last != NULL)
+ dlp->dl_last->di_next = dip;
+ else
+ dlp->dl_list = dip;
+
+ dlp->dl_last = dip;
+
+ if (dip->di_label == DT_LBL_NONE || dip->di_instr != DIF_INSTR_NOP)
+ dlp->dl_len++; /* don't count forward refs in instr count */
+}
+
+uint_t
+dt_irlist_label(dt_irlist_t *dlp)
+{
+ return (dlp->dl_label++);
+}
+
+/*ARGSUSED*/
+static int
+dt_countvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
+{
+ size_t *np = data;
+
+ if (idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW))
+ (*np)++; /* include variable in vartab */
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
+{
+ dt_pcb_t *pcb = data;
+ dtrace_difv_t *dvp;
+ ssize_t stroff;
+ dt_node_t dn;
+
+ if (!(idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW)))
+ return (0); /* omit variable from vartab */
+
+ dvp = &pcb->pcb_difo->dtdo_vartab[pcb->pcb_asvidx++];
+ stroff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name);
+
+ if (stroff == -1L)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ if (stroff > DIF_STROFF_MAX)
+ longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG);
+
+ dvp->dtdv_name = (uint_t)stroff;
+ dvp->dtdv_id = idp->di_id;
+ dvp->dtdv_flags = 0;
+
+ dvp->dtdv_kind = (idp->di_kind == DT_IDENT_ARRAY) ?
+ DIFV_KIND_ARRAY : DIFV_KIND_SCALAR;
+
+ if (idp->di_flags & DT_IDFLG_LOCAL)
+ dvp->dtdv_scope = DIFV_SCOPE_LOCAL;
+ else if (idp->di_flags & DT_IDFLG_TLS)
+ dvp->dtdv_scope = DIFV_SCOPE_THREAD;
+ else
+ dvp->dtdv_scope = DIFV_SCOPE_GLOBAL;
+
+ if (idp->di_flags & DT_IDFLG_DIFR)
+ dvp->dtdv_flags |= DIFV_F_REF;
+ if (idp->di_flags & DT_IDFLG_DIFW)
+ dvp->dtdv_flags |= DIFV_F_MOD;
+
+ bzero(&dn, sizeof (dn));
+ dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type);
+ dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type);
+
+ idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW);
+ return (0);
+}
+
+static ssize_t
+dt_copystr(const char *s, size_t n, size_t off, dt_pcb_t *pcb)
+{
+ bcopy(s, pcb->pcb_difo->dtdo_strtab + off, n);
+ return (n);
+}
+
+/*
+ * Rewrite the xlate/xlarg instruction at dtdo_buf[i] so that the instruction's
+ * xltab index reflects the offset 'xi' of the assigned dtdo_xlmtab[] location.
+ * We track the cumulative references to translators and members in the pcb's
+ * pcb_asxrefs[] array, a two-dimensional array of bitmaps indexed by the
+ * global translator id and then by the corresponding translator member id.
+ */
+static void
+dt_as_xlate(dt_pcb_t *pcb, dtrace_difo_t *dp,
+ uint_t i, uint_t xi, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = pcb->pcb_hdl;
+ dt_xlator_t *dxp = dnp->dn_membexpr->dn_xlator;
+
+ assert(i < dp->dtdo_len);
+ assert(xi < dp->dtdo_xlmlen);
+
+ assert(dnp->dn_kind == DT_NODE_MEMBER);
+ assert(dnp->dn_membexpr->dn_kind == DT_NODE_XLATOR);
+
+ assert(dxp->dx_id < dtp->dt_xlatorid);
+ assert(dnp->dn_membid < dxp->dx_nmembers);
+
+ if (pcb->pcb_asxrefs == NULL) {
+ pcb->pcb_asxreflen = dtp->dt_xlatorid;
+ pcb->pcb_asxrefs =
+ dt_zalloc(dtp, sizeof (ulong_t *) * pcb->pcb_asxreflen);
+ if (pcb->pcb_asxrefs == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ if (pcb->pcb_asxrefs[dxp->dx_id] == NULL) {
+ pcb->pcb_asxrefs[dxp->dx_id] =
+ dt_zalloc(dtp, BT_SIZEOFMAP(dxp->dx_nmembers));
+ if (pcb->pcb_asxrefs[dxp->dx_id] == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ dp->dtdo_buf[i] = DIF_INSTR_XLATE(
+ DIF_INSTR_OP(dp->dtdo_buf[i]), xi, DIF_INSTR_RD(dp->dtdo_buf[i]));
+
+ BT_SET(pcb->pcb_asxrefs[dxp->dx_id], dnp->dn_membid);
+ dp->dtdo_xlmtab[xi] = dnp;
+}
+
+static void
+dt_as_undef(const dt_ident_t *idp, uint_t offset)
+{
+ const char *kind, *mark = (idp->di_flags & DT_IDFLG_USER) ? "``" : "`";
+ const dtrace_syminfo_t *dts = idp->di_data;
+
+ if (idp->di_flags & DT_IDFLG_USER)
+ kind = "user";
+ else if (idp->di_flags & DT_IDFLG_PRIM)
+ kind = "primary kernel";
+ else
+ kind = "loadable kernel";
+
+ yylineno = idp->di_lineno;
+
+ xyerror(D_ASRELO, "relocation remains against %s symbol %s%s%s (offset "
+ "0x%x)\n", kind, dts->dts_object, mark, dts->dts_name, offset);
+}
+
+dtrace_difo_t *
+dt_as(dt_pcb_t *pcb)
+{
+ dtrace_hdl_t *dtp = pcb->pcb_hdl;
+ dt_irlist_t *dlp = &pcb->pcb_ir;
+ uint_t *labels = NULL;
+ dt_irnode_t *dip;
+ dtrace_difo_t *dp;
+ dt_ident_t *idp;
+
+ size_t n = 0;
+ uint_t i;
+
+ uint_t kmask, kbits, umask, ubits;
+ uint_t krel = 0, urel = 0, xlrefs = 0;
+
+ /*
+ * Select bitmasks based upon the desired symbol linking policy. We
+ * test (di_extern->di_flags & xmask) == xbits to determine if the
+ * symbol should have a relocation entry generated in the loop below.
+ *
+ * DT_LINK_KERNEL = kernel symbols static, user symbols dynamic
+ * DT_LINK_PRIMARY = primary kernel symbols static, others dynamic
+ * DT_LINK_DYNAMIC = all symbols dynamic
+ * DT_LINK_STATIC = all symbols static
+ *
+ * By 'static' we mean that we use the symbol's value at compile-time
+ * in the final DIF. By 'dynamic' we mean that we create a relocation
+ * table entry for the symbol's value so it can be relocated later.
+ */
+ switch (dtp->dt_linkmode) {
+ case DT_LINK_KERNEL:
+ kmask = 0;
+ kbits = -1u;
+ umask = DT_IDFLG_USER;
+ ubits = DT_IDFLG_USER;
+ break;
+ case DT_LINK_PRIMARY:
+ kmask = DT_IDFLG_USER | DT_IDFLG_PRIM;
+ kbits = 0;
+ umask = DT_IDFLG_USER;
+ ubits = DT_IDFLG_USER;
+ break;
+ case DT_LINK_DYNAMIC:
+ kmask = DT_IDFLG_USER;
+ kbits = 0;
+ umask = DT_IDFLG_USER;
+ ubits = DT_IDFLG_USER;
+ break;
+ case DT_LINK_STATIC:
+ kmask = umask = 0;
+ kbits = ubits = -1u;
+ break;
+ default:
+ xyerror(D_UNKNOWN, "internal error -- invalid link mode %u\n",
+ dtp->dt_linkmode);
+ }
+
+ assert(pcb->pcb_difo == NULL);
+ pcb->pcb_difo = dt_zalloc(dtp, sizeof (dtrace_difo_t));
+
+ if ((dp = pcb->pcb_difo) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * dlp->dl_len);
+
+ if (dp->dtdo_buf == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if ((labels = dt_alloc(dtp, sizeof (uint_t) * dlp->dl_label)) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * Make an initial pass through the instruction list, filling in the
+ * instruction buffer with valid instructions and skipping labeled nops.
+ * While doing this, we also fill in our labels[] translation table
+ * and we count up the number of relocation table entries we will need.
+ */
+ for (i = 0, dip = dlp->dl_list; dip != NULL; dip = dip->di_next) {
+ if (dip->di_label != DT_LBL_NONE)
+ labels[dip->di_label] = i;
+
+ if (dip->di_label == DT_LBL_NONE ||
+ dip->di_instr != DIF_INSTR_NOP)
+ dp->dtdo_buf[i++] = dip->di_instr;
+
+ if (dip->di_extern == NULL)
+ continue; /* no external references needed */
+
+ switch (DIF_INSTR_OP(dip->di_instr)) {
+ case DIF_OP_SETX:
+ idp = dip->di_extern;
+ if ((idp->di_flags & kmask) == kbits)
+ krel++;
+ else if ((idp->di_flags & umask) == ubits)
+ urel++;
+ break;
+ case DIF_OP_XLATE:
+ case DIF_OP_XLARG:
+ xlrefs++;
+ break;
+ default:
+ xyerror(D_UNKNOWN, "unexpected assembler relocation "
+ "for opcode 0x%x\n", DIF_INSTR_OP(dip->di_instr));
+ }
+ }
+
+ assert(i == dlp->dl_len);
+ dp->dtdo_len = dlp->dl_len;
+
+ /*
+ * Make a second pass through the instructions, relocating each branch
+ * label to the index of the final instruction in the buffer and noting
+ * any other instruction-specific DIFO flags such as dtdo_destructive.
+ */
+ for (i = 0; i < dp->dtdo_len; i++) {
+ dif_instr_t instr = dp->dtdo_buf[i];
+ uint_t op = DIF_INSTR_OP(instr);
+
+ if (op == DIF_OP_CALL) {
+ if (DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUT ||
+ DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUTSTR)
+ dp->dtdo_destructive = 1;
+ continue;
+ }
+
+ if (op >= DIF_OP_BA && op <= DIF_OP_BLEU) {
+ assert(DIF_INSTR_LABEL(instr) < dlp->dl_label);
+ dp->dtdo_buf[i] = DIF_INSTR_BRANCH(op,
+ labels[DIF_INSTR_LABEL(instr)]);
+ }
+ }
+
+ dt_free(dtp, labels);
+ pcb->pcb_asvidx = 0;
+
+ /*
+ * Allocate memory for the appropriate number of variable records and
+ * then fill in each variable record. As we populate the variable
+ * table we insert the corresponding variable names into the strtab.
+ */
+ (void) dt_idhash_iter(dtp->dt_tls, dt_countvar, &n);
+ (void) dt_idhash_iter(dtp->dt_globals, dt_countvar, &n);
+ (void) dt_idhash_iter(pcb->pcb_locals, dt_countvar, &n);
+
+ if (n != 0) {
+ dp->dtdo_vartab = dt_alloc(dtp, n * sizeof (dtrace_difv_t));
+ dp->dtdo_varlen = (uint32_t)n;
+
+ if (dp->dtdo_vartab == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ (void) dt_idhash_iter(dtp->dt_tls, dt_copyvar, pcb);
+ (void) dt_idhash_iter(dtp->dt_globals, dt_copyvar, pcb);
+ (void) dt_idhash_iter(pcb->pcb_locals, dt_copyvar, pcb);
+ }
+
+ /*
+ * Allocate memory for the appropriate number of relocation table
+ * entries based upon our kernel and user counts from the first pass.
+ */
+ if (krel != 0) {
+ dp->dtdo_kreltab = dt_alloc(dtp,
+ krel * sizeof (dof_relodesc_t));
+ dp->dtdo_krelen = krel;
+
+ if (dp->dtdo_kreltab == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ if (urel != 0) {
+ dp->dtdo_ureltab = dt_alloc(dtp,
+ urel * sizeof (dof_relodesc_t));
+ dp->dtdo_urelen = urel;
+
+ if (dp->dtdo_ureltab == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ if (xlrefs != 0) {
+ dp->dtdo_xlmtab = dt_zalloc(dtp, sizeof (dt_node_t *) * xlrefs);
+ dp->dtdo_xlmlen = xlrefs;
+
+ if (dp->dtdo_xlmtab == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ /*
+ * If any relocations are needed, make another pass through the
+ * instruction list and fill in the relocation table entries.
+ */
+ if (krel + urel + xlrefs != 0) {
+ uint_t knodef = pcb->pcb_cflags & DTRACE_C_KNODEF;
+ uint_t unodef = pcb->pcb_cflags & DTRACE_C_UNODEF;
+
+ dof_relodesc_t *krp = dp->dtdo_kreltab;
+ dof_relodesc_t *urp = dp->dtdo_ureltab;
+ dt_node_t **xlp = dp->dtdo_xlmtab;
+
+ i = 0; /* dtdo_buf[] index */
+
+ for (dip = dlp->dl_list; dip != NULL; dip = dip->di_next) {
+ dof_relodesc_t *rp;
+ ssize_t soff;
+ uint_t nodef;
+
+ if (dip->di_label != DT_LBL_NONE &&
+ dip->di_instr == DIF_INSTR_NOP)
+ continue; /* skip label declarations */
+
+ i++; /* advance dtdo_buf[] index */
+
+ if (DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLATE ||
+ DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLARG) {
+ assert(dp->dtdo_buf[i - 1] == dip->di_instr);
+ dt_as_xlate(pcb, dp, i - 1, (uint_t)
+ (xlp++ - dp->dtdo_xlmtab), dip->di_extern);
+ continue;
+ }
+
+ if ((idp = dip->di_extern) == NULL)
+ continue; /* no relocation entry needed */
+
+ if ((idp->di_flags & kmask) == kbits) {
+ nodef = knodef;
+ rp = krp++;
+ } else if ((idp->di_flags & umask) == ubits) {
+ nodef = unodef;
+ rp = urp++;
+ } else
+ continue;
+
+ if (!nodef)
+ dt_as_undef(idp, i);
+
+ assert(DIF_INSTR_OP(dip->di_instr) == DIF_OP_SETX);
+ soff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name);
+
+ if (soff == -1L)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+ if (soff > DIF_STROFF_MAX)
+ longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG);
+
+ rp->dofr_name = (dof_stridx_t)soff;
+ rp->dofr_type = DOF_RELO_SETX;
+ rp->dofr_offset = DIF_INSTR_INTEGER(dip->di_instr) *
+ sizeof (uint64_t);
+ rp->dofr_data = 0;
+ }
+
+ assert(krp == dp->dtdo_kreltab + dp->dtdo_krelen);
+ assert(urp == dp->dtdo_ureltab + dp->dtdo_urelen);
+ assert(xlp == dp->dtdo_xlmtab + dp->dtdo_xlmlen);
+ assert(i == dp->dtdo_len);
+ }
+
+ /*
+ * Allocate memory for the compiled string table and then copy the
+ * chunks from the string table into the final string buffer.
+ */
+ if ((n = dt_strtab_size(pcb->pcb_strtab)) != 0) {
+ if ((dp->dtdo_strtab = dt_alloc(dtp, n)) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ (void) dt_strtab_write(pcb->pcb_strtab,
+ (dt_strtab_write_f *)dt_copystr, pcb);
+ dp->dtdo_strlen = (uint32_t)n;
+ }
+
+ /*
+ * Allocate memory for the compiled integer table and then copy the
+ * integer constants from the table into the final integer buffer.
+ */
+ if ((n = dt_inttab_size(pcb->pcb_inttab)) != 0) {
+ if ((dp->dtdo_inttab = dt_alloc(dtp,
+ n * sizeof (uint64_t))) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dt_inttab_write(pcb->pcb_inttab, dp->dtdo_inttab);
+ dp->dtdo_intlen = (uint32_t)n;
+ }
+
+ /*
+ * Fill in the DIFO return type from the type associated with the
+ * node saved in pcb_dret, and then clear pcb_difo and pcb_dret
+ * now that the assembler has completed successfully.
+ */
+ dt_node_diftype(dtp, pcb->pcb_dret, &dp->dtdo_rtype);
+ pcb->pcb_difo = NULL;
+ pcb->pcb_dret = NULL;
+
+ if (pcb->pcb_cflags & DTRACE_C_DIFV)
+ dt_dis(dp, stderr);
+
+ return (dp);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.h
new file mode 100644
index 0000000..2acd940
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.h
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_AS_H
+#define _DT_AS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/dtrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_irnode {
+ uint_t di_label; /* label number or DT_LBL_NONE */
+ dif_instr_t di_instr; /* instruction opcode */
+ void *di_extern; /* opcode-specific external reference */
+ struct dt_irnode *di_next; /* next instruction */
+} dt_irnode_t;
+
+#define DT_LBL_NONE 0 /* no label on this instruction */
+
+typedef struct dt_irlist {
+ dt_irnode_t *dl_list; /* pointer to first node in list */
+ dt_irnode_t *dl_last; /* pointer to last node in list */
+ uint_t dl_len; /* number of valid instructions */
+ uint_t dl_label; /* next label number to assign */
+} dt_irlist_t;
+
+extern void dt_irlist_create(dt_irlist_t *);
+extern void dt_irlist_destroy(dt_irlist_t *);
+extern void dt_irlist_append(dt_irlist_t *, dt_irnode_t *);
+extern uint_t dt_irlist_label(dt_irlist_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_AS_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.c
new file mode 100644
index 0000000..324e778
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.c
@@ -0,0 +1,177 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * DTrace Memory Buffer Routines
+ *
+ * The routines in this file are used to create an automatically resizing
+ * memory buffer that can be written to like a file. Memory buffers are
+ * used to construct DOF to ioctl() to dtrace(7D), and provide semantics that
+ * simplify caller code. Specifically, any allocation errors result in an
+ * error code being set inside the buffer which is maintained persistently and
+ * propagates to another buffer if the buffer in error is concatenated. These
+ * semantics permit callers to execute a large series of writes without needing
+ * to check for errors and then perform a single check before using the buffer.
+ */
+
+#include <sys/sysmacros.h>
+#include <strings.h>
+
+#include <dt_impl.h>
+#include <dt_buf.h>
+
+void
+dt_buf_create(dtrace_hdl_t *dtp, dt_buf_t *bp, const char *name, size_t len)
+{
+ if (len == 0)
+ len = _dtrace_bufsize;
+
+ bp->dbu_buf = bp->dbu_ptr = dt_zalloc(dtp, len);
+ bp->dbu_len = len;
+
+ if (bp->dbu_buf == NULL)
+ bp->dbu_err = dtrace_errno(dtp);
+ else
+ bp->dbu_err = 0;
+
+ bp->dbu_resizes = 0;
+ bp->dbu_name = name;
+}
+
+void
+dt_buf_destroy(dtrace_hdl_t *dtp, dt_buf_t *bp)
+{
+ dt_dprintf("dt_buf_destroy(%s): size=%lu resizes=%u\n",
+ bp->dbu_name, (ulong_t)bp->dbu_len, bp->dbu_resizes);
+
+ dt_free(dtp, bp->dbu_buf);
+}
+
+void
+dt_buf_reset(dtrace_hdl_t *dtp, dt_buf_t *bp)
+{
+ if ((bp->dbu_ptr = bp->dbu_buf) != NULL)
+ bp->dbu_err = 0;
+ else
+ dt_buf_create(dtp, bp, bp->dbu_name, bp->dbu_len);
+}
+
+void
+dt_buf_write(dtrace_hdl_t *dtp, dt_buf_t *bp,
+ const void *buf, size_t len, size_t align)
+{
+ size_t off = (size_t)(bp->dbu_ptr - bp->dbu_buf);
+ size_t adj = roundup(off, align) - off;
+
+ if (bp->dbu_err != 0) {
+ (void) dt_set_errno(dtp, bp->dbu_err);
+ return; /* write silently fails */
+ }
+
+ if (bp->dbu_ptr + adj + len > bp->dbu_buf + bp->dbu_len) {
+ size_t new_len = bp->dbu_len * 2;
+ uchar_t *new_buf;
+ uint_t r = 1;
+
+ while (bp->dbu_ptr + adj + len > bp->dbu_buf + new_len) {
+ new_len *= 2;
+ r++;
+ }
+
+ if ((new_buf = dt_zalloc(dtp, new_len)) == NULL) {
+ bp->dbu_err = dtrace_errno(dtp);
+ return;
+ }
+
+ bcopy(bp->dbu_buf, new_buf, off);
+ dt_free(dtp, bp->dbu_buf);
+
+ bp->dbu_buf = new_buf;
+ bp->dbu_ptr = new_buf + off;
+ bp->dbu_len = new_len;
+ bp->dbu_resizes += r;
+ }
+
+ bp->dbu_ptr += adj;
+ bcopy(buf, bp->dbu_ptr, len);
+ bp->dbu_ptr += len;
+}
+
+void
+dt_buf_concat(dtrace_hdl_t *dtp, dt_buf_t *dst,
+ const dt_buf_t *src, size_t align)
+{
+ if (dst->dbu_err == 0 && src->dbu_err != 0) {
+ (void) dt_set_errno(dtp, src->dbu_err);
+ dst->dbu_err = src->dbu_err;
+ } else {
+ dt_buf_write(dtp, dst, src->dbu_buf,
+ (size_t)(src->dbu_ptr - src->dbu_buf), align);
+ }
+}
+
+size_t
+dt_buf_offset(const dt_buf_t *bp, size_t align)
+{
+ size_t off = (size_t)(bp->dbu_ptr - bp->dbu_buf);
+ return (roundup(off, align));
+}
+
+size_t
+dt_buf_len(const dt_buf_t *bp)
+{
+ return (bp->dbu_ptr - bp->dbu_buf);
+}
+
+int
+dt_buf_error(const dt_buf_t *bp)
+{
+ return (bp->dbu_err);
+}
+
+void *
+dt_buf_ptr(const dt_buf_t *bp)
+{
+ return (bp->dbu_buf);
+}
+
+void *
+dt_buf_claim(dtrace_hdl_t *dtp, dt_buf_t *bp)
+{
+ void *buf = bp->dbu_buf;
+
+ if (bp->dbu_err != 0) {
+ dt_free(dtp, buf);
+ buf = NULL;
+ }
+
+ bp->dbu_buf = bp->dbu_ptr = NULL;
+ bp->dbu_len = 0;
+
+ return (buf);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.h
new file mode 100644
index 0000000..eb93e13
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_buf.h
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_BUF_H
+#define _DT_BUF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dtrace.h>
+
+typedef struct dt_buf {
+ const char *dbu_name; /* string name for debugging */
+ uchar_t *dbu_buf; /* buffer base address */
+ uchar_t *dbu_ptr; /* current buffer location */
+ size_t dbu_len; /* buffer size in bytes */
+ int dbu_err; /* errno value if error */
+ int dbu_resizes; /* number of resizes */
+} dt_buf_t;
+
+extern void dt_buf_create(dtrace_hdl_t *, dt_buf_t *, const char *, size_t);
+extern void dt_buf_destroy(dtrace_hdl_t *, dt_buf_t *);
+extern void dt_buf_reset(dtrace_hdl_t *, dt_buf_t *);
+
+extern void dt_buf_write(dtrace_hdl_t *, dt_buf_t *,
+ const void *, size_t, size_t);
+
+extern void dt_buf_concat(dtrace_hdl_t *, dt_buf_t *,
+ const dt_buf_t *, size_t);
+
+extern size_t dt_buf_offset(const dt_buf_t *, size_t);
+extern size_t dt_buf_len(const dt_buf_t *);
+
+extern int dt_buf_error(const dt_buf_t *);
+extern void *dt_buf_ptr(const dt_buf_t *);
+
+extern void *dt_buf_claim(dtrace_hdl_t *, dt_buf_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_BUF_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
new file mode 100644
index 0000000..0ac4795
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -0,0 +1,2613 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+/*
+ * DTrace D Language Compiler
+ *
+ * The code in this source file implements the main engine for the D language
+ * compiler. The driver routine for the compiler is dt_compile(), below. The
+ * compiler operates on either stdio FILEs or in-memory strings as its input
+ * and can produce either dtrace_prog_t structures from a D program or a single
+ * dtrace_difo_t structure from a D expression. Multiple entry points are
+ * provided as wrappers around dt_compile() for the various input/output pairs.
+ * The compiler itself is implemented across the following source files:
+ *
+ * dt_lex.l - lex scanner
+ * dt_grammar.y - yacc grammar
+ * dt_parser.c - parse tree creation and semantic checking
+ * dt_decl.c - declaration stack processing
+ * dt_xlator.c - D translator lookup and creation
+ * dt_ident.c - identifier and symbol table routines
+ * dt_pragma.c - #pragma processing and D pragmas
+ * dt_printf.c - D printf() and printa() argument checking and processing
+ * dt_cc.c - compiler driver and dtrace_prog_t construction
+ * dt_cg.c - DIF code generator
+ * dt_as.c - DIF assembler
+ * dt_dof.c - dtrace_prog_t -> DOF conversion
+ *
+ * Several other source files provide collections of utility routines used by
+ * these major files. The compiler itself is implemented in multiple passes:
+ *
+ * (1) The input program is scanned and parsed by dt_lex.l and dt_grammar.y
+ * and parse tree nodes are constructed using the routines in dt_parser.c.
+ * This node construction pass is described further in dt_parser.c.
+ *
+ * (2) The parse tree is "cooked" by assigning each clause a context (see the
+ * routine dt_setcontext(), below) based on its probe description and then
+ * recursively descending the tree performing semantic checking. The cook
+ * routines are also implemented in dt_parser.c and described there.
+ *
+ * (3) For actions that are DIF expression statements, the DIF code generator
+ * and assembler are invoked to create a finished DIFO for the statement.
+ *
+ * (4) The dtrace_prog_t data structures for the program clauses and actions
+ * are built, containing pointers to any DIFOs created in step (3).
+ *
+ * (5) The caller invokes a routine in dt_dof.c to convert the finished program
+ * into DOF format for use in anonymous tracing or enabling in the kernel.
+ *
+ * In the implementation, steps 2-4 are intertwined in that they are performed
+ * in order for each clause as part of a loop that executes over the clauses.
+ *
+ * The D compiler currently implements nearly no optimization. The compiler
+ * implements integer constant folding as part of pass (1), and a set of very
+ * simple peephole optimizations as part of pass (3). As with any C compiler,
+ * a large number of optimizations are possible on both the intermediate data
+ * structures and the generated DIF code. These possibilities should be
+ * investigated in the context of whether they will have any substantive effect
+ * on the overall DTrace probe effect before they are undertaken.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/sysmacros.h>
+
+#include <assert.h>
+#include <string.h>
+#include <strings.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ucontext.h>
+#include <limits.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <dt_module.h>
+#include <dt_program.h>
+#include <dt_provider.h>
+#include <dt_printf.h>
+#include <dt_pid.h>
+#include <dt_grammar.h>
+#include <dt_ident.h>
+#include <dt_string.h>
+#include <dt_impl.h>
+
+static const dtrace_diftype_t dt_void_rtype = {
+ DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, 0
+};
+
+static const dtrace_diftype_t dt_int_rtype = {
+ DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, sizeof (uint64_t)
+};
+
+static void *dt_compile(dtrace_hdl_t *, int, dtrace_probespec_t, void *,
+ uint_t, int, char *const[], FILE *, const char *);
+
+
+/*ARGSUSED*/
+static int
+dt_idreset(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
+{
+ idp->di_flags &= ~(DT_IDFLG_REF | DT_IDFLG_MOD |
+ DT_IDFLG_DIFR | DT_IDFLG_DIFW);
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_idpragma(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
+{
+ yylineno = idp->di_lineno;
+ xyerror(D_PRAGMA_UNUSED, "unused #pragma %s\n", (char *)idp->di_iarg);
+ return (0);
+}
+
+static dtrace_stmtdesc_t *
+dt_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp,
+ dtrace_attribute_t descattr, dtrace_attribute_t stmtattr)
+{
+ dtrace_stmtdesc_t *sdp = dtrace_stmt_create(dtp, edp);
+
+ if (sdp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ assert(yypcb->pcb_stmt == NULL);
+ yypcb->pcb_stmt = sdp;
+
+ sdp->dtsd_descattr = descattr;
+ sdp->dtsd_stmtattr = stmtattr;
+
+ return (sdp);
+}
+
+static dtrace_actdesc_t *
+dt_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *new;
+
+ if ((new = dtrace_stmt_action(dtp, sdp)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ return (new);
+}
+
+/*
+ * Utility function to determine if a given action description is destructive.
+ * The dtdo_destructive bit is set for us by the DIF assembler (see dt_as.c).
+ */
+static int
+dt_action_destructive(const dtrace_actdesc_t *ap)
+{
+ return (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind) || (ap->dtad_kind ==
+ DTRACEACT_DIFEXPR && ap->dtad_difo->dtdo_destructive));
+}
+
+static void
+dt_stmt_append(dtrace_stmtdesc_t *sdp, const dt_node_t *dnp)
+{
+ dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
+ dtrace_actdesc_t *ap, *tap;
+ int commit = 0;
+ int speculate = 0;
+ int datarec = 0;
+
+ /*
+ * Make sure that the new statement jibes with the rest of the ECB.
+ */
+ for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
+ if (ap->dtad_kind == DTRACEACT_COMMIT) {
+ if (commit) {
+ dnerror(dnp, D_COMM_COMM, "commit( ) may "
+ "not follow commit( )\n");
+ }
+
+ if (datarec) {
+ dnerror(dnp, D_COMM_DREC, "commit( ) may "
+ "not follow data-recording action(s)\n");
+ }
+
+ for (tap = ap; tap != NULL; tap = tap->dtad_next) {
+ if (!DTRACEACT_ISAGG(tap->dtad_kind))
+ continue;
+
+ dnerror(dnp, D_AGG_COMM, "aggregating actions "
+ "may not follow commit( )\n");
+ }
+
+ commit = 1;
+ continue;
+ }
+
+ if (ap->dtad_kind == DTRACEACT_SPECULATE) {
+ if (speculate) {
+ dnerror(dnp, D_SPEC_SPEC, "speculate( ) may "
+ "not follow speculate( )\n");
+ }
+
+ if (commit) {
+ dnerror(dnp, D_SPEC_COMM, "speculate( ) may "
+ "not follow commit( )\n");
+ }
+
+ if (datarec) {
+ dnerror(dnp, D_SPEC_DREC, "speculate( ) may "
+ "not follow data-recording action(s)\n");
+ }
+
+ speculate = 1;
+ continue;
+ }
+
+ if (DTRACEACT_ISAGG(ap->dtad_kind)) {
+ if (speculate) {
+ dnerror(dnp, D_AGG_SPEC, "aggregating actions "
+ "may not follow speculate( )\n");
+ }
+
+ datarec = 1;
+ continue;
+ }
+
+ if (speculate) {
+ if (dt_action_destructive(ap)) {
+ dnerror(dnp, D_ACT_SPEC, "destructive actions "
+ "may not follow speculate( )\n");
+ }
+
+ if (ap->dtad_kind == DTRACEACT_EXIT) {
+ dnerror(dnp, D_EXIT_SPEC, "exit( ) may not "
+ "follow speculate( )\n");
+ }
+ }
+
+ /*
+ * Exclude all non data-recording actions.
+ */
+ if (dt_action_destructive(ap) ||
+ ap->dtad_kind == DTRACEACT_DISCARD)
+ continue;
+
+ if (ap->dtad_kind == DTRACEACT_DIFEXPR &&
+ ap->dtad_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_CTF &&
+ ap->dtad_difo->dtdo_rtype.dtdt_size == 0)
+ continue;
+
+ if (commit) {
+ dnerror(dnp, D_DREC_COMM, "data-recording actions "
+ "may not follow commit( )\n");
+ }
+
+ if (!speculate)
+ datarec = 1;
+ }
+
+ if (dtrace_stmt_add(yypcb->pcb_hdl, yypcb->pcb_prog, sdp) != 0)
+ longjmp(yypcb->pcb_jmpbuf, dtrace_errno(yypcb->pcb_hdl));
+
+ if (yypcb->pcb_stmt == sdp)
+ yypcb->pcb_stmt = NULL;
+}
+
+/*
+ * For the first element of an aggregation tuple or for printa(), we create a
+ * simple DIF program that simply returns the immediate value that is the ID
+ * of the aggregation itself. This could be optimized in the future by
+ * creating a new in-kernel dtad_kind that just returns an integer.
+ */
+static void
+dt_action_difconst(dtrace_actdesc_t *ap, uint_t id, dtrace_actkind_t kind)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_difo_t *dp = dt_zalloc(dtp, sizeof (dtrace_difo_t));
+
+ if (dp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * 2);
+ dp->dtdo_inttab = dt_alloc(dtp, sizeof (uint64_t));
+
+ if (dp->dtdo_buf == NULL || dp->dtdo_inttab == NULL) {
+ dt_difo_free(dtp, dp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ dp->dtdo_buf[0] = DIF_INSTR_SETX(0, 1); /* setx DIF_INTEGER[0], %r1 */
+ dp->dtdo_buf[1] = DIF_INSTR_RET(1); /* ret %r1 */
+ dp->dtdo_len = 2;
+ dp->dtdo_inttab[0] = id;
+ dp->dtdo_intlen = 1;
+ dp->dtdo_rtype = dt_int_rtype;
+
+ ap->dtad_difo = dp;
+ ap->dtad_kind = kind;
+}
+
+static void
+dt_action_clear(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dt_ident_t *aid;
+ dtrace_actdesc_t *ap;
+ dt_node_t *anp;
+
+ char n[DT_TYPE_NAMELEN];
+ int argc = 0;
+
+ for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
+ argc++; /* count up arguments for error messages below */
+
+ if (argc != 1) {
+ dnerror(dnp, D_CLEAR_PROTO,
+ "%s( ) prototype mismatch: %d args passed, 1 expected\n",
+ dnp->dn_ident->di_name, argc);
+ }
+
+ anp = dnp->dn_args;
+ assert(anp != NULL);
+
+ if (anp->dn_kind != DT_NODE_AGG) {
+ dnerror(dnp, D_CLEAR_AGGARG,
+ "%s( ) argument #1 is incompatible with prototype:\n"
+ "\tprototype: aggregation\n\t argument: %s\n",
+ dnp->dn_ident->di_name,
+ dt_node_type_name(anp, n, sizeof (n)));
+ }
+
+ aid = anp->dn_ident;
+
+ if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
+ dnerror(dnp, D_CLEAR_AGGBAD,
+ "undefined aggregation: @%s\n", aid->di_name);
+ }
+
+ ap = dt_stmt_action(dtp, sdp);
+ dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
+ ap->dtad_arg = DT_ACT_CLEAR;
+}
+
+static void
+dt_action_normalize(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dt_ident_t *aid;
+ dtrace_actdesc_t *ap;
+ dt_node_t *anp, *normal;
+ int denormal = (strcmp(dnp->dn_ident->di_name, "denormalize") == 0);
+
+ char n[DT_TYPE_NAMELEN];
+ int argc = 0;
+
+ for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
+ argc++; /* count up arguments for error messages below */
+
+ if ((denormal && argc != 1) || (!denormal && argc != 2)) {
+ dnerror(dnp, D_NORMALIZE_PROTO,
+ "%s( ) prototype mismatch: %d args passed, %d expected\n",
+ dnp->dn_ident->di_name, argc, denormal ? 1 : 2);
+ }
+
+ anp = dnp->dn_args;
+ assert(anp != NULL);
+
+ if (anp->dn_kind != DT_NODE_AGG) {
+ dnerror(dnp, D_NORMALIZE_AGGARG,
+ "%s( ) argument #1 is incompatible with prototype:\n"
+ "\tprototype: aggregation\n\t argument: %s\n",
+ dnp->dn_ident->di_name,
+ dt_node_type_name(anp, n, sizeof (n)));
+ }
+
+ if ((normal = anp->dn_list) != NULL && !dt_node_is_scalar(normal)) {
+ dnerror(dnp, D_NORMALIZE_SCALAR,
+ "%s( ) argument #2 must be of scalar type\n",
+ dnp->dn_ident->di_name);
+ }
+
+ aid = anp->dn_ident;
+
+ if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
+ dnerror(dnp, D_NORMALIZE_AGGBAD,
+ "undefined aggregation: @%s\n", aid->di_name);
+ }
+
+ ap = dt_stmt_action(dtp, sdp);
+ dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
+
+ if (denormal) {
+ ap->dtad_arg = DT_ACT_DENORMALIZE;
+ return;
+ }
+
+ ap->dtad_arg = DT_ACT_NORMALIZE;
+
+ assert(normal != NULL);
+ ap = dt_stmt_action(dtp, sdp);
+ dt_cg(yypcb, normal);
+
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_LIBACT;
+ ap->dtad_arg = DT_ACT_NORMALIZE;
+}
+
+static void
+dt_action_trunc(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dt_ident_t *aid;
+ dtrace_actdesc_t *ap;
+ dt_node_t *anp, *trunc;
+
+ char n[DT_TYPE_NAMELEN];
+ int argc = 0;
+
+ for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
+ argc++; /* count up arguments for error messages below */
+
+ if (argc > 2 || argc < 1) {
+ dnerror(dnp, D_TRUNC_PROTO,
+ "%s( ) prototype mismatch: %d args passed, %s expected\n",
+ dnp->dn_ident->di_name, argc,
+ argc < 1 ? "at least 1" : "no more than 2");
+ }
+
+ anp = dnp->dn_args;
+ assert(anp != NULL);
+ trunc = anp->dn_list;
+
+ if (anp->dn_kind != DT_NODE_AGG) {
+ dnerror(dnp, D_TRUNC_AGGARG,
+ "%s( ) argument #1 is incompatible with prototype:\n"
+ "\tprototype: aggregation\n\t argument: %s\n",
+ dnp->dn_ident->di_name,
+ dt_node_type_name(anp, n, sizeof (n)));
+ }
+
+ if (argc == 2) {
+ assert(trunc != NULL);
+ if (!dt_node_is_scalar(trunc)) {
+ dnerror(dnp, D_TRUNC_SCALAR,
+ "%s( ) argument #2 must be of scalar type\n",
+ dnp->dn_ident->di_name);
+ }
+ }
+
+ aid = anp->dn_ident;
+
+ if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
+ dnerror(dnp, D_TRUNC_AGGBAD,
+ "undefined aggregation: @%s\n", aid->di_name);
+ }
+
+ ap = dt_stmt_action(dtp, sdp);
+ dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
+ ap->dtad_arg = DT_ACT_TRUNC;
+
+ ap = dt_stmt_action(dtp, sdp);
+
+ if (argc == 1) {
+ dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
+ } else {
+ assert(trunc != NULL);
+ dt_cg(yypcb, trunc);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_LIBACT;
+ }
+
+ ap->dtad_arg = DT_ACT_TRUNC;
+}
+
+static void
+dt_action_printa(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dt_ident_t *aid, *fid;
+ dtrace_actdesc_t *ap;
+ const char *format;
+ dt_node_t *anp, *proto = NULL;
+
+ char n[DT_TYPE_NAMELEN];
+ int argc = 0, argr = 0;
+
+ for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
+ argc++; /* count up arguments for error messages below */
+
+ switch (dnp->dn_args->dn_kind) {
+ case DT_NODE_STRING:
+ format = dnp->dn_args->dn_string;
+ anp = dnp->dn_args->dn_list;
+ argr = 2;
+ break;
+ case DT_NODE_AGG:
+ format = NULL;
+ anp = dnp->dn_args;
+ argr = 1;
+ break;
+ default:
+ format = NULL;
+ anp = dnp->dn_args;
+ argr = 1;
+ }
+
+ if (argc < argr) {
+ dnerror(dnp, D_PRINTA_PROTO,
+ "%s( ) prototype mismatch: %d args passed, %d expected\n",
+ dnp->dn_ident->di_name, argc, argr);
+ }
+
+ assert(anp != NULL);
+
+ while (anp != NULL) {
+ if (anp->dn_kind != DT_NODE_AGG) {
+ dnerror(dnp, D_PRINTA_AGGARG,
+ "%s( ) argument #%d is incompatible with "
+ "prototype:\n\tprototype: aggregation\n"
+ "\t argument: %s\n", dnp->dn_ident->di_name, argr,
+ dt_node_type_name(anp, n, sizeof (n)));
+ }
+
+ aid = anp->dn_ident;
+ fid = aid->di_iarg;
+
+ if (aid->di_gen == dtp->dt_gen &&
+ !(aid->di_flags & DT_IDFLG_MOD)) {
+ dnerror(dnp, D_PRINTA_AGGBAD,
+ "undefined aggregation: @%s\n", aid->di_name);
+ }
+
+ /*
+ * If we have multiple aggregations, we must be sure that
+ * their key signatures match.
+ */
+ if (proto != NULL) {
+ dt_printa_validate(proto, anp);
+ } else {
+ proto = anp;
+ }
+
+ if (format != NULL) {
+ yylineno = dnp->dn_line;
+
+ sdp->dtsd_fmtdata =
+ dt_printf_create(yypcb->pcb_hdl, format);
+ dt_printf_validate(sdp->dtsd_fmtdata,
+ DT_PRINTF_AGGREGATION, dnp->dn_ident, 1,
+ fid->di_id, ((dt_idsig_t *)aid->di_data)->dis_args);
+ format = NULL;
+ }
+
+ ap = dt_stmt_action(dtp, sdp);
+ dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_PRINTA);
+
+ anp = anp->dn_list;
+ argr++;
+ }
+}
+
+static void
+dt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp,
+ dtrace_actkind_t kind)
+{
+ dt_node_t *anp, *arg1;
+ dtrace_actdesc_t *ap = NULL;
+ char n[DT_TYPE_NAMELEN], *str;
+
+ assert(DTRACEACT_ISPRINTFLIKE(kind));
+
+ if (dnp->dn_args->dn_kind != DT_NODE_STRING) {
+ dnerror(dnp, D_PRINTF_ARG_FMT,
+ "%s( ) argument #1 is incompatible with prototype:\n"
+ "\tprototype: string constant\n\t argument: %s\n",
+ dnp->dn_ident->di_name,
+ dt_node_type_name(dnp->dn_args, n, sizeof (n)));
+ }
+
+ arg1 = dnp->dn_args->dn_list;
+ yylineno = dnp->dn_line;
+ str = dnp->dn_args->dn_string;
+
+
+ /*
+ * If this is an freopen(), we use an empty string to denote that
+ * stdout should be restored. For other printf()-like actions, an
+ * empty format string is illegal: an empty format string would
+ * result in malformed DOF, and the compiler thus flags an empty
+ * format string as a compile-time error. To avoid propagating the
+ * freopen() special case throughout the system, we simply transpose
+ * an empty string into a sentinel string (DT_FREOPEN_RESTORE) that
+ * denotes that stdout should be restored.
+ */
+ if (kind == DTRACEACT_FREOPEN) {
+ if (strcmp(str, DT_FREOPEN_RESTORE) == 0) {
+ /*
+ * Our sentinel is always an invalid argument to
+ * freopen(), but if it's been manually specified, we
+ * must fail now instead of when the freopen() is
+ * actually evaluated.
+ */
+ dnerror(dnp, D_FREOPEN_INVALID,
+ "%s( ) argument #1 cannot be \"%s\"\n",
+ dnp->dn_ident->di_name, DT_FREOPEN_RESTORE);
+ }
+
+ if (str[0] == '\0')
+ str = DT_FREOPEN_RESTORE;
+ }
+
+ sdp->dtsd_fmtdata = dt_printf_create(dtp, str);
+
+ dt_printf_validate(sdp->dtsd_fmtdata, DT_PRINTF_EXACTLEN,
+ dnp->dn_ident, 1, DTRACEACT_AGGREGATION, arg1);
+
+ if (arg1 == NULL) {
+ dif_instr_t *dbuf;
+ dtrace_difo_t *dp;
+
+ if ((dbuf = dt_alloc(dtp, sizeof (dif_instr_t))) == NULL ||
+ (dp = dt_zalloc(dtp, sizeof (dtrace_difo_t))) == NULL) {
+ dt_free(dtp, dbuf);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ dbuf[0] = DIF_INSTR_RET(DIF_REG_R0); /* ret %r0 */
+
+ dp->dtdo_buf = dbuf;
+ dp->dtdo_len = 1;
+ dp->dtdo_rtype = dt_int_rtype;
+
+ ap = dt_stmt_action(dtp, sdp);
+ ap->dtad_difo = dp;
+ ap->dtad_kind = kind;
+ return;
+ }
+
+ for (anp = arg1; anp != NULL; anp = anp->dn_list) {
+ ap = dt_stmt_action(dtp, sdp);
+ dt_cg(yypcb, anp);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = kind;
+ }
+}
+
+static void
+dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ if (dt_node_is_void(dnp->dn_args)) {
+ dnerror(dnp->dn_args, D_TRACE_VOID,
+ "trace( ) may not be applied to a void expression\n");
+ }
+
+ if (dt_node_is_dynamic(dnp->dn_args)) {
+ dnerror(dnp->dn_args, D_TRACE_DYN,
+ "trace( ) may not be applied to a dynamic expression\n");
+ }
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_DIFEXPR;
+}
+
+/*
+ * The print() action behaves identically to trace(), except that it stores the
+ * CTF type of the argument (if present) within the DOF for the DIFEXPR action.
+ * To do this, we set the 'dtsd_strdata' to point to the fully-qualified CTF
+ * type ID for the result of the DIF action. We use the ID instead of the name
+ * to handles complex types like arrays and function pointers that can't be
+ * resolved by ctf_type_lookup(). This is later processed by
+ * dtrace_dof_create() and turned into a reference into the string table so
+ * that we can get the type information when we process the data after the
+ * fact.
+ */
+static void
+dt_action_print(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+ dt_node_t *dret;
+ size_t len;
+ dt_module_t *dmp;
+
+ if (dt_node_is_void(dnp->dn_args)) {
+ dnerror(dnp->dn_args, D_PRINT_VOID,
+ "print( ) may not be applied to a void expression\n");
+ }
+
+ if (dt_node_is_dynamic(dnp->dn_args)) {
+ dnerror(dnp->dn_args, D_PRINT_DYN,
+ "print( ) may not be applied to a dynamic expression\n");
+ }
+
+ dt_cg(yypcb, dnp->dn_args);
+
+ dret = yypcb->pcb_dret;
+ dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
+
+ len = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, dret->dn_type) + 1;
+ sdp->dtsd_strdata = dt_alloc(dtp, len);
+ if (sdp->dtsd_strdata == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ (void) snprintf(sdp->dtsd_strdata, len, "%s`%ld", dmp->dm_name,
+ dret->dn_type);
+
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_DIFEXPR;
+}
+
+static void
+dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_node_t *addr = dnp->dn_args;
+ dt_node_t *max = dnp->dn_args->dn_list;
+ dt_node_t *size;
+
+ char n[DT_TYPE_NAMELEN];
+
+ if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0) {
+ dnerror(addr, D_TRACEMEM_ADDR,
+ "tracemem( ) argument #1 is incompatible with "
+ "prototype:\n\tprototype: pointer or integer\n"
+ "\t argument: %s\n",
+ dt_node_type_name(addr, n, sizeof (n)));
+ }
+
+ if (dt_node_is_posconst(max) == 0) {
+ dnerror(max, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
+ "be a non-zero positive integral constant expression\n");
+ }
+
+ if ((size = max->dn_list) != NULL) {
+ if (size->dn_list != NULL) {
+ dnerror(size, D_TRACEMEM_ARGS, "tracemem ( ) prototype "
+ "mismatch: expected at most 3 args\n");
+ }
+
+ if (!dt_node_is_scalar(size)) {
+ dnerror(size, D_TRACEMEM_DYNSIZE, "tracemem ( ) "
+ "dynamic size (argument #3) must be of "
+ "scalar type\n");
+ }
+
+ dt_cg(yypcb, size);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_difo->dtdo_rtype = dt_int_rtype;
+ ap->dtad_kind = DTRACEACT_TRACEMEM_DYNSIZE;
+
+ ap = dt_stmt_action(dtp, sdp);
+ }
+
+ dt_cg(yypcb, addr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_TRACEMEM;
+
+ ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = max->dn_value;
+}
+
+static void
+dt_action_stack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *arg0)
+{
+ ap->dtad_kind = DTRACEACT_STACK;
+
+ if (dtp->dt_options[DTRACEOPT_STACKFRAMES] != DTRACEOPT_UNSET) {
+ ap->dtad_arg = dtp->dt_options[DTRACEOPT_STACKFRAMES];
+ } else {
+ ap->dtad_arg = 0;
+ }
+
+ if (arg0 != NULL) {
+ if (arg0->dn_list != NULL) {
+ dnerror(arg0, D_STACK_PROTO, "stack( ) prototype "
+ "mismatch: too many arguments\n");
+ }
+
+ if (dt_node_is_posconst(arg0) == 0) {
+ dnerror(arg0, D_STACK_SIZE, "stack( ) size must be a "
+ "non-zero positive integral constant expression\n");
+ }
+
+ ap->dtad_arg = arg0->dn_value;
+ }
+}
+
+static void
+dt_action_stack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+ dt_action_stack_args(dtp, ap, dnp->dn_args);
+}
+
+static void
+dt_action_ustack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *dnp)
+{
+ uint32_t nframes = 0;
+ uint32_t strsize = 0; /* default string table size */
+ dt_node_t *arg0 = dnp->dn_args;
+ dt_node_t *arg1 = arg0 != NULL ? arg0->dn_list : NULL;
+
+ assert(dnp->dn_ident->di_id == DT_ACT_JSTACK ||
+ dnp->dn_ident->di_id == DT_ACT_USTACK);
+
+ if (dnp->dn_ident->di_id == DT_ACT_JSTACK) {
+ if (dtp->dt_options[DTRACEOPT_JSTACKFRAMES] != DTRACEOPT_UNSET)
+ nframes = dtp->dt_options[DTRACEOPT_JSTACKFRAMES];
+
+ if (dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE] != DTRACEOPT_UNSET)
+ strsize = dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE];
+
+ ap->dtad_kind = DTRACEACT_JSTACK;
+ } else {
+ assert(dnp->dn_ident->di_id == DT_ACT_USTACK);
+
+ if (dtp->dt_options[DTRACEOPT_USTACKFRAMES] != DTRACEOPT_UNSET)
+ nframes = dtp->dt_options[DTRACEOPT_USTACKFRAMES];
+
+ ap->dtad_kind = DTRACEACT_USTACK;
+ }
+
+ if (arg0 != NULL) {
+ if (!dt_node_is_posconst(arg0)) {
+ dnerror(arg0, D_USTACK_FRAMES, "ustack( ) argument #1 "
+ "must be a non-zero positive integer constant\n");
+ }
+ nframes = (uint32_t)arg0->dn_value;
+ }
+
+ if (arg1 != NULL) {
+ if (arg1->dn_kind != DT_NODE_INT ||
+ ((arg1->dn_flags & DT_NF_SIGNED) &&
+ (int64_t)arg1->dn_value < 0)) {
+ dnerror(arg1, D_USTACK_STRSIZE, "ustack( ) argument #2 "
+ "must be a positive integer constant\n");
+ }
+
+ if (arg1->dn_list != NULL) {
+ dnerror(arg1, D_USTACK_PROTO, "ustack( ) prototype "
+ "mismatch: too many arguments\n");
+ }
+
+ strsize = (uint32_t)arg1->dn_value;
+ }
+
+ ap->dtad_arg = DTRACE_USTACK_ARG(nframes, strsize);
+}
+
+static void
+dt_action_ustack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+ dt_action_ustack_args(dtp, ap, dnp);
+}
+
+static void
+dt_action_setopt(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap;
+ dt_node_t *arg0, *arg1;
+
+ /*
+ * The prototype guarantees that we are called with either one or
+ * two arguments, and that any arguments that are present are strings.
+ */
+ arg0 = dnp->dn_args;
+ arg1 = arg0->dn_list;
+
+ ap = dt_stmt_action(dtp, sdp);
+ dt_cg(yypcb, arg0);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_LIBACT;
+ ap->dtad_arg = DT_ACT_SETOPT;
+
+ ap = dt_stmt_action(dtp, sdp);
+
+ if (arg1 == NULL) {
+ dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
+ } else {
+ dt_cg(yypcb, arg1);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_LIBACT;
+ }
+
+ ap->dtad_arg = DT_ACT_SETOPT;
+}
+
+/*ARGSUSED*/
+static void
+dt_action_symmod_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap,
+ dt_node_t *dnp, dtrace_actkind_t kind)
+{
+ assert(kind == DTRACEACT_SYM || kind == DTRACEACT_MOD ||
+ kind == DTRACEACT_USYM || kind == DTRACEACT_UMOD ||
+ kind == DTRACEACT_UADDR);
+
+ dt_cg(yypcb, dnp);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = kind;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = sizeof (uint64_t);
+}
+
+static void
+dt_action_symmod(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp,
+ dtrace_actkind_t kind)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+ dt_action_symmod_args(dtp, ap, dnp->dn_args, kind);
+}
+
+/*ARGSUSED*/
+static void
+dt_action_ftruncate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ /*
+ * Library actions need a DIFO that serves as an argument. As
+ * ftruncate() doesn't take an argument, we generate the constant 0
+ * in a DIFO; this constant will be ignored when the ftruncate() is
+ * processed.
+ */
+ dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
+ ap->dtad_arg = DT_ACT_FTRUNCATE;
+}
+
+/*ARGSUSED*/
+static void
+dt_action_stop(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ ap->dtad_kind = DTRACEACT_STOP;
+ ap->dtad_arg = 0;
+}
+
+/*ARGSUSED*/
+static void
+dt_action_breakpoint(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ ap->dtad_kind = DTRACEACT_BREAKPOINT;
+ ap->dtad_arg = 0;
+}
+
+/*ARGSUSED*/
+static void
+dt_action_panic(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ ap->dtad_kind = DTRACEACT_PANIC;
+ ap->dtad_arg = 0;
+}
+
+static void
+dt_action_chill(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_CHILL;
+}
+
+static void
+dt_action_raise(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_RAISE;
+}
+
+static void
+dt_action_exit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_EXIT;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = sizeof (int);
+}
+
+static void
+dt_action_speculate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_SPECULATE;
+}
+
+static void
+dt_action_printm(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_node_t *size = dnp->dn_args;
+ dt_node_t *addr = dnp->dn_args->dn_list;
+
+ char n[DT_TYPE_NAMELEN];
+
+ if (dt_node_is_posconst(size) == 0) {
+ dnerror(size, D_PRINTM_SIZE, "printm( ) argument #1 must "
+ "be a non-zero positive integral constant expression\n");
+ }
+
+ if (dt_node_is_pointer(addr) == 0) {
+ dnerror(addr, D_PRINTM_ADDR,
+ "printm( ) argument #2 is incompatible with "
+ "prototype:\n\tprototype: pointer\n"
+ "\t argument: %s\n",
+ dt_node_type_name(addr, n, sizeof (n)));
+ }
+
+ dt_cg(yypcb, addr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_PRINTM;
+
+ ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value + sizeof(uintptr_t);
+}
+
+static void
+dt_action_printt(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_node_t *size = dnp->dn_args;
+ dt_node_t *addr = dnp->dn_args->dn_list;
+
+ char n[DT_TYPE_NAMELEN];
+
+ if (dt_node_is_posconst(size) == 0) {
+ dnerror(size, D_PRINTT_SIZE, "printt( ) argument #1 must "
+ "be a non-zero positive integral constant expression\n");
+ }
+
+ if (addr == NULL || addr->dn_kind != DT_NODE_FUNC ||
+ addr->dn_ident != dt_idhash_lookup(dtp->dt_globals, "typeref")) {
+ dnerror(addr, D_PRINTT_ADDR,
+ "printt( ) argument #2 is incompatible with "
+ "prototype:\n\tprototype: typeref()\n"
+ "\t argument: %s\n",
+ dt_node_type_name(addr, n, sizeof (n)));
+ }
+
+ dt_cg(yypcb, addr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_PRINTT;
+
+ ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
+
+ /*
+ * Allow additional buffer space for the data size, type size,
+ * type string length and a stab in the dark (32 bytes) for the
+ * type string. The type string is part of the typeref() that
+ * this action references.
+ */
+ ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value + 3 * sizeof(uintptr_t) + 32;
+
+}
+
+static void
+dt_action_commit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_COMMIT;
+}
+
+static void
+dt_action_discard(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_DISCARD;
+}
+
+static void
+dt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ switch (dnp->dn_expr->dn_ident->di_id) {
+ case DT_ACT_BREAKPOINT:
+ dt_action_breakpoint(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_CHILL:
+ dt_action_chill(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_CLEAR:
+ dt_action_clear(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_COMMIT:
+ dt_action_commit(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_DENORMALIZE:
+ dt_action_normalize(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_DISCARD:
+ dt_action_discard(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_EXIT:
+ dt_action_exit(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_FREOPEN:
+ dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_FREOPEN);
+ break;
+ case DT_ACT_FTRUNCATE:
+ dt_action_ftruncate(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_MOD:
+ dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_MOD);
+ break;
+ case DT_ACT_NORMALIZE:
+ dt_action_normalize(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PANIC:
+ dt_action_panic(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PRINTA:
+ dt_action_printa(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PRINTF:
+ dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_PRINTF);
+ break;
+ case DT_ACT_PRINTM:
+ dt_action_printm(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PRINTT:
+ dt_action_printt(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_RAISE:
+ dt_action_raise(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_SETOPT:
+ dt_action_setopt(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_SPECULATE:
+ dt_action_speculate(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_STACK:
+ dt_action_stack(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_STOP:
+ dt_action_stop(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_SYM:
+ dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_SYM);
+ break;
+ case DT_ACT_SYSTEM:
+ dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_SYSTEM);
+ break;
+ case DT_ACT_TRACE:
+ dt_action_trace(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PRINT:
+ dt_action_print(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_TRACEMEM:
+ dt_action_tracemem(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_TRUNC:
+ dt_action_trunc(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_UADDR:
+ dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_UADDR);
+ break;
+ case DT_ACT_UMOD:
+ dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_UMOD);
+ break;
+ case DT_ACT_USYM:
+ dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_USYM);
+ break;
+ case DT_ACT_USTACK:
+ case DT_ACT_JSTACK:
+ dt_action_ustack(dtp, dnp->dn_expr, sdp);
+ break;
+ default:
+ dnerror(dnp->dn_expr, D_UNKNOWN, "tracing function %s( ) is "
+ "not yet supported\n", dnp->dn_expr->dn_ident->di_name);
+ }
+}
+
+static void
+dt_compile_exp(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_cg(yypcb, dnp->dn_expr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_difo->dtdo_rtype = dt_void_rtype;
+ ap->dtad_kind = DTRACEACT_DIFEXPR;
+}
+
+static void
+dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dt_ident_t *aid, *fid;
+ dt_node_t *anp, *incr = NULL;
+ dtrace_actdesc_t *ap;
+ uint_t n = 1, argmax;
+ uint64_t arg = 0;
+
+ /*
+ * If the aggregation has no aggregating function applied to it, then
+ * this statement has no effect. Flag this as a programming error.
+ */
+ if (dnp->dn_aggfun == NULL) {
+ dnerror(dnp, D_AGG_NULL, "expression has null effect: @%s\n",
+ dnp->dn_ident->di_name);
+ }
+
+ aid = dnp->dn_ident;
+ fid = dnp->dn_aggfun->dn_ident;
+
+ if (dnp->dn_aggfun->dn_args != NULL &&
+ dt_node_is_scalar(dnp->dn_aggfun->dn_args) == 0) {
+ dnerror(dnp->dn_aggfun, D_AGG_SCALAR, "%s( ) argument #1 must "
+ "be of scalar type\n", fid->di_name);
+ }
+
+ /*
+ * The ID of the aggregation itself is implicitly recorded as the first
+ * member of each aggregation tuple so we can distinguish them later.
+ */
+ ap = dt_stmt_action(dtp, sdp);
+ dt_action_difconst(ap, aid->di_id, DTRACEACT_DIFEXPR);
+
+ for (anp = dnp->dn_aggtup; anp != NULL; anp = anp->dn_list) {
+ ap = dt_stmt_action(dtp, sdp);
+ n++;
+
+ if (anp->dn_kind == DT_NODE_FUNC) {
+ if (anp->dn_ident->di_id == DT_ACT_STACK) {
+ dt_action_stack_args(dtp, ap, anp->dn_args);
+ continue;
+ }
+
+ if (anp->dn_ident->di_id == DT_ACT_USTACK ||
+ anp->dn_ident->di_id == DT_ACT_JSTACK) {
+ dt_action_ustack_args(dtp, ap, anp);
+ continue;
+ }
+
+ switch (anp->dn_ident->di_id) {
+ case DT_ACT_UADDR:
+ dt_action_symmod_args(dtp, ap,
+ anp->dn_args, DTRACEACT_UADDR);
+ continue;
+
+ case DT_ACT_USYM:
+ dt_action_symmod_args(dtp, ap,
+ anp->dn_args, DTRACEACT_USYM);
+ continue;
+
+ case DT_ACT_UMOD:
+ dt_action_symmod_args(dtp, ap,
+ anp->dn_args, DTRACEACT_UMOD);
+ continue;
+
+ case DT_ACT_SYM:
+ dt_action_symmod_args(dtp, ap,
+ anp->dn_args, DTRACEACT_SYM);
+ continue;
+
+ case DT_ACT_MOD:
+ dt_action_symmod_args(dtp, ap,
+ anp->dn_args, DTRACEACT_MOD);
+ continue;
+
+ default:
+ break;
+ }
+ }
+
+ dt_cg(yypcb, anp);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_DIFEXPR;
+ }
+
+ if (fid->di_id == DTRACEAGG_LQUANTIZE) {
+ /*
+ * For linear quantization, we have between two and four
+ * arguments in addition to the expression:
+ *
+ * arg1 => Base value
+ * arg2 => Limit value
+ * arg3 => Quantization level step size (defaults to 1)
+ * arg4 => Quantization increment value (defaults to 1)
+ */
+ dt_node_t *arg1 = dnp->dn_aggfun->dn_args->dn_list;
+ dt_node_t *arg2 = arg1->dn_list;
+ dt_node_t *arg3 = arg2->dn_list;
+ dt_idsig_t *isp;
+ uint64_t nlevels, step = 1, oarg;
+ int64_t baseval, limitval;
+
+ if (arg1->dn_kind != DT_NODE_INT) {
+ dnerror(arg1, D_LQUANT_BASETYPE, "lquantize( ) "
+ "argument #1 must be an integer constant\n");
+ }
+
+ baseval = (int64_t)arg1->dn_value;
+
+ if (baseval < INT32_MIN || baseval > INT32_MAX) {
+ dnerror(arg1, D_LQUANT_BASEVAL, "lquantize( ) "
+ "argument #1 must be a 32-bit quantity\n");
+ }
+
+ if (arg2->dn_kind != DT_NODE_INT) {
+ dnerror(arg2, D_LQUANT_LIMTYPE, "lquantize( ) "
+ "argument #2 must be an integer constant\n");
+ }
+
+ limitval = (int64_t)arg2->dn_value;
+
+ if (limitval < INT32_MIN || limitval > INT32_MAX) {
+ dnerror(arg2, D_LQUANT_LIMVAL, "lquantize( ) "
+ "argument #2 must be a 32-bit quantity\n");
+ }
+
+ if (limitval < baseval) {
+ dnerror(dnp, D_LQUANT_MISMATCH,
+ "lquantize( ) base (argument #1) must be less "
+ "than limit (argument #2)\n");
+ }
+
+ if (arg3 != NULL) {
+ if (!dt_node_is_posconst(arg3)) {
+ dnerror(arg3, D_LQUANT_STEPTYPE, "lquantize( ) "
+ "argument #3 must be a non-zero positive "
+ "integer constant\n");
+ }
+
+ if ((step = arg3->dn_value) > UINT16_MAX) {
+ dnerror(arg3, D_LQUANT_STEPVAL, "lquantize( ) "
+ "argument #3 must be a 16-bit quantity\n");
+ }
+ }
+
+ nlevels = (limitval - baseval) / step;
+
+ if (nlevels == 0) {
+ dnerror(dnp, D_LQUANT_STEPLARGE,
+ "lquantize( ) step (argument #3) too large: must "
+ "have at least one quantization level\n");
+ }
+
+ if (nlevels > UINT16_MAX) {
+ dnerror(dnp, D_LQUANT_STEPSMALL, "lquantize( ) step "
+ "(argument #3) too small: number of quantization "
+ "levels must be a 16-bit quantity\n");
+ }
+
+ arg = (step << DTRACE_LQUANTIZE_STEPSHIFT) |
+ (nlevels << DTRACE_LQUANTIZE_LEVELSHIFT) |
+ ((baseval << DTRACE_LQUANTIZE_BASESHIFT) &
+ DTRACE_LQUANTIZE_BASEMASK);
+
+ assert(arg != 0);
+
+ isp = (dt_idsig_t *)aid->di_data;
+
+ if (isp->dis_auxinfo == 0) {
+ /*
+ * This is the first time we've seen an lquantize()
+ * for this aggregation; we'll store our argument
+ * as the auxiliary signature information.
+ */
+ isp->dis_auxinfo = arg;
+ } else if ((oarg = isp->dis_auxinfo) != arg) {
+ /*
+ * If we have seen this lquantize() before and the
+ * argument doesn't match the original argument, pick
+ * the original argument apart to concisely report the
+ * mismatch.
+ */
+ int obaseval = DTRACE_LQUANTIZE_BASE(oarg);
+ int onlevels = DTRACE_LQUANTIZE_LEVELS(oarg);
+ int ostep = DTRACE_LQUANTIZE_STEP(oarg);
+
+ if (obaseval != baseval) {
+ dnerror(dnp, D_LQUANT_MATCHBASE, "lquantize( ) "
+ "base (argument #1) doesn't match previous "
+ "declaration: expected %d, found %d\n",
+ obaseval, (int)baseval);
+ }
+
+ if (onlevels * ostep != nlevels * step) {
+ dnerror(dnp, D_LQUANT_MATCHLIM, "lquantize( ) "
+ "limit (argument #2) doesn't match previous"
+ " declaration: expected %d, found %d\n",
+ obaseval + onlevels * ostep,
+ (int)baseval + (int)nlevels * (int)step);
+ }
+
+ if (ostep != step) {
+ dnerror(dnp, D_LQUANT_MATCHSTEP, "lquantize( ) "
+ "step (argument #3) doesn't match previous "
+ "declaration: expected %d, found %d\n",
+ ostep, (int)step);
+ }
+
+ /*
+ * We shouldn't be able to get here -- one of the
+ * parameters must be mismatched if the arguments
+ * didn't match.
+ */
+ assert(0);
+ }
+
+ incr = arg3 != NULL ? arg3->dn_list : NULL;
+ argmax = 5;
+ }
+
+ if (fid->di_id == DTRACEAGG_LLQUANTIZE) {
+ /*
+ * For log/linear quantizations, we have between one and five
+ * arguments in addition to the expression:
+ *
+ * arg1 => Factor
+ * arg2 => Low magnitude
+ * arg3 => High magnitude
+ * arg4 => Number of steps per magnitude
+ * arg5 => Quantization increment value (defaults to 1)
+ */
+ dt_node_t *llarg = dnp->dn_aggfun->dn_args->dn_list;
+ uint64_t oarg, order, v;
+ dt_idsig_t *isp;
+ int i;
+
+ struct {
+ char *str; /* string identifier */
+ int badtype; /* error on bad type */
+ int badval; /* error on bad value */
+ int mismatch; /* error on bad match */
+ int shift; /* shift value */
+ uint16_t value; /* value itself */
+ } args[] = {
+ { "factor", D_LLQUANT_FACTORTYPE,
+ D_LLQUANT_FACTORVAL, D_LLQUANT_FACTORMATCH,
+ DTRACE_LLQUANTIZE_FACTORSHIFT },
+ { "low magnitude", D_LLQUANT_LOWTYPE,
+ D_LLQUANT_LOWVAL, D_LLQUANT_LOWMATCH,
+ DTRACE_LLQUANTIZE_LOWSHIFT },
+ { "high magnitude", D_LLQUANT_HIGHTYPE,
+ D_LLQUANT_HIGHVAL, D_LLQUANT_HIGHMATCH,
+ DTRACE_LLQUANTIZE_HIGHSHIFT },
+ { "linear steps per magnitude", D_LLQUANT_NSTEPTYPE,
+ D_LLQUANT_NSTEPVAL, D_LLQUANT_NSTEPMATCH,
+ DTRACE_LLQUANTIZE_NSTEPSHIFT },
+ { NULL }
+ };
+
+ assert(arg == 0);
+
+ for (i = 0; args[i].str != NULL; i++) {
+ if (llarg->dn_kind != DT_NODE_INT) {
+ dnerror(llarg, args[i].badtype, "llquantize( ) "
+ "argument #%d (%s) must be an "
+ "integer constant\n", i + 1, args[i].str);
+ }
+
+ if ((uint64_t)llarg->dn_value > UINT16_MAX) {
+ dnerror(llarg, args[i].badval, "llquantize( ) "
+ "argument #%d (%s) must be an unsigned "
+ "16-bit quantity\n", i + 1, args[i].str);
+ }
+
+ args[i].value = (uint16_t)llarg->dn_value;
+
+ assert(!(arg & ((uint64_t)UINT16_MAX <<
+ args[i].shift)));
+ arg |= ((uint64_t)args[i].value << args[i].shift);
+ llarg = llarg->dn_list;
+ }
+
+ assert(arg != 0);
+
+ if (args[0].value < 2) {
+ dnerror(dnp, D_LLQUANT_FACTORSMALL, "llquantize( ) "
+ "factor (argument #1) must be two or more\n");
+ }
+
+ if (args[1].value >= args[2].value) {
+ dnerror(dnp, D_LLQUANT_MAGRANGE, "llquantize( ) "
+ "high magnitude (argument #3) must be greater "
+ "than low magnitude (argument #2)\n");
+ }
+
+ if (args[3].value < args[0].value) {
+ dnerror(dnp, D_LLQUANT_FACTORNSTEPS, "llquantize( ) "
+ "factor (argument #1) must be less than or "
+ "equal to the number of linear steps per "
+ "magnitude (argument #4)\n");
+ }
+
+ for (v = args[0].value; v < args[3].value; v *= args[0].value)
+ continue;
+
+ if ((args[3].value % args[0].value) || (v % args[3].value)) {
+ dnerror(dnp, D_LLQUANT_FACTOREVEN, "llquantize( ) "
+ "factor (argument #1) must evenly divide the "
+ "number of steps per magnitude (argument #4), "
+ "and the number of steps per magnitude must evenly "
+ "divide a power of the factor\n");
+ }
+
+ for (i = 0, order = 1; i < args[2].value; i++) {
+ if (order * args[0].value > order) {
+ order *= args[0].value;
+ continue;
+ }
+
+ dnerror(dnp, D_LLQUANT_MAGTOOBIG, "llquantize( ) "
+ "factor (%d) raised to power of high magnitude "
+ "(%d) overflows 64-bits\n", args[0].value,
+ args[2].value);
+ }
+
+ isp = (dt_idsig_t *)aid->di_data;
+
+ if (isp->dis_auxinfo == 0) {
+ /*
+ * This is the first time we've seen an llquantize()
+ * for this aggregation; we'll store our argument
+ * as the auxiliary signature information.
+ */
+ isp->dis_auxinfo = arg;
+ } else if ((oarg = isp->dis_auxinfo) != arg) {
+ /*
+ * If we have seen this llquantize() before and the
+ * argument doesn't match the original argument, pick
+ * the original argument apart to concisely report the
+ * mismatch.
+ */
+ int expected = 0, found = 0;
+
+ for (i = 0; expected == found; i++) {
+ assert(args[i].str != NULL);
+
+ expected = (oarg >> args[i].shift) & UINT16_MAX;
+ found = (arg >> args[i].shift) & UINT16_MAX;
+ }
+
+ dnerror(dnp, args[i - 1].mismatch, "llquantize( ) "
+ "%s (argument #%d) doesn't match previous "
+ "declaration: expected %d, found %d\n",
+ args[i - 1].str, i, expected, found);
+ }
+
+ incr = llarg;
+ argmax = 6;
+ }
+
+ if (fid->di_id == DTRACEAGG_QUANTIZE) {
+ incr = dnp->dn_aggfun->dn_args->dn_list;
+ argmax = 2;
+ }
+
+ if (incr != NULL) {
+ if (!dt_node_is_scalar(incr)) {
+ dnerror(dnp, D_PROTO_ARG, "%s( ) increment value "
+ "(argument #%d) must be of scalar type\n",
+ fid->di_name, argmax);
+ }
+
+ if ((anp = incr->dn_list) != NULL) {
+ int argc = argmax;
+
+ for (; anp != NULL; anp = anp->dn_list)
+ argc++;
+
+ dnerror(incr, D_PROTO_LEN, "%s( ) prototype "
+ "mismatch: %d args passed, at most %d expected",
+ fid->di_name, argc, argmax);
+ }
+
+ ap = dt_stmt_action(dtp, sdp);
+ n++;
+
+ dt_cg(yypcb, incr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_difo->dtdo_rtype = dt_void_rtype;
+ ap->dtad_kind = DTRACEACT_DIFEXPR;
+ }
+
+ assert(sdp->dtsd_aggdata == NULL);
+ sdp->dtsd_aggdata = aid;
+
+ ap = dt_stmt_action(dtp, sdp);
+ assert(fid->di_kind == DT_IDENT_AGGFUNC);
+ assert(DTRACEACT_ISAGG(fid->di_id));
+ ap->dtad_kind = fid->di_id;
+ ap->dtad_ntuple = n;
+ ap->dtad_arg = arg;
+
+ if (dnp->dn_aggfun->dn_args != NULL) {
+ dt_cg(yypcb, dnp->dn_aggfun->dn_args);
+ ap->dtad_difo = dt_as(yypcb);
+ }
+}
+
+static void
+dt_compile_one_clause(dtrace_hdl_t *dtp, dt_node_t *cnp, dt_node_t *pnp)
+{
+ dtrace_ecbdesc_t *edp;
+ dtrace_stmtdesc_t *sdp;
+ dt_node_t *dnp;
+
+ yylineno = pnp->dn_line;
+ dt_setcontext(dtp, pnp->dn_desc);
+ (void) dt_node_cook(cnp, DT_IDFLG_REF);
+
+ if (DT_TREEDUMP_PASS(dtp, 2))
+ dt_node_printr(cnp, stderr, 0);
+
+ if ((edp = dt_ecbdesc_create(dtp, pnp->dn_desc)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ assert(yypcb->pcb_ecbdesc == NULL);
+ yypcb->pcb_ecbdesc = edp;
+
+ if (cnp->dn_pred != NULL) {
+ dt_cg(yypcb, cnp->dn_pred);
+ edp->dted_pred.dtpdd_difo = dt_as(yypcb);
+ }
+
+ if (cnp->dn_acts == NULL) {
+ dt_stmt_append(dt_stmt_create(dtp, edp,
+ cnp->dn_ctxattr, _dtrace_defattr), cnp);
+ }
+
+ for (dnp = cnp->dn_acts; dnp != NULL; dnp = dnp->dn_list) {
+ assert(yypcb->pcb_stmt == NULL);
+ sdp = dt_stmt_create(dtp, edp, cnp->dn_ctxattr, cnp->dn_attr);
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_DEXPR:
+ if (dnp->dn_expr->dn_kind == DT_NODE_AGG)
+ dt_compile_agg(dtp, dnp->dn_expr, sdp);
+ else
+ dt_compile_exp(dtp, dnp, sdp);
+ break;
+ case DT_NODE_DFUNC:
+ dt_compile_fun(dtp, dnp, sdp);
+ break;
+ case DT_NODE_AGG:
+ dt_compile_agg(dtp, dnp, sdp);
+ break;
+ default:
+ dnerror(dnp, D_UNKNOWN, "internal error -- node kind "
+ "%u is not a valid statement\n", dnp->dn_kind);
+ }
+
+ assert(yypcb->pcb_stmt == sdp);
+ dt_stmt_append(sdp, dnp);
+ }
+
+ assert(yypcb->pcb_ecbdesc == edp);
+ dt_ecbdesc_release(dtp, edp);
+ dt_endcontext(dtp);
+ yypcb->pcb_ecbdesc = NULL;
+}
+
+static void
+dt_compile_clause(dtrace_hdl_t *dtp, dt_node_t *cnp)
+{
+ dt_node_t *pnp;
+
+ for (pnp = cnp->dn_pdescs; pnp != NULL; pnp = pnp->dn_list)
+ dt_compile_one_clause(dtp, cnp, pnp);
+}
+
+static void
+dt_compile_xlator(dt_node_t *dnp)
+{
+ dt_xlator_t *dxp = dnp->dn_xlator;
+ dt_node_t *mnp;
+
+ for (mnp = dnp->dn_members; mnp != NULL; mnp = mnp->dn_list) {
+ assert(dxp->dx_membdif[mnp->dn_membid] == NULL);
+ dt_cg(yypcb, mnp);
+ dxp->dx_membdif[mnp->dn_membid] = dt_as(yypcb);
+ }
+}
+
+void
+dt_setcontext(dtrace_hdl_t *dtp, dtrace_probedesc_t *pdp)
+{
+ const dtrace_pattr_t *pap;
+ dt_probe_t *prp;
+ dt_provider_t *pvp;
+ dt_ident_t *idp;
+ char attrstr[8];
+ int err;
+
+ /*
+ * Both kernel and pid based providers are allowed to have names
+ * ending with what could be interpreted as a number. We assume it's
+ * a pid and that we may need to dynamically create probes for
+ * that process if:
+ *
+ * (1) The provider doesn't exist, or,
+ * (2) The provider exists and has DTRACE_PRIV_PROC privilege.
+ *
+ * On an error, dt_pid_create_probes() will set the error message
+ * and tag -- we just have to longjmp() out of here.
+ */
+ if (isdigit(pdp->dtpd_provider[strlen(pdp->dtpd_provider) - 1]) &&
+ ((pvp = dt_provider_lookup(dtp, pdp->dtpd_provider)) == NULL ||
+ pvp->pv_desc.dtvd_priv.dtpp_flags & DTRACE_PRIV_PROC) &&
+ dt_pid_create_probes(pdp, dtp, yypcb) != 0) {
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ /*
+ * Call dt_probe_info() to get the probe arguments and attributes. If
+ * a representative probe is found, set 'pap' to the probe provider's
+ * attributes. Otherwise set 'pap' to default Unstable attributes.
+ */
+ if ((prp = dt_probe_info(dtp, pdp, &yypcb->pcb_pinfo)) == NULL) {
+ pap = &_dtrace_prvdesc;
+ err = dtrace_errno(dtp);
+ bzero(&yypcb->pcb_pinfo, sizeof (dtrace_probeinfo_t));
+ yypcb->pcb_pinfo.dtp_attr = pap->dtpa_provider;
+ yypcb->pcb_pinfo.dtp_arga = pap->dtpa_args;
+ } else {
+ pap = &prp->pr_pvp->pv_desc.dtvd_attr;
+ err = 0;
+ }
+
+ if (err == EDT_NOPROBE && !(yypcb->pcb_cflags & DTRACE_C_ZDEFS)) {
+ xyerror(D_PDESC_ZERO, "probe description %s:%s:%s:%s does not "
+ "match any probes\n", pdp->dtpd_provider, pdp->dtpd_mod,
+ pdp->dtpd_func, pdp->dtpd_name);
+ }
+
+ if (err != EDT_NOPROBE && err != EDT_UNSTABLE && err != 0)
+ xyerror(D_PDESC_INVAL, "%s\n", dtrace_errmsg(dtp, err));
+
+ dt_dprintf("set context to %s:%s:%s:%s [%u] prp=%p attr=%s argc=%d\n",
+ pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name,
+ pdp->dtpd_id, (void *)prp, dt_attr_str(yypcb->pcb_pinfo.dtp_attr,
+ attrstr, sizeof (attrstr)), yypcb->pcb_pinfo.dtp_argc);
+
+ /*
+ * Reset the stability attributes of D global variables that vary
+ * based on the attributes of the provider and context itself.
+ */
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, "probeprov")) != NULL)
+ idp->di_attr = pap->dtpa_provider;
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, "probemod")) != NULL)
+ idp->di_attr = pap->dtpa_mod;
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, "probefunc")) != NULL)
+ idp->di_attr = pap->dtpa_func;
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, "probename")) != NULL)
+ idp->di_attr = pap->dtpa_name;
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, "args")) != NULL)
+ idp->di_attr = pap->dtpa_args;
+
+ yypcb->pcb_pdesc = pdp;
+ yypcb->pcb_probe = prp;
+}
+
+/*
+ * Reset context-dependent variables and state at the end of cooking a D probe
+ * definition clause. This ensures that external declarations between clauses
+ * do not reference any stale context-dependent data from the previous clause.
+ */
+void
+dt_endcontext(dtrace_hdl_t *dtp)
+{
+ static const char *const cvars[] = {
+ "probeprov", "probemod", "probefunc", "probename", "args", NULL
+ };
+
+ dt_ident_t *idp;
+ int i;
+
+ for (i = 0; cvars[i] != NULL; i++) {
+ if ((idp = dt_idhash_lookup(dtp->dt_globals, cvars[i])) != NULL)
+ idp->di_attr = _dtrace_defattr;
+ }
+
+ yypcb->pcb_pdesc = NULL;
+ yypcb->pcb_probe = NULL;
+}
+
+static int
+dt_reduceid(dt_idhash_t *dhp, dt_ident_t *idp, dtrace_hdl_t *dtp)
+{
+ if (idp->di_vers != 0 && idp->di_vers > dtp->dt_vmax)
+ dt_idhash_delete(dhp, idp);
+
+ return (0);
+}
+
+/*
+ * When dtrace_setopt() is called for "version", it calls dt_reduce() to remove
+ * any identifiers or translators that have been previously defined as bound to
+ * a version greater than the specified version. Therefore, in our current
+ * version implementation, establishing a binding is a one-way transformation.
+ * In addition, no versioning is currently provided for types as our .d library
+ * files do not define any types and we reserve prefixes DTRACE_ and dtrace_
+ * for our exclusive use. If required, type versioning will require more work.
+ */
+int
+dt_reduce(dtrace_hdl_t *dtp, dt_version_t v)
+{
+ char s[DT_VERSION_STRMAX];
+ dt_xlator_t *dxp, *nxp;
+
+ if (v > dtp->dt_vmax)
+ return (dt_set_errno(dtp, EDT_VERSREDUCED));
+ else if (v == dtp->dt_vmax)
+ return (0); /* no reduction necessary */
+
+ dt_dprintf("reducing api version to %s\n",
+ dt_version_num2str(v, s, sizeof (s)));
+
+ dtp->dt_vmax = v;
+
+ for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; dxp = nxp) {
+ nxp = dt_list_next(dxp);
+ if ((dxp->dx_souid.di_vers != 0 && dxp->dx_souid.di_vers > v) ||
+ (dxp->dx_ptrid.di_vers != 0 && dxp->dx_ptrid.di_vers > v))
+ dt_list_delete(&dtp->dt_xlators, dxp);
+ }
+
+ (void) dt_idhash_iter(dtp->dt_macros, (dt_idhash_f *)dt_reduceid, dtp);
+ (void) dt_idhash_iter(dtp->dt_aggs, (dt_idhash_f *)dt_reduceid, dtp);
+ (void) dt_idhash_iter(dtp->dt_globals, (dt_idhash_f *)dt_reduceid, dtp);
+ (void) dt_idhash_iter(dtp->dt_tls, (dt_idhash_f *)dt_reduceid, dtp);
+
+ return (0);
+}
+
+/*
+ * Fork and exec the cpp(1) preprocessor to run over the specified input file,
+ * and return a FILE handle for the cpp output. We use the /dev/fd filesystem
+ * here to simplify the code by leveraging file descriptor inheritance.
+ */
+static FILE *
+dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
+{
+ int argc = dtp->dt_cpp_argc;
+ char **argv = malloc(sizeof (char *) * (argc + 5));
+ FILE *ofp = tmpfile();
+
+#if defined(sun)
+ char ipath[20], opath[20]; /* big enough for /dev/fd/ + INT_MAX + \0 */
+#endif
+ char verdef[32]; /* big enough for -D__SUNW_D_VERSION=0x%08x + \0 */
+
+ struct sigaction act, oact;
+ sigset_t mask, omask;
+
+ int wstat, estat;
+ pid_t pid;
+#if defined(sun)
+ off64_t off;
+#else
+ off_t off = 0;
+#endif
+ int c;
+
+ if (argv == NULL || ofp == NULL) {
+ (void) dt_set_errno(dtp, errno);
+ goto err;
+ }
+
+ /*
+ * If the input is a seekable file, see if it is an interpreter file.
+ * If we see #!, seek past the first line because cpp will choke on it.
+ * We start cpp just prior to the \n at the end of this line so that
+ * it still sees the newline, ensuring that #line values are correct.
+ */
+ if (isatty(fileno(ifp)) == 0 && (off = ftello64(ifp)) != -1) {
+ if ((c = fgetc(ifp)) == '#' && (c = fgetc(ifp)) == '!') {
+ for (off += 2; c != '\n'; off++) {
+ if ((c = fgetc(ifp)) == EOF)
+ break;
+ }
+ if (c == '\n')
+ off--; /* start cpp just prior to \n */
+ }
+ (void) fflush(ifp);
+ (void) fseeko64(ifp, off, SEEK_SET);
+ }
+
+#if defined(sun)
+ (void) snprintf(ipath, sizeof (ipath), "/dev/fd/%d", fileno(ifp));
+ (void) snprintf(opath, sizeof (opath), "/dev/fd/%d", fileno(ofp));
+#endif
+
+ bcopy(dtp->dt_cpp_argv, argv, sizeof (char *) * argc);
+
+ (void) snprintf(verdef, sizeof (verdef),
+ "-D__SUNW_D_VERSION=0x%08x", dtp->dt_vmax);
+ argv[argc++] = verdef;
+
+#if defined(sun)
+ switch (dtp->dt_stdcmode) {
+ case DT_STDC_XA:
+ case DT_STDC_XT:
+ argv[argc++] = "-D__STDC__=0";
+ break;
+ case DT_STDC_XC:
+ argv[argc++] = "-D__STDC__=1";
+ break;
+ }
+
+ argv[argc++] = ipath;
+ argv[argc++] = opath;
+#else
+ argv[argc++] = "-P";
+#endif
+ argv[argc] = NULL;
+
+ /*
+ * libdtrace must be able to be embedded in other programs that may
+ * include application-specific signal handlers. Therefore, if we
+ * need to fork to run cpp(1), we must avoid generating a SIGCHLD
+ * that could confuse the containing application. To do this,
+ * we block SIGCHLD and reset its disposition to SIG_DFL.
+ * We restore our signal state once we are done.
+ */
+ (void) sigemptyset(&mask);
+ (void) sigaddset(&mask, SIGCHLD);
+ (void) sigprocmask(SIG_BLOCK, &mask, &omask);
+
+ bzero(&act, sizeof (act));
+ act.sa_handler = SIG_DFL;
+ (void) sigaction(SIGCHLD, &act, &oact);
+
+ if ((pid = fork1()) == -1) {
+ (void) sigaction(SIGCHLD, &oact, NULL);
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+ (void) dt_set_errno(dtp, EDT_CPPFORK);
+ goto err;
+ }
+
+ if (pid == 0) {
+#if !defined(sun)
+ if (isatty(fileno(ifp)) == 0)
+ lseek(fileno(ifp), off, SEEK_SET);
+ dup2(fileno(ifp), 0);
+ dup2(fileno(ofp), 1);
+#endif
+ (void) execvp(dtp->dt_cpp_path, argv);
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+
+ do {
+ dt_dprintf("waiting for %s (PID %d)\n", dtp->dt_cpp_path,
+ (int)pid);
+ } while (waitpid(pid, &wstat, 0) == -1 && errno == EINTR);
+
+ (void) sigaction(SIGCHLD, &oact, NULL);
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+
+ dt_dprintf("%s returned exit status 0x%x\n", dtp->dt_cpp_path, wstat);
+ estat = WIFEXITED(wstat) ? WEXITSTATUS(wstat) : -1;
+
+ if (estat != 0) {
+ switch (estat) {
+ case 126:
+ (void) dt_set_errno(dtp, EDT_CPPEXEC);
+ break;
+ case 127:
+ (void) dt_set_errno(dtp, EDT_CPPENT);
+ break;
+ default:
+ (void) dt_set_errno(dtp, EDT_CPPERR);
+ }
+ goto err;
+ }
+
+ free(argv);
+ (void) fflush(ofp);
+ (void) fseek(ofp, 0, SEEK_SET);
+ return (ofp);
+
+err:
+ free(argv);
+ (void) fclose(ofp);
+ return (NULL);
+}
+
+static void
+dt_lib_depend_error(dtrace_hdl_t *dtp, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
+ va_end(ap);
+}
+
+int
+dt_lib_depend_add(dtrace_hdl_t *dtp, dt_list_t *dlp, const char *arg)
+{
+ dt_lib_depend_t *dld;
+ const char *end;
+
+ assert(arg != NULL);
+
+ if ((end = strrchr(arg, '/')) == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ if ((dld = dt_zalloc(dtp, sizeof (dt_lib_depend_t))) == NULL)
+ return (-1);
+
+ if ((dld->dtld_libpath = dt_alloc(dtp, MAXPATHLEN)) == NULL) {
+ dt_free(dtp, dld);
+ return (-1);
+ }
+
+ (void) strlcpy(dld->dtld_libpath, arg, end - arg + 2);
+ if ((dld->dtld_library = strdup(arg)) == NULL) {
+ dt_free(dtp, dld->dtld_libpath);
+ dt_free(dtp, dld);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dt_list_append(dlp, dld);
+ return (0);
+}
+
+dt_lib_depend_t *
+dt_lib_depend_lookup(dt_list_t *dld, const char *arg)
+{
+ dt_lib_depend_t *dldn;
+
+ for (dldn = dt_list_next(dld); dldn != NULL;
+ dldn = dt_list_next(dldn)) {
+ if (strcmp(dldn->dtld_library, arg) == 0)
+ return (dldn);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Go through all the library files, and, if any library dependencies exist for
+ * that file, add it to that node's list of dependents. The result of this
+ * will be a graph which can then be topologically sorted to produce a
+ * compilation order.
+ */
+static int
+dt_lib_build_graph(dtrace_hdl_t *dtp)
+{
+ dt_lib_depend_t *dld, *dpld;
+
+ for (dld = dt_list_next(&dtp->dt_lib_dep); dld != NULL;
+ dld = dt_list_next(dld)) {
+ char *library = dld->dtld_library;
+
+ for (dpld = dt_list_next(&dld->dtld_dependencies); dpld != NULL;
+ dpld = dt_list_next(dpld)) {
+ dt_lib_depend_t *dlda;
+
+ if ((dlda = dt_lib_depend_lookup(&dtp->dt_lib_dep,
+ dpld->dtld_library)) == NULL) {
+ dt_lib_depend_error(dtp,
+ "Invalid library dependency in %s: %s\n",
+ dld->dtld_library, dpld->dtld_library);
+
+ return (dt_set_errno(dtp, EDT_COMPILER));
+ }
+
+ if ((dt_lib_depend_add(dtp, &dlda->dtld_dependents,
+ library)) != 0) {
+ return (-1); /* preserve dt_errno */
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+dt_topo_sort(dtrace_hdl_t *dtp, dt_lib_depend_t *dld, int *count)
+{
+ dt_lib_depend_t *dpld, *dlda, *new;
+
+ dld->dtld_start = ++(*count);
+
+ for (dpld = dt_list_next(&dld->dtld_dependents); dpld != NULL;
+ dpld = dt_list_next(dpld)) {
+ dlda = dt_lib_depend_lookup(&dtp->dt_lib_dep,
+ dpld->dtld_library);
+ assert(dlda != NULL);
+
+ if (dlda->dtld_start == 0 &&
+ dt_topo_sort(dtp, dlda, count) == -1)
+ return (-1);
+ }
+
+ if ((new = dt_zalloc(dtp, sizeof (dt_lib_depend_t))) == NULL)
+ return (-1);
+
+ if ((new->dtld_library = strdup(dld->dtld_library)) == NULL) {
+ dt_free(dtp, new);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ new->dtld_start = dld->dtld_start;
+ new->dtld_finish = dld->dtld_finish = ++(*count);
+ dt_list_prepend(&dtp->dt_lib_dep_sorted, new);
+
+ dt_dprintf("library %s sorted (%d/%d)\n", new->dtld_library,
+ new->dtld_start, new->dtld_finish);
+
+ return (0);
+}
+
+static int
+dt_lib_depend_sort(dtrace_hdl_t *dtp)
+{
+ dt_lib_depend_t *dld, *dpld, *dlda;
+ int count = 0;
+
+ if (dt_lib_build_graph(dtp) == -1)
+ return (-1); /* preserve dt_errno */
+
+ /*
+ * Perform a topological sort of the graph that hangs off
+ * dtp->dt_lib_dep. The result of this process will be a
+ * dependency ordered list located at dtp->dt_lib_dep_sorted.
+ */
+ for (dld = dt_list_next(&dtp->dt_lib_dep); dld != NULL;
+ dld = dt_list_next(dld)) {
+ if (dld->dtld_start == 0 &&
+ dt_topo_sort(dtp, dld, &count) == -1)
+ return (-1); /* preserve dt_errno */;
+ }
+
+ /*
+ * Check the graph for cycles. If an ancestor's finishing time is
+ * less than any of its dependent's finishing times then a back edge
+ * exists in the graph and this is a cycle.
+ */
+ for (dld = dt_list_next(&dtp->dt_lib_dep); dld != NULL;
+ dld = dt_list_next(dld)) {
+ for (dpld = dt_list_next(&dld->dtld_dependents); dpld != NULL;
+ dpld = dt_list_next(dpld)) {
+ dlda = dt_lib_depend_lookup(&dtp->dt_lib_dep_sorted,
+ dpld->dtld_library);
+ assert(dlda != NULL);
+
+ if (dlda->dtld_finish > dld->dtld_finish) {
+ dt_lib_depend_error(dtp,
+ "Cyclic dependency detected: %s => %s\n",
+ dld->dtld_library, dpld->dtld_library);
+
+ return (dt_set_errno(dtp, EDT_COMPILER));
+ }
+ }
+ }
+
+ return (0);
+}
+
+static void
+dt_lib_depend_free(dtrace_hdl_t *dtp)
+{
+ dt_lib_depend_t *dld, *dlda;
+
+ while ((dld = dt_list_next(&dtp->dt_lib_dep)) != NULL) {
+ while ((dlda = dt_list_next(&dld->dtld_dependencies)) != NULL) {
+ dt_list_delete(&dld->dtld_dependencies, dlda);
+ dt_free(dtp, dlda->dtld_library);
+ dt_free(dtp, dlda->dtld_libpath);
+ dt_free(dtp, dlda);
+ }
+ while ((dlda = dt_list_next(&dld->dtld_dependents)) != NULL) {
+ dt_list_delete(&dld->dtld_dependents, dlda);
+ dt_free(dtp, dlda->dtld_library);
+ dt_free(dtp, dlda->dtld_libpath);
+ dt_free(dtp, dlda);
+ }
+ dt_list_delete(&dtp->dt_lib_dep, dld);
+ dt_free(dtp, dld->dtld_library);
+ dt_free(dtp, dld->dtld_libpath);
+ dt_free(dtp, dld);
+ }
+
+ while ((dld = dt_list_next(&dtp->dt_lib_dep_sorted)) != NULL) {
+ dt_list_delete(&dtp->dt_lib_dep_sorted, dld);
+ dt_free(dtp, dld->dtld_library);
+ dt_free(dtp, dld);
+ }
+}
+
+/*
+ * Open all the .d library files found in the specified directory and
+ * compile each one of them. We silently ignore any missing directories and
+ * other files found therein. We only fail (and thereby fail dt_load_libs()) if
+ * we fail to compile a library and the error is something other than #pragma D
+ * depends_on. Dependency errors are silently ignored to permit a library
+ * directory to contain libraries which may not be accessible depending on our
+ * privileges.
+ */
+static int
+dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
+{
+ struct dirent *dp;
+ const char *p, *end;
+ DIR *dirp;
+
+ char fname[PATH_MAX];
+ FILE *fp;
+ void *rv;
+ dt_lib_depend_t *dld;
+
+ if ((dirp = opendir(path)) == NULL) {
+ dt_dprintf("skipping lib dir %s: %s\n", path, strerror(errno));
+ return (0);
+ }
+
+ /* First, parse each file for library dependencies. */
+ while ((dp = readdir(dirp)) != NULL) {
+ if ((p = strrchr(dp->d_name, '.')) == NULL || strcmp(p, ".d"))
+ continue; /* skip any filename not ending in .d */
+
+ (void) snprintf(fname, sizeof (fname),
+ "%s/%s", path, dp->d_name);
+
+ if ((fp = fopen(fname, "r")) == NULL) {
+ dt_dprintf("skipping library %s: %s\n",
+ fname, strerror(errno));
+ continue;
+ }
+
+ /*
+ * Skip files whose name match an already processed library
+ */
+ for (dld = dt_list_next(&dtp->dt_lib_dep); dld != NULL;
+ dld = dt_list_next(dld)) {
+ end = strrchr(dld->dtld_library, '/');
+ /* dt_lib_depend_add ensures this */
+ assert(end != NULL);
+ if (strcmp(end + 1, dp->d_name) == 0)
+ break;
+ }
+
+ if (dld != NULL) {
+ dt_dprintf("skipping library %s, already processed "
+ "library with the same name: %s", dp->d_name,
+ dld->dtld_library);
+ continue;
+ }
+
+ dtp->dt_filetag = fname;
+ if (dt_lib_depend_add(dtp, &dtp->dt_lib_dep, fname) != 0)
+ return (-1); /* preserve dt_errno */
+
+ rv = dt_compile(dtp, DT_CTX_DPROG,
+ DTRACE_PROBESPEC_NAME, NULL,
+ DTRACE_C_EMPTY | DTRACE_C_CTL, 0, NULL, fp, NULL);
+
+ if (rv != NULL && dtp->dt_errno &&
+ (dtp->dt_errno != EDT_COMPILER ||
+ dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND)))
+ return (-1); /* preserve dt_errno */
+
+ if (dtp->dt_errno)
+ dt_dprintf("error parsing library %s: %s\n",
+ fname, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+
+ (void) fclose(fp);
+ dtp->dt_filetag = NULL;
+ }
+
+ (void) closedir(dirp);
+
+ return (0);
+}
+
+/*
+ * Perform a topological sorting of all the libraries found across the entire
+ * dt_lib_path. Once sorted, compile each one in topological order to cache its
+ * inlines and translators, etc. We silently ignore any missing directories and
+ * other files found therein. We only fail (and thereby fail dt_load_libs()) if
+ * we fail to compile a library and the error is something other than #pragma D
+ * depends_on. Dependency errors are silently ignored to permit a library
+ * directory to contain libraries which may not be accessible depending on our
+ * privileges.
+ */
+static int
+dt_load_libs_sort(dtrace_hdl_t *dtp)
+{
+ dtrace_prog_t *pgp;
+ FILE *fp;
+ dt_lib_depend_t *dld;
+
+ /*
+ * Finish building the graph containing the library dependencies
+ * and perform a topological sort to generate an ordered list
+ * for compilation.
+ */
+ if (dt_lib_depend_sort(dtp) == -1)
+ goto err;
+
+ for (dld = dt_list_next(&dtp->dt_lib_dep_sorted); dld != NULL;
+ dld = dt_list_next(dld)) {
+
+ if ((fp = fopen(dld->dtld_library, "r")) == NULL) {
+ dt_dprintf("skipping library %s: %s\n",
+ dld->dtld_library, strerror(errno));
+ continue;
+ }
+
+ dtp->dt_filetag = dld->dtld_library;
+ pgp = dtrace_program_fcompile(dtp, fp, DTRACE_C_EMPTY, 0, NULL);
+ (void) fclose(fp);
+ dtp->dt_filetag = NULL;
+
+ if (pgp == NULL && (dtp->dt_errno != EDT_COMPILER ||
+ dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND)))
+ goto err;
+
+ if (pgp == NULL) {
+ dt_dprintf("skipping library %s: %s\n",
+ dld->dtld_library,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ } else {
+ dld->dtld_loaded = B_TRUE;
+ dt_program_destroy(dtp, pgp);
+ }
+ }
+
+ dt_lib_depend_free(dtp);
+ return (0);
+
+err:
+ dt_lib_depend_free(dtp);
+ return (-1); /* preserve dt_errno */
+}
+
+/*
+ * Load the contents of any appropriate DTrace .d library files. These files
+ * contain inlines and translators that will be cached by the compiler. We
+ * defer this activity until the first compile to permit libdtrace clients to
+ * add their own library directories and so that we can properly report errors.
+ */
+static int
+dt_load_libs(dtrace_hdl_t *dtp)
+{
+ dt_dirpath_t *dirp;
+
+ if (dtp->dt_cflags & DTRACE_C_NOLIBS)
+ return (0); /* libraries already processed */
+
+ dtp->dt_cflags |= DTRACE_C_NOLIBS;
+
+ /*
+ * /usr/lib/dtrace is always at the head of the list. The rest of the
+ * list is specified in the precedence order the user requested. Process
+ * everything other than the head first. DTRACE_C_NOLIBS has already
+ * been spcified so dt_vopen will ensure that there is always one entry
+ * in dt_lib_path.
+ */
+ for (dirp = dt_list_next(dt_list_next(&dtp->dt_lib_path));
+ dirp != NULL; dirp = dt_list_next(dirp)) {
+ if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) {
+ dtp->dt_cflags &= ~DTRACE_C_NOLIBS;
+ return (-1); /* errno is set for us */
+ }
+ }
+
+ /* Handle /usr/lib/dtrace */
+ dirp = dt_list_next(&dtp->dt_lib_path);
+ if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) {
+ dtp->dt_cflags &= ~DTRACE_C_NOLIBS;
+ return (-1); /* errno is set for us */
+ }
+
+ if (dt_load_libs_sort(dtp) < 0)
+ return (-1); /* errno is set for us */
+
+ return (0);
+}
+
+static void *
+dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
+ uint_t cflags, int argc, char *const argv[], FILE *fp, const char *s)
+{
+ dt_node_t *dnp;
+ dt_decl_t *ddp;
+ dt_pcb_t pcb;
+ void *rv;
+ int err;
+
+ if ((fp == NULL && s == NULL) || (cflags & ~DTRACE_C_MASK) != 0) {
+ (void) dt_set_errno(dtp, EINVAL);
+ return (NULL);
+ }
+
+ if (dt_list_next(&dtp->dt_lib_path) != NULL && dt_load_libs(dtp) != 0)
+ return (NULL); /* errno is set for us */
+
+ if (dtp->dt_globals->dh_nelems != 0)
+ (void) dt_idhash_iter(dtp->dt_globals, dt_idreset, NULL);
+
+ if (dtp->dt_tls->dh_nelems != 0)
+ (void) dt_idhash_iter(dtp->dt_tls, dt_idreset, NULL);
+
+ if (fp && (cflags & DTRACE_C_CPP) && (fp = dt_preproc(dtp, fp)) == NULL)
+ return (NULL); /* errno is set for us */
+
+ dt_pcb_push(dtp, &pcb);
+
+ pcb.pcb_fileptr = fp;
+ pcb.pcb_string = s;
+ pcb.pcb_strptr = s;
+ pcb.pcb_strlen = s ? strlen(s) : 0;
+ pcb.pcb_sargc = argc;
+ pcb.pcb_sargv = argv;
+ pcb.pcb_sflagv = argc ? calloc(argc, sizeof (ushort_t)) : NULL;
+ pcb.pcb_pspec = pspec;
+ pcb.pcb_cflags = dtp->dt_cflags | cflags;
+ pcb.pcb_amin = dtp->dt_amin;
+ pcb.pcb_yystate = -1;
+ pcb.pcb_context = context;
+ pcb.pcb_token = context;
+
+ if (context != DT_CTX_DPROG)
+ yybegin(YYS_EXPR);
+ else if (cflags & DTRACE_C_CTL)
+ yybegin(YYS_CONTROL);
+ else
+ yybegin(YYS_CLAUSE);
+
+ if ((err = setjmp(yypcb->pcb_jmpbuf)) != 0)
+ goto out;
+
+ if (yypcb->pcb_sargc != 0 && yypcb->pcb_sflagv == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ yypcb->pcb_idents = dt_idhash_create("ambiguous", NULL, 0, 0);
+ yypcb->pcb_locals = dt_idhash_create("clause local", NULL,
+ DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
+
+ if (yypcb->pcb_idents == NULL || yypcb->pcb_locals == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * Invoke the parser to evaluate the D source code. If any errors
+ * occur during parsing, an error function will be called and we
+ * will longjmp back to pcb_jmpbuf to abort. If parsing succeeds,
+ * we optionally display the parse tree if debugging is enabled.
+ */
+ if (yyparse() != 0 || yypcb->pcb_root == NULL)
+ xyerror(D_EMPTY, "empty D program translation unit\n");
+
+ yybegin(YYS_DONE);
+
+ if (cflags & DTRACE_C_CTL)
+ goto out;
+
+ if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 1))
+ dt_node_printr(yypcb->pcb_root, stderr, 0);
+
+ if (yypcb->pcb_pragmas != NULL)
+ (void) dt_idhash_iter(yypcb->pcb_pragmas, dt_idpragma, NULL);
+
+ if (argc > 1 && !(yypcb->pcb_cflags & DTRACE_C_ARGREF) &&
+ !(yypcb->pcb_sflagv[argc - 1] & DT_IDFLG_REF)) {
+ xyerror(D_MACRO_UNUSED, "extraneous argument '%s' ($%d is "
+ "not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
+ }
+
+ /*
+ * If we have successfully created a parse tree for a D program, loop
+ * over the clauses and actions and instantiate the corresponding
+ * libdtrace program. If we are parsing a D expression, then we
+ * simply run the code generator and assembler on the resulting tree.
+ */
+ switch (context) {
+ case DT_CTX_DPROG:
+ assert(yypcb->pcb_root->dn_kind == DT_NODE_PROG);
+
+ if ((dnp = yypcb->pcb_root->dn_list) == NULL &&
+ !(yypcb->pcb_cflags & DTRACE_C_EMPTY))
+ xyerror(D_EMPTY, "empty D program translation unit\n");
+
+ if ((yypcb->pcb_prog = dt_program_create(dtp)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, dtrace_errno(dtp));
+
+ for (; dnp != NULL; dnp = dnp->dn_list) {
+ switch (dnp->dn_kind) {
+ case DT_NODE_CLAUSE:
+ dt_compile_clause(dtp, dnp);
+ break;
+ case DT_NODE_XLATOR:
+ if (dtp->dt_xlatemode == DT_XL_DYNAMIC)
+ dt_compile_xlator(dnp);
+ break;
+ case DT_NODE_PROVIDER:
+ (void) dt_node_cook(dnp, DT_IDFLG_REF);
+ break;
+ }
+ }
+
+ yypcb->pcb_prog->dp_xrefs = yypcb->pcb_asxrefs;
+ yypcb->pcb_prog->dp_xrefslen = yypcb->pcb_asxreflen;
+ yypcb->pcb_asxrefs = NULL;
+ yypcb->pcb_asxreflen = 0;
+
+ rv = yypcb->pcb_prog;
+ break;
+
+ case DT_CTX_DEXPR:
+ (void) dt_node_cook(yypcb->pcb_root, DT_IDFLG_REF);
+ dt_cg(yypcb, yypcb->pcb_root);
+ rv = dt_as(yypcb);
+ break;
+
+ case DT_CTX_DTYPE:
+ ddp = (dt_decl_t *)yypcb->pcb_root; /* root is really a decl */
+ err = dt_decl_type(ddp, arg);
+ dt_decl_free(ddp);
+
+ if (err != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+
+ rv = NULL;
+ break;
+ }
+
+out:
+ if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 3))
+ dt_node_printr(yypcb->pcb_root, stderr, 0);
+
+ if (dtp->dt_cdefs_fd != -1 && (ftruncate64(dtp->dt_cdefs_fd, 0) == -1 ||
+ lseek64(dtp->dt_cdefs_fd, 0, SEEK_SET) == -1 ||
+ ctf_write(dtp->dt_cdefs->dm_ctfp, dtp->dt_cdefs_fd) == CTF_ERR))
+ dt_dprintf("failed to update CTF cache: %s\n", strerror(errno));
+
+ if (dtp->dt_ddefs_fd != -1 && (ftruncate64(dtp->dt_ddefs_fd, 0) == -1 ||
+ lseek64(dtp->dt_ddefs_fd, 0, SEEK_SET) == -1 ||
+ ctf_write(dtp->dt_ddefs->dm_ctfp, dtp->dt_ddefs_fd) == CTF_ERR))
+ dt_dprintf("failed to update CTF cache: %s\n", strerror(errno));
+
+ if (yypcb->pcb_fileptr && (cflags & DTRACE_C_CPP))
+ (void) fclose(yypcb->pcb_fileptr); /* close dt_preproc() file */
+
+ dt_pcb_pop(dtp, err);
+ (void) dt_set_errno(dtp, err);
+ return (err ? NULL : rv);
+}
+
+dtrace_prog_t *
+dtrace_program_strcompile(dtrace_hdl_t *dtp, const char *s,
+ dtrace_probespec_t spec, uint_t cflags, int argc, char *const argv[])
+{
+ return (dt_compile(dtp, DT_CTX_DPROG,
+ spec, NULL, cflags, argc, argv, NULL, s));
+}
+
+dtrace_prog_t *
+dtrace_program_fcompile(dtrace_hdl_t *dtp, FILE *fp,
+ uint_t cflags, int argc, char *const argv[])
+{
+ return (dt_compile(dtp, DT_CTX_DPROG,
+ DTRACE_PROBESPEC_NAME, NULL, cflags, argc, argv, fp, NULL));
+}
+
+int
+dtrace_type_strcompile(dtrace_hdl_t *dtp, const char *s, dtrace_typeinfo_t *dtt)
+{
+ (void) dt_compile(dtp, DT_CTX_DTYPE,
+ DTRACE_PROBESPEC_NONE, dtt, 0, 0, NULL, NULL, s);
+ return (dtp->dt_errno ? -1 : 0);
+}
+
+int
+dtrace_type_fcompile(dtrace_hdl_t *dtp, FILE *fp, dtrace_typeinfo_t *dtt)
+{
+ (void) dt_compile(dtp, DT_CTX_DTYPE,
+ DTRACE_PROBESPEC_NONE, dtt, 0, 0, NULL, fp, NULL);
+ return (dtp->dt_errno ? -1 : 0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
new file mode 100644
index 0000000..a33cccd
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
@@ -0,0 +1,2006 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/isa_defs.h>
+
+#include <strings.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <dt_impl.h>
+#include <dt_grammar.h>
+#include <dt_parser.h>
+#include <dt_provider.h>
+
+static void dt_cg_node(dt_node_t *, dt_irlist_t *, dt_regset_t *);
+
+static dt_irnode_t *
+dt_cg_node_alloc(uint_t label, dif_instr_t instr)
+{
+ dt_irnode_t *dip = malloc(sizeof (dt_irnode_t));
+
+ if (dip == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dip->di_label = label;
+ dip->di_instr = instr;
+ dip->di_extern = NULL;
+ dip->di_next = NULL;
+
+ return (dip);
+}
+
+/*
+ * Code generator wrapper function for ctf_member_info. If we are given a
+ * reference to a forward declaration tag, search the entire type space for
+ * the actual definition and then call ctf_member_info on the result.
+ */
+static ctf_file_t *
+dt_cg_membinfo(ctf_file_t *fp, ctf_id_t type, const char *s, ctf_membinfo_t *mp)
+{
+ while (ctf_type_kind(fp, type) == CTF_K_FORWARD) {
+ char n[DT_TYPE_NAMELEN];
+ dtrace_typeinfo_t dtt;
+
+ if (ctf_type_name(fp, type, n, sizeof (n)) == NULL ||
+ dt_type_lookup(n, &dtt) == -1 || (
+ dtt.dtt_ctfp == fp && dtt.dtt_type == type))
+ break; /* unable to improve our position */
+
+ fp = dtt.dtt_ctfp;
+ type = ctf_type_resolve(fp, dtt.dtt_type);
+ }
+
+ if (ctf_member_info(fp, type, s, mp) == CTF_ERR)
+ return (NULL); /* ctf_errno is set for us */
+
+ return (fp);
+}
+
+static void
+dt_cg_xsetx(dt_irlist_t *dlp, dt_ident_t *idp, uint_t lbl, int reg, uint64_t x)
+{
+ int flag = idp != NULL ? DT_INT_PRIVATE : DT_INT_SHARED;
+ int intoff = dt_inttab_insert(yypcb->pcb_inttab, x, flag);
+ dif_instr_t instr = DIF_INSTR_SETX((uint_t)intoff, reg);
+
+ if (intoff == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (intoff > DIF_INTOFF_MAX)
+ longjmp(yypcb->pcb_jmpbuf, EDT_INT2BIG);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl, instr));
+
+ if (idp != NULL)
+ dlp->dl_last->di_extern = idp;
+}
+
+static void
+dt_cg_setx(dt_irlist_t *dlp, int reg, uint64_t x)
+{
+ dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, reg, x);
+}
+
+/*
+ * When loading bit-fields, we want to convert a byte count in the range
+ * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
+ * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
+ */
+static size_t
+clp2(size_t x)
+{
+ x--;
+
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+
+ return (x + 1);
+}
+
+/*
+ * Lookup the correct load opcode to use for the specified node and CTF type.
+ * We determine the size and convert it to a 3-bit index. Our lookup table
+ * is constructed to use a 5-bit index, consisting of the 3-bit size 0-7, a
+ * bit for the sign, and a bit for userland address. For example, a 4-byte
+ * signed load from userland would be at the following table index:
+ * user=1 sign=1 size=4 => binary index 11011 = decimal index 27
+ */
+static uint_t
+dt_cg_load(dt_node_t *dnp, ctf_file_t *ctfp, ctf_id_t type)
+{
+ static const uint_t ops[] = {
+ DIF_OP_LDUB, DIF_OP_LDUH, 0, DIF_OP_LDUW,
+ 0, 0, 0, DIF_OP_LDX,
+ DIF_OP_LDSB, DIF_OP_LDSH, 0, DIF_OP_LDSW,
+ 0, 0, 0, DIF_OP_LDX,
+ DIF_OP_ULDUB, DIF_OP_ULDUH, 0, DIF_OP_ULDUW,
+ 0, 0, 0, DIF_OP_ULDX,
+ DIF_OP_ULDSB, DIF_OP_ULDSH, 0, DIF_OP_ULDSW,
+ 0, 0, 0, DIF_OP_ULDX,
+ };
+
+ ctf_encoding_t e;
+ ssize_t size;
+
+ /*
+ * If we're loading a bit-field, the size of our load is found by
+ * rounding cte_bits up to a byte boundary and then finding the
+ * nearest power of two to this value (see clp2(), above).
+ */
+ if ((dnp->dn_flags & DT_NF_BITFIELD) &&
+ ctf_type_encoding(ctfp, type, &e) != CTF_ERR)
+ size = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY);
+ else
+ size = ctf_type_size(ctfp, type);
+
+ if (size < 1 || size > 8 || (size & (size - 1)) != 0) {
+ xyerror(D_UNKNOWN, "internal error -- cg cannot load "
+ "size %ld when passed by value\n", (long)size);
+ }
+
+ size--; /* convert size to 3-bit index */
+
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ size |= 0x08;
+ if (dnp->dn_flags & DT_NF_USERLAND)
+ size |= 0x10;
+
+ return (ops[size]);
+}
+
+static void
+dt_cg_ptrsize(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
+ uint_t op, int dreg)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_arinfo_t r;
+ dif_instr_t instr;
+ ctf_id_t type;
+ uint_t kind;
+ ssize_t size;
+ int sreg;
+
+ if ((sreg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ type = ctf_type_resolve(ctfp, dnp->dn_type);
+ kind = ctf_type_kind(ctfp, type);
+ assert(kind == CTF_K_POINTER || kind == CTF_K_ARRAY);
+
+ if (kind == CTF_K_ARRAY) {
+ if (ctf_array_info(ctfp, type, &r) != 0) {
+ yypcb->pcb_hdl->dt_ctferr = ctf_errno(ctfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+ type = r.ctr_contents;
+ } else
+ type = ctf_type_reference(ctfp, type);
+
+ if ((size = ctf_type_size(ctfp, type)) == 1)
+ return; /* multiply or divide by one can be omitted */
+
+ dt_cg_setx(dlp, sreg, size);
+ instr = DIF_INSTR_FMT(op, dreg, sreg, dreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, sreg);
+}
+
+/*
+ * If the result of a "." or "->" operation is a bit-field, we use this routine
+ * to generate an epilogue to the load instruction that extracts the value. In
+ * the diagrams below the "ld??" is the load instruction that is generated to
+ * load the containing word that is generating prior to calling this function.
+ *
+ * Epilogue for unsigned fields: Epilogue for signed fields:
+ *
+ * ldu? [r1], r1 lds? [r1], r1
+ * setx USHIFT, r2 setx 64 - SSHIFT, r2
+ * srl r1, r2, r1 sll r1, r2, r1
+ * setx (1 << bits) - 1, r2 setx 64 - bits, r2
+ * and r1, r2, r1 sra r1, r2, r1
+ *
+ * The *SHIFT constants above changes value depending on the endian-ness of our
+ * target architecture. Refer to the comments below for more details.
+ */
+static void
+dt_cg_field_get(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
+ ctf_file_t *fp, const ctf_membinfo_t *mp)
+{
+ ctf_encoding_t e;
+ dif_instr_t instr;
+ uint64_t shift;
+ int r1, r2;
+
+ if (ctf_type_encoding(fp, mp->ctm_type, &e) != 0 || e.cte_bits > 64) {
+ xyerror(D_UNKNOWN, "cg: bad field: off %lu type <%ld> "
+ "bits %u\n", mp->ctm_offset, mp->ctm_type, e.cte_bits);
+ }
+
+ assert(dnp->dn_op == DT_TOK_PTR || dnp->dn_op == DT_TOK_DOT);
+ r1 = dnp->dn_left->dn_reg;
+
+ if ((r2 = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ /*
+ * On little-endian architectures, ctm_offset counts from the right so
+ * ctm_offset % NBBY itself is the amount we want to shift right to
+ * move the value bits to the little end of the register to mask them.
+ * On big-endian architectures, ctm_offset counts from the left so we
+ * must subtract (ctm_offset % NBBY + cte_bits) from the size in bits
+ * we used for the load. The size of our load in turn is found by
+ * rounding cte_bits up to a byte boundary and then finding the
+ * nearest power of two to this value (see clp2(), above). These
+ * properties are used to compute shift as USHIFT or SSHIFT, below.
+ */
+ if (dnp->dn_flags & DT_NF_SIGNED) {
+#if BYTE_ORDER == _BIG_ENDIAN
+ shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
+ mp->ctm_offset % NBBY;
+#else
+ shift = mp->ctm_offset % NBBY + e.cte_bits;
+#endif
+ dt_cg_setx(dlp, r2, 64 - shift);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, r2, 64 - e.cte_bits);
+ instr = DIF_INSTR_FMT(DIF_OP_SRA, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+#if BYTE_ORDER == _BIG_ENDIAN
+ shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
+ (mp->ctm_offset % NBBY + e.cte_bits);
+#else
+ shift = mp->ctm_offset % NBBY;
+#endif
+ dt_cg_setx(dlp, r2, shift);
+ instr = DIF_INSTR_FMT(DIF_OP_SRL, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, r2, (1ULL << e.cte_bits) - 1);
+ instr = DIF_INSTR_FMT(DIF_OP_AND, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ }
+
+ dt_regset_free(drp, r2);
+}
+
+/*
+ * If the destination of a store operation is a bit-field, we use this routine
+ * to generate a prologue to the store instruction that loads the surrounding
+ * bits, clears the destination field, and ORs in the new value of the field.
+ * In the diagram below the "st?" is the store instruction that is generated to
+ * store the containing word that is generating after calling this function.
+ *
+ * ld [dst->dn_reg], r1
+ * setx ~(((1 << cte_bits) - 1) << (ctm_offset % NBBY)), r2
+ * and r1, r2, r1
+ *
+ * setx (1 << cte_bits) - 1, r2
+ * and src->dn_reg, r2, r2
+ * setx ctm_offset % NBBY, r3
+ * sll r2, r3, r2
+ *
+ * or r1, r2, r1
+ * st? r1, [dst->dn_reg]
+ *
+ * This routine allocates a new register to hold the value to be stored and
+ * returns it. The caller is responsible for freeing this register later.
+ */
+static int
+dt_cg_field_set(dt_node_t *src, dt_irlist_t *dlp,
+ dt_regset_t *drp, dt_node_t *dst)
+{
+ uint64_t cmask, fmask, shift;
+ dif_instr_t instr;
+ int r1, r2, r3;
+
+ ctf_membinfo_t m;
+ ctf_encoding_t e;
+ ctf_file_t *fp, *ofp;
+ ctf_id_t type;
+
+ assert(dst->dn_op == DT_TOK_PTR || dst->dn_op == DT_TOK_DOT);
+ assert(dst->dn_right->dn_kind == DT_NODE_IDENT);
+
+ fp = dst->dn_left->dn_ctfp;
+ type = ctf_type_resolve(fp, dst->dn_left->dn_type);
+
+ if (dst->dn_op == DT_TOK_PTR) {
+ type = ctf_type_reference(fp, type);
+ type = ctf_type_resolve(fp, type);
+ }
+
+ if ((fp = dt_cg_membinfo(ofp = fp, type,
+ dst->dn_right->dn_string, &m)) == NULL) {
+ yypcb->pcb_hdl->dt_ctferr = ctf_errno(ofp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+
+ if (ctf_type_encoding(fp, m.ctm_type, &e) != 0 || e.cte_bits > 64) {
+ xyerror(D_UNKNOWN, "cg: bad field: off %lu type <%ld> "
+ "bits %u\n", m.ctm_offset, m.ctm_type, e.cte_bits);
+ }
+
+ if ((r1 = dt_regset_alloc(drp)) == -1 ||
+ (r2 = dt_regset_alloc(drp)) == -1 ||
+ (r3 = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ /*
+ * Compute shifts and masks. We need to compute "shift" as the amount
+ * we need to shift left to position our field in the containing word.
+ * Refer to the comments in dt_cg_field_get(), above, for more info.
+ * We then compute fmask as the mask that truncates the value in the
+ * input register to width cte_bits, and cmask as the mask used to
+ * pass through the containing bits and zero the field bits.
+ */
+#if BYTE_ORDER == _BIG_ENDIAN
+ shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
+ (m.ctm_offset % NBBY + e.cte_bits);
+#else
+ shift = m.ctm_offset % NBBY;
+#endif
+ fmask = (1ULL << e.cte_bits) - 1;
+ cmask = ~(fmask << shift);
+
+ instr = DIF_INSTR_LOAD(
+ dt_cg_load(dst, fp, m.ctm_type), dst->dn_reg, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, r2, cmask);
+ instr = DIF_INSTR_FMT(DIF_OP_AND, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, r2, fmask);
+ instr = DIF_INSTR_FMT(DIF_OP_AND, src->dn_reg, r2, r2);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, r3, shift);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, r2, r3, r2);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_FMT(DIF_OP_OR, r1, r2, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_regset_free(drp, r3);
+ dt_regset_free(drp, r2);
+
+ return (r1);
+}
+
+static void
+dt_cg_store(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dst)
+{
+ ctf_encoding_t e;
+ dif_instr_t instr;
+ size_t size;
+ int reg;
+
+ /*
+ * If we're loading a bit-field, the size of our store is found by
+ * rounding dst's cte_bits up to a byte boundary and then finding the
+ * nearest power of two to this value (see clp2(), above).
+ */
+ if ((dst->dn_flags & DT_NF_BITFIELD) &&
+ ctf_type_encoding(dst->dn_ctfp, dst->dn_type, &e) != CTF_ERR)
+ size = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY);
+ else
+ size = dt_node_type_size(src);
+
+ if (src->dn_flags & DT_NF_REF) {
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dt_cg_setx(dlp, reg, size);
+ instr = DIF_INSTR_COPYS(src->dn_reg, reg, dst->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, reg);
+ } else {
+ if (dst->dn_flags & DT_NF_BITFIELD)
+ reg = dt_cg_field_set(src, dlp, drp, dst);
+ else
+ reg = src->dn_reg;
+
+ switch (size) {
+ case 1:
+ instr = DIF_INSTR_STORE(DIF_OP_STB, reg, dst->dn_reg);
+ break;
+ case 2:
+ instr = DIF_INSTR_STORE(DIF_OP_STH, reg, dst->dn_reg);
+ break;
+ case 4:
+ instr = DIF_INSTR_STORE(DIF_OP_STW, reg, dst->dn_reg);
+ break;
+ case 8:
+ instr = DIF_INSTR_STORE(DIF_OP_STX, reg, dst->dn_reg);
+ break;
+ default:
+ xyerror(D_UNKNOWN, "internal error -- cg cannot store "
+ "size %lu when passed by value\n", (ulong_t)size);
+ }
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ if (dst->dn_flags & DT_NF_BITFIELD)
+ dt_regset_free(drp, reg);
+ }
+}
+
+/*
+ * Generate code for a typecast or for argument promotion from the type of the
+ * actual to the type of the formal. We need to generate code for casts when
+ * a scalar type is being narrowed or changing signed-ness. We first shift the
+ * desired bits high (losing excess bits if narrowing) and then shift them down
+ * using logical shift (unsigned result) or arithmetic shift (signed result).
+ */
+static void
+dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
+ dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ size_t srcsize = dt_node_type_size(src);
+ size_t dstsize = dt_node_type_size(dst);
+
+ dif_instr_t instr;
+ int reg, n;
+
+ if (dt_node_is_scalar(dst) && (dstsize < srcsize ||
+ (src->dn_flags & DT_NF_SIGNED) ^ (dst->dn_flags & DT_NF_SIGNED))) {
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ if (dstsize < srcsize)
+ n = sizeof (uint64_t) * NBBY - dstsize * NBBY;
+ else
+ n = sizeof (uint64_t) * NBBY - srcsize * NBBY;
+
+ dt_cg_setx(dlp, reg, n);
+
+ instr = DIF_INSTR_FMT(DIF_OP_SLL,
+ src->dn_reg, reg, dst->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_FMT((dst->dn_flags & DT_NF_SIGNED) ?
+ DIF_OP_SRA : DIF_OP_SRL, dst->dn_reg, reg, dst->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, reg);
+ }
+}
+
+/*
+ * Generate code to push the specified argument list on to the tuple stack.
+ * We use this routine for handling subroutine calls and associative arrays.
+ * We must first generate code for all subexpressions before loading the stack
+ * because any subexpression could itself require the use of the tuple stack.
+ * This holds a number of registers equal to the number of arguments, but this
+ * is not a huge problem because the number of arguments can't exceed the
+ * number of tuple register stack elements anyway. At most one extra register
+ * is required (either by dt_cg_typecast() or for dtdt_size, below). This
+ * implies that a DIF implementation should offer a number of general purpose
+ * registers at least one greater than the number of tuple registers.
+ */
+static void
+dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
+ dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ const dt_idsig_t *isp = idp->di_data;
+ dt_node_t *dnp;
+ int i = 0;
+
+ for (dnp = args; dnp != NULL; dnp = dnp->dn_list)
+ dt_cg_node(dnp, dlp, drp);
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
+
+ for (dnp = args; dnp != NULL; dnp = dnp->dn_list, i++) {
+ dtrace_diftype_t t;
+ dif_instr_t instr;
+ uint_t op;
+ int reg;
+
+ dt_node_diftype(yypcb->pcb_hdl, dnp, &t);
+
+ isp->dis_args[i].dn_reg = dnp->dn_reg; /* re-use register */
+ dt_cg_typecast(dnp, &isp->dis_args[i], dlp, drp);
+ isp->dis_args[i].dn_reg = -1;
+
+ if (t.dtdt_flags & DIF_TF_BYREF)
+ op = DIF_OP_PUSHTR;
+ else
+ op = DIF_OP_PUSHTV;
+
+ if (t.dtdt_size != 0) {
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dt_cg_setx(dlp, reg, t.dtdt_size);
+ } else
+ reg = DIF_REG_R0;
+
+ instr = DIF_INSTR_PUSHTS(op, t.dtdt_kind, reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_reg);
+
+ if (reg != DIF_REG_R0)
+ dt_regset_free(drp, reg);
+ }
+
+ if (i > yypcb->pcb_hdl->dt_conf.dtc_diftupregs)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOTUPREG);
+}
+
+static void
+dt_cg_arithmetic_op(dt_node_t *dnp, dt_irlist_t *dlp,
+ dt_regset_t *drp, uint_t op)
+{
+ int is_ptr_op = (dnp->dn_op == DT_TOK_ADD || dnp->dn_op == DT_TOK_SUB ||
+ dnp->dn_op == DT_TOK_ADD_EQ || dnp->dn_op == DT_TOK_SUB_EQ);
+
+ int lp_is_ptr = dt_node_is_pointer(dnp->dn_left);
+ int rp_is_ptr = dt_node_is_pointer(dnp->dn_right);
+
+ dif_instr_t instr;
+
+ if (lp_is_ptr && rp_is_ptr) {
+ assert(dnp->dn_op == DT_TOK_SUB);
+ is_ptr_op = 0;
+ }
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ if (is_ptr_op && rp_is_ptr)
+ dt_cg_ptrsize(dnp, dlp, drp, DIF_OP_MUL, dnp->dn_left->dn_reg);
+
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ if (is_ptr_op && lp_is_ptr)
+ dt_cg_ptrsize(dnp, dlp, drp, DIF_OP_MUL, dnp->dn_right->dn_reg);
+
+ instr = DIF_INSTR_FMT(op, dnp->dn_left->dn_reg,
+ dnp->dn_right->dn_reg, dnp->dn_left->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_right->dn_reg);
+ dnp->dn_reg = dnp->dn_left->dn_reg;
+
+ if (lp_is_ptr && rp_is_ptr)
+ dt_cg_ptrsize(dnp->dn_right,
+ dlp, drp, DIF_OP_UDIV, dnp->dn_reg);
+}
+
+static uint_t
+dt_cg_stvar(const dt_ident_t *idp)
+{
+ static const uint_t aops[] = { DIF_OP_STGAA, DIF_OP_STTAA, DIF_OP_NOP };
+ static const uint_t sops[] = { DIF_OP_STGS, DIF_OP_STTS, DIF_OP_STLS };
+
+ uint_t i = (((idp->di_flags & DT_IDFLG_LOCAL) != 0) << 1) |
+ ((idp->di_flags & DT_IDFLG_TLS) != 0);
+
+ return (idp->di_kind == DT_IDENT_ARRAY ? aops[i] : sops[i]);
+}
+
+static void
+dt_cg_prearith_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ dif_instr_t instr;
+ ctf_id_t type;
+ ssize_t size = 1;
+ int reg;
+
+ if (dt_node_is_pointer(dnp)) {
+ type = ctf_type_resolve(ctfp, dnp->dn_type);
+ assert(ctf_type_kind(ctfp, type) == CTF_K_POINTER);
+ size = ctf_type_size(ctfp, ctf_type_reference(ctfp, type));
+ }
+
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_setx(dlp, reg, size);
+
+ instr = DIF_INSTR_FMT(op, dnp->dn_reg, reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, reg);
+
+ /*
+ * If we are modifying a variable, generate an stv instruction from
+ * the variable specified by the identifier. If we are storing to a
+ * memory address, generate code again for the left-hand side using
+ * DT_NF_REF to get the address, and then generate a store to it.
+ * In both paths, we store the value in dnp->dn_reg (the new value).
+ */
+ if (dnp->dn_child->dn_kind == DT_NODE_VAR) {
+ dt_ident_t *idp = dt_ident_resolve(dnp->dn_child->dn_ident);
+
+ idp->di_flags |= DT_IDFLG_DIFW;
+ instr = DIF_INSTR_STV(dt_cg_stvar(idp),
+ idp->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+ uint_t rbit = dnp->dn_child->dn_flags & DT_NF_REF;
+
+ assert(dnp->dn_child->dn_flags & DT_NF_WRITABLE);
+ assert(dnp->dn_child->dn_flags & DT_NF_LVALUE);
+
+ dnp->dn_child->dn_flags |= DT_NF_REF; /* force pass-by-ref */
+ dt_cg_node(dnp->dn_child, dlp, drp);
+
+ dt_cg_store(dnp, dlp, drp, dnp->dn_child);
+ dt_regset_free(drp, dnp->dn_child->dn_reg);
+
+ dnp->dn_left->dn_flags &= ~DT_NF_REF;
+ dnp->dn_left->dn_flags |= rbit;
+ }
+}
+
+static void
+dt_cg_postarith_op(dt_node_t *dnp, dt_irlist_t *dlp,
+ dt_regset_t *drp, uint_t op)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ dif_instr_t instr;
+ ctf_id_t type;
+ ssize_t size = 1;
+ int nreg;
+
+ if (dt_node_is_pointer(dnp)) {
+ type = ctf_type_resolve(ctfp, dnp->dn_type);
+ assert(ctf_type_kind(ctfp, type) == CTF_K_POINTER);
+ size = ctf_type_size(ctfp, ctf_type_reference(ctfp, type));
+ }
+
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ if ((nreg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_setx(dlp, nreg, size);
+ instr = DIF_INSTR_FMT(op, dnp->dn_reg, nreg, nreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ /*
+ * If we are modifying a variable, generate an stv instruction from
+ * the variable specified by the identifier. If we are storing to a
+ * memory address, generate code again for the left-hand side using
+ * DT_NF_REF to get the address, and then generate a store to it.
+ * In both paths, we store the value from 'nreg' (the new value).
+ */
+ if (dnp->dn_child->dn_kind == DT_NODE_VAR) {
+ dt_ident_t *idp = dt_ident_resolve(dnp->dn_child->dn_ident);
+
+ idp->di_flags |= DT_IDFLG_DIFW;
+ instr = DIF_INSTR_STV(dt_cg_stvar(idp), idp->di_id, nreg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+ uint_t rbit = dnp->dn_child->dn_flags & DT_NF_REF;
+ int oreg = dnp->dn_reg;
+
+ assert(dnp->dn_child->dn_flags & DT_NF_WRITABLE);
+ assert(dnp->dn_child->dn_flags & DT_NF_LVALUE);
+
+ dnp->dn_child->dn_flags |= DT_NF_REF; /* force pass-by-ref */
+ dt_cg_node(dnp->dn_child, dlp, drp);
+
+ dnp->dn_reg = nreg;
+ dt_cg_store(dnp, dlp, drp, dnp->dn_child);
+ dnp->dn_reg = oreg;
+
+ dt_regset_free(drp, dnp->dn_child->dn_reg);
+ dnp->dn_left->dn_flags &= ~DT_NF_REF;
+ dnp->dn_left->dn_flags |= rbit;
+ }
+
+ dt_regset_free(drp, nreg);
+}
+
+/*
+ * Determine if we should perform signed or unsigned comparison for an OP2.
+ * If both operands are of arithmetic type, perform the usual arithmetic
+ * conversions to determine the common real type for comparison [ISOC 6.5.8.3].
+ */
+static int
+dt_cg_compare_signed(dt_node_t *dnp)
+{
+ dt_node_t dn;
+
+ if (dt_node_is_string(dnp->dn_left) ||
+ dt_node_is_string(dnp->dn_right))
+ return (1); /* strings always compare signed */
+ else if (!dt_node_is_arith(dnp->dn_left) ||
+ !dt_node_is_arith(dnp->dn_right))
+ return (0); /* non-arithmetic types always compare unsigned */
+
+ bzero(&dn, sizeof (dn));
+ dt_node_promote(dnp->dn_left, dnp->dn_right, &dn);
+ return (dn.dn_flags & DT_NF_SIGNED);
+}
+
+static void
+dt_cg_compare_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
+{
+ uint_t lbl_true = dt_irlist_label(dlp);
+ uint_t lbl_post = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+ uint_t opc;
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ dt_cg_node(dnp->dn_right, dlp, drp);
+
+ if (dt_node_is_string(dnp->dn_left) || dt_node_is_string(dnp->dn_right))
+ opc = DIF_OP_SCMP;
+ else
+ opc = DIF_OP_CMP;
+
+ instr = DIF_INSTR_CMP(opc, dnp->dn_left->dn_reg, dnp->dn_right->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_right->dn_reg);
+ dnp->dn_reg = dnp->dn_left->dn_reg;
+
+ instr = DIF_INSTR_BRANCH(op, lbl_true);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_MOV(DIF_REG_R0, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BA, lbl_post);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_xsetx(dlp, NULL, lbl_true, dnp->dn_reg, 1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_post, DIF_INSTR_NOP));
+}
+
+/*
+ * Code generation for the ternary op requires some trickery with the assembler
+ * in order to conserve registers. We generate code for dn_expr and dn_left
+ * and free their registers so they do not have be consumed across codegen for
+ * dn_right. We insert a dummy MOV at the end of dn_left into the destination
+ * register, which is not yet known because we haven't done dn_right yet, and
+ * save the pointer to this instruction node. We then generate code for
+ * dn_right and use its register as our output. Finally, we reach back and
+ * patch the instruction for dn_left to move its output into this register.
+ */
+static void
+dt_cg_ternary_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ uint_t lbl_false = dt_irlist_label(dlp);
+ uint_t lbl_post = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+ dt_irnode_t *dip;
+
+ dt_cg_node(dnp->dn_expr, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_expr->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_expr->dn_reg);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_false);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ instr = DIF_INSTR_MOV(dnp->dn_left->dn_reg, DIF_REG_R0);
+ dip = dt_cg_node_alloc(DT_LBL_NONE, instr); /* save dip for below */
+ dt_irlist_append(dlp, dip);
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BA, lbl_post);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_false, DIF_INSTR_NOP));
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+
+ /*
+ * Now that dn_reg is assigned, reach back and patch the correct MOV
+ * instruction into the tail of dn_left. We know dn_reg was unused
+ * at that point because otherwise dn_right couldn't have allocated it.
+ */
+ dip->di_instr = DIF_INSTR_MOV(dnp->dn_left->dn_reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_post, DIF_INSTR_NOP));
+}
+
+static void
+dt_cg_logical_and(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ uint_t lbl_false = dt_irlist_label(dlp);
+ uint_t lbl_post = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_left->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_false);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_right->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_false);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, dnp->dn_reg, 1);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BA, lbl_post);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_MOV(DIF_REG_R0, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_false, instr));
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_post, DIF_INSTR_NOP));
+}
+
+static void
+dt_cg_logical_xor(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ uint_t lbl_next = dt_irlist_label(dlp);
+ uint_t lbl_tail = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_left->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_next);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_cg_setx(dlp, dnp->dn_left->dn_reg, 1);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_next, DIF_INSTR_NOP));
+ dt_cg_node(dnp->dn_right, dlp, drp);
+
+ instr = DIF_INSTR_TST(dnp->dn_right->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_tail);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_cg_setx(dlp, dnp->dn_right->dn_reg, 1);
+
+ instr = DIF_INSTR_FMT(DIF_OP_XOR, dnp->dn_left->dn_reg,
+ dnp->dn_right->dn_reg, dnp->dn_left->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_tail, instr));
+
+ dt_regset_free(drp, dnp->dn_right->dn_reg);
+ dnp->dn_reg = dnp->dn_left->dn_reg;
+}
+
+static void
+dt_cg_logical_or(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ uint_t lbl_true = dt_irlist_label(dlp);
+ uint_t lbl_false = dt_irlist_label(dlp);
+ uint_t lbl_post = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_left->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BNE, lbl_true);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ instr = DIF_INSTR_TST(dnp->dn_right->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_false);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_xsetx(dlp, NULL, lbl_true, dnp->dn_reg, 1);
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BA, lbl_post);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_MOV(DIF_REG_R0, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_false, instr));
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_post, DIF_INSTR_NOP));
+}
+
+static void
+dt_cg_logical_neg(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ uint_t lbl_zero = dt_irlist_label(dlp);
+ uint_t lbl_post = dt_irlist_label(dlp);
+
+ dif_instr_t instr;
+
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ instr = DIF_INSTR_TST(dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BE, lbl_zero);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_MOV(DIF_REG_R0, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BA, lbl_post);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_xsetx(dlp, NULL, lbl_zero, dnp->dn_reg, 1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(lbl_post, DIF_INSTR_NOP));
+}
+
+static void
+dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dif_instr_t instr;
+ dt_ident_t *idp;
+
+ /*
+ * If we are performing a structure assignment of a translated type,
+ * we must instantiate all members and create a snapshot of the object
+ * in scratch space. We allocs a chunk of memory, generate code for
+ * each member, and then set dnp->dn_reg to the scratch object address.
+ */
+ if ((idp = dt_node_resolve(dnp->dn_right, DT_IDENT_XLSOU)) != NULL) {
+ ctf_membinfo_t ctm;
+ dt_xlator_t *dxp = idp->di_data;
+ dt_node_t *mnp, dn, mn;
+ int r1, r2;
+
+ /*
+ * Create two fake dt_node_t's representing operator "." and a
+ * right-hand identifier child node. These will be repeatedly
+ * modified according to each instantiated member so that we
+ * can pass them to dt_cg_store() and effect a member store.
+ */
+ bzero(&dn, sizeof (dt_node_t));
+ dn.dn_kind = DT_NODE_OP2;
+ dn.dn_op = DT_TOK_DOT;
+ dn.dn_left = dnp;
+ dn.dn_right = &mn;
+
+ bzero(&mn, sizeof (dt_node_t));
+ mn.dn_kind = DT_NODE_IDENT;
+ mn.dn_op = DT_TOK_IDENT;
+
+ /*
+ * Allocate a register for our scratch data pointer. First we
+ * set it to the size of our data structure, and then replace
+ * it with the result of an allocs of the specified size.
+ */
+ if ((r1 = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_setx(dlp, r1,
+ ctf_type_size(dxp->dx_dst_ctfp, dxp->dx_dst_base));
+
+ instr = DIF_INSTR_ALLOCS(r1, r1);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ /*
+ * When dt_cg_asgn_op() is called, we have already generated
+ * code for dnp->dn_right, which is the translator input. We
+ * now associate this register with the translator's input
+ * identifier so it can be referenced during our member loop.
+ */
+ dxp->dx_ident->di_flags |= DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = dnp->dn_right->dn_reg;
+
+ for (mnp = dxp->dx_members; mnp != NULL; mnp = mnp->dn_list) {
+ /*
+ * Generate code for the translator member expression,
+ * and then cast the result to the member type.
+ */
+ dt_cg_node(mnp->dn_membexpr, dlp, drp);
+ mnp->dn_reg = mnp->dn_membexpr->dn_reg;
+ dt_cg_typecast(mnp->dn_membexpr, mnp, dlp, drp);
+
+ /*
+ * Ask CTF for the offset of the member so we can store
+ * to the appropriate offset. This call has already
+ * been done once by the parser, so it should succeed.
+ */
+ if (ctf_member_info(dxp->dx_dst_ctfp, dxp->dx_dst_base,
+ mnp->dn_membname, &ctm) == CTF_ERR) {
+ yypcb->pcb_hdl->dt_ctferr =
+ ctf_errno(dxp->dx_dst_ctfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+
+ /*
+ * If the destination member is at offset 0, store the
+ * result directly to r1 (the scratch buffer address).
+ * Otherwise allocate another temporary for the offset
+ * and add r1 to it before storing the result.
+ */
+ if (ctm.ctm_offset != 0) {
+ if ((r2 = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ /*
+ * Add the member offset rounded down to the
+ * nearest byte. If the offset was not aligned
+ * on a byte boundary, this member is a bit-
+ * field and dt_cg_store() will handle masking.
+ */
+ dt_cg_setx(dlp, r2, ctm.ctm_offset / NBBY);
+ instr = DIF_INSTR_FMT(DIF_OP_ADD, r1, r2, r2);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_node_type_propagate(mnp, &dn);
+ dn.dn_right->dn_string = mnp->dn_membname;
+ dn.dn_reg = r2;
+
+ dt_cg_store(mnp, dlp, drp, &dn);
+ dt_regset_free(drp, r2);
+
+ } else {
+ dt_node_type_propagate(mnp, &dn);
+ dn.dn_right->dn_string = mnp->dn_membname;
+ dn.dn_reg = r1;
+
+ dt_cg_store(mnp, dlp, drp, &dn);
+ }
+
+ dt_regset_free(drp, mnp->dn_reg);
+ }
+
+ dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = 0;
+
+ if (dnp->dn_right->dn_reg != -1)
+ dt_regset_free(drp, dnp->dn_right->dn_reg);
+
+ assert(dnp->dn_reg == dnp->dn_right->dn_reg);
+ dnp->dn_reg = r1;
+ }
+
+ /*
+ * If we are storing to a variable, generate an stv instruction from
+ * the variable specified by the identifier. If we are storing to a
+ * memory address, generate code again for the left-hand side using
+ * DT_NF_REF to get the address, and then generate a store to it.
+ * In both paths, we assume dnp->dn_reg already has the new value.
+ */
+ if (dnp->dn_left->dn_kind == DT_NODE_VAR) {
+ idp = dt_ident_resolve(dnp->dn_left->dn_ident);
+
+ if (idp->di_kind == DT_IDENT_ARRAY)
+ dt_cg_arglist(idp, dnp->dn_left->dn_args, dlp, drp);
+
+ idp->di_flags |= DT_IDFLG_DIFW;
+ instr = DIF_INSTR_STV(dt_cg_stvar(idp),
+ idp->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+ uint_t rbit = dnp->dn_left->dn_flags & DT_NF_REF;
+
+ assert(dnp->dn_left->dn_flags & DT_NF_WRITABLE);
+ assert(dnp->dn_left->dn_flags & DT_NF_LVALUE);
+
+ dnp->dn_left->dn_flags |= DT_NF_REF; /* force pass-by-ref */
+
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ dt_cg_store(dnp, dlp, drp, dnp->dn_left);
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+
+ dnp->dn_left->dn_flags &= ~DT_NF_REF;
+ dnp->dn_left->dn_flags |= rbit;
+ }
+}
+
+static void
+dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dif_instr_t instr;
+ uint_t op;
+
+ assert(dnp->dn_kind == DT_NODE_VAR);
+ assert(!(dnp->dn_ident->di_flags & DT_IDFLG_LOCAL));
+ assert(dnp->dn_args != NULL);
+
+ dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ if (dnp->dn_ident->di_flags & DT_IDFLG_TLS)
+ op = DIF_OP_LDTAA;
+ else
+ op = DIF_OP_LDGAA;
+
+ dnp->dn_ident->di_flags |= DT_IDFLG_DIFR;
+ instr = DIF_INSTR_LDV(op, dnp->dn_ident->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ /*
+ * If the associative array is a pass-by-reference type, then we are
+ * loading its value as a pointer to either load or store through it.
+ * The array element in question may not have been faulted in yet, in
+ * which case DIF_OP_LD*AA will return zero. We append an epilogue
+ * of instructions similar to the following:
+ *
+ * ld?aa id, %r1 ! base ld?aa instruction above
+ * tst %r1 ! start of epilogue
+ * +--- bne label
+ * | setx size, %r1
+ * | allocs %r1, %r1
+ * | st?aa id, %r1
+ * | ld?aa id, %r1
+ * v
+ * label: < rest of code >
+ *
+ * The idea is that we allocs a zero-filled chunk of scratch space and
+ * do a DIF_OP_ST*AA to fault in and initialize the array element, and
+ * then reload it to get the faulted-in address of the new variable
+ * storage. This isn't cheap, but pass-by-ref associative array values
+ * are (thus far) uncommon and the allocs cost only occurs once. If
+ * this path becomes important to DTrace users, we can improve things
+ * by adding a new DIF opcode to fault in associative array elements.
+ */
+ if (dnp->dn_flags & DT_NF_REF) {
+ uint_t stvop = op == DIF_OP_LDTAA ? DIF_OP_STTAA : DIF_OP_STGAA;
+ uint_t label = dt_irlist_label(dlp);
+
+ instr = DIF_INSTR_TST(dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_BRANCH(DIF_OP_BNE, label);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_cg_setx(dlp, dnp->dn_reg, dt_node_type_size(dnp));
+ instr = DIF_INSTR_ALLOCS(dnp->dn_reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dnp->dn_ident->di_flags |= DT_IDFLG_DIFW;
+ instr = DIF_INSTR_STV(stvop, dnp->dn_ident->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_LDV(op, dnp->dn_ident->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(label, DIF_INSTR_NOP));
+ }
+}
+
+static void
+dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dt_probe_t *prp = yypcb->pcb_probe;
+ uintmax_t saved = dnp->dn_args->dn_value;
+ dt_ident_t *idp = dnp->dn_ident;
+
+ dif_instr_t instr;
+ uint_t op;
+ size_t size;
+ int reg, n;
+
+ assert(dnp->dn_kind == DT_NODE_VAR);
+ assert(!(idp->di_flags & DT_IDFLG_LOCAL));
+
+ assert(dnp->dn_args->dn_kind == DT_NODE_INT);
+ assert(dnp->dn_args->dn_list == NULL);
+
+ /*
+ * If this is a reference in the args[] array, temporarily modify the
+ * array index according to the static argument mapping (if any),
+ * unless the argument reference is provided by a dynamic translator.
+ * If we're using a dynamic translator for args[], then just set dn_reg
+ * to an invalid reg and return: DIF_OP_XLARG will fetch the arg later.
+ */
+ if (idp->di_id == DIF_VAR_ARGS) {
+ if ((idp->di_kind == DT_IDENT_XLPTR ||
+ idp->di_kind == DT_IDENT_XLSOU) &&
+ dt_xlator_dynamic(idp->di_data)) {
+ dnp->dn_reg = -1;
+ return;
+ }
+ dnp->dn_args->dn_value = prp->pr_mapping[saved];
+ }
+
+ dt_cg_node(dnp->dn_args, dlp, drp);
+ dnp->dn_args->dn_value = saved;
+
+ dnp->dn_reg = dnp->dn_args->dn_reg;
+
+ if (idp->di_flags & DT_IDFLG_TLS)
+ op = DIF_OP_LDTA;
+ else
+ op = DIF_OP_LDGA;
+
+ idp->di_flags |= DT_IDFLG_DIFR;
+
+ instr = DIF_INSTR_LDA(op, idp->di_id,
+ dnp->dn_args->dn_reg, dnp->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ /*
+ * If this is a reference to the args[] array, we need to take the
+ * additional step of explicitly eliminating any bits larger than the
+ * type size: the DIF interpreter in the kernel will always give us
+ * the raw (64-bit) argument value, and any bits larger than the type
+ * size may be junk. As a practical matter, this arises only on 64-bit
+ * architectures and only when the argument index is larger than the
+ * number of arguments passed directly to DTrace: if a 8-, 16- or
+ * 32-bit argument must be retrieved from the stack, it is possible
+ * (and it some cases, likely) that the upper bits will be garbage.
+ */
+ if (idp->di_id != DIF_VAR_ARGS || !dt_node_is_scalar(dnp))
+ return;
+
+ if ((size = dt_node_type_size(dnp)) == sizeof (uint64_t))
+ return;
+
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ assert(size < sizeof (uint64_t));
+ n = sizeof (uint64_t) * NBBY - size * NBBY;
+
+ dt_cg_setx(dlp, reg, n);
+
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, dnp->dn_reg, reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_FMT((dnp->dn_flags & DT_NF_SIGNED) ?
+ DIF_OP_SRA : DIF_OP_SRL, dnp->dn_reg, reg, dnp->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, reg);
+}
+
+/*
+ * Generate code for an inlined variable reference. Inlines can be used to
+ * define either scalar or associative array substitutions. For scalars, we
+ * simply generate code for the parse tree saved in the identifier's din_root,
+ * and then cast the resulting expression to the inline's declaration type.
+ * For arrays, we take the input parameter subtrees from dnp->dn_args and
+ * temporarily store them in the din_root of each din_argv[i] identifier,
+ * which are themselves inlines and were set up for us by the parser. The
+ * result is that any reference to the inlined parameter inside the top-level
+ * din_root will turn into a recursive call to dt_cg_inline() for a scalar
+ * inline whose din_root will refer to the subtree pointed to by the argument.
+ */
+static void
+dt_cg_inline(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dt_ident_t *idp = dnp->dn_ident;
+ dt_idnode_t *inp = idp->di_iarg;
+
+ dt_idnode_t *pinp;
+ dt_node_t *pnp;
+ int i;
+
+ assert(idp->di_flags & DT_IDFLG_INLINE);
+ assert(idp->di_ops == &dt_idops_inline);
+
+ if (idp->di_kind == DT_IDENT_ARRAY) {
+ for (i = 0, pnp = dnp->dn_args;
+ pnp != NULL; pnp = pnp->dn_list, i++) {
+ if (inp->din_argv[i] != NULL) {
+ pinp = inp->din_argv[i]->di_iarg;
+ pinp->din_root = pnp;
+ }
+ }
+ }
+
+ dt_cg_node(inp->din_root, dlp, drp);
+ dnp->dn_reg = inp->din_root->dn_reg;
+ dt_cg_typecast(inp->din_root, dnp, dlp, drp);
+
+ if (idp->di_kind == DT_IDENT_ARRAY) {
+ for (i = 0; i < inp->din_argc; i++) {
+ pinp = inp->din_argv[i]->di_iarg;
+ pinp->din_root = NULL;
+ }
+ }
+}
+
+static void
+dt_cg_func_typeref(dtrace_hdl_t *dtp, dt_node_t *dnp)
+{
+ dtrace_typeinfo_t dtt;
+ dt_node_t *addr = dnp->dn_args;
+ dt_node_t *nelm = addr->dn_list;
+ dt_node_t *strp = nelm->dn_list;
+ dt_node_t *typs = strp->dn_list;
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+
+ ctf_type_name(addr->dn_ctfp, addr->dn_type, buf, sizeof (buf));
+
+ /*
+ * XXX Hack alert! XXX
+ * The prototype has two dummy args that we munge to represent
+ * the type string and the type size.
+ *
+ * Yes, I hear your grumble, but it works for now. We'll come
+ * up with a more elegant implementation later. :-)
+ */
+ free(strp->dn_string);
+
+ if ((p = strchr(buf, '*')) != NULL)
+ *p = '\0';
+
+ strp->dn_string = strdup(buf);
+
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY, buf, &dtt) < 0)
+ return;
+
+ typs->dn_value = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
+}
+
+static void
+dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_file_t *octfp;
+ ctf_membinfo_t m;
+ ctf_id_t type;
+
+ dif_instr_t instr;
+ dt_ident_t *idp;
+ ssize_t stroff;
+ uint_t op;
+ int reg;
+
+ switch (dnp->dn_op) {
+ case DT_TOK_COMMA:
+ dt_cg_node(dnp->dn_left, dlp, drp);
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+ break;
+
+ case DT_TOK_ASGN:
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_ADD_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_ADD);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_SUB_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SUB);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_MUL_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_MUL);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_DIV_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SDIV : DIF_OP_UDIV);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_MOD_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SREM : DIF_OP_UREM);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_AND_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_AND);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_XOR_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_XOR);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_OR_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_OR);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_LSH_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SLL);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_RSH_EQ:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SRA : DIF_OP_SRL);
+ dt_cg_asgn_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_QUESTION:
+ dt_cg_ternary_op(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_LOR:
+ dt_cg_logical_or(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_LXOR:
+ dt_cg_logical_xor(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_LAND:
+ dt_cg_logical_and(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_BOR:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_OR);
+ break;
+
+ case DT_TOK_XOR:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_XOR);
+ break;
+
+ case DT_TOK_BAND:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_AND);
+ break;
+
+ case DT_TOK_EQU:
+ dt_cg_compare_op(dnp, dlp, drp, DIF_OP_BE);
+ break;
+
+ case DT_TOK_NEQ:
+ dt_cg_compare_op(dnp, dlp, drp, DIF_OP_BNE);
+ break;
+
+ case DT_TOK_LT:
+ dt_cg_compare_op(dnp, dlp, drp,
+ dt_cg_compare_signed(dnp) ? DIF_OP_BL : DIF_OP_BLU);
+ break;
+
+ case DT_TOK_LE:
+ dt_cg_compare_op(dnp, dlp, drp,
+ dt_cg_compare_signed(dnp) ? DIF_OP_BLE : DIF_OP_BLEU);
+ break;
+
+ case DT_TOK_GT:
+ dt_cg_compare_op(dnp, dlp, drp,
+ dt_cg_compare_signed(dnp) ? DIF_OP_BG : DIF_OP_BGU);
+ break;
+
+ case DT_TOK_GE:
+ dt_cg_compare_op(dnp, dlp, drp,
+ dt_cg_compare_signed(dnp) ? DIF_OP_BGE : DIF_OP_BGEU);
+ break;
+
+ case DT_TOK_LSH:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SLL);
+ break;
+
+ case DT_TOK_RSH:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SRA : DIF_OP_SRL);
+ break;
+
+ case DT_TOK_ADD:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_ADD);
+ break;
+
+ case DT_TOK_SUB:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SUB);
+ break;
+
+ case DT_TOK_MUL:
+ dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_MUL);
+ break;
+
+ case DT_TOK_DIV:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SDIV : DIF_OP_UDIV);
+ break;
+
+ case DT_TOK_MOD:
+ dt_cg_arithmetic_op(dnp, dlp, drp,
+ (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SREM : DIF_OP_UREM);
+ break;
+
+ case DT_TOK_LNEG:
+ dt_cg_logical_neg(dnp, dlp, drp);
+ break;
+
+ case DT_TOK_BNEG:
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+ instr = DIF_INSTR_NOT(dnp->dn_reg, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ break;
+
+ case DT_TOK_PREINC:
+ dt_cg_prearith_op(dnp, dlp, drp, DIF_OP_ADD);
+ break;
+
+ case DT_TOK_POSTINC:
+ dt_cg_postarith_op(dnp, dlp, drp, DIF_OP_ADD);
+ break;
+
+ case DT_TOK_PREDEC:
+ dt_cg_prearith_op(dnp, dlp, drp, DIF_OP_SUB);
+ break;
+
+ case DT_TOK_POSTDEC:
+ dt_cg_postarith_op(dnp, dlp, drp, DIF_OP_SUB);
+ break;
+
+ case DT_TOK_IPOS:
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+ break;
+
+ case DT_TOK_INEG:
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ instr = DIF_INSTR_FMT(DIF_OP_SUB, DIF_REG_R0,
+ dnp->dn_reg, dnp->dn_reg);
+
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ break;
+
+ case DT_TOK_DEREF:
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ if (!(dnp->dn_flags & DT_NF_REF)) {
+ uint_t ubit = dnp->dn_flags & DT_NF_USERLAND;
+
+ /*
+ * Save and restore DT_NF_USERLAND across dt_cg_load():
+ * we need the sign bit from dnp and the user bit from
+ * dnp->dn_child in order to get the proper opcode.
+ */
+ dnp->dn_flags |=
+ (dnp->dn_child->dn_flags & DT_NF_USERLAND);
+
+ instr = DIF_INSTR_LOAD(dt_cg_load(dnp, ctfp,
+ dnp->dn_type), dnp->dn_reg, dnp->dn_reg);
+
+ dnp->dn_flags &= ~DT_NF_USERLAND;
+ dnp->dn_flags |= ubit;
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ }
+ break;
+
+ case DT_TOK_ADDROF: {
+ uint_t rbit = dnp->dn_child->dn_flags & DT_NF_REF;
+
+ dnp->dn_child->dn_flags |= DT_NF_REF; /* force pass-by-ref */
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+
+ dnp->dn_child->dn_flags &= ~DT_NF_REF;
+ dnp->dn_child->dn_flags |= rbit;
+ break;
+ }
+
+ case DT_TOK_SIZEOF: {
+ size_t size = dt_node_sizeof(dnp->dn_child);
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ assert(size != 0);
+ dt_cg_setx(dlp, dnp->dn_reg, size);
+ break;
+ }
+
+ case DT_TOK_STRINGOF:
+ dt_cg_node(dnp->dn_child, dlp, drp);
+ dnp->dn_reg = dnp->dn_child->dn_reg;
+ break;
+
+ case DT_TOK_XLATE:
+ /*
+ * An xlate operator appears in either an XLATOR, indicating a
+ * reference to a dynamic translator, or an OP2, indicating
+ * use of the xlate operator in the user's program. For the
+ * dynamic case, generate an xlate opcode with a reference to
+ * the corresponding member, pre-computed for us in dn_members.
+ */
+ if (dnp->dn_kind == DT_NODE_XLATOR) {
+ dt_xlator_t *dxp = dnp->dn_xlator;
+
+ assert(dxp->dx_ident->di_flags & DT_IDFLG_CGREG);
+ assert(dxp->dx_ident->di_id != 0);
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ if (dxp->dx_arg == -1) {
+ instr = DIF_INSTR_MOV(
+ dxp->dx_ident->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ op = DIF_OP_XLATE;
+ } else
+ op = DIF_OP_XLARG;
+
+ instr = DIF_INSTR_XLATE(op, 0, dnp->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ dlp->dl_last->di_extern = dnp->dn_xmember;
+ break;
+ }
+
+ assert(dnp->dn_kind == DT_NODE_OP2);
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+ break;
+
+ case DT_TOK_LPAR:
+ dt_cg_node(dnp->dn_right, dlp, drp);
+ dnp->dn_reg = dnp->dn_right->dn_reg;
+ dt_cg_typecast(dnp->dn_right, dnp, dlp, drp);
+ break;
+
+ case DT_TOK_PTR:
+ case DT_TOK_DOT:
+ assert(dnp->dn_right->dn_kind == DT_NODE_IDENT);
+ dt_cg_node(dnp->dn_left, dlp, drp);
+
+ /*
+ * If the left-hand side of PTR or DOT is a dynamic variable,
+ * we expect it to be the output of a D translator. In this
+ * case, we look up the parse tree corresponding to the member
+ * that is being accessed and run the code generator over it.
+ * We then cast the result as if by the assignment operator.
+ */
+ if ((idp = dt_node_resolve(
+ dnp->dn_left, DT_IDENT_XLSOU)) != NULL ||
+ (idp = dt_node_resolve(
+ dnp->dn_left, DT_IDENT_XLPTR)) != NULL) {
+
+ dt_xlator_t *dxp;
+ dt_node_t *mnp;
+
+ dxp = idp->di_data;
+ mnp = dt_xlator_member(dxp, dnp->dn_right->dn_string);
+ assert(mnp != NULL);
+
+ dxp->dx_ident->di_flags |= DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = dnp->dn_left->dn_reg;
+
+ dt_cg_node(mnp->dn_membexpr, dlp, drp);
+ dnp->dn_reg = mnp->dn_membexpr->dn_reg;
+ dt_cg_typecast(mnp->dn_membexpr, dnp, dlp, drp);
+
+ dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = 0;
+
+ if (dnp->dn_left->dn_reg != -1)
+ dt_regset_free(drp, dnp->dn_left->dn_reg);
+ break;
+ }
+
+ ctfp = dnp->dn_left->dn_ctfp;
+ type = ctf_type_resolve(ctfp, dnp->dn_left->dn_type);
+
+ if (dnp->dn_op == DT_TOK_PTR) {
+ type = ctf_type_reference(ctfp, type);
+ type = ctf_type_resolve(ctfp, type);
+ }
+
+ if ((ctfp = dt_cg_membinfo(octfp = ctfp, type,
+ dnp->dn_right->dn_string, &m)) == NULL) {
+ yypcb->pcb_hdl->dt_ctferr = ctf_errno(octfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+
+ if (m.ctm_offset != 0) {
+ if ((reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ /*
+ * If the offset is not aligned on a byte boundary, it
+ * is a bit-field member and we will extract the value
+ * bits below after we generate the appropriate load.
+ */
+ dt_cg_setx(dlp, reg, m.ctm_offset / NBBY);
+
+ instr = DIF_INSTR_FMT(DIF_OP_ADD,
+ dnp->dn_left->dn_reg, reg, dnp->dn_left->dn_reg);
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, reg);
+ }
+
+ if (!(dnp->dn_flags & DT_NF_REF)) {
+ uint_t ubit = dnp->dn_flags & DT_NF_USERLAND;
+
+ /*
+ * Save and restore DT_NF_USERLAND across dt_cg_load():
+ * we need the sign bit from dnp and the user bit from
+ * dnp->dn_left in order to get the proper opcode.
+ */
+ dnp->dn_flags |=
+ (dnp->dn_left->dn_flags & DT_NF_USERLAND);
+
+ instr = DIF_INSTR_LOAD(dt_cg_load(dnp,
+ ctfp, m.ctm_type), dnp->dn_left->dn_reg,
+ dnp->dn_left->dn_reg);
+
+ dnp->dn_flags &= ~DT_NF_USERLAND;
+ dnp->dn_flags |= ubit;
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ if (dnp->dn_flags & DT_NF_BITFIELD)
+ dt_cg_field_get(dnp, dlp, drp, ctfp, &m);
+ }
+
+ dnp->dn_reg = dnp->dn_left->dn_reg;
+ break;
+
+ case DT_TOK_STRING:
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ assert(dnp->dn_kind == DT_NODE_STRING);
+ stroff = dt_strtab_insert(yypcb->pcb_strtab, dnp->dn_string);
+
+ if (stroff == -1L)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ if (stroff > DIF_STROFF_MAX)
+ longjmp(yypcb->pcb_jmpbuf, EDT_STR2BIG);
+
+ instr = DIF_INSTR_SETS((ulong_t)stroff, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ break;
+
+ case DT_TOK_IDENT:
+ /*
+ * If the specified identifier is a variable on which we have
+ * set the code generator register flag, then this variable
+ * has already had code generated for it and saved in di_id.
+ * Allocate a new register and copy the existing value to it.
+ */
+ if (dnp->dn_kind == DT_NODE_VAR &&
+ (dnp->dn_ident->di_flags & DT_IDFLG_CGREG)) {
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ instr = DIF_INSTR_MOV(dnp->dn_ident->di_id,
+ dnp->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ break;
+ }
+
+ /*
+ * Identifiers can represent function calls, variable refs, or
+ * symbols. First we check for inlined variables, and handle
+ * them by generating code for the inline parse tree.
+ */
+ if (dnp->dn_kind == DT_NODE_VAR &&
+ (dnp->dn_ident->di_flags & DT_IDFLG_INLINE)) {
+ dt_cg_inline(dnp, dlp, drp);
+ break;
+ }
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_FUNC: {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ if ((idp = dnp->dn_ident)->di_kind != DT_IDENT_FUNC) {
+ dnerror(dnp, D_CG_EXPR, "%s %s( ) may not be "
+ "called from a D expression (D program "
+ "context required)\n",
+ dt_idkind_name(idp->di_kind), idp->di_name);
+ }
+
+ switch (idp->di_id) {
+ case DIF_SUBR_TYPEREF:
+ dt_cg_func_typeref(dtp, dnp);
+ break;
+
+ default:
+ break;
+ }
+
+ dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ instr = DIF_INSTR_CALL(
+ dnp->dn_ident->di_id, dnp->dn_reg);
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ break;
+ }
+
+ case DT_NODE_VAR:
+ if (dnp->dn_ident->di_kind == DT_IDENT_XLSOU ||
+ dnp->dn_ident->di_kind == DT_IDENT_XLPTR) {
+ /*
+ * This can only happen if we have translated
+ * args[]. See dt_idcook_args() for details.
+ */
+ assert(dnp->dn_ident->di_id == DIF_VAR_ARGS);
+ dt_cg_array_op(dnp, dlp, drp);
+ break;
+ }
+
+ if (dnp->dn_ident->di_kind == DT_IDENT_ARRAY) {
+ if (dnp->dn_ident->di_id > DIF_VAR_ARRAY_MAX)
+ dt_cg_assoc_op(dnp, dlp, drp);
+ else
+ dt_cg_array_op(dnp, dlp, drp);
+ break;
+ }
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ if (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL)
+ op = DIF_OP_LDLS;
+ else if (dnp->dn_ident->di_flags & DT_IDFLG_TLS)
+ op = DIF_OP_LDTS;
+ else
+ op = DIF_OP_LDGS;
+
+ dnp->dn_ident->di_flags |= DT_IDFLG_DIFR;
+
+ instr = DIF_INSTR_LDV(op,
+ dnp->dn_ident->di_id, dnp->dn_reg);
+
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ break;
+
+ case DT_NODE_SYM: {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_syminfo_t *sip = dnp->dn_ident->di_data;
+ GElf_Sym sym;
+
+ if (dtrace_lookup_by_name(dtp,
+ sip->dts_object, sip->dts_name, &sym, NULL) == -1) {
+ xyerror(D_UNKNOWN, "cg failed for symbol %s`%s:"
+ " %s\n", sip->dts_object, sip->dts_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_xsetx(dlp, dnp->dn_ident,
+ DT_LBL_NONE, dnp->dn_reg, sym.st_value);
+
+ if (!(dnp->dn_flags & DT_NF_REF)) {
+ instr = DIF_INSTR_LOAD(dt_cg_load(dnp, ctfp,
+ dnp->dn_type), dnp->dn_reg, dnp->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ }
+ break;
+ }
+
+ default:
+ xyerror(D_UNKNOWN, "internal error -- node type %u is "
+ "not valid for an identifier\n", dnp->dn_kind);
+ }
+ break;
+
+ case DT_TOK_INT:
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_setx(dlp, dnp->dn_reg, dnp->dn_value);
+ break;
+
+ default:
+ xyerror(D_UNKNOWN, "internal error -- token type %u is not a "
+ "valid D compilation token\n", dnp->dn_op);
+ }
+}
+
+void
+dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
+{
+ dif_instr_t instr;
+ dt_xlator_t *dxp;
+
+ if (pcb->pcb_regs == NULL && (pcb->pcb_regs =
+ dt_regset_create(pcb->pcb_hdl->dt_conf.dtc_difintregs)) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dt_regset_reset(pcb->pcb_regs);
+ (void) dt_regset_alloc(pcb->pcb_regs); /* allocate %r0 */
+
+ if (pcb->pcb_inttab != NULL)
+ dt_inttab_destroy(pcb->pcb_inttab);
+
+ if ((pcb->pcb_inttab = dt_inttab_create(yypcb->pcb_hdl)) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (pcb->pcb_strtab != NULL)
+ dt_strtab_destroy(pcb->pcb_strtab);
+
+ if ((pcb->pcb_strtab = dt_strtab_create(BUFSIZ)) == NULL)
+ longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dt_irlist_destroy(&pcb->pcb_ir);
+ dt_irlist_create(&pcb->pcb_ir);
+
+ assert(pcb->pcb_dret == NULL);
+ pcb->pcb_dret = dnp;
+
+ if (dt_node_is_dynamic(dnp)) {
+ dnerror(dnp, D_CG_DYN, "expression cannot evaluate to result "
+ "of dynamic type\n");
+ }
+
+ /*
+ * If we're generating code for a translator body, assign the input
+ * parameter to the first available register (i.e. caller passes %r1).
+ */
+ if (dnp->dn_kind == DT_NODE_MEMBER) {
+ dxp = dnp->dn_membxlator;
+ dnp = dnp->dn_membexpr;
+
+ dxp->dx_ident->di_flags |= DT_IDFLG_CGREG;
+ dxp->dx_ident->di_id = dt_regset_alloc(pcb->pcb_regs);
+ }
+
+ dt_cg_node(dnp, &pcb->pcb_ir, pcb->pcb_regs);
+ instr = DIF_INSTR_RET(dnp->dn_reg);
+ dt_regset_free(pcb->pcb_regs, dnp->dn_reg);
+ dt_irlist_append(&pcb->pcb_ir, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ if (dnp->dn_kind == DT_NODE_MEMBER) {
+ dt_regset_free(pcb->pcb_regs, dxp->dx_ident->di_id);
+ dxp->dx_ident->di_id = 0;
+ dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
new file mode 100644
index 0000000..797e7e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -0,0 +1,2804 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
+#include <ctype.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <dt_impl.h>
+#if !defined(sun)
+#include <libproc_compat.h>
+#endif
+
+#define DT_MASK_LO 0x00000000FFFFFFFFULL
+
+/*
+ * We declare this here because (1) we need it and (2) we want to avoid a
+ * dependency on libm in libdtrace.
+ */
+static long double
+dt_fabsl(long double x)
+{
+ if (x < 0)
+ return (-x);
+
+ return (x);
+}
+
+/*
+ * 128-bit arithmetic functions needed to support the stddev() aggregating
+ * action.
+ */
+static int
+dt_gt_128(uint64_t *a, uint64_t *b)
+{
+ return (a[1] > b[1] || (a[1] == b[1] && a[0] > b[0]));
+}
+
+static int
+dt_ge_128(uint64_t *a, uint64_t *b)
+{
+ return (a[1] > b[1] || (a[1] == b[1] && a[0] >= b[0]));
+}
+
+static int
+dt_le_128(uint64_t *a, uint64_t *b)
+{
+ return (a[1] < b[1] || (a[1] == b[1] && a[0] <= b[0]));
+}
+
+/*
+ * Shift the 128-bit value in a by b. If b is positive, shift left.
+ * If b is negative, shift right.
+ */
+static void
+dt_shift_128(uint64_t *a, int b)
+{
+ uint64_t mask;
+
+ if (b == 0)
+ return;
+
+ if (b < 0) {
+ b = -b;
+ if (b >= 64) {
+ a[0] = a[1] >> (b - 64);
+ a[1] = 0;
+ } else {
+ a[0] >>= b;
+ mask = 1LL << (64 - b);
+ mask -= 1;
+ a[0] |= ((a[1] & mask) << (64 - b));
+ a[1] >>= b;
+ }
+ } else {
+ if (b >= 64) {
+ a[1] = a[0] << (b - 64);
+ a[0] = 0;
+ } else {
+ a[1] <<= b;
+ mask = a[0] >> (64 - b);
+ a[1] |= mask;
+ a[0] <<= b;
+ }
+ }
+}
+
+static int
+dt_nbits_128(uint64_t *a)
+{
+ int nbits = 0;
+ uint64_t tmp[2];
+ uint64_t zero[2] = { 0, 0 };
+
+ tmp[0] = a[0];
+ tmp[1] = a[1];
+
+ dt_shift_128(tmp, -1);
+ while (dt_gt_128(tmp, zero)) {
+ dt_shift_128(tmp, -1);
+ nbits++;
+ }
+
+ return (nbits);
+}
+
+static void
+dt_subtract_128(uint64_t *minuend, uint64_t *subtrahend, uint64_t *difference)
+{
+ uint64_t result[2];
+
+ result[0] = minuend[0] - subtrahend[0];
+ result[1] = minuend[1] - subtrahend[1] -
+ (minuend[0] < subtrahend[0] ? 1 : 0);
+
+ difference[0] = result[0];
+ difference[1] = result[1];
+}
+
+static void
+dt_add_128(uint64_t *addend1, uint64_t *addend2, uint64_t *sum)
+{
+ uint64_t result[2];
+
+ result[0] = addend1[0] + addend2[0];
+ result[1] = addend1[1] + addend2[1] +
+ (result[0] < addend1[0] || result[0] < addend2[0] ? 1 : 0);
+
+ sum[0] = result[0];
+ sum[1] = result[1];
+}
+
+/*
+ * The basic idea is to break the 2 64-bit values into 4 32-bit values,
+ * use native multiplication on those, and then re-combine into the
+ * resulting 128-bit value.
+ *
+ * (hi1 << 32 + lo1) * (hi2 << 32 + lo2) =
+ * hi1 * hi2 << 64 +
+ * hi1 * lo2 << 32 +
+ * hi2 * lo1 << 32 +
+ * lo1 * lo2
+ */
+static void
+dt_multiply_128(uint64_t factor1, uint64_t factor2, uint64_t *product)
+{
+ uint64_t hi1, hi2, lo1, lo2;
+ uint64_t tmp[2];
+
+ hi1 = factor1 >> 32;
+ hi2 = factor2 >> 32;
+
+ lo1 = factor1 & DT_MASK_LO;
+ lo2 = factor2 & DT_MASK_LO;
+
+ product[0] = lo1 * lo2;
+ product[1] = hi1 * hi2;
+
+ tmp[0] = hi1 * lo2;
+ tmp[1] = 0;
+ dt_shift_128(tmp, 32);
+ dt_add_128(product, tmp, product);
+
+ tmp[0] = hi2 * lo1;
+ tmp[1] = 0;
+ dt_shift_128(tmp, 32);
+ dt_add_128(product, tmp, product);
+}
+
+/*
+ * This is long-hand division.
+ *
+ * We initialize subtrahend by shifting divisor left as far as possible. We
+ * loop, comparing subtrahend to dividend: if subtrahend is smaller, we
+ * subtract and set the appropriate bit in the result. We then shift
+ * subtrahend right by one bit for the next comparison.
+ */
+static void
+dt_divide_128(uint64_t *dividend, uint64_t divisor, uint64_t *quotient)
+{
+ uint64_t result[2] = { 0, 0 };
+ uint64_t remainder[2];
+ uint64_t subtrahend[2];
+ uint64_t divisor_128[2];
+ uint64_t mask[2] = { 1, 0 };
+ int log = 0;
+
+ assert(divisor != 0);
+
+ divisor_128[0] = divisor;
+ divisor_128[1] = 0;
+
+ remainder[0] = dividend[0];
+ remainder[1] = dividend[1];
+
+ subtrahend[0] = divisor;
+ subtrahend[1] = 0;
+
+ while (divisor > 0) {
+ log++;
+ divisor >>= 1;
+ }
+
+ dt_shift_128(subtrahend, 128 - log);
+ dt_shift_128(mask, 128 - log);
+
+ while (dt_ge_128(remainder, divisor_128)) {
+ if (dt_ge_128(remainder, subtrahend)) {
+ dt_subtract_128(remainder, subtrahend, remainder);
+ result[0] |= mask[0];
+ result[1] |= mask[1];
+ }
+
+ dt_shift_128(subtrahend, -1);
+ dt_shift_128(mask, -1);
+ }
+
+ quotient[0] = result[0];
+ quotient[1] = result[1];
+}
+
+/*
+ * This is the long-hand method of calculating a square root.
+ * The algorithm is as follows:
+ *
+ * 1. Group the digits by 2 from the right.
+ * 2. Over the leftmost group, find the largest single-digit number
+ * whose square is less than that group.
+ * 3. Subtract the result of the previous step (2 or 4, depending) and
+ * bring down the next two-digit group.
+ * 4. For the result R we have so far, find the largest single-digit number
+ * x such that 2 * R * 10 * x + x^2 is less than the result from step 3.
+ * (Note that this is doubling R and performing a decimal left-shift by 1
+ * and searching for the appropriate decimal to fill the one's place.)
+ * The value x is the next digit in the square root.
+ * Repeat steps 3 and 4 until the desired precision is reached. (We're
+ * dealing with integers, so the above is sufficient.)
+ *
+ * In decimal, the square root of 582,734 would be calculated as so:
+ *
+ * __7__6__3
+ * | 58 27 34
+ * -49 (7^2 == 49 => 7 is the first digit in the square root)
+ * --
+ * 9 27 (Subtract and bring down the next group.)
+ * 146 8 76 (2 * 7 * 10 * 6 + 6^2 == 876 => 6 is the next digit in
+ * ----- the square root)
+ * 51 34 (Subtract and bring down the next group.)
+ * 1523 45 69 (2 * 76 * 10 * 3 + 3^2 == 4569 => 3 is the next digit in
+ * ----- the square root)
+ * 5 65 (remainder)
+ *
+ * The above algorithm applies similarly in binary, but note that the
+ * only possible non-zero value for x in step 4 is 1, so step 4 becomes a
+ * simple decision: is 2 * R * 2 * 1 + 1^2 (aka R << 2 + 1) less than the
+ * preceding difference?
+ *
+ * In binary, the square root of 11011011 would be calculated as so:
+ *
+ * __1__1__1__0
+ * | 11 01 10 11
+ * 01 (0 << 2 + 1 == 1 < 11 => this bit is 1)
+ * --
+ * 10 01 10 11
+ * 101 1 01 (1 << 2 + 1 == 101 < 1001 => next bit is 1)
+ * -----
+ * 1 00 10 11
+ * 1101 11 01 (11 << 2 + 1 == 1101 < 10010 => next bit is 1)
+ * -------
+ * 1 01 11
+ * 11101 1 11 01 (111 << 2 + 1 == 11101 > 10111 => last bit is 0)
+ *
+ */
+static uint64_t
+dt_sqrt_128(uint64_t *square)
+{
+ uint64_t result[2] = { 0, 0 };
+ uint64_t diff[2] = { 0, 0 };
+ uint64_t one[2] = { 1, 0 };
+ uint64_t next_pair[2];
+ uint64_t next_try[2];
+ uint64_t bit_pairs, pair_shift;
+ int i;
+
+ bit_pairs = dt_nbits_128(square) / 2;
+ pair_shift = bit_pairs * 2;
+
+ for (i = 0; i <= bit_pairs; i++) {
+ /*
+ * Bring down the next pair of bits.
+ */
+ next_pair[0] = square[0];
+ next_pair[1] = square[1];
+ dt_shift_128(next_pair, -pair_shift);
+ next_pair[0] &= 0x3;
+ next_pair[1] = 0;
+
+ dt_shift_128(diff, 2);
+ dt_add_128(diff, next_pair, diff);
+
+ /*
+ * next_try = R << 2 + 1
+ */
+ next_try[0] = result[0];
+ next_try[1] = result[1];
+ dt_shift_128(next_try, 2);
+ dt_add_128(next_try, one, next_try);
+
+ if (dt_le_128(next_try, diff)) {
+ dt_subtract_128(diff, next_try, diff);
+ dt_shift_128(result, 1);
+ dt_add_128(result, one, result);
+ } else {
+ dt_shift_128(result, 1);
+ }
+
+ pair_shift -= 2;
+ }
+
+ assert(result[1] == 0);
+
+ return (result[0]);
+}
+
+uint64_t
+dt_stddev(uint64_t *data, uint64_t normal)
+{
+ uint64_t avg_of_squares[2];
+ uint64_t square_of_avg[2];
+ int64_t norm_avg;
+ uint64_t diff[2];
+
+ /*
+ * The standard approximation for standard deviation is
+ * sqrt(average(x**2) - average(x)**2), i.e. the square root
+ * of the average of the squares minus the square of the average.
+ */
+ dt_divide_128(data + 2, normal, avg_of_squares);
+ dt_divide_128(avg_of_squares, data[0], avg_of_squares);
+
+ norm_avg = (int64_t)data[1] / (int64_t)normal / (int64_t)data[0];
+
+ if (norm_avg < 0)
+ norm_avg = -norm_avg;
+
+ dt_multiply_128((uint64_t)norm_avg, (uint64_t)norm_avg, square_of_avg);
+
+ dt_subtract_128(avg_of_squares, square_of_avg, diff);
+
+ return (dt_sqrt_128(diff));
+}
+
+static int
+dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last,
+ dtrace_bufdesc_t *buf, size_t offs)
+{
+ dtrace_probedesc_t *pd = data->dtpda_pdesc, *npd;
+ dtrace_eprobedesc_t *epd = data->dtpda_edesc, *nepd;
+ char *p = pd->dtpd_provider, *n = pd->dtpd_name, *sub;
+ dtrace_flowkind_t flow = DTRACEFLOW_NONE;
+ const char *str = NULL;
+ static const char *e_str[2] = { " -> ", " => " };
+ static const char *r_str[2] = { " <- ", " <= " };
+ static const char *ent = "entry", *ret = "return";
+ static int entlen = 0, retlen = 0;
+ dtrace_epid_t next, id = epd->dtepd_epid;
+ int rval;
+
+ if (entlen == 0) {
+ assert(retlen == 0);
+ entlen = strlen(ent);
+ retlen = strlen(ret);
+ }
+
+ /*
+ * If the name of the probe is "entry" or ends with "-entry", we
+ * treat it as an entry; if it is "return" or ends with "-return",
+ * we treat it as a return. (This allows application-provided probes
+ * like "method-entry" or "function-entry" to participate in flow
+ * indentation -- without accidentally misinterpreting popular probe
+ * names like "carpentry", "gentry" or "Coventry".)
+ */
+ if ((sub = strstr(n, ent)) != NULL && sub[entlen] == '\0' &&
+ (sub == n || sub[-1] == '-')) {
+ flow = DTRACEFLOW_ENTRY;
+ str = e_str[strcmp(p, "syscall") == 0];
+ } else if ((sub = strstr(n, ret)) != NULL && sub[retlen] == '\0' &&
+ (sub == n || sub[-1] == '-')) {
+ flow = DTRACEFLOW_RETURN;
+ str = r_str[strcmp(p, "syscall") == 0];
+ }
+
+ /*
+ * If we're going to indent this, we need to check the ID of our last
+ * call. If we're looking at the same probe ID but a different EPID,
+ * we _don't_ want to indent. (Yes, there are some minor holes in
+ * this scheme -- it's a heuristic.)
+ */
+ if (flow == DTRACEFLOW_ENTRY) {
+ if ((last != DTRACE_EPIDNONE && id != last &&
+ pd->dtpd_id == dtp->dt_pdesc[last]->dtpd_id))
+ flow = DTRACEFLOW_NONE;
+ }
+
+ /*
+ * If we're going to unindent this, it's more difficult to see if
+ * we don't actually want to unindent it -- we need to look at the
+ * _next_ EPID.
+ */
+ if (flow == DTRACEFLOW_RETURN) {
+ offs += epd->dtepd_size;
+
+ do {
+ if (offs >= buf->dtbd_size) {
+ /*
+ * We're at the end -- maybe. If the oldest
+ * record is non-zero, we need to wrap.
+ */
+ if (buf->dtbd_oldest != 0) {
+ offs = 0;
+ } else {
+ goto out;
+ }
+ }
+
+ next = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs);
+
+ if (next == DTRACE_EPIDNONE)
+ offs += sizeof (id);
+ } while (next == DTRACE_EPIDNONE);
+
+ if ((rval = dt_epid_lookup(dtp, next, &nepd, &npd)) != 0)
+ return (rval);
+
+ if (next != id && npd->dtpd_id == pd->dtpd_id)
+ flow = DTRACEFLOW_NONE;
+ }
+
+out:
+ if (flow == DTRACEFLOW_ENTRY || flow == DTRACEFLOW_RETURN) {
+ data->dtpda_prefix = str;
+ } else {
+ data->dtpda_prefix = "| ";
+ }
+
+ if (flow == DTRACEFLOW_RETURN && data->dtpda_indent > 0)
+ data->dtpda_indent -= 2;
+
+ data->dtpda_flow = flow;
+
+ return (0);
+}
+
+static int
+dt_nullprobe()
+{
+ return (DTRACE_CONSUME_THIS);
+}
+
+static int
+dt_nullrec()
+{
+ return (DTRACE_CONSUME_NEXT);
+}
+
+int
+dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val,
+ uint64_t normal, long double total, char positives, char negatives)
+{
+ long double f;
+ uint_t depth, len = 40;
+
+ const char *ats = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
+ const char *spaces = " ";
+
+ assert(strlen(ats) == len && strlen(spaces) == len);
+ assert(!(total == 0 && (positives || negatives)));
+ assert(!(val < 0 && !negatives));
+ assert(!(val > 0 && !positives));
+ assert(!(val != 0 && total == 0));
+
+ if (!negatives) {
+ if (positives) {
+ f = (dt_fabsl((long double)val) * len) / total;
+ depth = (uint_t)(f + 0.5);
+ } else {
+ depth = 0;
+ }
+
+ return (dt_printf(dtp, fp, "|%s%s %-9lld\n", ats + len - depth,
+ spaces + depth, (long long)val / normal));
+ }
+
+ if (!positives) {
+ f = (dt_fabsl((long double)val) * len) / total;
+ depth = (uint_t)(f + 0.5);
+
+ return (dt_printf(dtp, fp, "%s%s| %-9lld\n", spaces + depth,
+ ats + len - depth, (long long)val / normal));
+ }
+
+ /*
+ * If we're here, we have both positive and negative bucket values.
+ * To express this graphically, we're going to generate both positive
+ * and negative bars separated by a centerline. These bars are half
+ * the size of normal quantize()/lquantize() bars, so we divide the
+ * length in half before calculating the bar length.
+ */
+ len /= 2;
+ ats = &ats[len];
+ spaces = &spaces[len];
+
+ f = (dt_fabsl((long double)val) * len) / total;
+ depth = (uint_t)(f + 0.5);
+
+ if (val <= 0) {
+ return (dt_printf(dtp, fp, "%s%s|%*s %-9lld\n", spaces + depth,
+ ats + len - depth, len, "", (long long)val / normal));
+ } else {
+ return (dt_printf(dtp, fp, "%20s|%s%s %-9lld\n", "",
+ ats + len - depth, spaces + depth,
+ (long long)val / normal));
+ }
+}
+
+int
+dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+ size_t size, uint64_t normal)
+{
+ const int64_t *data = addr;
+ int i, first_bin = 0, last_bin = DTRACE_QUANTIZE_NBUCKETS - 1;
+ long double total = 0;
+ char positives = 0, negatives = 0;
+
+ if (size != DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ while (first_bin < DTRACE_QUANTIZE_NBUCKETS - 1 && data[first_bin] == 0)
+ first_bin++;
+
+ if (first_bin == DTRACE_QUANTIZE_NBUCKETS - 1) {
+ /*
+ * There isn't any data. This is possible if (and only if)
+ * negative increment values have been used. In this case,
+ * we'll print the buckets around 0.
+ */
+ first_bin = DTRACE_QUANTIZE_ZEROBUCKET - 1;
+ last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 1;
+ } else {
+ if (first_bin > 0)
+ first_bin--;
+
+ while (last_bin > 0 && data[last_bin] == 0)
+ last_bin--;
+
+ if (last_bin < DTRACE_QUANTIZE_NBUCKETS - 1)
+ last_bin++;
+ }
+
+ for (i = first_bin; i <= last_bin; i++) {
+ positives |= (data[i] > 0);
+ negatives |= (data[i] < 0);
+ total += dt_fabsl((long double)data[i]);
+ }
+
+ if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
+ "------------- Distribution -------------", "count") < 0)
+ return (-1);
+
+ for (i = first_bin; i <= last_bin; i++) {
+ if (dt_printf(dtp, fp, "%16lld ",
+ (long long)DTRACE_QUANTIZE_BUCKETVAL(i)) < 0)
+ return (-1);
+
+ if (dt_print_quantline(dtp, fp, data[i], normal, total,
+ positives, negatives) < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+ size_t size, uint64_t normal)
+{
+ const int64_t *data = addr;
+ int i, first_bin, last_bin, base;
+ uint64_t arg;
+ long double total = 0;
+ uint16_t step, levels;
+ char positives = 0, negatives = 0;
+
+ if (size < sizeof (uint64_t))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ arg = *data++;
+ size -= sizeof (uint64_t);
+
+ base = DTRACE_LQUANTIZE_BASE(arg);
+ step = DTRACE_LQUANTIZE_STEP(arg);
+ levels = DTRACE_LQUANTIZE_LEVELS(arg);
+
+ first_bin = 0;
+ last_bin = levels + 1;
+
+ if (size != sizeof (uint64_t) * (levels + 2))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ while (first_bin <= levels + 1 && data[first_bin] == 0)
+ first_bin++;
+
+ if (first_bin > levels + 1) {
+ first_bin = 0;
+ last_bin = 2;
+ } else {
+ if (first_bin > 0)
+ first_bin--;
+
+ while (last_bin > 0 && data[last_bin] == 0)
+ last_bin--;
+
+ if (last_bin < levels + 1)
+ last_bin++;
+ }
+
+ for (i = first_bin; i <= last_bin; i++) {
+ positives |= (data[i] > 0);
+ negatives |= (data[i] < 0);
+ total += dt_fabsl((long double)data[i]);
+ }
+
+ if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
+ "------------- Distribution -------------", "count") < 0)
+ return (-1);
+
+ for (i = first_bin; i <= last_bin; i++) {
+ char c[32];
+ int err;
+
+ if (i == 0) {
+ (void) snprintf(c, sizeof (c), "< %d",
+ base / (uint32_t)normal);
+ err = dt_printf(dtp, fp, "%16s ", c);
+ } else if (i == levels + 1) {
+ (void) snprintf(c, sizeof (c), ">= %d",
+ base + (levels * step));
+ err = dt_printf(dtp, fp, "%16s ", c);
+ } else {
+ err = dt_printf(dtp, fp, "%16d ",
+ base + (i - 1) * step);
+ }
+
+ if (err < 0 || dt_print_quantline(dtp, fp, data[i], normal,
+ total, positives, negatives) < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+ size_t size, uint64_t normal)
+{
+ int i, first_bin, last_bin, bin = 1, order, levels;
+ uint16_t factor, low, high, nsteps;
+ const int64_t *data = addr;
+ int64_t value = 1, next, step;
+ char positives = 0, negatives = 0;
+ long double total = 0;
+ uint64_t arg;
+ char c[32];
+
+ if (size < sizeof (uint64_t))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ arg = *data++;
+ size -= sizeof (uint64_t);
+
+ factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+ low = DTRACE_LLQUANTIZE_LOW(arg);
+ high = DTRACE_LLQUANTIZE_HIGH(arg);
+ nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+
+ /*
+ * We don't expect to be handed invalid llquantize() parameters here,
+ * but sanity check them (to a degree) nonetheless.
+ */
+ if (size > INT32_MAX || factor < 2 || low >= high ||
+ nsteps == 0 || factor > nsteps)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ levels = (int)size / sizeof (uint64_t);
+
+ first_bin = 0;
+ last_bin = levels - 1;
+
+ while (first_bin < levels && data[first_bin] == 0)
+ first_bin++;
+
+ if (first_bin == levels) {
+ first_bin = 0;
+ last_bin = 1;
+ } else {
+ if (first_bin > 0)
+ first_bin--;
+
+ while (last_bin > 0 && data[last_bin] == 0)
+ last_bin--;
+
+ if (last_bin < levels - 1)
+ last_bin++;
+ }
+
+ for (i = first_bin; i <= last_bin; i++) {
+ positives |= (data[i] > 0);
+ negatives |= (data[i] < 0);
+ total += dt_fabsl((long double)data[i]);
+ }
+
+ if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
+ "------------- Distribution -------------", "count") < 0)
+ return (-1);
+
+ for (order = 0; order < low; order++)
+ value *= factor;
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+
+ if (first_bin == 0) {
+ (void) snprintf(c, sizeof (c), "< %lld", (long long)value);
+
+ if (dt_printf(dtp, fp, "%16s ", c) < 0)
+ return (-1);
+
+ if (dt_print_quantline(dtp, fp, data[0], normal,
+ total, positives, negatives) < 0)
+ return (-1);
+ }
+
+ while (order <= high) {
+ if (bin >= first_bin && bin <= last_bin) {
+ if (dt_printf(dtp, fp, "%16lld ", (long long)value) < 0)
+ return (-1);
+
+ if (dt_print_quantline(dtp, fp, data[bin],
+ normal, total, positives, negatives) < 0)
+ return (-1);
+ }
+
+ assert(value < next);
+ bin++;
+
+ if ((value += step) != next)
+ continue;
+
+ next = value * factor;
+ step = next > nsteps ? next / nsteps : 1;
+ order++;
+ }
+
+ if (last_bin < bin)
+ return (0);
+
+ assert(last_bin == bin);
+ (void) snprintf(c, sizeof (c), ">= %lld", (long long)value);
+
+ if (dt_printf(dtp, fp, "%16s ", c) < 0)
+ return (-1);
+
+ return (dt_print_quantline(dtp, fp, data[bin], normal,
+ total, positives, negatives));
+}
+
+/*ARGSUSED*/
+static int
+dt_print_average(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
+ size_t size, uint64_t normal)
+{
+ /* LINTED - alignment */
+ int64_t *data = (int64_t *)addr;
+
+ return (dt_printf(dtp, fp, " %16lld", data[0] ?
+ (long long)(data[1] / (int64_t)normal / data[0]) : 0));
+}
+
+/*ARGSUSED*/
+static int
+dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
+ size_t size, uint64_t normal)
+{
+ /* LINTED - alignment */
+ uint64_t *data = (uint64_t *)addr;
+
+ return (dt_printf(dtp, fp, " %16llu", data[0] ?
+ (unsigned long long) dt_stddev(data, normal) : 0));
+}
+
+/*ARGSUSED*/
+int
+dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
+ size_t nbytes, int width, int quiet, int forceraw)
+{
+ /*
+ * If the byte stream is a series of printable characters, followed by
+ * a terminating byte, we print it out as a string. Otherwise, we
+ * assume that it's something else and just print the bytes.
+ */
+ int i, j, margin = 5;
+ char *c = (char *)addr;
+
+ if (nbytes == 0)
+ return (0);
+
+ if (forceraw)
+ goto raw;
+
+ if (dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
+ goto raw;
+
+ for (i = 0; i < nbytes; i++) {
+ /*
+ * We define a "printable character" to be one for which
+ * isprint(3C) returns non-zero, isspace(3C) returns non-zero,
+ * or a character which is either backspace or the bell.
+ * Backspace and the bell are regrettably special because
+ * they fail the first two tests -- and yet they are entirely
+ * printable. These are the only two control characters that
+ * have meaning for the terminal and for which isprint(3C) and
+ * isspace(3C) return 0.
+ */
+ if (isprint(c[i]) || isspace(c[i]) ||
+ c[i] == '\b' || c[i] == '\a')
+ continue;
+
+ if (c[i] == '\0' && i > 0) {
+ /*
+ * This looks like it might be a string. Before we
+ * assume that it is indeed a string, check the
+ * remainder of the byte range; if it contains
+ * additional non-nul characters, we'll assume that
+ * it's a binary stream that just happens to look like
+ * a string, and we'll print out the individual bytes.
+ */
+ for (j = i + 1; j < nbytes; j++) {
+ if (c[j] != '\0')
+ break;
+ }
+
+ if (j != nbytes)
+ break;
+
+ if (quiet)
+ return (dt_printf(dtp, fp, "%s", c));
+ else
+ return (dt_printf(dtp, fp, " %-*s", width, c));
+ }
+
+ break;
+ }
+
+ if (i == nbytes) {
+ /*
+ * The byte range is all printable characters, but there is
+ * no trailing nul byte. We'll assume that it's a string and
+ * print it as such.
+ */
+ char *s = alloca(nbytes + 1);
+ bcopy(c, s, nbytes);
+ s[nbytes] = '\0';
+ return (dt_printf(dtp, fp, " %-*s", width, s));
+ }
+
+raw:
+ if (dt_printf(dtp, fp, "\n%*s ", margin, "") < 0)
+ return (-1);
+
+ for (i = 0; i < 16; i++)
+ if (dt_printf(dtp, fp, " %c", "0123456789abcdef"[i]) < 0)
+ return (-1);
+
+ if (dt_printf(dtp, fp, " 0123456789abcdef\n") < 0)
+ return (-1);
+
+
+ for (i = 0; i < nbytes; i += 16) {
+ if (dt_printf(dtp, fp, "%*s%5x:", margin, "", i) < 0)
+ return (-1);
+
+ for (j = i; j < i + 16 && j < nbytes; j++) {
+ if (dt_printf(dtp, fp, " %02x", (uchar_t)c[j]) < 0)
+ return (-1);
+ }
+
+ while (j++ % 16) {
+ if (dt_printf(dtp, fp, " ") < 0)
+ return (-1);
+ }
+
+ if (dt_printf(dtp, fp, " ") < 0)
+ return (-1);
+
+ for (j = i; j < i + 16 && j < nbytes; j++) {
+ if (dt_printf(dtp, fp, "%c",
+ c[j] < ' ' || c[j] > '~' ? '.' : c[j]) < 0)
+ return (-1);
+ }
+
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+dt_print_stack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ caddr_t addr, int depth, int size)
+{
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+ int i, indent;
+ char c[PATH_MAX * 2];
+ uint64_t pc;
+
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+
+ if (format == NULL)
+ format = "%s";
+
+ if (dtp->dt_options[DTRACEOPT_STACKINDENT] != DTRACEOPT_UNSET)
+ indent = (int)dtp->dt_options[DTRACEOPT_STACKINDENT];
+ else
+ indent = _dtrace_stkindent;
+
+ for (i = 0; i < depth; i++) {
+ switch (size) {
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ pc = *((uint32_t *)addr);
+ break;
+
+ case sizeof (uint64_t):
+ /* LINTED - alignment */
+ pc = *((uint64_t *)addr);
+ break;
+
+ default:
+ return (dt_set_errno(dtp, EDT_BADSTACKPC));
+ }
+
+ if (pc == 0)
+ break;
+
+ addr += size;
+
+ if (dt_printf(dtp, fp, "%*s", indent, "") < 0)
+ return (-1);
+
+ if (dtrace_lookup_by_addr(dtp, pc, &sym, &dts) == 0) {
+ if (pc > sym.st_value) {
+ (void) snprintf(c, sizeof (c), "%s`%s+0x%llx",
+ dts.dts_object, dts.dts_name,
+ (u_longlong_t)(pc - sym.st_value));
+ } else {
+ (void) snprintf(c, sizeof (c), "%s`%s",
+ dts.dts_object, dts.dts_name);
+ }
+ } else {
+ /*
+ * We'll repeat the lookup, but this time we'll specify
+ * a NULL GElf_Sym -- indicating that we're only
+ * interested in the containing module.
+ */
+ if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) {
+ (void) snprintf(c, sizeof (c), "%s`0x%llx",
+ dts.dts_object, (u_longlong_t)pc);
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%llx",
+ (u_longlong_t)pc);
+ }
+ }
+
+ if (dt_printf(dtp, fp, format, c) < 0)
+ return (-1);
+
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ caddr_t addr, uint64_t arg)
+{
+ /* LINTED - alignment */
+ uint64_t *pc = (uint64_t *)addr;
+ uint32_t depth = DTRACE_USTACK_NFRAMES(arg);
+ uint32_t strsize = DTRACE_USTACK_STRSIZE(arg);
+ const char *strbase = addr + (depth + 1) * sizeof (uint64_t);
+ const char *str = strsize ? strbase : NULL;
+ int err = 0;
+
+ char name[PATH_MAX], objname[PATH_MAX], c[PATH_MAX * 2];
+ struct ps_prochandle *P;
+ GElf_Sym sym;
+ int i, indent;
+ pid_t pid;
+
+ if (depth == 0)
+ return (0);
+
+ pid = (pid_t)*pc++;
+
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+
+ if (format == NULL)
+ format = "%s";
+
+ if (dtp->dt_options[DTRACEOPT_STACKINDENT] != DTRACEOPT_UNSET)
+ indent = (int)dtp->dt_options[DTRACEOPT_STACKINDENT];
+ else
+ indent = _dtrace_stkindent;
+
+ /*
+ * Ultimately, we need to add an entry point in the library vector for
+ * determining <symbol, offset> from <pid, address>. For now, if
+ * this is a vector open, we just print the raw address or string.
+ */
+ if (dtp->dt_vector == NULL)
+ P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0);
+ else
+ P = NULL;
+
+ if (P != NULL)
+ dt_proc_lock(dtp, P); /* lock handle while we perform lookups */
+
+ for (i = 0; i < depth && pc[i] != 0; i++) {
+ const prmap_t *map;
+
+ if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0)
+ break;
+
+ if (P != NULL && Plookup_by_addr(P, pc[i],
+ name, sizeof (name), &sym) == 0) {
+ (void) Pobjname(P, pc[i], objname, sizeof (objname));
+
+ if (pc[i] > sym.st_value) {
+ (void) snprintf(c, sizeof (c),
+ "%s`%s+0x%llx", dt_basename(objname), name,
+ (u_longlong_t)(pc[i] - sym.st_value));
+ } else {
+ (void) snprintf(c, sizeof (c),
+ "%s`%s", dt_basename(objname), name);
+ }
+ } else if (str != NULL && str[0] != '\0' && str[0] != '@' &&
+ (P != NULL && ((map = Paddr_to_map(P, pc[i])) == NULL ||
+ (map->pr_mflags & MA_WRITE)))) {
+ /*
+ * If the current string pointer in the string table
+ * does not point to an empty string _and_ the program
+ * counter falls in a writable region, we'll use the
+ * string from the string table instead of the raw
+ * address. This last condition is necessary because
+ * some (broken) ustack helpers will return a string
+ * even for a program counter that they can't
+ * identify. If we have a string for a program
+ * counter that falls in a segment that isn't
+ * writable, we assume that we have fallen into this
+ * case and we refuse to use the string.
+ */
+ (void) snprintf(c, sizeof (c), "%s", str);
+ } else {
+ if (P != NULL && Pobjname(P, pc[i], objname,
+ sizeof (objname)) != 0) {
+ (void) snprintf(c, sizeof (c), "%s`0x%llx",
+ dt_basename(objname), (u_longlong_t)pc[i]);
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%llx",
+ (u_longlong_t)pc[i]);
+ }
+ }
+
+ if ((err = dt_printf(dtp, fp, format, c)) < 0)
+ break;
+
+ if ((err = dt_printf(dtp, fp, "\n")) < 0)
+ break;
+
+ if (str != NULL && str[0] == '@') {
+ /*
+ * If the first character of the string is an "at" sign,
+ * then the string is inferred to be an annotation --
+ * and it is printed out beneath the frame and offset
+ * with brackets.
+ */
+ if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0)
+ break;
+
+ (void) snprintf(c, sizeof (c), " [ %s ]", &str[1]);
+
+ if ((err = dt_printf(dtp, fp, format, c)) < 0)
+ break;
+
+ if ((err = dt_printf(dtp, fp, "\n")) < 0)
+ break;
+ }
+
+ if (str != NULL) {
+ str += strlen(str) + 1;
+ if (str - strbase >= strsize)
+ str = NULL;
+ }
+ }
+
+ if (P != NULL) {
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+ }
+
+ return (err);
+}
+
+static int
+dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act)
+{
+ /* LINTED - alignment */
+ uint64_t pid = ((uint64_t *)addr)[0];
+ /* LINTED - alignment */
+ uint64_t pc = ((uint64_t *)addr)[1];
+ const char *format = " %-50s";
+ char *s;
+ int n, len = 256;
+
+ if (act == DTRACEACT_USYM && dtp->dt_vector == NULL) {
+ struct ps_prochandle *P;
+
+ if ((P = dt_proc_grab(dtp, pid,
+ PGRAB_RDONLY | PGRAB_FORCE, 0)) != NULL) {
+ GElf_Sym sym;
+
+ dt_proc_lock(dtp, P);
+
+ if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0)
+ pc = sym.st_value;
+
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+ }
+ }
+
+ do {
+ n = len;
+ s = alloca(n);
+ } while ((len = dtrace_uaddr2str(dtp, pid, pc, s, n)) > n);
+
+ return (dt_printf(dtp, fp, format, s));
+}
+
+int
+dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
+{
+ /* LINTED - alignment */
+ uint64_t pid = ((uint64_t *)addr)[0];
+ /* LINTED - alignment */
+ uint64_t pc = ((uint64_t *)addr)[1];
+ int err = 0;
+
+ char objname[PATH_MAX], c[PATH_MAX * 2];
+ struct ps_prochandle *P;
+
+ if (format == NULL)
+ format = " %-50s";
+
+ /*
+ * See the comment in dt_print_ustack() for the rationale for
+ * printing raw addresses in the vectored case.
+ */
+ if (dtp->dt_vector == NULL)
+ P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0);
+ else
+ P = NULL;
+
+ if (P != NULL)
+ dt_proc_lock(dtp, P); /* lock handle while we perform lookups */
+
+ if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != 0) {
+ (void) snprintf(c, sizeof (c), "%s", dt_basename(objname));
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc);
+ }
+
+ err = dt_printf(dtp, fp, format, c);
+
+ if (P != NULL) {
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+ }
+
+ return (err);
+}
+
+int
+dt_print_memory(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr)
+{
+ int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+ size_t nbytes = *((uintptr_t *) addr);
+
+ return (dt_print_bytes(dtp, fp, addr + sizeof(uintptr_t),
+ nbytes, 50, quiet, 1));
+}
+
+typedef struct dt_type_cbdata {
+ dtrace_hdl_t *dtp;
+ dtrace_typeinfo_t dtt;
+ caddr_t addr;
+ caddr_t addrend;
+ const char *name;
+ int f_type;
+ int indent;
+ int type_width;
+ int name_width;
+ FILE *fp;
+} dt_type_cbdata_t;
+
+static int dt_print_type_data(dt_type_cbdata_t *, ctf_id_t);
+
+static int
+dt_print_type_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ dt_type_cbdata_t cbdata;
+ dt_type_cbdata_t *cbdatap = arg;
+ ssize_t ssz;
+
+ if ((ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type)) <= 0)
+ return (0);
+
+ off /= 8;
+
+ cbdata = *cbdatap;
+ cbdata.name = name;
+ cbdata.addr += off;
+ cbdata.addrend = cbdata.addr + ssz;
+
+ return (dt_print_type_data(&cbdata, type));
+}
+
+static int
+dt_print_type_width(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+ dt_type_cbdata_t *cbdatap = arg;
+ size_t sz = strlen(name);
+
+ ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+ if ((p = strchr(buf, '[')) != NULL)
+ p[-1] = '\0';
+ else
+ p = "";
+
+ sz += strlen(p);
+
+ if (sz > cbdatap->name_width)
+ cbdatap->name_width = sz;
+
+ sz = strlen(buf);
+
+ if (sz > cbdatap->type_width)
+ cbdatap->type_width = sz;
+
+ return (0);
+}
+
+static int
+dt_print_type_data(dt_type_cbdata_t *cbdatap, ctf_id_t type)
+{
+ caddr_t addr = cbdatap->addr;
+ caddr_t addrend = cbdatap->addrend;
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+ int cnt = 0;
+ uint_t kind = ctf_type_kind(cbdatap->dtt.dtt_ctfp, type);
+ ssize_t ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type);
+
+ ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+ if ((p = strchr(buf, '[')) != NULL)
+ p[-1] = '\0';
+ else
+ p = "";
+
+ if (cbdatap->f_type) {
+ int type_width = roundup(cbdatap->type_width + 1, 4);
+ int name_width = roundup(cbdatap->name_width + 1, 4);
+
+ name_width -= strlen(cbdatap->name);
+
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s%-*s%s%-*s = ",cbdatap->indent * 4,"",type_width,buf,cbdatap->name,name_width,p);
+ }
+
+ while (addr < addrend) {
+ dt_type_cbdata_t cbdata;
+ ctf_arinfo_t arinfo;
+ ctf_encoding_t cte;
+ uintptr_t *up;
+ void *vp = addr;
+ cbdata = *cbdatap;
+ cbdata.name = "";
+ cbdata.addr = addr;
+ cbdata.addrend = addr + ssz;
+ cbdata.f_type = 0;
+ cbdata.indent++;
+ cbdata.type_width = 0;
+ cbdata.name_width = 0;
+
+ if (cnt > 0)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s", cbdatap->indent * 4,"");
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ if (ctf_type_encoding(cbdatap->dtt.dtt_ctfp, type, &cte) != 0)
+ return (-1);
+ if ((cte.cte_format & CTF_INT_SIGNED) != 0)
+ switch (cte.cte_bits) {
+ case 8:
+ if (isprint(*((char *) vp)))
+ dt_printf(cbdatap->dtp, cbdatap->fp, "'%c', ", *((char *) vp));
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((char *) vp), *((char *) vp));
+ break;
+ case 16:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%hd (0x%hx);\n", *((short *) vp), *((u_short *) vp));
+ break;
+ case 32:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((int *) vp), *((u_int *) vp));
+ break;
+ case 64:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%jd (0x%jx);\n", *((long long *) vp), *((unsigned long long *) vp));
+ break;
+ default:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ }
+ else
+ switch (cte.cte_bits) {
+ case 8:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((uint8_t *) vp) & 0xff, *((uint8_t *) vp) & 0xff);
+ break;
+ case 16:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%hu (0x%hx);\n", *((u_short *) vp), *((u_short *) vp));
+ break;
+ case 32:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((u_int *) vp), *((u_int *) vp));
+ break;
+ case 64:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%ju (0x%jx);\n", *((unsigned long long *) vp), *((unsigned long long *) vp));
+ break;
+ default:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ }
+ break;
+ case CTF_K_FLOAT:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FLOAT: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ case CTF_K_POINTER:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%p;\n", *((void **) addr));
+ break;
+ case CTF_K_ARRAY:
+ if (ctf_array_info(cbdatap->dtt.dtt_ctfp, type, &arinfo) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n%*s",cbdata.indent * 4,"");
+ dt_print_type_data(&cbdata, arinfo.ctr_contents);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_FUNCTION:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FUNCTION:\n");
+ break;
+ case CTF_K_STRUCT:
+ cbdata.f_type = 1;
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_width, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_member, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_UNION:
+ cbdata.f_type = 1;
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_width, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_member, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_ENUM:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%s;\n", ctf_enum_name(cbdatap->dtt.dtt_ctfp, type, *((int *) vp)));
+ break;
+ case CTF_K_TYPEDEF:
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_VOLATILE:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "volatile ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_CONST:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "const ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_RESTRICT:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "restrict ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ default:
+ break;
+ }
+
+ addr += ssz;
+ cnt++;
+ }
+
+ return (0);
+}
+
+static int
+dt_print_type(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr)
+{
+ caddr_t addrend;
+ char *p;
+ dtrace_typeinfo_t dtt;
+ dt_type_cbdata_t cbdata;
+ int num = 0;
+ int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+ ssize_t ssz;
+
+ if (!quiet)
+ dt_printf(dtp, fp, "\n");
+
+ /* Get the total number of bytes of data buffered. */
+ size_t nbytes = *((uintptr_t *) addr);
+ addr += sizeof(uintptr_t);
+
+ /*
+ * Get the size of the type so that we can check that it matches
+ * the CTF data we look up and so that we can figure out how many
+ * type elements are buffered.
+ */
+ size_t typs = *((uintptr_t *) addr);
+ addr += sizeof(uintptr_t);
+
+ /*
+ * Point to the type string in the buffer. Get it's string
+ * length and round it up to become the offset to the start
+ * of the buffered type data which we would like to be aligned
+ * for easy access.
+ */
+ char *strp = (char *) addr;
+ int offset = roundup(strlen(strp) + 1, sizeof(uintptr_t));
+
+ /*
+ * The type string might have a format such as 'int [20]'.
+ * Check if there is an array dimension present.
+ */
+ if ((p = strchr(strp, '[')) != NULL) {
+ /* Strip off the array dimension. */
+ *p++ = '\0';
+
+ for (; *p != '\0' && *p != ']'; p++)
+ num = num * 10 + *p - '0';
+ } else
+ /* No array dimension, so default. */
+ num = 1;
+
+ /* Lookup the CTF type from the type string. */
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY, strp, &dtt) < 0)
+ return (-1);
+
+ /* Offset the buffer address to the start of the data... */
+ addr += offset;
+
+ ssz = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
+
+ if (typs != ssz) {
+ printf("Expected type size from buffer (%lu) to match type size looked up now (%ld)\n", (u_long) typs, (long) ssz);
+ return (-1);
+ }
+
+ cbdata.dtp = dtp;
+ cbdata.dtt = dtt;
+ cbdata.name = "";
+ cbdata.addr = addr;
+ cbdata.addrend = addr + nbytes;
+ cbdata.indent = 1;
+ cbdata.f_type = 1;
+ cbdata.type_width = 0;
+ cbdata.name_width = 0;
+ cbdata.fp = fp;
+
+ return (dt_print_type_data(&cbdata, dtt.dtt_type));
+}
+
+static int
+dt_print_sym(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
+{
+ /* LINTED - alignment */
+ uint64_t pc = *((uint64_t *)addr);
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+ char c[PATH_MAX * 2];
+
+ if (format == NULL)
+ format = " %-50s";
+
+ if (dtrace_lookup_by_addr(dtp, pc, &sym, &dts) == 0) {
+ (void) snprintf(c, sizeof (c), "%s`%s",
+ dts.dts_object, dts.dts_name);
+ } else {
+ /*
+ * We'll repeat the lookup, but this time we'll specify a
+ * NULL GElf_Sym -- indicating that we're only interested in
+ * the containing module.
+ */
+ if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) {
+ (void) snprintf(c, sizeof (c), "%s`0x%llx",
+ dts.dts_object, (u_longlong_t)pc);
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%llx",
+ (u_longlong_t)pc);
+ }
+ }
+
+ if (dt_printf(dtp, fp, format, c) < 0)
+ return (-1);
+
+ return (0);
+}
+
+int
+dt_print_mod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
+{
+ /* LINTED - alignment */
+ uint64_t pc = *((uint64_t *)addr);
+ dtrace_syminfo_t dts;
+ char c[PATH_MAX * 2];
+
+ if (format == NULL)
+ format = " %-50s";
+
+ if (dtrace_lookup_by_addr(dtp, pc, NULL, &dts) == 0) {
+ (void) snprintf(c, sizeof (c), "%s", dts.dts_object);
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc);
+ }
+
+ if (dt_printf(dtp, fp, format, c) < 0)
+ return (-1);
+
+ return (0);
+}
+
+typedef struct dt_normal {
+ dtrace_aggvarid_t dtnd_id;
+ uint64_t dtnd_normal;
+} dt_normal_t;
+
+static int
+dt_normalize_agg(const dtrace_aggdata_t *aggdata, void *arg)
+{
+ dt_normal_t *normal = arg;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_aggvarid_t id = normal->dtnd_id;
+
+ if (agg->dtagd_nrecs == 0)
+ return (DTRACE_AGGWALK_NEXT);
+
+ if (agg->dtagd_varid != id)
+ return (DTRACE_AGGWALK_NEXT);
+
+ ((dtrace_aggdata_t *)aggdata)->dtada_normal = normal->dtnd_normal;
+ return (DTRACE_AGGWALK_NORMALIZE);
+}
+
+static int
+dt_normalize(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
+{
+ dt_normal_t normal;
+ caddr_t addr;
+
+ /*
+ * We (should) have two records: the aggregation ID followed by the
+ * normalization value.
+ */
+ addr = base + rec->dtrd_offset;
+
+ if (rec->dtrd_size != sizeof (dtrace_aggvarid_t))
+ return (dt_set_errno(dtp, EDT_BADNORMAL));
+
+ /* LINTED - alignment */
+ normal.dtnd_id = *((dtrace_aggvarid_t *)addr);
+ rec++;
+
+ if (rec->dtrd_action != DTRACEACT_LIBACT)
+ return (dt_set_errno(dtp, EDT_BADNORMAL));
+
+ if (rec->dtrd_arg != DT_ACT_NORMALIZE)
+ return (dt_set_errno(dtp, EDT_BADNORMAL));
+
+ addr = base + rec->dtrd_offset;
+
+ switch (rec->dtrd_size) {
+ case sizeof (uint64_t):
+ /* LINTED - alignment */
+ normal.dtnd_normal = *((uint64_t *)addr);
+ break;
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ normal.dtnd_normal = *((uint32_t *)addr);
+ break;
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ normal.dtnd_normal = *((uint16_t *)addr);
+ break;
+ case sizeof (uint8_t):
+ normal.dtnd_normal = *((uint8_t *)addr);
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_BADNORMAL));
+ }
+
+ (void) dtrace_aggregate_walk(dtp, dt_normalize_agg, &normal);
+
+ return (0);
+}
+
+static int
+dt_denormalize_agg(const dtrace_aggdata_t *aggdata, void *arg)
+{
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg);
+
+ if (agg->dtagd_nrecs == 0)
+ return (DTRACE_AGGWALK_NEXT);
+
+ if (agg->dtagd_varid != id)
+ return (DTRACE_AGGWALK_NEXT);
+
+ return (DTRACE_AGGWALK_DENORMALIZE);
+}
+
+static int
+dt_clear_agg(const dtrace_aggdata_t *aggdata, void *arg)
+{
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg);
+
+ if (agg->dtagd_nrecs == 0)
+ return (DTRACE_AGGWALK_NEXT);
+
+ if (agg->dtagd_varid != id)
+ return (DTRACE_AGGWALK_NEXT);
+
+ return (DTRACE_AGGWALK_CLEAR);
+}
+
+typedef struct dt_trunc {
+ dtrace_aggvarid_t dttd_id;
+ uint64_t dttd_remaining;
+} dt_trunc_t;
+
+static int
+dt_trunc_agg(const dtrace_aggdata_t *aggdata, void *arg)
+{
+ dt_trunc_t *trunc = arg;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_aggvarid_t id = trunc->dttd_id;
+
+ if (agg->dtagd_nrecs == 0)
+ return (DTRACE_AGGWALK_NEXT);
+
+ if (agg->dtagd_varid != id)
+ return (DTRACE_AGGWALK_NEXT);
+
+ if (trunc->dttd_remaining == 0)
+ return (DTRACE_AGGWALK_REMOVE);
+
+ trunc->dttd_remaining--;
+ return (DTRACE_AGGWALK_NEXT);
+}
+
+static int
+dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
+{
+ dt_trunc_t trunc;
+ caddr_t addr;
+ int64_t remaining;
+ int (*func)(dtrace_hdl_t *, dtrace_aggregate_f *, void *);
+
+ /*
+ * We (should) have two records: the aggregation ID followed by the
+ * number of aggregation entries after which the aggregation is to be
+ * truncated.
+ */
+ addr = base + rec->dtrd_offset;
+
+ if (rec->dtrd_size != sizeof (dtrace_aggvarid_t))
+ return (dt_set_errno(dtp, EDT_BADTRUNC));
+
+ /* LINTED - alignment */
+ trunc.dttd_id = *((dtrace_aggvarid_t *)addr);
+ rec++;
+
+ if (rec->dtrd_action != DTRACEACT_LIBACT)
+ return (dt_set_errno(dtp, EDT_BADTRUNC));
+
+ if (rec->dtrd_arg != DT_ACT_TRUNC)
+ return (dt_set_errno(dtp, EDT_BADTRUNC));
+
+ addr = base + rec->dtrd_offset;
+
+ switch (rec->dtrd_size) {
+ case sizeof (uint64_t):
+ /* LINTED - alignment */
+ remaining = *((int64_t *)addr);
+ break;
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ remaining = *((int32_t *)addr);
+ break;
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ remaining = *((int16_t *)addr);
+ break;
+ case sizeof (uint8_t):
+ remaining = *((int8_t *)addr);
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_BADNORMAL));
+ }
+
+ if (remaining < 0) {
+ func = dtrace_aggregate_walk_valsorted;
+ remaining = -remaining;
+ } else {
+ func = dtrace_aggregate_walk_valrevsorted;
+ }
+
+ assert(remaining >= 0);
+ trunc.dttd_remaining = remaining;
+
+ (void) func(dtp, dt_trunc_agg, &trunc);
+
+ return (0);
+}
+
+static int
+dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec,
+ caddr_t addr, size_t size, uint64_t normal)
+{
+ int err;
+ dtrace_actkind_t act = rec->dtrd_action;
+
+ switch (act) {
+ case DTRACEACT_STACK:
+ return (dt_print_stack(dtp, fp, NULL, addr,
+ rec->dtrd_arg, rec->dtrd_size / rec->dtrd_arg));
+
+ case DTRACEACT_USTACK:
+ case DTRACEACT_JSTACK:
+ return (dt_print_ustack(dtp, fp, NULL, addr, rec->dtrd_arg));
+
+ case DTRACEACT_USYM:
+ case DTRACEACT_UADDR:
+ return (dt_print_usym(dtp, fp, addr, act));
+
+ case DTRACEACT_UMOD:
+ return (dt_print_umod(dtp, fp, NULL, addr));
+
+ case DTRACEACT_SYM:
+ return (dt_print_sym(dtp, fp, NULL, addr));
+
+ case DTRACEACT_MOD:
+ return (dt_print_mod(dtp, fp, NULL, addr));
+
+ case DTRACEAGG_QUANTIZE:
+ return (dt_print_quantize(dtp, fp, addr, size, normal));
+
+ case DTRACEAGG_LQUANTIZE:
+ return (dt_print_lquantize(dtp, fp, addr, size, normal));
+
+ case DTRACEAGG_LLQUANTIZE:
+ return (dt_print_llquantize(dtp, fp, addr, size, normal));
+
+ case DTRACEAGG_AVG:
+ return (dt_print_average(dtp, fp, addr, size, normal));
+
+ case DTRACEAGG_STDDEV:
+ return (dt_print_stddev(dtp, fp, addr, size, normal));
+
+ default:
+ break;
+ }
+
+ switch (size) {
+ case sizeof (uint64_t):
+ err = dt_printf(dtp, fp, " %16lld",
+ /* LINTED - alignment */
+ (long long)*((uint64_t *)addr) / normal);
+ break;
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) /
+ (uint32_t)normal);
+ break;
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) /
+ (uint32_t)normal);
+ break;
+ case sizeof (uint8_t):
+ err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) /
+ (uint32_t)normal);
+ break;
+ default:
+ err = dt_print_bytes(dtp, fp, addr, size, 50, 0, 0);
+ break;
+ }
+
+ return (err);
+}
+
+int
+dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
+{
+ int i, aggact = 0;
+ dt_print_aggdata_t *pd = arg;
+ const dtrace_aggdata_t *aggdata = aggsdata[0];
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ FILE *fp = pd->dtpa_fp;
+ dtrace_hdl_t *dtp = pd->dtpa_dtp;
+ dtrace_recdesc_t *rec;
+ dtrace_actkind_t act;
+ caddr_t addr;
+ size_t size;
+
+ /*
+ * Iterate over each record description in the key, printing the traced
+ * data, skipping the first datum (the tuple member created by the
+ * compiler).
+ */
+ for (i = 1; i < agg->dtagd_nrecs; i++) {
+ rec = &agg->dtagd_rec[i];
+ act = rec->dtrd_action;
+ addr = aggdata->dtada_data + rec->dtrd_offset;
+ size = rec->dtrd_size;
+
+ if (DTRACEACT_ISAGG(act)) {
+ aggact = i;
+ break;
+ }
+
+ if (dt_print_datum(dtp, fp, rec, addr, size, 1) < 0)
+ return (-1);
+
+ if (dt_buffered_flush(dtp, NULL, rec, aggdata,
+ DTRACE_BUFDATA_AGGKEY) < 0)
+ return (-1);
+ }
+
+ assert(aggact != 0);
+
+ for (i = (naggvars == 1 ? 0 : 1); i < naggvars; i++) {
+ uint64_t normal;
+
+ aggdata = aggsdata[i];
+ agg = aggdata->dtada_desc;
+ rec = &agg->dtagd_rec[aggact];
+ act = rec->dtrd_action;
+ addr = aggdata->dtada_data + rec->dtrd_offset;
+ size = rec->dtrd_size;
+
+ assert(DTRACEACT_ISAGG(act));
+ normal = aggdata->dtada_normal;
+
+ if (dt_print_datum(dtp, fp, rec, addr, size, normal) < 0)
+ return (-1);
+
+ if (dt_buffered_flush(dtp, NULL, rec, aggdata,
+ DTRACE_BUFDATA_AGGVAL) < 0)
+ return (-1);
+
+ if (!pd->dtpa_allunprint)
+ agg->dtagd_flags |= DTRACE_AGD_PRINTED;
+ }
+
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+
+ if (dt_buffered_flush(dtp, NULL, NULL, aggdata,
+ DTRACE_BUFDATA_AGGFORMAT | DTRACE_BUFDATA_AGGLAST) < 0)
+ return (-1);
+
+ return (0);
+}
+
+int
+dt_print_agg(const dtrace_aggdata_t *aggdata, void *arg)
+{
+ dt_print_aggdata_t *pd = arg;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_aggvarid_t aggvarid = pd->dtpa_id;
+
+ if (pd->dtpa_allunprint) {
+ if (agg->dtagd_flags & DTRACE_AGD_PRINTED)
+ return (0);
+ } else {
+ /*
+ * If we're not printing all unprinted aggregations, then the
+ * aggregation variable ID denotes a specific aggregation
+ * variable that we should print -- skip any other aggregations
+ * that we encounter.
+ */
+ if (agg->dtagd_nrecs == 0)
+ return (0);
+
+ if (aggvarid != agg->dtagd_varid)
+ return (0);
+ }
+
+ return (dt_print_aggs(&aggdata, 1, arg));
+}
+
+int
+dt_setopt(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
+ const char *option, const char *value)
+{
+ int len, rval;
+ char *msg;
+ const char *errstr;
+ dtrace_setoptdata_t optdata;
+
+ bzero(&optdata, sizeof (optdata));
+ (void) dtrace_getopt(dtp, option, &optdata.dtsda_oldval);
+
+ if (dtrace_setopt(dtp, option, value) == 0) {
+ (void) dtrace_getopt(dtp, option, &optdata.dtsda_newval);
+ optdata.dtsda_probe = data;
+ optdata.dtsda_option = option;
+ optdata.dtsda_handle = dtp;
+
+ if ((rval = dt_handle_setopt(dtp, &optdata)) != 0)
+ return (rval);
+
+ return (0);
+ }
+
+ errstr = dtrace_errmsg(dtp, dtrace_errno(dtp));
+ len = strlen(option) + strlen(value) + strlen(errstr) + 80;
+ msg = alloca(len);
+
+ (void) snprintf(msg, len, "couldn't set option \"%s\" to \"%s\": %s\n",
+ option, value, errstr);
+
+ if ((rval = dt_handle_liberr(dtp, data, msg)) == 0)
+ return (0);
+
+ return (rval);
+}
+
+static int
+dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf,
+ dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc, void *arg)
+{
+ dtrace_epid_t id;
+ size_t offs, start = buf->dtbd_oldest, end = buf->dtbd_size;
+ int flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET);
+ int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+ int rval, i, n;
+ dtrace_epid_t last = DTRACE_EPIDNONE;
+ uint64_t tracememsize = 0;
+ dtrace_probedata_t data;
+ uint64_t drops;
+ caddr_t addr;
+
+ bzero(&data, sizeof (data));
+ data.dtpda_handle = dtp;
+ data.dtpda_cpu = cpu;
+
+again:
+ for (offs = start; offs < end; ) {
+ dtrace_eprobedesc_t *epd;
+
+ /*
+ * We're guaranteed to have an ID.
+ */
+ id = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs);
+
+ if (id == DTRACE_EPIDNONE) {
+ /*
+ * This is filler to assure proper alignment of the
+ * next record; we simply ignore it.
+ */
+ offs += sizeof (id);
+ continue;
+ }
+
+ if ((rval = dt_epid_lookup(dtp, id, &data.dtpda_edesc,
+ &data.dtpda_pdesc)) != 0)
+ return (rval);
+
+ epd = data.dtpda_edesc;
+ data.dtpda_data = buf->dtbd_data + offs;
+
+ if (data.dtpda_edesc->dtepd_uarg != DT_ECB_DEFAULT) {
+ rval = dt_handle(dtp, &data);
+
+ if (rval == DTRACE_CONSUME_NEXT)
+ goto nextepid;
+
+ if (rval == DTRACE_CONSUME_ERROR)
+ return (-1);
+ }
+
+ if (flow)
+ (void) dt_flowindent(dtp, &data, last, buf, offs);
+
+ rval = (*efunc)(&data, arg);
+
+ if (flow) {
+ if (data.dtpda_flow == DTRACEFLOW_ENTRY)
+ data.dtpda_indent += 2;
+ }
+
+ if (rval == DTRACE_CONSUME_NEXT)
+ goto nextepid;
+
+ if (rval == DTRACE_CONSUME_ABORT)
+ return (dt_set_errno(dtp, EDT_DIRABORT));
+
+ if (rval != DTRACE_CONSUME_THIS)
+ return (dt_set_errno(dtp, EDT_BADRVAL));
+
+ for (i = 0; i < epd->dtepd_nrecs; i++) {
+ dtrace_recdesc_t *rec = &epd->dtepd_rec[i];
+ dtrace_actkind_t act = rec->dtrd_action;
+
+ data.dtpda_data = buf->dtbd_data + offs +
+ rec->dtrd_offset;
+ addr = data.dtpda_data;
+
+ if (act == DTRACEACT_LIBACT) {
+ uint64_t arg = rec->dtrd_arg;
+ dtrace_aggvarid_t id;
+
+ switch (arg) {
+ case DT_ACT_CLEAR:
+ /* LINTED - alignment */
+ id = *((dtrace_aggvarid_t *)addr);
+ (void) dtrace_aggregate_walk(dtp,
+ dt_clear_agg, &id);
+ continue;
+
+ case DT_ACT_DENORMALIZE:
+ /* LINTED - alignment */
+ id = *((dtrace_aggvarid_t *)addr);
+ (void) dtrace_aggregate_walk(dtp,
+ dt_denormalize_agg, &id);
+ continue;
+
+ case DT_ACT_FTRUNCATE:
+ if (fp == NULL)
+ continue;
+
+ (void) fflush(fp);
+ (void) ftruncate(fileno(fp), 0);
+ (void) fseeko(fp, 0, SEEK_SET);
+ continue;
+
+ case DT_ACT_NORMALIZE:
+ if (i == epd->dtepd_nrecs - 1)
+ return (dt_set_errno(dtp,
+ EDT_BADNORMAL));
+
+ if (dt_normalize(dtp,
+ buf->dtbd_data + offs, rec) != 0)
+ return (-1);
+
+ i++;
+ continue;
+
+ case DT_ACT_SETOPT: {
+ uint64_t *opts = dtp->dt_options;
+ dtrace_recdesc_t *valrec;
+ uint32_t valsize;
+ caddr_t val;
+ int rv;
+
+ if (i == epd->dtepd_nrecs - 1) {
+ return (dt_set_errno(dtp,
+ EDT_BADSETOPT));
+ }
+
+ valrec = &epd->dtepd_rec[++i];
+ valsize = valrec->dtrd_size;
+
+ if (valrec->dtrd_action != act ||
+ valrec->dtrd_arg != arg) {
+ return (dt_set_errno(dtp,
+ EDT_BADSETOPT));
+ }
+
+ if (valsize > sizeof (uint64_t)) {
+ val = buf->dtbd_data + offs +
+ valrec->dtrd_offset;
+ } else {
+ val = "1";
+ }
+
+ rv = dt_setopt(dtp, &data, addr, val);
+
+ if (rv != 0)
+ return (-1);
+
+ flow = (opts[DTRACEOPT_FLOWINDENT] !=
+ DTRACEOPT_UNSET);
+ quiet = (opts[DTRACEOPT_QUIET] !=
+ DTRACEOPT_UNSET);
+
+ continue;
+ }
+
+ case DT_ACT_TRUNC:
+ if (i == epd->dtepd_nrecs - 1)
+ return (dt_set_errno(dtp,
+ EDT_BADTRUNC));
+
+ if (dt_trunc(dtp,
+ buf->dtbd_data + offs, rec) != 0)
+ return (-1);
+
+ i++;
+ continue;
+
+ default:
+ continue;
+ }
+ }
+
+ if (act == DTRACEACT_TRACEMEM_DYNSIZE &&
+ rec->dtrd_size == sizeof (uint64_t)) {
+ /* LINTED - alignment */
+ tracememsize = *((unsigned long long *)addr);
+ continue;
+ }
+
+ rval = (*rfunc)(&data, rec, arg);
+
+ if (rval == DTRACE_CONSUME_NEXT)
+ continue;
+
+ if (rval == DTRACE_CONSUME_ABORT)
+ return (dt_set_errno(dtp, EDT_DIRABORT));
+
+ if (rval != DTRACE_CONSUME_THIS)
+ return (dt_set_errno(dtp, EDT_BADRVAL));
+
+ if (act == DTRACEACT_STACK) {
+ int depth = rec->dtrd_arg;
+
+ if (dt_print_stack(dtp, fp, NULL, addr, depth,
+ rec->dtrd_size / depth) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_USTACK ||
+ act == DTRACEACT_JSTACK) {
+ if (dt_print_ustack(dtp, fp, NULL,
+ addr, rec->dtrd_arg) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_SYM) {
+ if (dt_print_sym(dtp, fp, NULL, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_MOD) {
+ if (dt_print_mod(dtp, fp, NULL, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_USYM || act == DTRACEACT_UADDR) {
+ if (dt_print_usym(dtp, fp, addr, act) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_UMOD) {
+ if (dt_print_umod(dtp, fp, NULL, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_PRINTM) {
+ if (dt_print_memory(dtp, fp, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_PRINTT) {
+ if (dt_print_type(dtp, fp, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (DTRACEACT_ISPRINTFLIKE(act)) {
+ void *fmtdata;
+ int (*func)(dtrace_hdl_t *, FILE *, void *,
+ const dtrace_probedata_t *,
+ const dtrace_recdesc_t *, uint_t,
+ const void *buf, size_t);
+
+ if ((fmtdata = dt_format_lookup(dtp,
+ rec->dtrd_format)) == NULL)
+ goto nofmt;
+
+ switch (act) {
+ case DTRACEACT_PRINTF:
+ func = dtrace_fprintf;
+ break;
+ case DTRACEACT_PRINTA:
+ func = dtrace_fprinta;
+ break;
+ case DTRACEACT_SYSTEM:
+ func = dtrace_system;
+ break;
+ case DTRACEACT_FREOPEN:
+ func = dtrace_freopen;
+ break;
+ }
+
+ n = (*func)(dtp, fp, fmtdata, &data,
+ rec, epd->dtepd_nrecs - i,
+ (uchar_t *)buf->dtbd_data + offs,
+ buf->dtbd_size - offs);
+
+ if (n < 0)
+ return (-1); /* errno is set for us */
+
+ if (n > 0)
+ i += n - 1;
+ goto nextrec;
+ }
+
+ /*
+ * If this is a DIF expression, and the record has a
+ * format set, this indicates we have a CTF type name
+ * associated with the data and we should try to print
+ * it out by type.
+ */
+ if (act == DTRACEACT_DIFEXPR) {
+ const char *strdata = dt_strdata_lookup(dtp,
+ rec->dtrd_format);
+ if (strdata != NULL) {
+ n = dtrace_print(dtp, fp, strdata,
+ addr, rec->dtrd_size);
+
+ /*
+ * dtrace_print() will return -1 on
+ * error, or return the number of bytes
+ * consumed. It will return 0 if the
+ * type couldn't be determined, and we
+ * should fall through to the normal
+ * trace method.
+ */
+ if (n < 0)
+ return (-1);
+
+ if (n > 0)
+ goto nextrec;
+ }
+ }
+
+nofmt:
+ if (act == DTRACEACT_PRINTA) {
+ dt_print_aggdata_t pd;
+ dtrace_aggvarid_t *aggvars;
+ int j, naggvars = 0;
+ size_t size = ((epd->dtepd_nrecs - i) *
+ sizeof (dtrace_aggvarid_t));
+
+ if ((aggvars = dt_alloc(dtp, size)) == NULL)
+ return (-1);
+
+ /*
+ * This might be a printa() with multiple
+ * aggregation variables. We need to scan
+ * forward through the records until we find
+ * a record from a different statement.
+ */
+ for (j = i; j < epd->dtepd_nrecs; j++) {
+ dtrace_recdesc_t *nrec;
+ caddr_t naddr;
+
+ nrec = &epd->dtepd_rec[j];
+
+ if (nrec->dtrd_uarg != rec->dtrd_uarg)
+ break;
+
+ if (nrec->dtrd_action != act) {
+ return (dt_set_errno(dtp,
+ EDT_BADAGG));
+ }
+
+ naddr = buf->dtbd_data + offs +
+ nrec->dtrd_offset;
+
+ aggvars[naggvars++] =
+ /* LINTED - alignment */
+ *((dtrace_aggvarid_t *)naddr);
+ }
+
+ i = j - 1;
+ bzero(&pd, sizeof (pd));
+ pd.dtpa_dtp = dtp;
+ pd.dtpa_fp = fp;
+
+ assert(naggvars >= 1);
+
+ if (naggvars == 1) {
+ pd.dtpa_id = aggvars[0];
+ dt_free(dtp, aggvars);
+
+ if (dt_printf(dtp, fp, "\n") < 0 ||
+ dtrace_aggregate_walk_sorted(dtp,
+ dt_print_agg, &pd) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (dt_printf(dtp, fp, "\n") < 0 ||
+ dtrace_aggregate_walk_joined(dtp, aggvars,
+ naggvars, dt_print_aggs, &pd) < 0) {
+ dt_free(dtp, aggvars);
+ return (-1);
+ }
+
+ dt_free(dtp, aggvars);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_TRACEMEM) {
+ if (tracememsize == 0 ||
+ tracememsize > rec->dtrd_size) {
+ tracememsize = rec->dtrd_size;
+ }
+
+ n = dt_print_bytes(dtp, fp, addr,
+ tracememsize, 33, quiet, 1);
+
+ tracememsize = 0;
+
+ if (n < 0)
+ return (-1);
+
+ goto nextrec;
+ }
+
+ switch (rec->dtrd_size) {
+ case sizeof (uint64_t):
+ n = dt_printf(dtp, fp,
+ quiet ? "%lld" : " %16lld",
+ /* LINTED - alignment */
+ *((unsigned long long *)addr));
+ break;
+ case sizeof (uint32_t):
+ n = dt_printf(dtp, fp, quiet ? "%d" : " %8d",
+ /* LINTED - alignment */
+ *((uint32_t *)addr));
+ break;
+ case sizeof (uint16_t):
+ n = dt_printf(dtp, fp, quiet ? "%d" : " %5d",
+ /* LINTED - alignment */
+ *((uint16_t *)addr));
+ break;
+ case sizeof (uint8_t):
+ n = dt_printf(dtp, fp, quiet ? "%d" : " %3d",
+ *((uint8_t *)addr));
+ break;
+ default:
+ n = dt_print_bytes(dtp, fp, addr,
+ rec->dtrd_size, 33, quiet, 0);
+ break;
+ }
+
+ if (n < 0)
+ return (-1); /* errno is set for us */
+
+nextrec:
+ if (dt_buffered_flush(dtp, &data, rec, NULL, 0) < 0)
+ return (-1); /* errno is set for us */
+ }
+
+ /*
+ * Call the record callback with a NULL record to indicate
+ * that we're done processing this EPID.
+ */
+ rval = (*rfunc)(&data, NULL, arg);
+nextepid:
+ offs += epd->dtepd_size;
+ last = id;
+ }
+
+ if (buf->dtbd_oldest != 0 && start == buf->dtbd_oldest) {
+ end = buf->dtbd_oldest;
+ start = 0;
+ goto again;
+ }
+
+ if ((drops = buf->dtbd_drops) == 0)
+ return (0);
+
+ /*
+ * Explicitly zero the drops to prevent us from processing them again.
+ */
+ buf->dtbd_drops = 0;
+
+ return (dt_handle_cpudrop(dtp, cpu, DTRACEDROP_PRINCIPAL, drops));
+}
+
+typedef struct dt_begin {
+ dtrace_consume_probe_f *dtbgn_probefunc;
+ dtrace_consume_rec_f *dtbgn_recfunc;
+ void *dtbgn_arg;
+ dtrace_handle_err_f *dtbgn_errhdlr;
+ void *dtbgn_errarg;
+ int dtbgn_beginonly;
+} dt_begin_t;
+
+static int
+dt_consume_begin_probe(const dtrace_probedata_t *data, void *arg)
+{
+ dt_begin_t *begin = (dt_begin_t *)arg;
+ dtrace_probedesc_t *pd = data->dtpda_pdesc;
+
+ int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0);
+ int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0);
+
+ if (begin->dtbgn_beginonly) {
+ if (!(r1 && r2))
+ return (DTRACE_CONSUME_NEXT);
+ } else {
+ if (r1 && r2)
+ return (DTRACE_CONSUME_NEXT);
+ }
+
+ /*
+ * We have a record that we're interested in. Now call the underlying
+ * probe function...
+ */
+ return (begin->dtbgn_probefunc(data, begin->dtbgn_arg));
+}
+
+static int
+dt_consume_begin_record(const dtrace_probedata_t *data,
+ const dtrace_recdesc_t *rec, void *arg)
+{
+ dt_begin_t *begin = (dt_begin_t *)arg;
+
+ return (begin->dtbgn_recfunc(data, rec, begin->dtbgn_arg));
+}
+
+static int
+dt_consume_begin_error(const dtrace_errdata_t *data, void *arg)
+{
+ dt_begin_t *begin = (dt_begin_t *)arg;
+ dtrace_probedesc_t *pd = data->dteda_pdesc;
+
+ int r1 = (strcmp(pd->dtpd_provider, "dtrace") == 0);
+ int r2 = (strcmp(pd->dtpd_name, "BEGIN") == 0);
+
+ if (begin->dtbgn_beginonly) {
+ if (!(r1 && r2))
+ return (DTRACE_HANDLE_OK);
+ } else {
+ if (r1 && r2)
+ return (DTRACE_HANDLE_OK);
+ }
+
+ return (begin->dtbgn_errhdlr(data, begin->dtbgn_errarg));
+}
+
+static int
+dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
+ dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)
+{
+ /*
+ * There's this idea that the BEGIN probe should be processed before
+ * everything else, and that the END probe should be processed after
+ * anything else. In the common case, this is pretty easy to deal
+ * with. However, a situation may arise where the BEGIN enabling and
+ * END enabling are on the same CPU, and some enabling in the middle
+ * occurred on a different CPU. To deal with this (blech!) we need to
+ * consume the BEGIN buffer up until the end of the BEGIN probe, and
+ * then set it aside. We will then process every other CPU, and then
+ * we'll return to the BEGIN CPU and process the rest of the data
+ * (which will inevitably include the END probe, if any). Making this
+ * even more complicated (!) is the library's ERROR enabling. Because
+ * this enabling is processed before we even get into the consume call
+ * back, any ERROR firing would result in the library's ERROR enabling
+ * being processed twice -- once in our first pass (for BEGIN probes),
+ * and again in our second pass (for everything but BEGIN probes). To
+ * deal with this, we interpose on the ERROR handler to assure that we
+ * only process ERROR enablings induced by BEGIN enablings in the
+ * first pass, and that we only process ERROR enablings _not_ induced
+ * by BEGIN enablings in the second pass.
+ */
+ dt_begin_t begin;
+ processorid_t cpu = dtp->dt_beganon;
+ dtrace_bufdesc_t nbuf;
+#if !defined(sun)
+ dtrace_bufdesc_t *pbuf;
+#endif
+ int rval, i;
+ static int max_ncpus;
+ dtrace_optval_t size;
+
+ dtp->dt_beganon = -1;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
+ /*
+ * We really don't expect this to fail, but it is at least
+ * technically possible for this to fail with ENOENT. In this
+ * case, we just drive on...
+ */
+ if (errno == ENOENT)
+ return (0);
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if (!dtp->dt_stopped || buf->dtbd_cpu != dtp->dt_endedon) {
+ /*
+ * This is the simple case. We're either not stopped, or if
+ * we are, we actually processed any END probes on another
+ * CPU. We can simply consume this buffer and return.
+ */
+ return (dt_consume_cpu(dtp, fp, cpu, buf, pf, rf, arg));
+ }
+
+ begin.dtbgn_probefunc = pf;
+ begin.dtbgn_recfunc = rf;
+ begin.dtbgn_arg = arg;
+ begin.dtbgn_beginonly = 1;
+
+ /*
+ * We need to interpose on the ERROR handler to be sure that we
+ * only process ERRORs induced by BEGIN.
+ */
+ begin.dtbgn_errhdlr = dtp->dt_errhdlr;
+ begin.dtbgn_errarg = dtp->dt_errarg;
+ dtp->dt_errhdlr = dt_consume_begin_error;
+ dtp->dt_errarg = &begin;
+
+ rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe,
+ dt_consume_begin_record, &begin);
+
+ dtp->dt_errhdlr = begin.dtbgn_errhdlr;
+ dtp->dt_errarg = begin.dtbgn_errarg;
+
+ if (rval != 0)
+ return (rval);
+
+ /*
+ * Now allocate a new buffer. We'll use this to deal with every other
+ * CPU.
+ */
+ bzero(&nbuf, sizeof (dtrace_bufdesc_t));
+ (void) dtrace_getopt(dtp, "bufsize", &size);
+ if ((nbuf.dtbd_data = malloc(size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ if (max_ncpus == 0)
+ max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
+
+ for (i = 0; i < max_ncpus; i++) {
+ nbuf.dtbd_cpu = i;
+
+ if (i == cpu)
+ continue;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &nbuf) == -1) {
+#else
+ pbuf = &nbuf;
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &pbuf) == -1) {
+#endif
+ /*
+ * If we failed with ENOENT, it may be because the
+ * CPU was unconfigured -- this is okay. Any other
+ * error, however, is unexpected.
+ */
+ if (errno == ENOENT)
+ continue;
+
+ free(nbuf.dtbd_data);
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if ((rval = dt_consume_cpu(dtp, fp,
+ i, &nbuf, pf, rf, arg)) != 0) {
+ free(nbuf.dtbd_data);
+ return (rval);
+ }
+ }
+
+ free(nbuf.dtbd_data);
+
+ /*
+ * Okay -- we're done with the other buffers. Now we want to
+ * reconsume the first buffer -- but this time we're looking for
+ * everything _but_ BEGIN. And of course, in order to only consume
+ * those ERRORs _not_ associated with BEGIN, we need to reinstall our
+ * ERROR interposition function...
+ */
+ begin.dtbgn_beginonly = 0;
+
+ assert(begin.dtbgn_errhdlr == dtp->dt_errhdlr);
+ assert(begin.dtbgn_errarg == dtp->dt_errarg);
+ dtp->dt_errhdlr = dt_consume_begin_error;
+ dtp->dt_errarg = &begin;
+
+ rval = dt_consume_cpu(dtp, fp, cpu, buf, dt_consume_begin_probe,
+ dt_consume_begin_record, &begin);
+
+ dtp->dt_errhdlr = begin.dtbgn_errhdlr;
+ dtp->dt_errarg = begin.dtbgn_errarg;
+
+ return (rval);
+}
+
+int
+dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
+ dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)
+{
+ dtrace_bufdesc_t *buf = &dtp->dt_buf;
+ dtrace_optval_t size;
+ static int max_ncpus;
+ int i, rval;
+ dtrace_optval_t interval = dtp->dt_options[DTRACEOPT_SWITCHRATE];
+ hrtime_t now = gethrtime();
+
+ if (dtp->dt_lastswitch != 0) {
+ if (now - dtp->dt_lastswitch < interval)
+ return (0);
+
+ dtp->dt_lastswitch += interval;
+ } else {
+ dtp->dt_lastswitch = now;
+ }
+
+ if (!dtp->dt_active)
+ return (dt_set_errno(dtp, EINVAL));
+
+ if (max_ncpus == 0)
+ max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
+
+ if (pf == NULL)
+ pf = (dtrace_consume_probe_f *)dt_nullprobe;
+
+ if (rf == NULL)
+ rf = (dtrace_consume_rec_f *)dt_nullrec;
+
+ if (buf->dtbd_data == NULL) {
+ (void) dtrace_getopt(dtp, "bufsize", &size);
+ if ((buf->dtbd_data = malloc(size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ buf->dtbd_size = size;
+ }
+
+ /*
+ * If we have just begun, we want to first process the CPU that
+ * executed the BEGIN probe (if any).
+ */
+ if (dtp->dt_active && dtp->dt_beganon != -1) {
+ buf->dtbd_cpu = dtp->dt_beganon;
+ if ((rval = dt_consume_begin(dtp, fp, buf, pf, rf, arg)) != 0)
+ return (rval);
+ }
+
+ for (i = 0; i < max_ncpus; i++) {
+ buf->dtbd_cpu = i;
+
+ /*
+ * If we have stopped, we want to process the CPU on which the
+ * END probe was processed only _after_ we have processed
+ * everything else.
+ */
+ if (dtp->dt_stopped && (i == dtp->dt_endedon))
+ continue;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
+ /*
+ * If we failed with ENOENT, it may be because the
+ * CPU was unconfigured -- this is okay. Any other
+ * error, however, is unexpected.
+ */
+ if (errno == ENOENT)
+ continue;
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if ((rval = dt_consume_cpu(dtp, fp, i, buf, pf, rf, arg)) != 0)
+ return (rval);
+ }
+
+ if (!dtp->dt_stopped)
+ return (0);
+
+ buf->dtbd_cpu = dtp->dt_endedon;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
+ /*
+ * This _really_ shouldn't fail, but it is strictly speaking
+ * possible for this to return ENOENT if the CPU that called
+ * the END enabling somehow managed to become unconfigured.
+ * It's unclear how the user can possibly expect anything
+ * rational to happen in this case -- the state has been thrown
+ * out along with the unconfigured CPU -- so we'll just drive
+ * on...
+ */
+ if (errno == ENOENT)
+ return (0);
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (dt_consume_cpu(dtp, fp, dtp->dt_endedon, buf, pf, rf, arg));
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
new file mode 100644
index 0000000..bb77984
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
@@ -0,0 +1,1127 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <strings.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <alloca.h>
+#include <assert.h>
+
+#include <dt_decl.h>
+#include <dt_parser.h>
+#include <dt_module.h>
+#include <dt_impl.h>
+
+static dt_decl_t *
+dt_decl_check(dt_decl_t *ddp)
+{
+ if (ddp->dd_kind == CTF_K_UNKNOWN)
+ return (ddp); /* nothing to check if the type is not yet set */
+
+ if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "char") == 0 &&
+ (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG))) {
+ xyerror(D_DECL_CHARATTR, "invalid type declaration: short and "
+ "long may not be used with char type\n");
+ }
+
+ if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "void") == 0 &&
+ (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG |
+ (DT_DA_SIGNED | DT_DA_UNSIGNED)))) {
+ xyerror(D_DECL_VOIDATTR, "invalid type declaration: attributes "
+ "may not be used with void type\n");
+ }
+
+ if (ddp->dd_kind != CTF_K_INTEGER &&
+ (ddp->dd_attr & (DT_DA_SIGNED | DT_DA_UNSIGNED))) {
+ xyerror(D_DECL_SIGNINT, "invalid type declaration: signed and "
+ "unsigned may only be used with integer type\n");
+ }
+
+ if (ddp->dd_kind != CTF_K_INTEGER && ddp->dd_kind != CTF_K_FLOAT &&
+ (ddp->dd_attr & (DT_DA_LONG | DT_DA_LONGLONG))) {
+ xyerror(D_DECL_LONGINT, "invalid type declaration: long and "
+ "long long may only be used with integer or "
+ "floating-point type\n");
+ }
+
+ return (ddp);
+}
+
+dt_decl_t *
+dt_decl_alloc(ushort_t kind, char *name)
+{
+ dt_decl_t *ddp = malloc(sizeof (dt_decl_t));
+
+ if (ddp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ ddp->dd_kind = kind;
+ ddp->dd_attr = 0;
+ ddp->dd_ctfp = NULL;
+ ddp->dd_type = CTF_ERR;
+ ddp->dd_name = name;
+ ddp->dd_node = NULL;
+ ddp->dd_next = NULL;
+
+ return (ddp);
+}
+
+void
+dt_decl_free(dt_decl_t *ddp)
+{
+ dt_decl_t *ndp;
+
+ for (; ddp != NULL; ddp = ndp) {
+ ndp = ddp->dd_next;
+ free(ddp->dd_name);
+ dt_node_list_free(&ddp->dd_node);
+ free(ddp);
+ }
+}
+
+void
+dt_decl_reset(void)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *ddp = dsp->ds_decl;
+
+ while (ddp->dd_next != NULL) {
+ dsp->ds_decl = ddp->dd_next;
+ ddp->dd_next = NULL;
+ dt_decl_free(ddp);
+ ddp = dsp->ds_decl;
+ }
+}
+
+dt_decl_t *
+dt_decl_push(dt_decl_t *ddp)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *top = dsp->ds_decl;
+
+ if (top != NULL &&
+ top->dd_kind == CTF_K_UNKNOWN && top->dd_name == NULL) {
+ top->dd_kind = CTF_K_INTEGER;
+ (void) dt_decl_check(top);
+ }
+
+ assert(ddp->dd_next == NULL);
+ ddp->dd_next = top;
+ dsp->ds_decl = ddp;
+
+ return (ddp);
+}
+
+dt_decl_t *
+dt_decl_pop(void)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *ddp = dt_decl_top();
+
+ dsp->ds_decl = NULL;
+ free(dsp->ds_ident);
+ dsp->ds_ident = NULL;
+ dsp->ds_ctfp = NULL;
+ dsp->ds_type = CTF_ERR;
+ dsp->ds_class = DT_DC_DEFAULT;
+ dsp->ds_enumval = -1;
+
+ return (ddp);
+}
+
+dt_decl_t *
+dt_decl_pop_param(char **idp)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+
+ if (dsp->ds_class != DT_DC_DEFAULT && dsp->ds_class != DT_DC_REGISTER) {
+ xyerror(D_DECL_PARMCLASS, "inappropriate storage class "
+ "for function or associative array parameter\n");
+ }
+
+ if (idp != NULL && dt_decl_top() != NULL) {
+ *idp = dsp->ds_ident;
+ dsp->ds_ident = NULL;
+ }
+
+ return (dt_decl_pop());
+}
+
+dt_decl_t *
+dt_decl_top(void)
+{
+ dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
+
+ if (ddp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
+
+ if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
+ ddp->dd_kind = CTF_K_INTEGER;
+ (void) dt_decl_check(ddp);
+ }
+
+ return (ddp);
+}
+
+dt_decl_t *
+dt_decl_ident(char *name)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *ddp = dsp->ds_decl;
+
+ if (dsp->ds_ident != NULL) {
+ free(name);
+ xyerror(D_DECL_IDENT, "old-style declaration or "
+ "incorrect type specified\n");
+ }
+
+ dsp->ds_ident = name;
+
+ if (ddp == NULL)
+ ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
+
+ return (ddp);
+}
+
+void
+dt_decl_class(dt_dclass_t class)
+{
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+
+ if (dsp->ds_class != DT_DC_DEFAULT) {
+ xyerror(D_DECL_CLASS, "only one storage class allowed "
+ "in a declaration\n");
+ }
+
+ dsp->ds_class = class;
+}
+
+/*
+ * Set the kind and name of the current declaration. If none is allocated,
+ * make a new decl and push it on to the top of our stack. If the name or kind
+ * is already set for the current decl, then we need to fail this declaration.
+ * This can occur because too many types were given (e.g. "int int"), etc.
+ */
+dt_decl_t *
+dt_decl_spec(ushort_t kind, char *name)
+{
+ dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
+
+ if (ddp == NULL)
+ return (dt_decl_push(dt_decl_alloc(kind, name)));
+
+ /*
+ * If we already have a type name specified and we see another type
+ * name, this is an error if the declaration is a typedef. If the
+ * declaration is not a typedef, then the user may be trying to declare
+ * a variable whose name has been returned by lex as a TNAME token:
+ * call dt_decl_ident() as if the grammar's IDENT rule was matched.
+ */
+ if (ddp->dd_name != NULL && kind == CTF_K_TYPEDEF) {
+ if (yypcb->pcb_dstack.ds_class != DT_DC_TYPEDEF)
+ return (dt_decl_ident(name));
+ xyerror(D_DECL_IDRED, "identifier redeclared: %s\n", name);
+ }
+
+ if (ddp->dd_name != NULL || ddp->dd_kind != CTF_K_UNKNOWN)
+ xyerror(D_DECL_COMBO, "invalid type combination\n");
+
+ ddp->dd_kind = kind;
+ ddp->dd_name = name;
+
+ if (name != NULL && strchr(name, '`') != NULL) {
+ xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
+ "in a type name\n");
+ }
+
+ return (dt_decl_check(ddp));
+}
+
+dt_decl_t *
+dt_decl_attr(ushort_t attr)
+{
+ dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
+
+ if (ddp == NULL) {
+ ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
+ ddp->dd_attr = attr;
+ return (ddp);
+ }
+
+ if (attr == DT_DA_LONG && (ddp->dd_attr & DT_DA_LONG)) {
+ ddp->dd_attr &= ~DT_DA_LONG;
+ attr = DT_DA_LONGLONG;
+ }
+
+ ddp->dd_attr |= attr;
+ return (dt_decl_check(ddp));
+}
+
+/*
+ * Examine the list of formal parameters 'flist' and determine if the formal
+ * name fnp->dn_string is defined in this list (B_TRUE) or not (B_FALSE).
+ * If 'fnp' is in 'flist', do not search beyond 'fnp' itself in 'flist'.
+ */
+static int
+dt_decl_protoform(dt_node_t *fnp, dt_node_t *flist)
+{
+ dt_node_t *dnp;
+
+ for (dnp = flist; dnp != fnp && dnp != NULL; dnp = dnp->dn_list) {
+ if (dnp->dn_string != NULL &&
+ strcmp(dnp->dn_string, fnp->dn_string) == 0)
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * Common code for parsing array, function, and probe definition prototypes.
+ * The prototype node list is specified as 'plist'. The formal prototype
+ * against which to compare the prototype is specified as 'flist'. If plist
+ * and flist are the same, we require that named parameters are unique. If
+ * plist and flist are different, we require that named parameters in plist
+ * match a name that is present in flist.
+ */
+int
+dt_decl_prototype(dt_node_t *plist,
+ dt_node_t *flist, const char *kind, uint_t flags)
+{
+ char n[DT_TYPE_NAMELEN];
+ int is_void, v = 0, i = 1;
+ int form = plist != flist;
+ dt_node_t *dnp;
+
+ for (dnp = plist; dnp != NULL; dnp = dnp->dn_list, i++) {
+
+ if (dnp->dn_type == CTF_ERR && !(flags & DT_DP_VARARGS)) {
+ dnerror(dnp, D_DECL_PROTO_VARARGS, "%s prototype may "
+ "not use a variable-length argument list\n", kind);
+ }
+
+ if (dt_node_is_dynamic(dnp) && !(flags & DT_DP_DYNAMIC)) {
+ dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
+ "use parameter of type %s: %s, parameter #%d\n",
+ kind, dt_node_type_name(dnp, n, sizeof (n)),
+ dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
+ }
+
+ is_void = dt_node_is_void(dnp);
+ v += is_void;
+
+ if (is_void && !(flags & DT_DP_VOID)) {
+ dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
+ "use parameter of type %s: %s, parameter #%d\n",
+ kind, dt_node_type_name(dnp, n, sizeof (n)),
+ dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
+ }
+
+ if (is_void && dnp->dn_string != NULL) {
+ dnerror(dnp, D_DECL_PROTO_NAME, "void parameter may "
+ "not have a name: %s\n", dnp->dn_string);
+ }
+
+ if (dnp->dn_string != NULL &&
+ dt_decl_protoform(dnp, flist) != form) {
+ dnerror(dnp, D_DECL_PROTO_FORM, "parameter is "
+ "%s declared in %s prototype: %s, parameter #%d\n",
+ form ? "not" : "already", kind, dnp->dn_string, i);
+ }
+
+ if (dnp->dn_string == NULL &&
+ !is_void && !(flags & DT_DP_ANON)) {
+ dnerror(dnp, D_DECL_PROTO_NAME, "parameter declaration "
+ "requires a name: parameter #%d\n", i);
+ }
+ }
+
+ if (v != 0 && plist->dn_list != NULL)
+ xyerror(D_DECL_PROTO_VOID, "void must be sole parameter\n");
+
+ return (v ? 0 : i - 1); /* return zero if sole parameter is 'void' */
+}
+
+dt_decl_t *
+dt_decl_array(dt_node_t *dnp)
+{
+ dt_decl_t *ddp = dt_decl_push(dt_decl_alloc(CTF_K_ARRAY, NULL));
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *ndp = ddp;
+
+ /*
+ * After pushing the array on to the decl stack, scan ahead for multi-
+ * dimensional array declarations and push the current decl to the
+ * bottom to match the resulting CTF type tree and data layout. Refer
+ * to the comments in dt_decl_type() and ISO C 6.5.2.1 for more info.
+ */
+ while (ndp->dd_next != NULL && ndp->dd_next->dd_kind == CTF_K_ARRAY)
+ ndp = ndp->dd_next; /* skip to bottom-most array declaration */
+
+ if (ndp != ddp) {
+ if (dnp != NULL && dnp->dn_kind == DT_NODE_TYPE) {
+ xyerror(D_DECL_DYNOBJ,
+ "cannot declare array of associative arrays\n");
+ }
+ dsp->ds_decl = ddp->dd_next;
+ ddp->dd_next = ndp->dd_next;
+ ndp->dd_next = ddp;
+ }
+
+ if (ddp->dd_next->dd_name != NULL &&
+ strcmp(ddp->dd_next->dd_name, "void") == 0)
+ xyerror(D_DECL_VOIDOBJ, "cannot declare array of void\n");
+
+ if (dnp != NULL && dnp->dn_kind != DT_NODE_TYPE) {
+ dnp = ddp->dd_node = dt_node_cook(dnp, DT_IDFLG_REF);
+
+ if (dt_node_is_posconst(dnp) == 0) {
+ xyerror(D_DECL_ARRSUB, "positive integral constant "
+ "expression or tuple signature expected as "
+ "array declaration subscript\n");
+ }
+
+ if (dnp->dn_value > UINT_MAX)
+ xyerror(D_DECL_ARRBIG, "array dimension too big\n");
+
+ } else if (dnp != NULL) {
+ ddp->dd_node = dnp;
+ (void) dt_decl_prototype(dnp, dnp, "array", DT_DP_ANON);
+ }
+
+ return (ddp);
+}
+
+/*
+ * When a function is declared, we need to fudge the decl stack a bit if the
+ * declaration uses the function pointer (*)() syntax. In this case, the
+ * dt_decl_func() call occurs *after* the dt_decl_ptr() call, even though the
+ * resulting type is "pointer to function". To make the pointer land on top,
+ * we check to see if 'pdp' is non-NULL and a pointer. If it is, we search
+ * backward for a decl tagged with DT_DA_PAREN, and if one is found, the func
+ * decl is inserted behind this node in the decl list instead of at the top.
+ * In all cases, the func decl's dd_next pointer is set to the decl chain
+ * for the function's return type and the function parameter list is discarded.
+ */
+dt_decl_t *
+dt_decl_func(dt_decl_t *pdp, dt_node_t *dnp)
+{
+ dt_decl_t *ddp = dt_decl_alloc(CTF_K_FUNCTION, NULL);
+
+ ddp->dd_node = dnp;
+
+ (void) dt_decl_prototype(dnp, dnp, "function",
+ DT_DP_VARARGS | DT_DP_VOID | DT_DP_ANON);
+
+ if (pdp == NULL || pdp->dd_kind != CTF_K_POINTER)
+ return (dt_decl_push(ddp));
+
+ while (pdp->dd_next != NULL && !(pdp->dd_next->dd_attr & DT_DA_PAREN))
+ pdp = pdp->dd_next;
+
+ if (pdp->dd_next == NULL)
+ return (dt_decl_push(ddp));
+
+ ddp->dd_next = pdp->dd_next;
+ pdp->dd_next = ddp;
+
+ return (pdp);
+}
+
+dt_decl_t *
+dt_decl_ptr(void)
+{
+ return (dt_decl_push(dt_decl_alloc(CTF_K_POINTER, NULL)));
+}
+
+dt_decl_t *
+dt_decl_sou(uint_t kind, char *name)
+{
+ dt_decl_t *ddp = dt_decl_spec(kind, name);
+ char n[DT_TYPE_NAMELEN];
+ ctf_file_t *ctfp;
+ ctf_id_t type;
+ uint_t flag;
+
+ if (yypcb->pcb_idepth != 0)
+ ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
+ else
+ ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
+
+ if (yypcb->pcb_dstack.ds_next != NULL)
+ flag = CTF_ADD_NONROOT;
+ else
+ flag = CTF_ADD_ROOT;
+
+ (void) snprintf(n, sizeof (n), "%s %s",
+ kind == CTF_K_STRUCT ? "struct" : "union",
+ name == NULL ? "(anon)" : name);
+
+ if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR &&
+ ctf_type_kind(ctfp, type) != CTF_K_FORWARD)
+ xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
+
+ if (kind == CTF_K_STRUCT)
+ type = ctf_add_struct(ctfp, flag, name);
+ else
+ type = ctf_add_union(ctfp, flag, name);
+
+ if (type == CTF_ERR || ctf_update(ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to define %s: %s\n",
+ n, ctf_errmsg(ctf_errno(ctfp)));
+ }
+
+ ddp->dd_ctfp = ctfp;
+ ddp->dd_type = type;
+
+ dt_scope_push(ctfp, type);
+ return (ddp);
+}
+
+void
+dt_decl_member(dt_node_t *dnp)
+{
+ dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
+ dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
+ char *ident = yypcb->pcb_dstack.ds_ident;
+
+ const char *idname = ident ? ident : "(anon)";
+ char n[DT_TYPE_NAMELEN];
+
+ dtrace_typeinfo_t dtt;
+ ctf_encoding_t cte;
+ ctf_id_t base;
+ uint_t kind;
+ ssize_t size;
+
+ if (dsp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
+
+ if (ddp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
+
+ if (dnp == NULL && ident == NULL)
+ xyerror(D_DECL_MNAME, "member declaration requires a name\n");
+
+ if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
+ ddp->dd_kind = CTF_K_INTEGER;
+ (void) dt_decl_check(ddp);
+ }
+
+ if (dt_decl_type(ddp, &dtt) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+
+ if (ident != NULL && strchr(ident, '`') != NULL) {
+ xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
+ "in a member name (%s)\n", ident);
+ }
+
+ if (dtt.dtt_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
+ dtt.dtt_type == DT_DYN_TYPE(yypcb->pcb_hdl)) {
+ xyerror(D_DECL_DYNOBJ,
+ "cannot have dynamic member: %s\n", ident);
+ }
+
+ base = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);
+ kind = ctf_type_kind(dtt.dtt_ctfp, base);
+ size = ctf_type_size(dtt.dtt_ctfp, base);
+
+ if (kind == CTF_K_FORWARD || ((kind == CTF_K_STRUCT ||
+ kind == CTF_K_UNION) && size == 0)) {
+ xyerror(D_DECL_INCOMPLETE, "incomplete struct/union/enum %s: "
+ "%s\n", dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
+ n, sizeof (n)), ident);
+ }
+
+ if (size == 0)
+ xyerror(D_DECL_VOIDOBJ, "cannot have void member: %s\n", ident);
+
+ /*
+ * If a bit-field qualifier was part of the member declaration, create
+ * a new integer type of the same name and attributes as the base type
+ * and size equal to the specified number of bits. We reset 'dtt' to
+ * refer to this new bit-field type and continue on to add the member.
+ */
+ if (dnp != NULL) {
+ dnp = dt_node_cook(dnp, DT_IDFLG_REF);
+
+ /*
+ * A bit-field member with no declarator is permitted to have
+ * size zero and indicates that no more fields are to be packed
+ * into the current storage unit. We ignore these directives
+ * as the underlying ctf code currently does so for all fields.
+ */
+ if (ident == NULL && dnp->dn_kind == DT_NODE_INT &&
+ dnp->dn_value == 0) {
+ dt_node_free(dnp);
+ goto done;
+ }
+
+ if (dt_node_is_posconst(dnp) == 0) {
+ xyerror(D_DECL_BFCONST, "positive integral constant "
+ "expression expected as bit-field size\n");
+ }
+
+ if (ctf_type_kind(dtt.dtt_ctfp, base) != CTF_K_INTEGER ||
+ ctf_type_encoding(dtt.dtt_ctfp, base, &cte) == CTF_ERR ||
+ IS_VOID(cte)) {
+ xyerror(D_DECL_BFTYPE, "invalid type for "
+ "bit-field: %s\n", idname);
+ }
+
+ if (dnp->dn_value > cte.cte_bits) {
+ xyerror(D_DECL_BFSIZE, "bit-field too big "
+ "for type: %s\n", idname);
+ }
+
+ cte.cte_offset = 0;
+ cte.cte_bits = (uint_t)dnp->dn_value;
+
+ dtt.dtt_type = ctf_add_integer(dsp->ds_ctfp,
+ CTF_ADD_NONROOT, ctf_type_name(dtt.dtt_ctfp,
+ dtt.dtt_type, n, sizeof (n)), &cte);
+
+ if (dtt.dtt_type == CTF_ERR ||
+ ctf_update(dsp->ds_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to create type for "
+ "member '%s': %s\n", idname,
+ ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
+ }
+
+ dtt.dtt_ctfp = dsp->ds_ctfp;
+ dt_node_free(dnp);
+ }
+
+ /*
+ * If the member type is not defined in the same CTF container as the
+ * one associated with the current scope (i.e. the container for the
+ * struct or union itself) or its parent, copy the member type into
+ * this container and reset dtt to refer to the copied type.
+ */
+ if (dtt.dtt_ctfp != dsp->ds_ctfp &&
+ dtt.dtt_ctfp != ctf_parent_file(dsp->ds_ctfp)) {
+
+ dtt.dtt_type = ctf_add_type(dsp->ds_ctfp,
+ dtt.dtt_ctfp, dtt.dtt_type);
+ dtt.dtt_ctfp = dsp->ds_ctfp;
+
+ if (dtt.dtt_type == CTF_ERR ||
+ ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to copy type of '%s': %s\n",
+ idname, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
+ }
+ }
+
+ if (ctf_add_member(dsp->ds_ctfp, dsp->ds_type,
+ ident, dtt.dtt_type) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to define member '%s': %s\n",
+ idname, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
+ }
+
+done:
+ free(ident);
+ yypcb->pcb_dstack.ds_ident = NULL;
+ dt_decl_reset();
+}
+
+/*ARGSUSED*/
+static int
+dt_decl_hasmembers(const char *name, int value, void *private)
+{
+ return (1); /* abort search and return true if a member exists */
+}
+
+dt_decl_t *
+dt_decl_enum(char *name)
+{
+ dt_decl_t *ddp = dt_decl_spec(CTF_K_ENUM, name);
+ char n[DT_TYPE_NAMELEN];
+ ctf_file_t *ctfp;
+ ctf_id_t type;
+ uint_t flag;
+
+ if (yypcb->pcb_idepth != 0)
+ ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
+ else
+ ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
+
+ if (yypcb->pcb_dstack.ds_next != NULL)
+ flag = CTF_ADD_NONROOT;
+ else
+ flag = CTF_ADD_ROOT;
+
+ (void) snprintf(n, sizeof (n), "enum %s", name ? name : "(anon)");
+
+ if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR) {
+ if (ctf_enum_iter(ctfp, type, dt_decl_hasmembers, NULL))
+ xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
+ } else if ((type = ctf_add_enum(ctfp, flag, name)) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to define %s: %s\n",
+ n, ctf_errmsg(ctf_errno(ctfp)));
+ }
+
+ ddp->dd_ctfp = ctfp;
+ ddp->dd_type = type;
+
+ dt_scope_push(ctfp, type);
+ return (ddp);
+}
+
+void
+dt_decl_enumerator(char *s, dt_node_t *dnp)
+{
+ dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ dt_idnode_t *inp;
+ dt_ident_t *idp;
+ char *name;
+ int value;
+
+ name = alloca(strlen(s) + 1);
+ (void) strcpy(name, s);
+ free(s);
+
+ if (dsp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
+
+ assert(dsp->ds_decl->dd_kind == CTF_K_ENUM);
+ value = dsp->ds_enumval + 1; /* default is previous value plus one */
+
+ if (strchr(name, '`') != NULL) {
+ xyerror(D_DECL_SCOPE, "D scoping operator may not be used in "
+ "an enumerator name (%s)\n", name);
+ }
+
+ /*
+ * If the enumerator is being assigned a value, cook and check the node
+ * and then free it after we get the value. We also permit references
+ * to identifiers which are previously defined enumerators in the type.
+ */
+ if (dnp != NULL) {
+ if (dnp->dn_kind != DT_NODE_IDENT || ctf_enum_value(
+ dsp->ds_ctfp, dsp->ds_type, dnp->dn_string, &value) != 0) {
+ dnp = dt_node_cook(dnp, DT_IDFLG_REF);
+
+ if (dnp->dn_kind != DT_NODE_INT) {
+ xyerror(D_DECL_ENCONST, "enumerator '%s' must "
+ "be assigned to an integral constant "
+ "expression\n", name);
+ }
+
+ if ((intmax_t)dnp->dn_value > INT_MAX ||
+ (intmax_t)dnp->dn_value < INT_MIN) {
+ xyerror(D_DECL_ENOFLOW, "enumerator '%s' value "
+ "overflows INT_MAX (%d)\n", name, INT_MAX);
+ }
+
+ value = (int)dnp->dn_value;
+ }
+ dt_node_free(dnp);
+ }
+
+ if (ctf_add_enumerator(dsp->ds_ctfp, dsp->ds_type,
+ name, value) == CTF_ERR || ctf_update(dsp->ds_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to define enumerator '%s': %s\n",
+ name, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
+ }
+
+ dsp->ds_enumval = value; /* save most recent value */
+
+ /*
+ * If the enumerator name matches an identifier in the global scope,
+ * flag this as an error. We only do this for "D" enumerators to
+ * prevent "C" header file enumerators from conflicting with the ever-
+ * growing list of D built-in global variables and inlines. If a "C"
+ * enumerator conflicts with a global identifier, we add the enumerator
+ * but do not insert a corresponding inline (i.e. the D variable wins).
+ */
+ if (dt_idstack_lookup(&yypcb->pcb_globals, name) != NULL) {
+ if (dsp->ds_ctfp == dtp->dt_ddefs->dm_ctfp) {
+ xyerror(D_DECL_IDRED,
+ "identifier redeclared: %s\n", name);
+ } else
+ return;
+ }
+
+ dt_dprintf("add global enumerator %s = %d\n", name, value);
+
+ idp = dt_idhash_insert(dtp->dt_globals, name, DT_IDENT_ENUM,
+ DT_IDFLG_INLINE | DT_IDFLG_REF, 0, _dtrace_defattr, 0,
+ &dt_idops_inline, NULL, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ yyintprefix = 0;
+ yyintsuffix[0] = '\0';
+ yyintdecimal = 0;
+
+ dnp = dt_node_int(value);
+ dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type);
+
+ if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * Remove the INT node from the node allocation list and store it in
+ * din_list and din_root so it persists with and is freed by the ident.
+ */
+ assert(yypcb->pcb_list == dnp);
+ yypcb->pcb_list = dnp->dn_link;
+ dnp->dn_link = NULL;
+
+ bzero(inp, sizeof (dt_idnode_t));
+ inp->din_list = dnp;
+ inp->din_root = dnp;
+
+ idp->di_iarg = inp;
+ idp->di_ctfp = dsp->ds_ctfp;
+ idp->di_type = dsp->ds_type;
+}
+
+/*
+ * Look up the type corresponding to the specified decl stack. The scoping of
+ * the underlying type names is handled by dt_type_lookup(). We build up the
+ * name from the specified string and prefixes and then lookup the type. If
+ * we fail, an errmsg is saved and the caller must abort with EDT_COMPILER.
+ */
+int
+dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ dt_module_t *dmp;
+ ctf_arinfo_t r;
+ ctf_id_t type;
+
+ char n[DT_TYPE_NAMELEN];
+ uint_t flag;
+ char *name;
+ int rv;
+
+ /*
+ * Based on our current #include depth and decl stack depth, determine
+ * which dynamic CTF module and scope to use when adding any new types.
+ */
+ dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs;
+ flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT;
+
+ /*
+ * If we have already cached a CTF type for this decl, then we just
+ * return the type information for the cached type.
+ */
+ if (ddp->dd_ctfp != NULL &&
+ (dmp = dt_module_lookup_by_ctf(dtp, ddp->dd_ctfp)) != NULL) {
+ tip->dtt_object = dmp->dm_name;
+ tip->dtt_ctfp = ddp->dd_ctfp;
+ tip->dtt_type = ddp->dd_type;
+ return (0);
+ }
+
+ /*
+ * Currently CTF treats all function pointers identically. We cache a
+ * representative ID of kind CTF_K_FUNCTION and just return that type.
+ * If we want to support full function declarations, dd_next refers to
+ * the declaration of the function return type, and the parameter list
+ * should be parsed and hung off a new pointer inside of this decl.
+ */
+ if (ddp->dd_kind == CTF_K_FUNCTION) {
+ tip->dtt_object = dtp->dt_ddefs->dm_name;
+ tip->dtt_ctfp = DT_FUNC_CTFP(dtp);
+ tip->dtt_type = DT_FUNC_TYPE(dtp);
+ return (0);
+ }
+
+ /*
+ * If the decl is a pointer, resolve the rest of the stack by calling
+ * dt_decl_type() recursively and then compute a pointer to the result.
+ * Similar to the code above, we return a cached id for function ptrs.
+ */
+ if (ddp->dd_kind == CTF_K_POINTER) {
+ if (ddp->dd_next->dd_kind == CTF_K_FUNCTION) {
+ tip->dtt_object = dtp->dt_ddefs->dm_name;
+ tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
+ tip->dtt_type = DT_FPTR_TYPE(dtp);
+ return (0);
+ }
+
+ if ((rv = dt_decl_type(ddp->dd_next, tip)) == 0 &&
+ (rv = dt_type_pointer(tip)) != 0) {
+ xywarn(D_UNKNOWN, "cannot find type: %s*: %s\n",
+ dt_type_name(tip->dtt_ctfp, tip->dtt_type,
+ n, sizeof (n)), ctf_errmsg(dtp->dt_ctferr));
+ }
+
+ return (rv);
+ }
+
+ /*
+ * If the decl is an array, we must find the base type and then call
+ * dt_decl_type() recursively and then build an array of the result.
+ * The C and D multi-dimensional array syntax requires that consecutive
+ * array declarations be processed from right-to-left (i.e. top-down
+ * from the perspective of the declaration stack). For example, an
+ * array declaration such as int x[3][5] is stored on the stack as:
+ *
+ * (bottom) NULL <- ( INT "int" ) <- ( ARR [3] ) <- ( ARR [5] ) (top)
+ *
+ * but means that x is declared to be an array of 3 objects each of
+ * which is an array of 5 integers, or in CTF representation:
+ *
+ * type T1:( content=int, nelems=5 ) type T2:( content=T1, nelems=3 )
+ *
+ * For more details, refer to K&R[5.7] and ISO C 6.5.2.1. Rather than
+ * overcomplicate the implementation of dt_decl_type(), we push array
+ * declarations down into the stack in dt_decl_array(), above, so that
+ * by the time dt_decl_type() is called, the decl stack looks like:
+ *
+ * (bottom) NULL <- ( INT "int" ) <- ( ARR [5] ) <- ( ARR [3] ) (top)
+ *
+ * which permits a straightforward recursive descent of the decl stack
+ * to build the corresponding CTF type tree in the appropriate order.
+ */
+ if (ddp->dd_kind == CTF_K_ARRAY) {
+ /*
+ * If the array decl has a parameter list associated with it,
+ * this is an associative array declaration: return <DYN>.
+ */
+ if (ddp->dd_node != NULL &&
+ ddp->dd_node->dn_kind == DT_NODE_TYPE) {
+ tip->dtt_object = dtp->dt_ddefs->dm_name;
+ tip->dtt_ctfp = DT_DYN_CTFP(dtp);
+ tip->dtt_type = DT_DYN_TYPE(dtp);
+ return (0);
+ }
+
+ if ((rv = dt_decl_type(ddp->dd_next, tip)) != 0)
+ return (rv);
+
+ /*
+ * If the array base type is not defined in the target
+ * container or its parent, copy the type to the target
+ * container and reset dtt_ctfp and dtt_type to the copy.
+ */
+ if (tip->dtt_ctfp != dmp->dm_ctfp &&
+ tip->dtt_ctfp != ctf_parent_file(dmp->dm_ctfp)) {
+
+ tip->dtt_type = ctf_add_type(dmp->dm_ctfp,
+ tip->dtt_ctfp, tip->dtt_type);
+ tip->dtt_ctfp = dmp->dm_ctfp;
+
+ if (tip->dtt_type == CTF_ERR ||
+ ctf_update(tip->dtt_ctfp) == CTF_ERR) {
+ xywarn(D_UNKNOWN, "failed to copy type: %s\n",
+ ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
+ return (-1);
+ }
+ }
+
+ /*
+ * The array index type is irrelevant in C and D: just set it
+ * to "long" for all array types that we create on-the-fly.
+ */
+ r.ctr_contents = tip->dtt_type;
+ r.ctr_index = ctf_lookup_by_name(tip->dtt_ctfp, "long");
+ r.ctr_nelems = ddp->dd_node ?
+ (uint_t)ddp->dd_node->dn_value : 0;
+
+ tip->dtt_object = dmp->dm_name;
+ tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_type = ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &r);
+
+ if (tip->dtt_type == CTF_ERR ||
+ ctf_update(tip->dtt_ctfp) == CTF_ERR) {
+ xywarn(D_UNKNOWN, "failed to create array type: %s\n",
+ ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
+ return (-1);
+ }
+
+ return (0);
+ }
+
+ /*
+ * Allocate space for the type name and enough space for the maximum
+ * additional text ("unsigned long long \0" requires 20 more bytes).
+ */
+ name = alloca(ddp->dd_name ? strlen(ddp->dd_name) + 20 : 20);
+ name[0] = '\0';
+
+ switch (ddp->dd_kind) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ if (ddp->dd_attr & DT_DA_SIGNED)
+ (void) strcat(name, "signed ");
+ if (ddp->dd_attr & DT_DA_UNSIGNED)
+ (void) strcat(name, "unsigned ");
+ if (ddp->dd_attr & DT_DA_SHORT)
+ (void) strcat(name, "short ");
+ if (ddp->dd_attr & DT_DA_LONG)
+ (void) strcat(name, "long ");
+ if (ddp->dd_attr & DT_DA_LONGLONG)
+ (void) strcat(name, "long long ");
+ if (ddp->dd_attr == 0 && ddp->dd_name == NULL)
+ (void) strcat(name, "int");
+ break;
+ case CTF_K_STRUCT:
+ (void) strcpy(name, "struct ");
+ break;
+ case CTF_K_UNION:
+ (void) strcpy(name, "union ");
+ break;
+ case CTF_K_ENUM:
+ (void) strcpy(name, "enum ");
+ break;
+ case CTF_K_TYPEDEF:
+ break;
+ default:
+ xywarn(D_UNKNOWN, "internal error -- "
+ "bad decl kind %u\n", ddp->dd_kind);
+ return (-1);
+ }
+
+ /*
+ * Add dd_name unless a short, long, or long long is explicitly
+ * suffixed by int. We use the C/CTF canonical names for integers.
+ */
+ if (ddp->dd_name != NULL && (ddp->dd_kind != CTF_K_INTEGER ||
+ (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG)) == 0))
+ (void) strcat(name, ddp->dd_name);
+
+ /*
+ * Lookup the type. If we find it, we're done. Otherwise create a
+ * forward tag for the type if it is a struct, union, or enum. If
+ * we can't find it and we can't create a tag, return failure.
+ */
+ if ((rv = dt_type_lookup(name, tip)) == 0)
+ return (rv);
+
+ switch (ddp->dd_kind) {
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ case CTF_K_ENUM:
+ type = ctf_add_forward(dmp->dm_ctfp, flag,
+ ddp->dd_name, ddp->dd_kind);
+ break;
+ default:
+ xywarn(D_UNKNOWN, "failed to resolve type %s: %s\n", name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ return (rv);
+ }
+
+ if (type == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
+ xywarn(D_UNKNOWN, "failed to add forward tag for %s: %s\n",
+ name, ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (-1);
+ }
+
+ ddp->dd_ctfp = dmp->dm_ctfp;
+ ddp->dd_type = type;
+
+ tip->dtt_object = dmp->dm_name;
+ tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_type = type;
+
+ return (0);
+}
+
+void
+dt_scope_create(dt_scope_t *dsp)
+{
+ dsp->ds_decl = NULL;
+ dsp->ds_next = NULL;
+ dsp->ds_ident = NULL;
+ dsp->ds_ctfp = NULL;
+ dsp->ds_type = CTF_ERR;
+ dsp->ds_class = DT_DC_DEFAULT;
+ dsp->ds_enumval = -1;
+}
+
+void
+dt_scope_destroy(dt_scope_t *dsp)
+{
+ dt_scope_t *nsp;
+
+ for (; dsp != NULL; dsp = nsp) {
+ dt_decl_free(dsp->ds_decl);
+ free(dsp->ds_ident);
+ nsp = dsp->ds_next;
+ if (dsp != &yypcb->pcb_dstack)
+ free(dsp);
+ }
+}
+
+void
+dt_scope_push(ctf_file_t *ctfp, ctf_id_t type)
+{
+ dt_scope_t *rsp = &yypcb->pcb_dstack;
+ dt_scope_t *dsp = malloc(sizeof (dt_scope_t));
+
+ if (dsp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dsp->ds_decl = rsp->ds_decl;
+ dsp->ds_next = rsp->ds_next;
+ dsp->ds_ident = rsp->ds_ident;
+ dsp->ds_ctfp = ctfp;
+ dsp->ds_type = type;
+ dsp->ds_class = rsp->ds_class;
+ dsp->ds_enumval = rsp->ds_enumval;
+
+ dt_scope_create(rsp);
+ rsp->ds_next = dsp;
+}
+
+dt_decl_t *
+dt_scope_pop(void)
+{
+ dt_scope_t *rsp = &yypcb->pcb_dstack;
+ dt_scope_t *dsp = rsp->ds_next;
+
+ if (dsp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
+
+ if (dsp->ds_ctfp != NULL && ctf_update(dsp->ds_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to update type definitions: %s\n",
+ ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
+ }
+
+ dt_decl_free(rsp->ds_decl);
+ free(rsp->ds_ident);
+
+ rsp->ds_decl = dsp->ds_decl;
+ rsp->ds_next = dsp->ds_next;
+ rsp->ds_ident = dsp->ds_ident;
+ rsp->ds_ctfp = dsp->ds_ctfp;
+ rsp->ds_type = dsp->ds_type;
+ rsp->ds_class = dsp->ds_class;
+ rsp->ds_enumval = dsp->ds_enumval;
+
+ free(dsp);
+ return (rsp->ds_decl);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
new file mode 100644
index 0000000..2933155
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
@@ -0,0 +1,126 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_DECL_H
+#define _DT_DECL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <libctf.h>
+#include <dtrace.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dt_node; /* forward declaration of dt_node_t */
+
+typedef struct dt_decl {
+ ushort_t dd_kind; /* declaration kind (CTF_K_* kind) */
+ ushort_t dd_attr; /* attributes (DT_DA_* flags) */
+ ctf_file_t *dd_ctfp; /* CTF container for decl's type */
+ ctf_id_t dd_type; /* CTF identifier for decl's type */
+ char *dd_name; /* string name of this decl (or NULL) */
+ struct dt_node *dd_node; /* node for array size or parm list */
+ struct dt_decl *dd_next; /* next declaration in list */
+} dt_decl_t;
+
+#define DT_DA_SIGNED 0x0001 /* signed integer value */
+#define DT_DA_UNSIGNED 0x0002 /* unsigned integer value */
+#define DT_DA_SHORT 0x0004 /* short integer value */
+#define DT_DA_LONG 0x0008 /* long integer or double */
+#define DT_DA_LONGLONG 0x0010 /* long long integer value */
+#define DT_DA_CONST 0x0020 /* qualify type as const */
+#define DT_DA_RESTRICT 0x0040 /* qualify type as restrict */
+#define DT_DA_VOLATILE 0x0080 /* qualify type as volatile */
+#define DT_DA_PAREN 0x0100 /* parenthesis tag */
+
+typedef enum dt_dclass {
+ DT_DC_DEFAULT, /* no storage class specified */
+ DT_DC_AUTO, /* automatic storage */
+ DT_DC_REGISTER, /* register storage */
+ DT_DC_STATIC, /* static storage */
+ DT_DC_EXTERN, /* extern storage */
+ DT_DC_TYPEDEF, /* type definition */
+ DT_DC_SELF, /* thread-local storage */
+ DT_DC_THIS /* clause-local storage */
+} dt_dclass_t;
+
+typedef struct dt_scope {
+ dt_decl_t *ds_decl; /* pointer to top of decl stack */
+ struct dt_scope *ds_next; /* pointer to next scope */
+ char *ds_ident; /* identifier for this scope (if any) */
+ ctf_file_t *ds_ctfp; /* CTF container for this scope */
+ ctf_id_t ds_type; /* CTF id of enclosing type */
+ dt_dclass_t ds_class; /* declaration class for this scope */
+ int ds_enumval; /* most recent enumerator value */
+} dt_scope_t;
+
+extern dt_decl_t *dt_decl_alloc(ushort_t, char *);
+extern void dt_decl_free(dt_decl_t *);
+extern void dt_decl_reset(void);
+extern dt_decl_t *dt_decl_push(dt_decl_t *);
+extern dt_decl_t *dt_decl_pop(void);
+extern dt_decl_t *dt_decl_pop_param(char **);
+extern dt_decl_t *dt_decl_top(void);
+
+extern dt_decl_t *dt_decl_ident(char *);
+extern void dt_decl_class(dt_dclass_t);
+
+#define DT_DP_VARARGS 0x1 /* permit varargs in prototype */
+#define DT_DP_DYNAMIC 0x2 /* permit dynamic type in prototype */
+#define DT_DP_VOID 0x4 /* permit void type in prototype */
+#define DT_DP_ANON 0x8 /* permit anonymous parameters */
+
+extern int dt_decl_prototype(struct dt_node *, struct dt_node *,
+ const char *, uint_t);
+
+extern dt_decl_t *dt_decl_spec(ushort_t, char *);
+extern dt_decl_t *dt_decl_attr(ushort_t);
+extern dt_decl_t *dt_decl_array(struct dt_node *);
+extern dt_decl_t *dt_decl_func(dt_decl_t *, struct dt_node *);
+extern dt_decl_t *dt_decl_ptr(void);
+
+extern dt_decl_t *dt_decl_sou(uint_t, char *);
+extern void dt_decl_member(struct dt_node *);
+
+extern dt_decl_t *dt_decl_enum(char *);
+extern void dt_decl_enumerator(char *, struct dt_node *);
+
+extern int dt_decl_type(dt_decl_t *, dtrace_typeinfo_t *);
+
+extern void dt_scope_create(dt_scope_t *);
+extern void dt_scope_destroy(dt_scope_t *);
+extern void dt_scope_push(ctf_file_t *, ctf_id_t);
+extern dt_decl_t *dt_scope_pop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_DECL_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
new file mode 100644
index 0000000..f4bb0c4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
@@ -0,0 +1,511 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <strings.h>
+#include <stdio.h>
+
+#include <dt_impl.h>
+#include <dt_ident.h>
+
+/*ARGSUSED*/
+static void
+dt_dis_log(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u, %%r%u, %%r%u", name,
+ DIF_INSTR_R1(in), DIF_INSTR_R2(in), DIF_INSTR_RD(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_branch(const dtrace_difo_t *dp, const char *name,
+ dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %u", name, DIF_INSTR_LABEL(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_load(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s [%%r%u], %%r%u", name,
+ DIF_INSTR_R1(in), DIF_INSTR_RD(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_store(const dtrace_difo_t *dp, const char *name,
+ dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u, [%%r%u]", name,
+ DIF_INSTR_R1(in), DIF_INSTR_RD(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_str(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%s", name);
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_r1rd(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u, %%r%u", name,
+ DIF_INSTR_R1(in), DIF_INSTR_RD(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_cmp(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u, %%r%u", name,
+ DIF_INSTR_R1(in), DIF_INSTR_R2(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_tst(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u", name, DIF_INSTR_R1(in));
+}
+
+static const char *
+dt_dis_varname(const dtrace_difo_t *dp, uint_t id, uint_t scope)
+{
+ const dtrace_difv_t *dvp = dp->dtdo_vartab;
+ uint_t i;
+
+ for (i = 0; i < dp->dtdo_varlen; i++, dvp++) {
+ if (dvp->dtdv_id == id && dvp->dtdv_scope == scope) {
+ if (dvp->dtdv_name < dp->dtdo_strlen)
+ return (dp->dtdo_strtab + dvp->dtdv_name);
+ break;
+ }
+ }
+
+ return (NULL);
+}
+
+static uint_t
+dt_dis_scope(const char *name)
+{
+ switch (name[2]) {
+ case 'l': return (DIFV_SCOPE_LOCAL);
+ case 't': return (DIFV_SCOPE_THREAD);
+ case 'g': return (DIFV_SCOPE_GLOBAL);
+ default: return (-1u);
+ }
+}
+
+static void
+dt_dis_lda(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t var = DIF_INSTR_R1(in);
+ const char *vname;
+
+ (void) fprintf(fp, "%-4s DT_VAR(%u), %%r%u, %%r%u", name,
+ var, DIF_INSTR_R2(in), DIF_INSTR_RD(in));
+
+ if ((vname = dt_dis_varname(dp, var, dt_dis_scope(name))) != NULL)
+ (void) fprintf(fp, "\t\t! DT_VAR(%u) = \"%s\"", var, vname);
+}
+
+static void
+dt_dis_ldv(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t var = DIF_INSTR_VAR(in);
+ const char *vname;
+
+ (void) fprintf(fp, "%-4s DT_VAR(%u), %%r%u",
+ name, var, DIF_INSTR_RD(in));
+
+ if ((vname = dt_dis_varname(dp, var, dt_dis_scope(name))) != NULL)
+ (void) fprintf(fp, "\t\t! DT_VAR(%u) = \"%s\"", var, vname);
+}
+
+static void
+dt_dis_stv(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t var = DIF_INSTR_VAR(in);
+ const char *vname;
+
+ (void) fprintf(fp, "%-4s %%r%u, DT_VAR(%u)",
+ name, DIF_INSTR_RS(in), var);
+
+ if ((vname = dt_dis_varname(dp, var, dt_dis_scope(name))) != NULL)
+ (void) fprintf(fp, "\t\t! DT_VAR(%u) = \"%s\"", var, vname);
+}
+
+static void
+dt_dis_setx(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t intptr = DIF_INSTR_INTEGER(in);
+
+ (void) fprintf(fp, "%-4s DT_INTEGER[%u], %%r%u", name,
+ intptr, DIF_INSTR_RD(in));
+
+ if (intptr < dp->dtdo_intlen) {
+ (void) fprintf(fp, "\t\t! 0x%llx",
+ (u_longlong_t)dp->dtdo_inttab[intptr]);
+ }
+}
+
+static void
+dt_dis_sets(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t strptr = DIF_INSTR_STRING(in);
+
+ (void) fprintf(fp, "%-4s DT_STRING[%u], %%r%u", name,
+ strptr, DIF_INSTR_RD(in));
+
+ if (strptr < dp->dtdo_strlen)
+ (void) fprintf(fp, "\t\t! \"%s\"", dp->dtdo_strtab + strptr);
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_ret(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ (void) fprintf(fp, "%-4s %%r%u", name, DIF_INSTR_RD(in));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_call(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t subr = DIF_INSTR_SUBR(in);
+
+ (void) fprintf(fp, "%-4s DIF_SUBR(%u), %%r%u\t\t! %s",
+ name, subr, DIF_INSTR_RD(in), dtrace_subrstr(NULL, subr));
+}
+
+/*ARGSUSED*/
+static void
+dt_dis_pushts(const dtrace_difo_t *dp,
+ const char *name, dif_instr_t in, FILE *fp)
+{
+ static const char *const tnames[] = { "D type", "string" };
+ uint_t type = DIF_INSTR_TYPE(in);
+
+ (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u, %%r%u",
+ name, type, DIF_INSTR_R2(in), DIF_INSTR_RS(in));
+
+ if (type < sizeof (tnames) / sizeof (tnames[0]))
+ (void) fprintf(fp, "\t! DT_TYPE(%u) = %s", type, tnames[type]);
+}
+
+static void
+dt_dis_xlate(const dtrace_difo_t *dp,
+ const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t xlr = DIF_INSTR_XLREF(in);
+
+ (void) fprintf(fp, "%-4s DT_XLREF[%u], %%r%u",
+ name, xlr, DIF_INSTR_RD(in));
+
+ if (xlr < dp->dtdo_xlmlen) {
+ (void) fprintf(fp, "\t\t! DT_XLREF[%u] = %u.%s", xlr,
+ (uint_t)dp->dtdo_xlmtab[xlr]->dn_membexpr->dn_xlator->dx_id,
+ dp->dtdo_xlmtab[xlr]->dn_membname);
+ }
+}
+
+static char *
+dt_dis_typestr(const dtrace_diftype_t *t, char *buf, size_t len)
+{
+ char kind[16], ckind[16];
+
+ switch (t->dtdt_kind) {
+ case DIF_TYPE_CTF:
+ (void) strcpy(kind, "D type");
+ break;
+ case DIF_TYPE_STRING:
+ (void) strcpy(kind, "string");
+ break;
+ default:
+ (void) snprintf(kind, sizeof (kind), "0x%x", t->dtdt_kind);
+ }
+
+ switch (t->dtdt_ckind) {
+ case CTF_K_UNKNOWN:
+ (void) strcpy(ckind, "unknown");
+ break;
+ case CTF_K_INTEGER:
+ (void) strcpy(ckind, "integer");
+ break;
+ case CTF_K_FLOAT:
+ (void) strcpy(ckind, "float");
+ break;
+ case CTF_K_POINTER:
+ (void) strcpy(ckind, "pointer");
+ break;
+ case CTF_K_ARRAY:
+ (void) strcpy(ckind, "array");
+ break;
+ case CTF_K_FUNCTION:
+ (void) strcpy(ckind, "function");
+ break;
+ case CTF_K_STRUCT:
+ (void) strcpy(ckind, "struct");
+ break;
+ case CTF_K_UNION:
+ (void) strcpy(ckind, "union");
+ break;
+ case CTF_K_ENUM:
+ (void) strcpy(ckind, "enum");
+ break;
+ case CTF_K_FORWARD:
+ (void) strcpy(ckind, "forward");
+ break;
+ case CTF_K_TYPEDEF:
+ (void) strcpy(ckind, "typedef");
+ break;
+ case CTF_K_VOLATILE:
+ (void) strcpy(ckind, "volatile");
+ break;
+ case CTF_K_CONST:
+ (void) strcpy(ckind, "const");
+ break;
+ case CTF_K_RESTRICT:
+ (void) strcpy(ckind, "restrict");
+ break;
+ default:
+ (void) snprintf(ckind, sizeof (ckind), "0x%x", t->dtdt_ckind);
+ }
+
+ if (t->dtdt_flags & DIF_TF_BYREF) {
+ (void) snprintf(buf, len, "%s (%s) by ref (size %lu)",
+ kind, ckind, (ulong_t)t->dtdt_size);
+ } else {
+ (void) snprintf(buf, len, "%s (%s) (size %lu)",
+ kind, ckind, (ulong_t)t->dtdt_size);
+ }
+
+ return (buf);
+}
+
+static void
+dt_dis_rtab(const char *rtag, const dtrace_difo_t *dp, FILE *fp,
+ const dof_relodesc_t *rp, uint32_t len)
+{
+ (void) fprintf(fp, "\n%-4s %-8s %-8s %s\n",
+ rtag, "OFFSET", "DATA", "NAME");
+
+ for (; len != 0; len--, rp++) {
+ (void) fprintf(fp, "%-4u %-8llu %-8llu %s\n",
+ rp->dofr_type, (u_longlong_t)rp->dofr_offset,
+ (u_longlong_t)rp->dofr_data,
+ &dp->dtdo_strtab[rp->dofr_name]);
+ }
+}
+
+void
+dt_dis(const dtrace_difo_t *dp, FILE *fp)
+{
+ static const struct opent {
+ const char *op_name;
+ void (*op_func)(const dtrace_difo_t *, const char *,
+ dif_instr_t, FILE *);
+ } optab[] = {
+ { "(illegal opcode)", dt_dis_str },
+ { "or", dt_dis_log }, /* DIF_OP_OR */
+ { "xor", dt_dis_log }, /* DIF_OP_XOR */
+ { "and", dt_dis_log }, /* DIF_OP_AND */
+ { "sll", dt_dis_log }, /* DIF_OP_SLL */
+ { "srl", dt_dis_log }, /* DIF_OP_SRL */
+ { "sub", dt_dis_log }, /* DIF_OP_SUB */
+ { "add", dt_dis_log }, /* DIF_OP_ADD */
+ { "mul", dt_dis_log }, /* DIF_OP_MUL */
+ { "sdiv", dt_dis_log }, /* DIF_OP_SDIV */
+ { "udiv", dt_dis_log }, /* DIF_OP_UDIV */
+ { "srem", dt_dis_log }, /* DIF_OP_SREM */
+ { "urem", dt_dis_log }, /* DIF_OP_UREM */
+ { "not", dt_dis_r1rd }, /* DIF_OP_NOT */
+ { "mov", dt_dis_r1rd }, /* DIF_OP_MOV */
+ { "cmp", dt_dis_cmp }, /* DIF_OP_CMP */
+ { "tst", dt_dis_tst }, /* DIF_OP_TST */
+ { "ba", dt_dis_branch }, /* DIF_OP_BA */
+ { "be", dt_dis_branch }, /* DIF_OP_BE */
+ { "bne", dt_dis_branch }, /* DIF_OP_BNE */
+ { "bg", dt_dis_branch }, /* DIF_OP_BG */
+ { "bgu", dt_dis_branch }, /* DIF_OP_BGU */
+ { "bge", dt_dis_branch }, /* DIF_OP_BGE */
+ { "bgeu", dt_dis_branch }, /* DIF_OP_BGEU */
+ { "bl", dt_dis_branch }, /* DIF_OP_BL */
+ { "blu", dt_dis_branch }, /* DIF_OP_BLU */
+ { "ble", dt_dis_branch }, /* DIF_OP_BLE */
+ { "bleu", dt_dis_branch }, /* DIF_OP_BLEU */
+ { "ldsb", dt_dis_load }, /* DIF_OP_LDSB */
+ { "ldsh", dt_dis_load }, /* DIF_OP_LDSH */
+ { "ldsw", dt_dis_load }, /* DIF_OP_LDSW */
+ { "ldub", dt_dis_load }, /* DIF_OP_LDUB */
+ { "lduh", dt_dis_load }, /* DIF_OP_LDUH */
+ { "lduw", dt_dis_load }, /* DIF_OP_LDUW */
+ { "ldx", dt_dis_load }, /* DIF_OP_LDX */
+ { "ret", dt_dis_ret }, /* DIF_OP_RET */
+ { "nop", dt_dis_str }, /* DIF_OP_NOP */
+ { "setx", dt_dis_setx }, /* DIF_OP_SETX */
+ { "sets", dt_dis_sets }, /* DIF_OP_SETS */
+ { "scmp", dt_dis_cmp }, /* DIF_OP_SCMP */
+ { "ldga", dt_dis_lda }, /* DIF_OP_LDGA */
+ { "ldgs", dt_dis_ldv }, /* DIF_OP_LDGS */
+ { "stgs", dt_dis_stv }, /* DIF_OP_STGS */
+ { "ldta", dt_dis_lda }, /* DIF_OP_LDTA */
+ { "ldts", dt_dis_ldv }, /* DIF_OP_LDTS */
+ { "stts", dt_dis_stv }, /* DIF_OP_STTS */
+ { "sra", dt_dis_log }, /* DIF_OP_SRA */
+ { "call", dt_dis_call }, /* DIF_OP_CALL */
+ { "pushtr", dt_dis_pushts }, /* DIF_OP_PUSHTR */
+ { "pushtv", dt_dis_pushts }, /* DIF_OP_PUSHTV */
+ { "popts", dt_dis_str }, /* DIF_OP_POPTS */
+ { "flushts", dt_dis_str }, /* DIF_OP_FLUSHTS */
+ { "ldgaa", dt_dis_ldv }, /* DIF_OP_LDGAA */
+ { "ldtaa", dt_dis_ldv }, /* DIF_OP_LDTAA */
+ { "stgaa", dt_dis_stv }, /* DIF_OP_STGAA */
+ { "sttaa", dt_dis_stv }, /* DIF_OP_STTAA */
+ { "ldls", dt_dis_ldv }, /* DIF_OP_LDLS */
+ { "stls", dt_dis_stv }, /* DIF_OP_STLS */
+ { "allocs", dt_dis_r1rd }, /* DIF_OP_ALLOCS */
+ { "copys", dt_dis_log }, /* DIF_OP_COPYS */
+ { "stb", dt_dis_store }, /* DIF_OP_STB */
+ { "sth", dt_dis_store }, /* DIF_OP_STH */
+ { "stw", dt_dis_store }, /* DIF_OP_STW */
+ { "stx", dt_dis_store }, /* DIF_OP_STX */
+ { "uldsb", dt_dis_load }, /* DIF_OP_ULDSB */
+ { "uldsh", dt_dis_load }, /* DIF_OP_ULDSH */
+ { "uldsw", dt_dis_load }, /* DIF_OP_ULDSW */
+ { "uldub", dt_dis_load }, /* DIF_OP_ULDUB */
+ { "ulduh", dt_dis_load }, /* DIF_OP_ULDUH */
+ { "ulduw", dt_dis_load }, /* DIF_OP_ULDUW */
+ { "uldx", dt_dis_load }, /* DIF_OP_ULDX */
+ { "rldsb", dt_dis_load }, /* DIF_OP_RLDSB */
+ { "rldsh", dt_dis_load }, /* DIF_OP_RLDSH */
+ { "rldsw", dt_dis_load }, /* DIF_OP_RLDSW */
+ { "rldub", dt_dis_load }, /* DIF_OP_RLDUB */
+ { "rlduh", dt_dis_load }, /* DIF_OP_RLDUH */
+ { "rlduw", dt_dis_load }, /* DIF_OP_RLDUW */
+ { "rldx", dt_dis_load }, /* DIF_OP_RLDX */
+ { "xlate", dt_dis_xlate }, /* DIF_OP_XLATE */
+ { "xlarg", dt_dis_xlate }, /* DIF_OP_XLARG */
+ };
+
+ const struct opent *op;
+ ulong_t i = 0;
+ char type[DT_TYPE_NAMELEN];
+
+ (void) fprintf(fp, "\nDIFO 0x%p returns %s\n", (void *)dp,
+ dt_dis_typestr(&dp->dtdo_rtype, type, sizeof (type)));
+
+ (void) fprintf(fp, "%-3s %-8s %s\n",
+ "OFF", "OPCODE", "INSTRUCTION");
+
+ for (i = 0; i < dp->dtdo_len; i++) {
+ dif_instr_t instr = dp->dtdo_buf[i];
+ dif_instr_t opcode = DIF_INSTR_OP(instr);
+
+ if (opcode >= sizeof (optab) / sizeof (optab[0]))
+ opcode = 0; /* force invalid opcode message */
+
+ op = &optab[opcode];
+ (void) fprintf(fp, "%02lu: %08x ", i, instr);
+ op->op_func(dp, op->op_name, instr, fp);
+ (void) fprintf(fp, "\n");
+ }
+
+ if (dp->dtdo_varlen != 0) {
+ (void) fprintf(fp, "\n%-16s %-4s %-3s %-3s %-4s %s\n",
+ "NAME", "ID", "KND", "SCP", "FLAG", "TYPE");
+ }
+
+ for (i = 0; i < dp->dtdo_varlen; i++) {
+ dtrace_difv_t *v = &dp->dtdo_vartab[i];
+ char kind[4], scope[4], flags[16] = { 0 };
+
+ switch (v->dtdv_kind) {
+ case DIFV_KIND_ARRAY:
+ (void) strcpy(kind, "arr");
+ break;
+ case DIFV_KIND_SCALAR:
+ (void) strcpy(kind, "scl");
+ break;
+ default:
+ (void) snprintf(kind, sizeof (kind),
+ "%u", v->dtdv_kind);
+ }
+
+ switch (v->dtdv_scope) {
+ case DIFV_SCOPE_GLOBAL:
+ (void) strcpy(scope, "glb");
+ break;
+ case DIFV_SCOPE_THREAD:
+ (void) strcpy(scope, "tls");
+ break;
+ case DIFV_SCOPE_LOCAL:
+ (void) strcpy(scope, "loc");
+ break;
+ default:
+ (void) snprintf(scope, sizeof (scope),
+ "%u", v->dtdv_scope);
+ }
+
+ if (v->dtdv_flags & ~(DIFV_F_REF | DIFV_F_MOD)) {
+ (void) snprintf(flags, sizeof (flags), "/0x%x",
+ v->dtdv_flags & ~(DIFV_F_REF | DIFV_F_MOD));
+ }
+
+ if (v->dtdv_flags & DIFV_F_REF)
+ (void) strcat(flags, "/r");
+ if (v->dtdv_flags & DIFV_F_MOD)
+ (void) strcat(flags, "/w");
+
+ (void) fprintf(fp, "%-16s %-4x %-3s %-3s %-4s %s\n",
+ &dp->dtdo_strtab[v->dtdv_name],
+ v->dtdv_id, kind, scope, flags + 1,
+ dt_dis_typestr(&v->dtdv_type, type, sizeof (type)));
+ }
+
+ if (dp->dtdo_xlmlen != 0) {
+ (void) fprintf(fp, "\n%-4s %-3s %-12s %s\n",
+ "XLID", "ARG", "MEMBER", "TYPE");
+ }
+
+ for (i = 0; i < dp->dtdo_xlmlen; i++) {
+ dt_node_t *dnp = dp->dtdo_xlmtab[i];
+ dt_xlator_t *dxp = dnp->dn_membexpr->dn_xlator;
+ (void) fprintf(fp, "%-4u %-3d %-12s %s\n",
+ (uint_t)dxp->dx_id, dxp->dx_arg, dnp->dn_membname,
+ dt_node_type_name(dnp, type, sizeof (type)));
+ }
+
+ if (dp->dtdo_krelen != 0)
+ dt_dis_rtab("KREL", dp, fp, dp->dtdo_kreltab, dp->dtdo_krelen);
+
+ if (dp->dtdo_urelen != 0)
+ dt_dis_rtab("UREL", dp, fp, dp->dtdo_ureltab, dp->dtdo_urelen);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
new file mode 100644
index 0000000..01ef0f9
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
@@ -0,0 +1,974 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/sysmacros.h>
+#endif
+
+#include <strings.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <dt_impl.h>
+#include <dt_strtab.h>
+#include <dt_program.h>
+#include <dt_provider.h>
+#include <dt_xlator.h>
+#include <dt_dof.h>
+
+void
+dt_dof_init(dtrace_hdl_t *dtp)
+{
+ dt_dof_t *ddo = &dtp->dt_dof;
+
+ ddo->ddo_hdl = dtp;
+ ddo->ddo_nsecs = 0;
+ ddo->ddo_strsec = DOF_SECIDX_NONE;
+ ddo->ddo_xlimport = NULL;
+ ddo->ddo_xlexport = NULL;
+
+ dt_buf_create(dtp, &ddo->ddo_secs, "section headers", 0);
+ dt_buf_create(dtp, &ddo->ddo_strs, "string table", 0);
+ dt_buf_create(dtp, &ddo->ddo_ldata, "loadable data", 0);
+ dt_buf_create(dtp, &ddo->ddo_udata, "unloadable data", 0);
+
+ dt_buf_create(dtp, &ddo->ddo_probes, "probe data", 0);
+ dt_buf_create(dtp, &ddo->ddo_args, "probe args", 0);
+ dt_buf_create(dtp, &ddo->ddo_offs, "probe offs", 0);
+ dt_buf_create(dtp, &ddo->ddo_enoffs, "probe is-enabled offs", 0);
+ dt_buf_create(dtp, &ddo->ddo_rels, "probe rels", 0);
+
+ dt_buf_create(dtp, &ddo->ddo_xlms, "xlate members", 0);
+}
+
+void
+dt_dof_fini(dtrace_hdl_t *dtp)
+{
+ dt_dof_t *ddo = &dtp->dt_dof;
+
+ dt_free(dtp, ddo->ddo_xlimport);
+ dt_free(dtp, ddo->ddo_xlexport);
+
+ dt_buf_destroy(dtp, &ddo->ddo_secs);
+ dt_buf_destroy(dtp, &ddo->ddo_strs);
+ dt_buf_destroy(dtp, &ddo->ddo_ldata);
+ dt_buf_destroy(dtp, &ddo->ddo_udata);
+
+ dt_buf_destroy(dtp, &ddo->ddo_probes);
+ dt_buf_destroy(dtp, &ddo->ddo_args);
+ dt_buf_destroy(dtp, &ddo->ddo_offs);
+ dt_buf_destroy(dtp, &ddo->ddo_enoffs);
+ dt_buf_destroy(dtp, &ddo->ddo_rels);
+
+ dt_buf_destroy(dtp, &ddo->ddo_xlms);
+}
+
+static int
+dt_dof_reset(dtrace_hdl_t *dtp, dtrace_prog_t *pgp)
+{
+ dt_dof_t *ddo = &dtp->dt_dof;
+ uint_t i, nx = dtp->dt_xlatorid;
+
+ assert(ddo->ddo_hdl == dtp);
+ ddo->ddo_pgp = pgp;
+
+ ddo->ddo_nsecs = 0;
+ ddo->ddo_strsec = DOF_SECIDX_NONE;
+
+ dt_free(dtp, ddo->ddo_xlimport);
+ dt_free(dtp, ddo->ddo_xlexport);
+
+ ddo->ddo_xlimport = dt_alloc(dtp, sizeof (dof_secidx_t) * nx);
+ ddo->ddo_xlexport = dt_alloc(dtp, sizeof (dof_secidx_t) * nx);
+
+ if (nx != 0 && (ddo->ddo_xlimport == NULL || ddo->ddo_xlexport == NULL))
+ return (-1); /* errno is set for us */
+
+ for (i = 0; i < nx; i++) {
+ ddo->ddo_xlimport[i] = DOF_SECIDX_NONE;
+ ddo->ddo_xlexport[i] = DOF_SECIDX_NONE;
+ }
+
+ dt_buf_reset(dtp, &ddo->ddo_secs);
+ dt_buf_reset(dtp, &ddo->ddo_strs);
+ dt_buf_reset(dtp, &ddo->ddo_ldata);
+ dt_buf_reset(dtp, &ddo->ddo_udata);
+
+ dt_buf_reset(dtp, &ddo->ddo_probes);
+ dt_buf_reset(dtp, &ddo->ddo_args);
+ dt_buf_reset(dtp, &ddo->ddo_offs);
+ dt_buf_reset(dtp, &ddo->ddo_enoffs);
+ dt_buf_reset(dtp, &ddo->ddo_rels);
+
+ dt_buf_reset(dtp, &ddo->ddo_xlms);
+ return (0);
+}
+
+/*
+ * Add a loadable DOF section to the file using the specified data buffer and
+ * the specified DOF section attributes. DOF_SECF_LOAD must be set in flags.
+ * If 'data' is NULL, the caller is responsible for manipulating the ldata buf.
+ */
+static dof_secidx_t
+dof_add_lsect(dt_dof_t *ddo, const void *data, uint32_t type,
+ uint32_t align, uint32_t flags, uint32_t entsize, uint64_t size)
+{
+ dtrace_hdl_t *dtp = ddo->ddo_hdl;
+ dof_sec_t s;
+
+ s.dofs_type = type;
+ s.dofs_align = align;
+ s.dofs_flags = flags | DOF_SECF_LOAD;
+ s.dofs_entsize = entsize;
+ s.dofs_offset = dt_buf_offset(&ddo->ddo_ldata, align);
+ s.dofs_size = size;
+
+ dt_buf_write(dtp, &ddo->ddo_secs, &s, sizeof (s), sizeof (uint64_t));
+
+ if (data != NULL)
+ dt_buf_write(dtp, &ddo->ddo_ldata, data, size, align);
+
+ return (ddo->ddo_nsecs++);
+}
+
+/*
+ * Add an unloadable DOF section to the file using the specified data buffer
+ * and DOF section attributes. DOF_SECF_LOAD must *not* be set in flags.
+ * If 'data' is NULL, the caller is responsible for manipulating the udata buf.
+ */
+static dof_secidx_t
+dof_add_usect(dt_dof_t *ddo, const void *data, uint32_t type,
+ uint32_t align, uint32_t flags, uint32_t entsize, uint64_t size)
+{
+ dtrace_hdl_t *dtp = ddo->ddo_hdl;
+ dof_sec_t s;
+
+ s.dofs_type = type;
+ s.dofs_align = align;
+ s.dofs_flags = flags & ~DOF_SECF_LOAD;
+ s.dofs_entsize = entsize;
+ s.dofs_offset = dt_buf_offset(&ddo->ddo_udata, align);
+ s.dofs_size = size;
+
+ dt_buf_write(dtp, &ddo->ddo_secs, &s, sizeof (s), sizeof (uint64_t));
+
+ if (data != NULL)
+ dt_buf_write(dtp, &ddo->ddo_udata, data, size, align);
+
+ return (ddo->ddo_nsecs++);
+}
+
+/*
+ * Add a string to the global string table associated with the DOF. The offset
+ * of the string is returned as an index into the string table.
+ */
+static dof_stridx_t
+dof_add_string(dt_dof_t *ddo, const char *s)
+{
+ dt_buf_t *bp = &ddo->ddo_strs;
+ dof_stridx_t i = dt_buf_len(bp);
+
+ if (i != 0 && (s == NULL || *s == '\0'))
+ return (0); /* string table has \0 at offset 0 */
+
+ dt_buf_write(ddo->ddo_hdl, bp, s, strlen(s) + 1, sizeof (char));
+ return (i);
+}
+
+static dof_attr_t
+dof_attr(const dtrace_attribute_t *ap)
+{
+ return (DOF_ATTR(ap->dtat_name, ap->dtat_data, ap->dtat_class));
+}
+
+static dof_secidx_t
+dof_add_difo(dt_dof_t *ddo, const dtrace_difo_t *dp)
+{
+ dof_secidx_t dsecs[5]; /* enough for all possible DIFO sections */
+ uint_t nsecs = 0;
+
+ dof_difohdr_t *dofd;
+ dof_relohdr_t dofr;
+ dof_secidx_t relsec;
+
+ dof_secidx_t strsec = DOF_SECIDX_NONE;
+ dof_secidx_t intsec = DOF_SECIDX_NONE;
+ dof_secidx_t hdrsec = DOF_SECIDX_NONE;
+
+ if (dp->dtdo_buf != NULL) {
+ dsecs[nsecs++] = dof_add_lsect(ddo, dp->dtdo_buf,
+ DOF_SECT_DIF, sizeof (dif_instr_t), 0,
+ sizeof (dif_instr_t), sizeof (dif_instr_t) * dp->dtdo_len);
+ }
+
+ if (dp->dtdo_inttab != NULL) {
+ dsecs[nsecs++] = intsec = dof_add_lsect(ddo, dp->dtdo_inttab,
+ DOF_SECT_INTTAB, sizeof (uint64_t), 0,
+ sizeof (uint64_t), sizeof (uint64_t) * dp->dtdo_intlen);
+ }
+
+ if (dp->dtdo_strtab != NULL) {
+ dsecs[nsecs++] = strsec = dof_add_lsect(ddo, dp->dtdo_strtab,
+ DOF_SECT_STRTAB, sizeof (char), 0, 0, dp->dtdo_strlen);
+ }
+
+ if (dp->dtdo_vartab != NULL) {
+ dsecs[nsecs++] = dof_add_lsect(ddo, dp->dtdo_vartab,
+ DOF_SECT_VARTAB, sizeof (uint_t), 0, sizeof (dtrace_difv_t),
+ sizeof (dtrace_difv_t) * dp->dtdo_varlen);
+ }
+
+ if (dp->dtdo_xlmtab != NULL) {
+ dof_xlref_t *xlt, *xlp;
+ dt_node_t **pnp;
+
+ xlt = alloca(sizeof (dof_xlref_t) * dp->dtdo_xlmlen);
+ pnp = dp->dtdo_xlmtab;
+
+ /*
+ * dtdo_xlmtab contains pointers to the translator members.
+ * The translator itself is in sect ddo_xlimport[dxp->dx_id].
+ * The XLMEMBERS entries are in order by their dn_membid, so
+ * the member section offset is the population count of bits
+ * in ddo_pgp->dp_xlrefs[] up to and not including dn_membid.
+ */
+ for (xlp = xlt; xlp < xlt + dp->dtdo_xlmlen; xlp++) {
+ dt_node_t *dnp = *pnp++;
+ dt_xlator_t *dxp = dnp->dn_membexpr->dn_xlator;
+
+ xlp->dofxr_xlator = ddo->ddo_xlimport[dxp->dx_id];
+ xlp->dofxr_member = dt_popcb(
+ ddo->ddo_pgp->dp_xrefs[dxp->dx_id], dnp->dn_membid);
+ xlp->dofxr_argn = (uint32_t)dxp->dx_arg;
+ }
+
+ dsecs[nsecs++] = dof_add_lsect(ddo, xlt, DOF_SECT_XLTAB,
+ sizeof (dof_secidx_t), 0, sizeof (dof_xlref_t),
+ sizeof (dof_xlref_t) * dp->dtdo_xlmlen);
+ }
+
+ /*
+ * Copy the return type and the array of section indices that form the
+ * DIFO into a single dof_difohdr_t and then add DOF_SECT_DIFOHDR.
+ */
+ assert(nsecs <= sizeof (dsecs) / sizeof (dsecs[0]));
+ dofd = alloca(sizeof (dtrace_diftype_t) + sizeof (dsecs));
+ bcopy(&dp->dtdo_rtype, &dofd->dofd_rtype, sizeof (dtrace_diftype_t));
+ bcopy(dsecs, &dofd->dofd_links, sizeof (dof_secidx_t) * nsecs);
+
+ hdrsec = dof_add_lsect(ddo, dofd, DOF_SECT_DIFOHDR,
+ sizeof (dof_secidx_t), 0, 0,
+ sizeof (dtrace_diftype_t) + sizeof (dof_secidx_t) * nsecs);
+
+ /*
+ * Add any other sections related to dtrace_difo_t. These are not
+ * referenced in dof_difohdr_t because they are not used by emulation.
+ */
+ if (dp->dtdo_kreltab != NULL) {
+ relsec = dof_add_lsect(ddo, dp->dtdo_kreltab, DOF_SECT_RELTAB,
+ sizeof (uint64_t), 0, sizeof (dof_relodesc_t),
+ sizeof (dof_relodesc_t) * dp->dtdo_krelen);
+
+ /*
+ * This code assumes the target of all relocations is the
+ * integer table 'intsec' (DOF_SECT_INTTAB). If other sections
+ * need relocation in the future this will need to change.
+ */
+ dofr.dofr_strtab = strsec;
+ dofr.dofr_relsec = relsec;
+ dofr.dofr_tgtsec = intsec;
+
+ (void) dof_add_lsect(ddo, &dofr, DOF_SECT_KRELHDR,
+ sizeof (dof_secidx_t), 0, 0, sizeof (dof_relohdr_t));
+ }
+
+ if (dp->dtdo_ureltab != NULL) {
+ relsec = dof_add_lsect(ddo, dp->dtdo_ureltab, DOF_SECT_RELTAB,
+ sizeof (uint64_t), 0, sizeof (dof_relodesc_t),
+ sizeof (dof_relodesc_t) * dp->dtdo_urelen);
+
+ /*
+ * This code assumes the target of all relocations is the
+ * integer table 'intsec' (DOF_SECT_INTTAB). If other sections
+ * need relocation in the future this will need to change.
+ */
+ dofr.dofr_strtab = strsec;
+ dofr.dofr_relsec = relsec;
+ dofr.dofr_tgtsec = intsec;
+
+ (void) dof_add_lsect(ddo, &dofr, DOF_SECT_URELHDR,
+ sizeof (dof_secidx_t), 0, 0, sizeof (dof_relohdr_t));
+ }
+
+ return (hdrsec);
+}
+
+static void
+dof_add_translator(dt_dof_t *ddo, const dt_xlator_t *dxp, uint_t type)
+{
+ dtrace_hdl_t *dtp = ddo->ddo_hdl;
+ dof_xlmember_t dofxm;
+ dof_xlator_t dofxl;
+ dof_secidx_t *xst;
+
+ char buf[DT_TYPE_NAMELEN];
+ dt_node_t *dnp;
+ uint_t i = 0;
+
+ assert(type == DOF_SECT_XLIMPORT || type == DOF_SECT_XLEXPORT);
+ xst = type == DOF_SECT_XLIMPORT ? ddo->ddo_xlimport : ddo->ddo_xlexport;
+
+ if (xst[dxp->dx_id] != DOF_SECIDX_NONE)
+ return; /* translator has already been emitted */
+
+ dt_buf_reset(dtp, &ddo->ddo_xlms);
+
+ /*
+ * Generate an array of dof_xlmember_t's into ddo_xlms. If we are
+ * importing the translator, add only those members referenced by the
+ * program and set the dofxm_difo reference of each member to NONE. If
+ * we're exporting the translator, add all members and a DIFO for each.
+ */
+ for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list, i++) {
+ if (type == DOF_SECT_XLIMPORT) {
+ if (!BT_TEST(ddo->ddo_pgp->dp_xrefs[dxp->dx_id], i))
+ continue; /* member is not referenced */
+ dofxm.dofxm_difo = DOF_SECIDX_NONE;
+ } else {
+ dofxm.dofxm_difo = dof_add_difo(ddo,
+ dxp->dx_membdif[dnp->dn_membid]);
+ }
+
+ dofxm.dofxm_name = dof_add_string(ddo, dnp->dn_membname);
+ dt_node_diftype(dtp, dnp, &dofxm.dofxm_type);
+
+ dt_buf_write(dtp, &ddo->ddo_xlms,
+ &dofxm, sizeof (dofxm), sizeof (uint32_t));
+ }
+
+ dofxl.dofxl_members = dof_add_lsect(ddo, NULL, DOF_SECT_XLMEMBERS,
+ sizeof (uint32_t), 0, sizeof (dofxm), dt_buf_len(&ddo->ddo_xlms));
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_xlms, sizeof (uint32_t));
+
+ dofxl.dofxl_strtab = ddo->ddo_strsec;
+ dofxl.dofxl_argv = dof_add_string(ddo, ctf_type_name(
+ dxp->dx_src_ctfp, dxp->dx_src_type, buf, sizeof (buf)));
+ dofxl.dofxl_argc = 1;
+ dofxl.dofxl_type = dof_add_string(ddo, ctf_type_name(
+ dxp->dx_dst_ctfp, dxp->dx_dst_type, buf, sizeof (buf)));
+ dofxl.dofxl_attr = dof_attr(&dxp->dx_souid.di_attr);
+
+ xst[dxp->dx_id] = dof_add_lsect(ddo, &dofxl, type,
+ sizeof (uint32_t), 0, 0, sizeof (dofxl));
+}
+
+/*ARGSUSED*/
+static int
+dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
+{
+ dt_dof_t *ddo = data;
+ dtrace_hdl_t *dtp = ddo->ddo_hdl;
+ dt_probe_t *prp = idp->di_data;
+
+ dof_probe_t dofpr;
+ dof_relodesc_t dofr;
+ dt_probe_instance_t *pip;
+ dt_node_t *dnp;
+
+ char buf[DT_TYPE_NAMELEN];
+ uint_t i;
+
+ dofpr.dofpr_addr = 0;
+ dofpr.dofpr_name = dof_add_string(ddo, prp->pr_name);
+ dofpr.dofpr_nargv = dt_buf_len(&ddo->ddo_strs);
+
+ for (dnp = prp->pr_nargs; dnp != NULL; dnp = dnp->dn_list) {
+ (void) dof_add_string(ddo, ctf_type_name(dnp->dn_ctfp,
+ dnp->dn_type, buf, sizeof (buf)));
+ }
+
+ dofpr.dofpr_xargv = dt_buf_len(&ddo->ddo_strs);
+
+ for (dnp = prp->pr_xargs; dnp != NULL; dnp = dnp->dn_list) {
+ (void) dof_add_string(ddo, ctf_type_name(dnp->dn_ctfp,
+ dnp->dn_type, buf, sizeof (buf)));
+ }
+
+ dofpr.dofpr_argidx = dt_buf_len(&ddo->ddo_args) / sizeof (uint8_t);
+
+ for (i = 0; i < prp->pr_xargc; i++) {
+ dt_buf_write(dtp, &ddo->ddo_args, &prp->pr_mapping[i],
+ sizeof (uint8_t), sizeof (uint8_t));
+ }
+
+ dofpr.dofpr_nargc = prp->pr_nargc;
+ dofpr.dofpr_xargc = prp->pr_xargc;
+ dofpr.dofpr_pad1 = 0;
+ dofpr.dofpr_pad2 = 0;
+
+ for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
+ dt_dprintf("adding probe for %s:%s\n", pip->pi_fname,
+ prp->pr_name);
+
+ dofpr.dofpr_func = dof_add_string(ddo, pip->pi_fname);
+
+ /*
+ * There should be one probe offset or is-enabled probe offset
+ * or else this probe instance won't have been created. The
+ * kernel will reject DOF which has a probe with no offsets.
+ */
+ assert(pip->pi_noffs + pip->pi_nenoffs > 0);
+
+ dofpr.dofpr_offidx =
+ dt_buf_len(&ddo->ddo_offs) / sizeof (uint32_t);
+ dofpr.dofpr_noffs = pip->pi_noffs;
+ dt_buf_write(dtp, &ddo->ddo_offs, pip->pi_offs,
+ pip->pi_noffs * sizeof (uint32_t), sizeof (uint32_t));
+
+ dofpr.dofpr_enoffidx =
+ dt_buf_len(&ddo->ddo_enoffs) / sizeof (uint32_t);
+ dofpr.dofpr_nenoffs = pip->pi_nenoffs;
+ dt_buf_write(dtp, &ddo->ddo_enoffs, pip->pi_enoffs,
+ pip->pi_nenoffs * sizeof (uint32_t), sizeof (uint32_t));
+
+ /*
+ * If pi_rname isn't set, the relocation will be against the
+ * function name. If it is, the relocation will be against
+ * pi_rname. This will be used if the function is scoped
+ * locally so an alternate symbol is added for the purpose
+ * of this relocation.
+ */
+ if (pip->pi_rname[0] == '\0')
+ dofr.dofr_name = dofpr.dofpr_func;
+ else
+ dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);
+ dofr.dofr_type = DOF_RELO_SETX;
+ dofr.dofr_offset = dt_buf_len(&ddo->ddo_probes);
+ dofr.dofr_data = 0;
+
+ dt_buf_write(dtp, &ddo->ddo_rels, &dofr,
+ sizeof (dofr), sizeof (uint64_t));
+
+ dt_buf_write(dtp, &ddo->ddo_probes, &dofpr,
+ sizeof (dofpr), sizeof (uint64_t));
+ }
+
+ return (0);
+}
+
+static void
+dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
+{
+ dtrace_hdl_t *dtp = ddo->ddo_hdl;
+ dof_provider_t dofpv;
+ dof_relohdr_t dofr;
+ dof_secidx_t *dofs;
+ ulong_t xr, nxr;
+ size_t sz;
+ id_t i;
+
+ if (pvp->pv_flags & DT_PROVIDER_IMPL)
+ return; /* ignore providers that are exported by dtrace(7D) */
+
+ nxr = dt_popcb(pvp->pv_xrefs, pvp->pv_xrmax);
+ dofs = alloca(sizeof (dof_secidx_t) * (nxr + 1));
+ xr = 1; /* reserve dofs[0] for the provider itself */
+
+ /*
+ * For each translator referenced by the provider (pv_xrefs), emit an
+ * exported translator section for it if one hasn't been created yet.
+ */
+ for (i = 0; i < pvp->pv_xrmax; i++) {
+ if (BT_TEST(pvp->pv_xrefs, i) &&
+ dtp->dt_xlatemode == DT_XL_DYNAMIC) {
+ dof_add_translator(ddo,
+ dt_xlator_lookup_id(dtp, i), DOF_SECT_XLEXPORT);
+ dofs[xr++] = ddo->ddo_xlexport[i];
+ }
+ }
+
+ dt_buf_reset(dtp, &ddo->ddo_probes);
+ dt_buf_reset(dtp, &ddo->ddo_args);
+ dt_buf_reset(dtp, &ddo->ddo_offs);
+ dt_buf_reset(dtp, &ddo->ddo_enoffs);
+ dt_buf_reset(dtp, &ddo->ddo_rels);
+
+ (void) dt_idhash_iter(pvp->pv_probes, dof_add_probe, ddo);
+
+ dofpv.dofpv_probes = dof_add_lsect(ddo, NULL, DOF_SECT_PROBES,
+ sizeof (uint64_t), 0, sizeof (dof_probe_t),
+ dt_buf_len(&ddo->ddo_probes));
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata,
+ &ddo->ddo_probes, sizeof (uint64_t));
+
+ dofpv.dofpv_prargs = dof_add_lsect(ddo, NULL, DOF_SECT_PRARGS,
+ sizeof (uint8_t), 0, sizeof (uint8_t), dt_buf_len(&ddo->ddo_args));
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_args, sizeof (uint8_t));
+
+ dofpv.dofpv_proffs = dof_add_lsect(ddo, NULL, DOF_SECT_PROFFS,
+ sizeof (uint_t), 0, sizeof (uint_t), dt_buf_len(&ddo->ddo_offs));
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_offs, sizeof (uint_t));
+
+ if ((sz = dt_buf_len(&ddo->ddo_enoffs)) != 0) {
+ dofpv.dofpv_prenoffs = dof_add_lsect(ddo, NULL,
+ DOF_SECT_PRENOFFS, sizeof (uint_t), 0, sizeof (uint_t), sz);
+ } else {
+ dofpv.dofpv_prenoffs = DOF_SECT_NONE;
+ }
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_enoffs, sizeof (uint_t));
+
+ dofpv.dofpv_strtab = ddo->ddo_strsec;
+ dofpv.dofpv_name = dof_add_string(ddo, pvp->pv_desc.dtvd_name);
+
+ dofpv.dofpv_provattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_provider);
+ dofpv.dofpv_modattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_mod);
+ dofpv.dofpv_funcattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_func);
+ dofpv.dofpv_nameattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_name);
+ dofpv.dofpv_argsattr = dof_attr(&pvp->pv_desc.dtvd_attr.dtpa_args);
+
+ dofs[0] = dof_add_lsect(ddo, &dofpv, DOF_SECT_PROVIDER,
+ sizeof (dof_secidx_t), 0, 0, sizeof (dof_provider_t));
+
+ dofr.dofr_strtab = dofpv.dofpv_strtab;
+ dofr.dofr_tgtsec = dofpv.dofpv_probes;
+ dofr.dofr_relsec = dof_add_lsect(ddo, NULL, DOF_SECT_RELTAB,
+ sizeof (uint64_t), 0, sizeof (dof_relodesc_t),
+ dt_buf_len(&ddo->ddo_rels));
+
+ dt_buf_concat(dtp, &ddo->ddo_ldata, &ddo->ddo_rels, sizeof (uint64_t));
+
+ (void) dof_add_lsect(ddo, &dofr, DOF_SECT_URELHDR,
+ sizeof (dof_secidx_t), 0, 0, sizeof (dof_relohdr_t));
+
+ if (nxr != 0 && dtp->dt_xlatemode == DT_XL_DYNAMIC) {
+ (void) dof_add_lsect(ddo, dofs, DOF_SECT_PREXPORT,
+ sizeof (dof_secidx_t), 0, sizeof (dof_secidx_t),
+ sizeof (dof_secidx_t) * (nxr + 1));
+ }
+}
+
+static int
+dof_hdr(dtrace_hdl_t *dtp, uint8_t dofversion, dof_hdr_t *hp)
+{
+ /*
+ * If our config values cannot fit in a uint8_t, we can't generate a
+ * DOF header since the values won't fit. This can only happen if the
+ * user forcibly compiles a program with an artificial configuration.
+ */
+ if (dtp->dt_conf.dtc_difversion > UINT8_MAX ||
+ dtp->dt_conf.dtc_difintregs > UINT8_MAX ||
+ dtp->dt_conf.dtc_diftupregs > UINT8_MAX)
+ return (dt_set_errno(dtp, EOVERFLOW));
+
+ bzero(hp, sizeof (dof_hdr_t));
+
+ hp->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
+ hp->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
+ hp->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
+ hp->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
+
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
+ hp->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_LP64;
+ else
+ hp->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_ILP32;
+
+ hp->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
+ hp->dofh_ident[DOF_ID_VERSION] = dofversion;
+ hp->dofh_ident[DOF_ID_DIFVERS] = dtp->dt_conf.dtc_difversion;
+ hp->dofh_ident[DOF_ID_DIFIREG] = dtp->dt_conf.dtc_difintregs;
+ hp->dofh_ident[DOF_ID_DIFTREG] = dtp->dt_conf.dtc_diftupregs;
+
+ hp->dofh_hdrsize = sizeof (dof_hdr_t);
+ hp->dofh_secsize = sizeof (dof_sec_t);
+ hp->dofh_secoff = sizeof (dof_hdr_t);
+
+ return (0);
+}
+
+void *
+dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags)
+{
+ dt_dof_t *ddo = &dtp->dt_dof;
+
+ const dtrace_ecbdesc_t *edp, *last;
+ const dtrace_probedesc_t *pdp;
+ const dtrace_actdesc_t *ap;
+ const dt_stmt_t *stp;
+
+ uint_t maxacts = 0;
+ uint_t maxfmt = 0;
+
+ dt_provider_t *pvp;
+ dt_xlator_t *dxp;
+ dof_actdesc_t *dofa;
+ dof_sec_t *sp;
+ size_t ssize, lsize;
+ dof_hdr_t h;
+
+ dt_buf_t dof;
+ char *fmt;
+ uint_t i;
+
+ if (flags & ~DTRACE_D_MASK) {
+ (void) dt_set_errno(dtp, EINVAL);
+ return (NULL);
+ }
+
+ flags |= dtp->dt_dflags;
+
+ if (dof_hdr(dtp, pgp->dp_dofversion, &h) != 0)
+ return (NULL);
+
+ if (dt_dof_reset(dtp, pgp) != 0)
+ return (NULL);
+
+ /*
+ * Iterate through the statement list computing the maximum number of
+ * actions and the maximum format string for allocating local buffers.
+ */
+ for (last = NULL, stp = dt_list_next(&pgp->dp_stmts);
+ stp != NULL; stp = dt_list_next(stp), last = edp) {
+
+ dtrace_stmtdesc_t *sdp = stp->ds_desc;
+ dtrace_actdesc_t *ap = sdp->dtsd_action;
+
+ if (sdp->dtsd_fmtdata != NULL) {
+ i = dtrace_printf_format(dtp,
+ sdp->dtsd_fmtdata, NULL, 0);
+ maxfmt = MAX(maxfmt, i);
+ }
+
+ if ((edp = sdp->dtsd_ecbdesc) == last)
+ continue; /* same ecb as previous statement */
+
+ for (i = 0, ap = edp->dted_action; ap; ap = ap->dtad_next)
+ i++;
+
+ maxacts = MAX(maxacts, i);
+ }
+
+ dofa = alloca(sizeof (dof_actdesc_t) * maxacts);
+ fmt = alloca(maxfmt + 1);
+
+ ddo->ddo_strsec = dof_add_lsect(ddo, NULL, DOF_SECT_STRTAB, 1, 0, 0, 0);
+ (void) dof_add_string(ddo, "");
+
+ /*
+ * If there are references to dynamic translators in the program, add
+ * an imported translator table entry for each referenced translator.
+ */
+ if (pgp->dp_xrefslen != 0) {
+ for (dxp = dt_list_next(&dtp->dt_xlators);
+ dxp != NULL; dxp = dt_list_next(dxp)) {
+ if (dxp->dx_id < pgp->dp_xrefslen &&
+ pgp->dp_xrefs[dxp->dx_id] != NULL)
+ dof_add_translator(ddo, dxp, DOF_SECT_XLIMPORT);
+ }
+ }
+
+ /*
+ * Now iterate through the statement list, creating the DOF section
+ * headers and data for each one and adding them to our buffers.
+ */
+ for (last = NULL, stp = dt_list_next(&pgp->dp_stmts);
+ stp != NULL; stp = dt_list_next(stp), last = edp) {
+
+ dof_secidx_t probesec = DOF_SECIDX_NONE;
+ dof_secidx_t prdsec = DOF_SECIDX_NONE;
+ dof_secidx_t actsec = DOF_SECIDX_NONE;
+
+ const dt_stmt_t *next = stp;
+ dtrace_stmtdesc_t *sdp = stp->ds_desc;
+ dof_stridx_t strndx = 0;
+ dof_probedesc_t dofp;
+ dof_ecbdesc_t dofe;
+ uint_t i;
+
+ if ((edp = stp->ds_desc->dtsd_ecbdesc) == last)
+ continue; /* same ecb as previous statement */
+
+ pdp = &edp->dted_probe;
+
+ /*
+ * Add a DOF_SECT_PROBEDESC for the ECB's probe description,
+ * and copy the probe description strings into the string table.
+ */
+ dofp.dofp_strtab = ddo->ddo_strsec;
+ dofp.dofp_provider = dof_add_string(ddo, pdp->dtpd_provider);
+ dofp.dofp_mod = dof_add_string(ddo, pdp->dtpd_mod);
+ dofp.dofp_func = dof_add_string(ddo, pdp->dtpd_func);
+ dofp.dofp_name = dof_add_string(ddo, pdp->dtpd_name);
+ dofp.dofp_id = pdp->dtpd_id;
+
+ probesec = dof_add_lsect(ddo, &dofp, DOF_SECT_PROBEDESC,
+ sizeof (dof_secidx_t), 0,
+ sizeof (dof_probedesc_t), sizeof (dof_probedesc_t));
+
+ /*
+ * If there is a predicate DIFO associated with the ecbdesc,
+ * write out the DIFO sections and save the DIFO section index.
+ */
+ if (edp->dted_pred.dtpdd_difo != NULL)
+ prdsec = dof_add_difo(ddo, edp->dted_pred.dtpdd_difo);
+
+ /*
+ * Now iterate through the action list generating DIFOs as
+ * referenced therein and adding action descriptions to 'dofa'.
+ */
+ for (i = 0, ap = edp->dted_action;
+ ap != NULL; ap = ap->dtad_next, i++) {
+
+ if (ap->dtad_difo != NULL) {
+ dofa[i].dofa_difo =
+ dof_add_difo(ddo, ap->dtad_difo);
+ } else
+ dofa[i].dofa_difo = DOF_SECIDX_NONE;
+
+ /*
+ * If the first action in a statement has string data,
+ * add the string to the global string table. This can
+ * be due either to a printf() format string
+ * (dtsd_fmtdata) or a print() type string
+ * (dtsd_strdata).
+ */
+ if (sdp != NULL && ap == sdp->dtsd_action) {
+ if (sdp->dtsd_fmtdata != NULL) {
+ (void) dtrace_printf_format(dtp,
+ sdp->dtsd_fmtdata, fmt, maxfmt + 1);
+ strndx = dof_add_string(ddo, fmt);
+ } else if (sdp->dtsd_strdata != NULL) {
+ strndx = dof_add_string(ddo,
+ sdp->dtsd_strdata);
+ } else {
+ strndx = 0; /* use dtad_arg instead */
+ }
+
+ if ((next = dt_list_next(next)) != NULL)
+ sdp = next->ds_desc;
+ else
+ sdp = NULL;
+ }
+
+ if (strndx != 0) {
+ dofa[i].dofa_arg = strndx;
+ dofa[i].dofa_strtab = ddo->ddo_strsec;
+ } else {
+ dofa[i].dofa_arg = ap->dtad_arg;
+ dofa[i].dofa_strtab = DOF_SECIDX_NONE;
+ }
+
+ dofa[i].dofa_kind = ap->dtad_kind;
+ dofa[i].dofa_ntuple = ap->dtad_ntuple;
+ dofa[i].dofa_uarg = ap->dtad_uarg;
+ }
+
+ if (i > 0) {
+ actsec = dof_add_lsect(ddo, dofa, DOF_SECT_ACTDESC,
+ sizeof (uint64_t), 0, sizeof (dof_actdesc_t),
+ sizeof (dof_actdesc_t) * i);
+ }
+
+ /*
+ * Now finally, add the DOF_SECT_ECBDESC referencing all the
+ * previously created sub-sections.
+ */
+ dofe.dofe_probes = probesec;
+ dofe.dofe_pred = prdsec;
+ dofe.dofe_actions = actsec;
+ dofe.dofe_pad = 0;
+ dofe.dofe_uarg = edp->dted_uarg;
+
+ (void) dof_add_lsect(ddo, &dofe, DOF_SECT_ECBDESC,
+ sizeof (uint64_t), 0, 0, sizeof (dof_ecbdesc_t));
+ }
+
+ /*
+ * If any providers are user-defined, output DOF sections corresponding
+ * to the providers and the probes and arguments that they define.
+ */
+ if (flags & DTRACE_D_PROBES) {
+ for (pvp = dt_list_next(&dtp->dt_provlist);
+ pvp != NULL; pvp = dt_list_next(pvp))
+ dof_add_provider(ddo, pvp);
+ }
+
+ /*
+ * If we're not stripping unloadable sections, generate compiler
+ * comments and any other unloadable miscellany.
+ */
+ if (!(flags & DTRACE_D_STRIP)) {
+ (void) dof_add_usect(ddo, _dtrace_version, DOF_SECT_COMMENTS,
+ sizeof (char), 0, 0, strlen(_dtrace_version) + 1);
+ (void) dof_add_usect(ddo, &dtp->dt_uts, DOF_SECT_UTSNAME,
+ sizeof (char), 0, 0, sizeof (struct utsname));
+ }
+
+ /*
+ * Compute and fill in the appropriate values for the dof_hdr_t's
+ * dofh_secnum, dofh_loadsz, and dofh_filez values.
+ */
+ h.dofh_secnum = ddo->ddo_nsecs;
+ ssize = sizeof (h) + dt_buf_len(&ddo->ddo_secs);
+
+ h.dofh_loadsz = ssize +
+ dt_buf_len(&ddo->ddo_ldata) +
+ dt_buf_len(&ddo->ddo_strs);
+
+ if (dt_buf_len(&ddo->ddo_udata) != 0) {
+ lsize = roundup(h.dofh_loadsz, sizeof (uint64_t));
+ h.dofh_filesz = lsize + dt_buf_len(&ddo->ddo_udata);
+ } else {
+ lsize = h.dofh_loadsz;
+ h.dofh_filesz = lsize;
+ }
+
+ /*
+ * Set the global DOF_SECT_STRTAB's offset to be after the header,
+ * section headers, and other loadable data. Since we're going to
+ * iterate over the buffer data directly, we must check for errors.
+ */
+ if ((i = dt_buf_error(&ddo->ddo_secs)) != 0) {
+ (void) dt_set_errno(dtp, i);
+ return (NULL);
+ }
+
+ sp = dt_buf_ptr(&ddo->ddo_secs);
+ assert(sp[ddo->ddo_strsec].dofs_type == DOF_SECT_STRTAB);
+ assert(ssize == sizeof (h) + sizeof (dof_sec_t) * ddo->ddo_nsecs);
+
+ sp[ddo->ddo_strsec].dofs_offset = ssize + dt_buf_len(&ddo->ddo_ldata);
+ sp[ddo->ddo_strsec].dofs_size = dt_buf_len(&ddo->ddo_strs);
+
+ /*
+ * Now relocate all the other section headers by adding the appropriate
+ * delta to their respective dofs_offset values.
+ */
+ for (i = 0; i < ddo->ddo_nsecs; i++, sp++) {
+ if (i == ddo->ddo_strsec)
+ continue; /* already relocated above */
+
+ if (sp->dofs_flags & DOF_SECF_LOAD)
+ sp->dofs_offset += ssize;
+ else
+ sp->dofs_offset += lsize;
+ }
+
+ /*
+ * Finally, assemble the complete in-memory DOF buffer by writing the
+ * header and then concatenating all our buffers. dt_buf_concat() will
+ * propagate any errors and cause dt_buf_claim() to return NULL.
+ */
+ dt_buf_create(dtp, &dof, "dof", h.dofh_filesz);
+
+ dt_buf_write(dtp, &dof, &h, sizeof (h), sizeof (uint64_t));
+ dt_buf_concat(dtp, &dof, &ddo->ddo_secs, sizeof (uint64_t));
+ dt_buf_concat(dtp, &dof, &ddo->ddo_ldata, sizeof (uint64_t));
+ dt_buf_concat(dtp, &dof, &ddo->ddo_strs, sizeof (char));
+ dt_buf_concat(dtp, &dof, &ddo->ddo_udata, sizeof (uint64_t));
+
+ return (dt_buf_claim(dtp, &dof));
+}
+
+void
+dtrace_dof_destroy(dtrace_hdl_t *dtp, void *dof)
+{
+ dt_free(dtp, dof);
+}
+
+void *
+dtrace_getopt_dof(dtrace_hdl_t *dtp)
+{
+ dof_hdr_t *dof;
+ dof_sec_t *sec;
+ dof_optdesc_t *dofo;
+ int i, nopts = 0, len = sizeof (dof_hdr_t) +
+ roundup(sizeof (dof_sec_t), sizeof (uint64_t));
+
+ for (i = 0; i < DTRACEOPT_MAX; i++) {
+ if (dtp->dt_options[i] != DTRACEOPT_UNSET)
+ nopts++;
+ }
+
+ len += sizeof (dof_optdesc_t) * nopts;
+
+ if ((dof = dt_zalloc(dtp, len)) == NULL ||
+ dof_hdr(dtp, DOF_VERSION, dof) != 0) {
+ dt_free(dtp, dof);
+ return (NULL);
+ }
+
+ dof->dofh_secnum = 1; /* only DOF_SECT_OPTDESC */
+ dof->dofh_loadsz = len;
+ dof->dofh_filesz = len;
+
+ /*
+ * Fill in the option section header...
+ */
+ sec = (dof_sec_t *)((uintptr_t)dof + sizeof (dof_hdr_t));
+ sec->dofs_type = DOF_SECT_OPTDESC;
+ sec->dofs_align = sizeof (uint64_t);
+ sec->dofs_flags = DOF_SECF_LOAD;
+ sec->dofs_entsize = sizeof (dof_optdesc_t);
+
+ dofo = (dof_optdesc_t *)((uintptr_t)sec +
+ roundup(sizeof (dof_sec_t), sizeof (uint64_t)));
+
+ sec->dofs_offset = (uintptr_t)dofo - (uintptr_t)dof;
+ sec->dofs_size = sizeof (dof_optdesc_t) * nopts;
+
+ for (i = 0; i < DTRACEOPT_MAX; i++) {
+ if (dtp->dt_options[i] == DTRACEOPT_UNSET)
+ continue;
+
+ dofo->dofo_option = i;
+ dofo->dofo_strtab = DOF_SECIDX_NONE;
+ dofo->dofo_value = dtp->dt_options[i];
+ dofo++;
+ }
+
+ return (dof);
+}
+
+void *
+dtrace_geterr_dof(dtrace_hdl_t *dtp)
+{
+ if (dtp->dt_errprog != NULL)
+ return (dtrace_dof_create(dtp, dtp->dt_errprog, 0));
+
+ (void) dt_set_errno(dtp, EDT_BADERROR);
+ return (NULL);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.h
new file mode 100644
index 0000000..e0a4bf5
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_DOF_H
+#define _DT_DOF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dtrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dt_buf.h>
+
+typedef struct dt_dof {
+ dtrace_hdl_t *ddo_hdl; /* libdtrace handle */
+ dtrace_prog_t *ddo_pgp; /* current program */
+ uint_t ddo_nsecs; /* number of sections */
+ dof_secidx_t ddo_strsec; /* global strings section index */
+ dof_secidx_t *ddo_xlimport; /* imported xlator section indices */
+ dof_secidx_t *ddo_xlexport; /* exported xlator section indices */
+ dt_buf_t ddo_secs; /* section headers */
+ dt_buf_t ddo_strs; /* global strings */
+ dt_buf_t ddo_ldata; /* loadable section data */
+ dt_buf_t ddo_udata; /* unloadable section data */
+ dt_buf_t ddo_probes; /* probe section data */
+ dt_buf_t ddo_args; /* probe arguments section data */
+ dt_buf_t ddo_offs; /* probe offsets section data */
+ dt_buf_t ddo_enoffs; /* is-enabled offsets section data */
+ dt_buf_t ddo_rels; /* probe relocation section data */
+ dt_buf_t ddo_xlms; /* xlate members section data */
+} dt_dof_t;
+
+extern void dt_dof_init(dtrace_hdl_t *);
+extern void dt_dof_fini(dtrace_hdl_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_DOF_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
new file mode 100644
index 0000000..a28505c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
@@ -0,0 +1,234 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <string.h>
+#include <strings.h>
+#include <dt_impl.h>
+
+static const struct {
+ int err;
+ const char *msg;
+} _dt_errlist[] = {
+ { EDT_VERSION, "Client requested version newer than library" },
+ { EDT_VERSINVAL, "Version is not properly formatted or is too large" },
+ { EDT_VERSUNDEF, "Requested version is not supported by compiler" },
+ { EDT_VERSREDUCED, "Requested version conflicts with earlier setting" },
+ { EDT_CTF, "Unexpected libctf error" },
+ { EDT_COMPILER, "Error in D program compilation" },
+ { EDT_NOREG, "Insufficient registers to generate code" },
+ { EDT_NOTUPREG, "Insufficient tuple registers to generate code" },
+ { EDT_NOMEM, "Memory allocation failure" },
+ { EDT_INT2BIG, "Integer constant table limit exceeded" },
+ { EDT_STR2BIG, "String constant table limit exceeded" },
+ { EDT_NOMOD, "Unknown module name" },
+ { EDT_NOPROV, "Unknown provider name" },
+ { EDT_NOPROBE, "No probe matches description" },
+ { EDT_NOSYM, "Unknown symbol name" },
+ { EDT_NOSYMADDR, "No symbol corresponds to address" },
+ { EDT_NOTYPE, "Unknown type name" },
+ { EDT_NOVAR, "Unknown variable name" },
+ { EDT_NOAGG, "Unknown aggregation name" },
+ { EDT_BADSCOPE, "Improper use of scoping operator in type name" },
+ { EDT_BADSPEC, "Overspecified probe description" },
+ { EDT_BADSPCV, "Undefined macro variable in probe description" },
+ { EDT_BADID, "Unknown probe identifier" },
+ { EDT_NOTLOADED, "Module is no longer loaded" },
+ { EDT_NOCTF, "Module does not contain any CTF data" },
+ { EDT_DATAMODEL, "Module and program data models do not match" },
+ { EDT_DIFVERS, "Library uses newer DIF version than kernel" },
+ { EDT_BADAGG, "Unknown aggregating action" },
+ { EDT_FIO, "Error occurred while reading from input stream" },
+ { EDT_DIFINVAL, "DIF program content is invalid" },
+ { EDT_DIFSIZE, "DIF program exceeds maximum program size" },
+ { EDT_DIFFAULT, "DIF program contains invalid pointer" },
+ { EDT_BADPROBE, "Invalid probe specification" },
+ { EDT_BADPGLOB, "Probe description has too many globbing characters" },
+ { EDT_NOSCOPE, "Declaration scope stack underflow" },
+ { EDT_NODECL, "Declaration stack underflow" },
+ { EDT_DMISMATCH, "Data record list does not match statement" },
+ { EDT_DOFFSET, "Data record offset exceeds buffer boundary" },
+ { EDT_DALIGN, "Data record has inappropriate alignment" },
+ { EDT_BADOPTNAME, "Invalid option name" },
+ { EDT_BADOPTVAL, "Invalid value for specified option" },
+ { EDT_BADOPTCTX, "Option cannot be used from within a D program" },
+ { EDT_CPPFORK, "Failed to fork preprocessor" },
+ { EDT_CPPEXEC, "Failed to exec preprocessor" },
+ { EDT_CPPENT, "Preprocessor not found" },
+ { EDT_CPPERR, "Preprocessor failed to process input program" },
+ { EDT_SYMOFLOW, "Symbol table identifier space exhausted" },
+ { EDT_ACTIVE, "Operation illegal when tracing is active" },
+ { EDT_DESTRUCTIVE, "Destructive actions not allowed" },
+ { EDT_NOANON, "No anonymous tracing state" },
+ { EDT_ISANON, "Can't claim anonymous state and enable probes" },
+ { EDT_ENDTOOBIG, "END enablings exceed size of principal buffer" },
+ { EDT_NOCONV, "Failed to load type for printf conversion" },
+ { EDT_BADCONV, "Incomplete printf conversion" },
+ { EDT_BADERROR, "Invalid library ERROR action" },
+ { EDT_ERRABORT, "Abort due to error" },
+ { EDT_DROPABORT, "Abort due to drop" },
+ { EDT_DIRABORT, "Abort explicitly directed" },
+ { EDT_BADRVAL, "Invalid return value from callback" },
+ { EDT_BADNORMAL, "Invalid normalization" },
+ { EDT_BUFTOOSMALL, "Enabling exceeds size of buffer" },
+ { EDT_BADTRUNC, "Invalid truncation" },
+ { EDT_BUSY, "DTrace cannot be used when kernel debugger is active" },
+ { EDT_ACCESS, "DTrace requires additional privileges" },
+ { EDT_NOENT, "DTrace device not available on system" },
+ { EDT_BRICKED, "Abort due to systemic unresponsiveness" },
+ { EDT_HARDWIRE, "Failed to load language definitions" },
+ { EDT_ELFVERSION, "libelf is out-of-date with respect to libdtrace" },
+ { EDT_NOBUFFERED, "Attempt to buffer output without handler" },
+ { EDT_UNSTABLE, "Description matched an unstable set of probes" },
+ { EDT_BADSETOPT, "Invalid setopt() library action" },
+ { EDT_BADSTACKPC, "Invalid stack program counter size" },
+ { EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
+ { EDT_OVERSION, "Client requested deprecated version of library" },
+ { EDT_ENABLING_ERR, "Failed to enable probe" }
+};
+
+static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);
+
+const char *
+dtrace_errmsg(dtrace_hdl_t *dtp, int error)
+{
+ const char *str;
+ int i;
+
+ if (error == EDT_COMPILER && dtp != NULL && dtp->dt_errmsg[0] != '\0')
+ str = dtp->dt_errmsg;
+ else if (error == EDT_CTF && dtp != NULL && dtp->dt_ctferr != 0)
+ str = ctf_errmsg(dtp->dt_ctferr);
+ else if (error >= EDT_BASE && (error - EDT_BASE) < _dt_nerr) {
+ for (i = 0; i < _dt_nerr; i++) {
+ if (_dt_errlist[i].err == error)
+ return (_dt_errlist[i].msg);
+ }
+ str = NULL;
+ } else
+ str = strerror(error);
+
+ return (str ? str : "Unknown error");
+}
+
+int
+dtrace_errno(dtrace_hdl_t *dtp)
+{
+ return (dtp->dt_errno);
+}
+
+#if defined(sun)
+int
+dt_set_errno(dtrace_hdl_t *dtp, int err)
+{
+ dtp->dt_errno = err;
+ return (-1);
+}
+#else
+int
+_dt_set_errno(dtrace_hdl_t *dtp, int err, const char *errfile, int errline)
+{
+ dtp->dt_errno = err;
+ dtp->dt_errfile = errfile;
+ dtp->dt_errline = errline;
+ return (-1);
+}
+
+void dt_get_errloc(dtrace_hdl_t *dtp, const char **p_errfile, int *p_errline)
+{
+ *p_errfile = dtp->dt_errfile;
+ *p_errline = dtp->dt_errline;
+}
+#endif
+
+void
+dt_set_errmsg(dtrace_hdl_t *dtp, const char *errtag, const char *region,
+ const char *filename, int lineno, const char *format, va_list ap)
+{
+ size_t len, n;
+ char *p, *s;
+
+ s = dtp->dt_errmsg;
+ n = sizeof (dtp->dt_errmsg);
+
+ if (errtag != NULL && (yypcb->pcb_cflags & DTRACE_C_ETAGS))
+ (void) snprintf(s, n, "[%s] ", errtag);
+ else
+ s[0] = '\0';
+
+ len = strlen(dtp->dt_errmsg);
+ s = dtp->dt_errmsg + len;
+ n = sizeof (dtp->dt_errmsg) - len;
+
+ if (filename == NULL)
+ filename = dtp->dt_filetag;
+
+ if (filename != NULL)
+ (void) snprintf(s, n, "\"%s\", line %d: ", filename, lineno);
+ else if (lineno != 0)
+ (void) snprintf(s, n, "line %d: ", lineno);
+ else if (region != NULL)
+ (void) snprintf(s, n, "in %s: ", region);
+
+ len = strlen(dtp->dt_errmsg);
+ s = dtp->dt_errmsg + len;
+ n = sizeof (dtp->dt_errmsg) - len;
+ (void) vsnprintf(s, n, format, ap);
+
+ if ((p = strrchr(dtp->dt_errmsg, '\n')) != NULL)
+ *p = '\0'; /* remove trailing \n from message buffer */
+
+ dtp->dt_errtag = errtag;
+}
+
+/*ARGSUSED*/
+const char *
+dtrace_faultstr(dtrace_hdl_t *dtp, int fault)
+{
+ int i;
+
+ static const struct {
+ int code;
+ const char *str;
+ } faults[] = {
+ { DTRACEFLT_BADADDR, "invalid address" },
+ { DTRACEFLT_BADALIGN, "invalid alignment" },
+ { DTRACEFLT_ILLOP, "illegal operation" },
+ { DTRACEFLT_DIVZERO, "divide-by-zero" },
+ { DTRACEFLT_NOSCRATCH, "out of scratch space" },
+ { DTRACEFLT_KPRIV, "invalid kernel access" },
+ { DTRACEFLT_UPRIV, "invalid user access" },
+ { DTRACEFLT_TUPOFLOW, "tuple stack overflow" },
+ { DTRACEFLT_BADSTACK, "bad stack" },
+ { DTRACEFLT_LIBRARY, "library-level fault" },
+ { 0, NULL }
+ };
+
+ for (i = 0; faults[i].str != NULL; i++) {
+ if (faults[i].code == fault)
+ return (faults[i].str);
+ }
+
+ return ("unknown fault");
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
new file mode 100644
index 0000000..eff9f28
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
@@ -0,0 +1,275 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+ /*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#ifndef _DT_ERRTAGS_H
+#define _DT_ERRTAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This enum definition is used to define a set of error tags associated with
+ * the D compiler's various error conditions. The shell script mkerrtags.sh is
+ * used to parse this file and create a corresponding dt_errtags.c source file.
+ * If you do something other than add a new error tag here, you may need to
+ * update the mkerrtags shell script as it is based upon simple regexps.
+ */
+typedef enum {
+ D_UNKNOWN, /* unknown D compiler error */
+ D_SYNTAX, /* syntax error in input stream */
+ D_EMPTY, /* empty translation unit */
+ D_TYPE_ERR, /* type definition missing */
+ D_TYPE_MEMBER, /* type member not found */
+ D_ASRELO, /* relocation remains against symbol */
+ D_CG_EXPR, /* tracing function called from expr */
+ D_CG_DYN, /* expression returns dynamic result */
+ D_ATTR_MIN, /* attributes less than amin setting */
+ D_ID_OFLOW, /* identifier space overflow */
+ D_PDESC_ZERO, /* probedesc matches zero probes */
+ D_PDESC_INVAL, /* probedesc is not valid */
+ D_PRED_SCALAR, /* predicate must be of scalar type */
+ D_FUNC_IDENT, /* function designator is not ident */
+ D_FUNC_UNDEF, /* function ident is not defined */
+ D_FUNC_IDKIND, /* function ident is of wrong idkind */
+ D_OFFSETOF_TYPE, /* offsetof arg is not sou type */
+ D_OFFSETOF_BITFIELD, /* offsetof applied to field member */
+ D_SIZEOF_TYPE, /* invalid sizeof type */
+ D_SIZEOF_BITFIELD, /* sizeof applied to field member */
+ D_STRINGOF_TYPE, /* invalid stringof type */
+ D_OP_IDENT, /* operand must be an identifier */
+ D_OP_INT, /* operand must be integral type */
+ D_OP_SCALAR, /* operand must be scalar type */
+ D_OP_ARITH, /* operand must be arithmetic type */
+ D_OP_WRITE, /* operand must be writable variable */
+ D_OP_LVAL, /* operand must be lvalue */
+ D_OP_INCOMPAT, /* operand types are not compatible */
+ D_OP_VFPTR, /* operand cannot be void or func ptr */
+ D_OP_ARRFUN, /* operand cannot be array or func */
+ D_OP_PTR, /* operand must be a pointer */
+ D_OP_SOU, /* operand must be struct or union */
+ D_OP_INCOMPLETE, /* operand is an incomplete type */
+ D_OP_DYN, /* operand cannot be of dynamic type */
+ D_OP_ACT, /* operand cannot be action */
+ D_AGG_REDEF, /* aggregation cannot be redefined */
+ D_AGG_FUNC, /* aggregating function required */
+ D_AGG_MDIM, /* aggregation used as multi-dim arr */
+ D_ARR_BADREF, /* access non-array using tuple */
+ D_ARR_LOCAL, /* cannot define local assc array */
+ D_DIV_ZERO, /* division by zero detected */
+ D_DEREF_NONPTR, /* dereference non-pointer type */
+ D_DEREF_VOID, /* dereference void pointer */
+ D_DEREF_FUNC, /* dereference function pointer */
+ D_ADDROF_LVAL, /* unary & applied to non-lvalue */
+ D_ADDROF_VAR, /* unary & applied to variable */
+ D_ADDROF_BITFIELD, /* unary & applied to field member */
+ D_XLATE_REDECL, /* translator redeclared */
+ D_XLATE_NOCONV, /* no conversion for member defined */
+ D_XLATE_NONE, /* no translator for type combo */
+ D_XLATE_SOU, /* dst must be struct or union type */
+ D_XLATE_INCOMPAT, /* translator member type incompat */
+ D_XLATE_MEMB, /* translator member is not valid */
+ D_CAST_INVAL, /* invalid cast expression */
+ D_PRAGERR, /* #pragma error message */
+ D_PRAGCTL_INVAL, /* invalid control directive */
+ D_PRAGMA_INVAL, /* invalid compiler pragma */
+ D_PRAGMA_UNUSED, /* unused compiler pragma */
+ D_PRAGMA_MALFORM, /* malformed #pragma argument list */
+ D_PRAGMA_OPTSET, /* failed to set #pragma option */
+ D_PRAGMA_SCOPE, /* #pragma identifier scope error */
+ D_PRAGMA_DEPEND, /* #pragma dependency not satisfied */
+ D_MACRO_UNDEF, /* macro parameter is not defined */
+ D_MACRO_OFLOW, /* macro parameter integer overflow */
+ D_MACRO_UNUSED, /* macro parameter is never used */
+ D_INT_OFLOW, /* integer constant overflow */
+ D_INT_DIGIT, /* integer digit is not valid */
+ D_STR_NL, /* newline in string literal */
+ D_CHR_NL, /* newline in character constant */
+ D_CHR_NULL, /* empty character constant */
+ D_CHR_OFLOW, /* character constant is too long */
+ D_IDENT_BADREF, /* identifier expected type mismatch */
+ D_IDENT_UNDEF, /* identifier is not known/defined */
+ D_IDENT_AMBIG, /* identifier is ambiguous (var/enum) */
+ D_SYM_BADREF, /* kernel/user symbol ref mismatch */
+ D_SYM_NOTYPES, /* no CTF data available for sym ref */
+ D_SYM_MODEL, /* module/program data model mismatch */
+ D_VAR_UNDEF, /* reference to undefined variable */
+ D_VAR_UNSUP, /* unsupported variable specification */
+ D_PROTO_LEN, /* prototype length mismatch */
+ D_PROTO_ARG, /* prototype argument mismatch */
+ D_ARGS_MULTI, /* description matches unstable set */
+ D_ARGS_XLATOR, /* no args[] translator defined */
+ D_ARGS_NONE, /* no args[] available */
+ D_ARGS_TYPE, /* invalid args[] type */
+ D_ARGS_IDX, /* invalid args[] index */
+ D_REGS_IDX, /* invalid regs[] index */
+ D_KEY_TYPE, /* invalid agg or array key type */
+ D_PRINTF_DYN_PROTO, /* dynamic size argument missing */
+ D_PRINTF_DYN_TYPE, /* dynamic size type mismatch */
+ D_PRINTF_AGG_CONV, /* improper use of %@ conversion */
+ D_PRINTF_ARG_PROTO, /* conversion missing value argument */
+ D_PRINTF_ARG_TYPE, /* conversion arg has wrong type */
+ D_PRINTF_ARG_EXTRA, /* extra arguments specified */
+ D_PRINTF_ARG_FMT, /* format string is not a constant */
+ D_PRINTF_FMT_EMPTY, /* format string is empty */
+ D_DECL_CHARATTR, /* bad attributes for char decl */
+ D_DECL_VOIDATTR, /* bad attributes for void decl */
+ D_DECL_SIGNINT, /* sign/unsign with non-integer decl */
+ D_DECL_LONGINT, /* long with non-arithmetic decl */
+ D_DECL_IDENT, /* old-style declaration or bad type */
+ D_DECL_CLASS, /* more than one storage class given */
+ D_DECL_BADCLASS, /* decl class not supported in D */
+ D_DECL_PARMCLASS, /* invalid class for parameter type */
+ D_DECL_COMBO, /* bad decl specifier combination */
+ D_DECL_ARRSUB, /* const int required for array size */
+ D_DECL_ARRNULL, /* array decl requires dim or tuple */
+ D_DECL_ARRBIG, /* array size too big */
+ D_DECL_IDRED, /* decl identifier redeclared */
+ D_DECL_TYPERED, /* decl type redeclared */
+ D_DECL_MNAME, /* member name missing */
+ D_DECL_SCOPE, /* scoping operator used in decl */
+ D_DECL_BFCONST, /* bit-field requires const size expr */
+ D_DECL_BFSIZE, /* bit-field size too big for type */
+ D_DECL_BFTYPE, /* bit-field type is not valid */
+ D_DECL_ENCONST, /* enum tag requires const size expr */
+ D_DECL_ENOFLOW, /* enumerator value overflows INT_MAX */
+ D_DECL_USELESS, /* useless external declaration */
+ D_DECL_LOCASSC, /* attempt to decl local assc array */
+ D_DECL_VOIDOBJ, /* attempt to decl void object */
+ D_DECL_DYNOBJ, /* attempt to decl dynamic object */
+ D_DECL_INCOMPLETE, /* declaration uses incomplete type */
+ D_DECL_PROTO_VARARGS, /* varargs not allowed in prototype */
+ D_DECL_PROTO_TYPE, /* type not allowed in prototype */
+ D_DECL_PROTO_VOID, /* void must be sole parameter */
+ D_DECL_PROTO_NAME, /* void parameter may not have a name */
+ D_DECL_PROTO_FORM, /* parameter name has no formal */
+ D_COMM_COMM, /* commit() after commit() */
+ D_COMM_DREC, /* commit() after data action */
+ D_SPEC_SPEC, /* speculate() after speculate() */
+ D_SPEC_COMM, /* speculate() after commit() */
+ D_SPEC_DREC, /* speculate() after data action */
+ D_AGG_COMM, /* aggregating act after commit() */
+ D_AGG_SPEC, /* aggregating act after speculate() */
+ D_AGG_NULL, /* aggregation stmt has null effect */
+ D_AGG_SCALAR, /* aggregating function needs scalar */
+ D_ACT_SPEC, /* destructive action after speculate */
+ D_EXIT_SPEC, /* exit() action after speculate */
+ D_DREC_COMM, /* data action after commit() */
+ D_PRINTA_PROTO, /* printa() prototype mismatch */
+ D_PRINTA_AGGARG, /* aggregation arg type mismatch */
+ D_PRINTA_AGGBAD, /* printa() aggregation not defined */
+ D_PRINTA_AGGKEY, /* printa() aggregation key mismatch */
+ D_PRINTA_AGGPROTO, /* printa() aggregation mismatch */
+ D_TRACE_VOID, /* trace() argument has void type */
+ D_TRACE_DYN, /* trace() argument has dynamic type */
+ D_PRINT_VOID, /* print() argument has void type */
+ D_PRINT_DYN, /* print() argument has dynamic type */
+ D_TRACEMEM_ADDR, /* tracemem() address bad type */
+ D_TRACEMEM_SIZE, /* tracemem() size bad type */
+ D_TRACEMEM_ARGS, /* tracemem() illegal number of args */
+ D_TRACEMEM_DYNSIZE, /* tracemem() dynamic size bad type */
+ D_STACK_PROTO, /* stack() prototype mismatch */
+ D_STACK_SIZE, /* stack() size argument bad type */
+ D_USTACK_FRAMES, /* ustack() frames arg bad type */
+ D_USTACK_STRSIZE, /* ustack() strsize arg bad type */
+ D_USTACK_PROTO, /* ustack() prototype mismatch */
+ D_LQUANT_BASETYPE, /* lquantize() bad base type */
+ D_LQUANT_BASEVAL, /* lquantize() bad base value */
+ D_LQUANT_LIMTYPE, /* lquantize() bad limit type */
+ D_LQUANT_LIMVAL, /* lquantize() bad limit value */
+ D_LQUANT_MISMATCH, /* lquantize() limit < base */
+ D_LQUANT_STEPTYPE, /* lquantize() bad step type */
+ D_LQUANT_STEPVAL, /* lquantize() bad step value */
+ D_LQUANT_STEPLARGE, /* lquantize() step too large */
+ D_LQUANT_STEPSMALL, /* lquantize() step too small */
+ D_QUANT_PROTO, /* quantize() prototype mismatch */
+ D_PROC_OFF, /* byte offset exceeds function size */
+ D_PROC_ALIGN, /* byte offset has invalid alignment */
+ D_PROC_NAME, /* invalid process probe name */
+ D_PROC_GRAB, /* failed to grab process */
+ D_PROC_DYN, /* process is not dynamically linked */
+ D_PROC_LIB, /* invalid process library name */
+ D_PROC_FUNC, /* no such function in process */
+ D_PROC_CREATEFAIL, /* pid probe creation failed */
+ D_PROC_NODEV, /* fasttrap device is not installed */
+ D_PROC_BADPID, /* user probe pid invalid */
+ D_PROC_BADPROV, /* user probe provider invalid */
+ D_PROC_USDT, /* problem initializing usdt */
+ D_CLEAR_PROTO, /* clear() prototype mismatch */
+ D_CLEAR_AGGARG, /* aggregation arg type mismatch */
+ D_CLEAR_AGGBAD, /* clear() aggregation not defined */
+ D_NORMALIZE_PROTO, /* normalize() prototype mismatch */
+ D_NORMALIZE_SCALAR, /* normalize() value must be scalar */
+ D_NORMALIZE_AGGARG, /* aggregation arg type mismatch */
+ D_NORMALIZE_AGGBAD, /* normalize() aggregation not def. */
+ D_TRUNC_PROTO, /* trunc() prototype mismatch */
+ D_TRUNC_SCALAR, /* trunc() value must be scalar */
+ D_TRUNC_AGGARG, /* aggregation arg type mismatch */
+ D_TRUNC_AGGBAD, /* trunc() aggregation not def. */
+ D_PROV_BADNAME, /* invalid provider name */
+ D_PROV_INCOMPAT, /* provider/probe interface mismatch */
+ D_PROV_PRDUP, /* duplicate probe declaration */
+ D_PROV_PRARGLEN, /* probe argument list too long */
+ D_PROV_PRXLATOR, /* probe argument translator missing */
+ D_FREOPEN_INVALID, /* frename() filename is invalid */
+ D_LQUANT_MATCHBASE, /* lquantize() mismatch on base */
+ D_LQUANT_MATCHLIM, /* lquantize() mismatch on limit */
+ D_LQUANT_MATCHSTEP, /* lquantize() mismatch on step */
+ D_LLQUANT_FACTORTYPE, /* llquantize() bad magnitude type */
+ D_LLQUANT_FACTORVAL, /* llquantize() bad magnitude value */
+ D_LLQUANT_FACTORMATCH, /* llquantize() mismatch on magnitude */
+ D_LLQUANT_LOWTYPE, /* llquantize() bad low mag type */
+ D_LLQUANT_LOWVAL, /* llquantize() bad low mag value */
+ D_LLQUANT_LOWMATCH, /* llquantize() mismatch on low mag */
+ D_LLQUANT_HIGHTYPE, /* llquantize() bad high mag type */
+ D_LLQUANT_HIGHVAL, /* llquantize() bad high mag value */
+ D_LLQUANT_HIGHMATCH, /* llquantize() mismatch on high mag */
+ D_LLQUANT_NSTEPTYPE, /* llquantize() bad # steps type */
+ D_LLQUANT_NSTEPVAL, /* llquantize() bad # steps value */
+ D_LLQUANT_NSTEPMATCH, /* llquantize() mismatch on # steps */
+ D_LLQUANT_MAGRANGE, /* llquantize() bad magnitude range */
+ D_LLQUANT_FACTORNSTEPS, /* llquantize() # steps < factor */
+ D_LLQUANT_FACTOREVEN, /* llquantize() bad # steps/factor */
+ D_LLQUANT_FACTORSMALL, /* llquantize() magnitude too small */
+ D_LLQUANT_MAGTOOBIG, /* llquantize() high mag too large */
+ D_PRINTM_ADDR, /* printm() memref bad type */
+ D_PRINTM_SIZE, /* printm() size bad type */
+ D_PRINTT_ADDR, /* printt() typeref bad type */
+ D_PRINTT_SIZE /* printt() size bad type */
+} dt_errtag_t;
+
+extern const char *dt_errtag(dt_errtag_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_ERRTAGS_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
new file mode 100644
index 0000000..0c12623
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
@@ -0,0 +1,834 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dt_impl.h>
+
+#define OP1(op, c) dt_node_op1(op, c)
+#define OP2(op, l, r) dt_node_op2(op, l, r)
+#define OP3(x, y, z) dt_node_op3(x, y, z)
+#define LINK(l, r) dt_node_link(l, r)
+#define DUP(s) strdup(s)
+
+%}
+
+%union {
+ dt_node_t *l_node;
+ dt_decl_t *l_decl;
+ char *l_str;
+ uintmax_t l_int;
+ int l_tok;
+}
+
+%token DT_TOK_COMMA DT_TOK_ELLIPSIS
+%token DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ
+%token DT_TOK_DIV_EQ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ
+%token DT_TOK_LSH_EQ DT_TOK_RSH_EQ DT_TOK_QUESTION DT_TOK_COLON
+%token DT_TOK_LOR DT_TOK_LXOR DT_TOK_LAND
+%token DT_TOK_BOR DT_TOK_XOR DT_TOK_BAND DT_TOK_EQU DT_TOK_NEQ
+%token DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE DT_TOK_LSH DT_TOK_RSH
+%token DT_TOK_ADD DT_TOK_SUB DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
+%token DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
+%token DT_TOK_PREINC DT_TOK_POSTINC DT_TOK_PREDEC DT_TOK_POSTDEC
+%token DT_TOK_IPOS DT_TOK_INEG DT_TOK_DEREF DT_TOK_ADDROF
+%token DT_TOK_OFFSETOF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
+%token DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
+
+%token <l_str> DT_TOK_STRING
+%token <l_str> DT_TOK_IDENT
+%token <l_str> DT_TOK_PSPEC
+%token <l_str> DT_TOK_AGG
+%token <l_str> DT_TOK_TNAME
+%token <l_int> DT_TOK_INT
+
+%token DT_KEY_AUTO
+%token DT_KEY_BREAK
+%token DT_KEY_CASE
+%token DT_KEY_CHAR
+%token DT_KEY_CONST
+%token DT_KEY_CONTINUE
+%token DT_KEY_COUNTER
+%token DT_KEY_DEFAULT
+%token DT_KEY_DO
+%token DT_KEY_DOUBLE
+%token DT_KEY_ELSE
+%token DT_KEY_ENUM
+%token DT_KEY_EXTERN
+%token DT_KEY_FLOAT
+%token DT_KEY_FOR
+%token DT_KEY_GOTO
+%token DT_KEY_IF
+%token DT_KEY_IMPORT
+%token DT_KEY_INLINE
+%token DT_KEY_INT
+%token DT_KEY_LONG
+%token DT_KEY_PROBE
+%token DT_KEY_PROVIDER
+%token DT_KEY_REGISTER
+%token DT_KEY_RESTRICT
+%token DT_KEY_RETURN
+%token DT_KEY_SELF
+%token DT_KEY_SHORT
+%token DT_KEY_SIGNED
+%token DT_KEY_STATIC
+%token DT_KEY_STRING
+%token DT_KEY_STRUCT
+%token DT_KEY_SWITCH
+%token DT_KEY_THIS
+%token DT_KEY_TYPEDEF
+%token DT_KEY_UNION
+%token DT_KEY_UNSIGNED
+%token DT_KEY_VOID
+%token DT_KEY_VOLATILE
+%token DT_KEY_WHILE
+%token DT_KEY_XLATOR
+
+%token DT_TOK_EPRED
+%token DT_CTX_DEXPR
+%token DT_CTX_DPROG
+%token DT_CTX_DTYPE
+%token DT_TOK_EOF 0
+
+%left DT_TOK_COMMA
+%right DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ DT_TOK_DIV_EQ
+ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ DT_TOK_LSH_EQ
+ DT_TOK_RSH_EQ
+%left DT_TOK_QUESTION DT_TOK_COLON
+%left DT_TOK_LOR
+%left DT_TOK_LXOR
+%left DT_TOK_LAND
+%left DT_TOK_BOR
+%left DT_TOK_XOR
+%left DT_TOK_BAND
+%left DT_TOK_EQU DT_TOK_NEQ
+%left DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE
+%left DT_TOK_LSH DT_TOK_RSH
+%left DT_TOK_ADD DT_TOK_SUB
+%left DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
+%right DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
+ DT_TOK_IPOS DT_TOK_INEG
+%right DT_TOK_DEREF DT_TOK_ADDROF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
+%left DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
+
+%type <l_node> d_expression
+%type <l_node> d_program
+%type <l_node> d_type
+
+%type <l_node> translation_unit
+%type <l_node> external_declaration
+%type <l_node> inline_definition
+%type <l_node> translator_definition
+%type <l_node> translator_member_list
+%type <l_node> translator_member
+%type <l_node> provider_definition
+%type <l_node> provider_probe_list
+%type <l_node> provider_probe
+%type <l_node> probe_definition
+%type <l_node> probe_specifiers
+%type <l_node> probe_specifier_list
+%type <l_node> probe_specifier
+%type <l_node> statement_list
+%type <l_node> statement
+%type <l_node> declaration
+%type <l_node> init_declarator_list
+%type <l_node> init_declarator
+
+%type <l_decl> type_specifier
+%type <l_decl> type_qualifier
+%type <l_decl> struct_or_union_specifier
+%type <l_decl> specifier_qualifier_list
+%type <l_decl> enum_specifier
+%type <l_decl> declarator
+%type <l_decl> direct_declarator
+%type <l_decl> pointer
+%type <l_decl> type_qualifier_list
+%type <l_decl> type_name
+%type <l_decl> abstract_declarator
+%type <l_decl> direct_abstract_declarator
+
+%type <l_node> parameter_type_list
+%type <l_node> parameter_list
+%type <l_node> parameter_declaration
+
+%type <l_node> array
+%type <l_node> array_parameters
+%type <l_node> function
+%type <l_node> function_parameters
+
+%type <l_node> expression
+%type <l_node> assignment_expression
+%type <l_node> conditional_expression
+%type <l_node> constant_expression
+%type <l_node> logical_or_expression
+%type <l_node> logical_xor_expression
+%type <l_node> logical_and_expression
+%type <l_node> inclusive_or_expression
+%type <l_node> exclusive_or_expression
+%type <l_node> and_expression
+%type <l_node> equality_expression
+%type <l_node> relational_expression
+%type <l_node> shift_expression
+%type <l_node> additive_expression
+%type <l_node> multiplicative_expression
+%type <l_node> cast_expression
+%type <l_node> unary_expression
+%type <l_node> postfix_expression
+%type <l_node> primary_expression
+%type <l_node> argument_expression_list
+
+%type <l_tok> assignment_operator
+%type <l_tok> unary_operator
+%type <l_tok> struct_or_union
+
+%%
+
+dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
+ | d_program DT_TOK_EOF { return (dt_node_root($1)); }
+ | d_type DT_TOK_EOF { return (dt_node_root($1)); }
+ ;
+
+d_expression: DT_CTX_DEXPR { $$ = NULL; }
+ | DT_CTX_DEXPR expression { $$ = $2; }
+ ;
+
+d_program: DT_CTX_DPROG { $$ = dt_node_program(NULL); }
+ | DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
+ ;
+
+d_type: DT_CTX_DTYPE { $$ = NULL; }
+ | DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
+ ;
+
+translation_unit:
+ external_declaration
+ | translation_unit external_declaration { $$ = LINK($1, $2); }
+ ;
+
+external_declaration:
+ inline_definition
+ | translator_definition
+ | provider_definition
+ | probe_definition
+ | declaration
+ ;
+
+inline_definition:
+ DT_KEY_INLINE declaration_specifiers declarator
+ { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
+ assignment_expression ';' {
+ /*
+ * We push a new declaration scope before shifting the
+ * assignment_expression in order to preserve ds_class
+ * and ds_ident for use in dt_node_inline(). Once the
+ * entire inline_definition rule is matched, pop the
+ * scope and construct the inline using the saved decl.
+ */
+ dt_scope_pop();
+ $$ = dt_node_inline($6);
+ }
+ ;
+
+translator_definition:
+ DT_KEY_XLATOR type_name DT_TOK_LT type_name
+ DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
+ $$ = dt_node_xlator($2, $4, $5, $8);
+ }
+ | DT_KEY_XLATOR type_name DT_TOK_LT type_name
+ DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
+ $$ = dt_node_xlator($2, $4, $5, NULL);
+ }
+ ;
+
+translator_member_list:
+ translator_member
+ | translator_member_list translator_member { $$ = LINK($1,$2); }
+ ;
+
+translator_member:
+ DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
+ $$ = dt_node_member(NULL, $1, $3);
+ }
+ ;
+
+provider_definition:
+ DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' {
+ $$ = dt_node_provider($2, $4);
+ }
+ | DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' {
+ $$ = dt_node_provider($2, NULL);
+ }
+ ;
+
+provider_probe_list:
+ provider_probe
+ | provider_probe_list provider_probe { $$ = LINK($1, $2); }
+ ;
+
+provider_probe:
+ DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' {
+ $$ = dt_node_probe($2, 2, $3, $5);
+ }
+ | DT_KEY_PROBE DT_TOK_IDENT function ';' {
+ $$ = dt_node_probe($2, 1, $3, NULL);
+ }
+ ;
+
+
+probe_definition:
+ probe_specifiers {
+ /*
+ * If the input stream is a file, do not permit a probe
+ * specification without / <pred> / or { <act> } after
+ * it. This can only occur if the next token is EOF or
+ * an ambiguous predicate was slurped up as a comment.
+ * We cannot perform this check if input() is a string
+ * because dtrace(1M) [-fmnP] also use the compiler and
+ * things like dtrace -n BEGIN have to be accepted.
+ */
+ if (yypcb->pcb_fileptr != NULL) {
+ dnerror($1, D_SYNTAX, "expected predicate and/"
+ "or actions following probe description\n");
+ }
+ $$ = dt_node_clause($1, NULL, NULL);
+ }
+ | probe_specifiers '{' statement_list '}' {
+ $$ = dt_node_clause($1, NULL, $3);
+ }
+ | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
+ dnerror($3, D_SYNTAX, "expected actions { } following "
+ "probe description and predicate\n");
+ }
+ | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
+ '{' statement_list '}' {
+ $$ = dt_node_clause($1, $3, $6);
+ }
+ ;
+
+probe_specifiers:
+ probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
+ ;
+
+probe_specifier_list:
+ probe_specifier
+ | probe_specifier_list DT_TOK_COMMA probe_specifier {
+ $$ = LINK($1, $3);
+ }
+ ;
+
+probe_specifier:
+ DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
+ | DT_TOK_INT { $$ = dt_node_pdesc_by_id($1); }
+ ;
+
+statement_list: statement { $$ = $1; }
+ | statement_list ';' statement { $$ = LINK($1, $3); }
+ ;
+
+statement: /* empty */ { $$ = NULL; }
+ | expression { $$ = dt_node_statement($1); }
+ ;
+
+argument_expression_list:
+ assignment_expression
+ | argument_expression_list DT_TOK_COMMA assignment_expression {
+ $$ = LINK($1, $3);
+ }
+ ;
+
+primary_expression:
+ DT_TOK_IDENT { $$ = dt_node_ident($1); }
+ | DT_TOK_AGG { $$ = dt_node_ident($1); }
+ | DT_TOK_INT { $$ = dt_node_int($1); }
+ | DT_TOK_STRING { $$ = dt_node_string($1); }
+ | DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
+ | DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
+ | DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
+ ;
+
+postfix_expression:
+ primary_expression
+ | postfix_expression
+ DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC {
+ $$ = OP2(DT_TOK_LBRAC, $1, $3);
+ }
+ | postfix_expression DT_TOK_LPAR DT_TOK_RPAR {
+ $$ = dt_node_func($1, NULL);
+ }
+ | postfix_expression
+ DT_TOK_LPAR argument_expression_list DT_TOK_RPAR {
+ $$ = dt_node_func($1, $3);
+ }
+ | postfix_expression DT_TOK_DOT DT_TOK_IDENT {
+ $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
+ }
+ | postfix_expression DT_TOK_DOT DT_TOK_TNAME {
+ $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
+ }
+ | postfix_expression DT_TOK_PTR DT_TOK_IDENT {
+ $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
+ }
+ | postfix_expression DT_TOK_PTR DT_TOK_TNAME {
+ $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
+ }
+ | postfix_expression DT_TOK_ADDADD {
+ $$ = OP1(DT_TOK_POSTINC, $1);
+ }
+ | postfix_expression DT_TOK_SUBSUB {
+ $$ = OP1(DT_TOK_POSTDEC, $1);
+ }
+ | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
+ DT_TOK_IDENT DT_TOK_RPAR {
+ $$ = dt_node_offsetof($3, $5);
+ }
+ | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
+ DT_TOK_TNAME DT_TOK_RPAR {
+ $$ = dt_node_offsetof($3, $5);
+ }
+ | DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT
+ DT_TOK_LPAR expression DT_TOK_RPAR {
+ $$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6);
+ }
+ ;
+
+unary_expression:
+ postfix_expression
+ | DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); }
+ | DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); }
+ | unary_operator cast_expression { $$ = OP1($1, $2); }
+ | DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); }
+ | DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR {
+ $$ = OP1(DT_TOK_SIZEOF, dt_node_type($3));
+ }
+ | DT_TOK_STRINGOF unary_expression {
+ $$ = OP1(DT_TOK_STRINGOF, $2);
+ }
+ ;
+
+unary_operator: DT_TOK_BAND { $$ = DT_TOK_ADDROF; }
+ | DT_TOK_MUL { $$ = DT_TOK_DEREF; }
+ | DT_TOK_ADD { $$ = DT_TOK_IPOS; }
+ | DT_TOK_SUB { $$ = DT_TOK_INEG; }
+ | DT_TOK_BNEG { $$ = DT_TOK_BNEG; }
+ | DT_TOK_LNEG { $$ = DT_TOK_LNEG; }
+ ;
+
+cast_expression:
+ unary_expression
+ | DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression {
+ $$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4);
+ }
+ ;
+
+multiplicative_expression:
+ cast_expression
+ | multiplicative_expression DT_TOK_MUL cast_expression {
+ $$ = OP2(DT_TOK_MUL, $1, $3);
+ }
+ | multiplicative_expression DT_TOK_DIV cast_expression {
+ $$ = OP2(DT_TOK_DIV, $1, $3);
+ }
+ | multiplicative_expression DT_TOK_MOD cast_expression {
+ $$ = OP2(DT_TOK_MOD, $1, $3);
+ }
+ ;
+
+additive_expression:
+ multiplicative_expression
+ | additive_expression DT_TOK_ADD multiplicative_expression {
+ $$ = OP2(DT_TOK_ADD, $1, $3);
+ }
+ | additive_expression DT_TOK_SUB multiplicative_expression {
+ $$ = OP2(DT_TOK_SUB, $1, $3);
+ }
+ ;
+
+shift_expression:
+ additive_expression
+ | shift_expression DT_TOK_LSH additive_expression {
+ $$ = OP2(DT_TOK_LSH, $1, $3);
+ }
+ | shift_expression DT_TOK_RSH additive_expression {
+ $$ = OP2(DT_TOK_RSH, $1, $3);
+ }
+ ;
+
+relational_expression:
+ shift_expression
+ | relational_expression DT_TOK_LT shift_expression {
+ $$ = OP2(DT_TOK_LT, $1, $3);
+ }
+ | relational_expression DT_TOK_GT shift_expression {
+ $$ = OP2(DT_TOK_GT, $1, $3);
+ }
+ | relational_expression DT_TOK_LE shift_expression {
+ $$ = OP2(DT_TOK_LE, $1, $3);
+ }
+ | relational_expression DT_TOK_GE shift_expression {
+ $$ = OP2(DT_TOK_GE, $1, $3);
+ }
+ ;
+
+equality_expression:
+ relational_expression
+ | equality_expression DT_TOK_EQU relational_expression {
+ $$ = OP2(DT_TOK_EQU, $1, $3);
+ }
+ | equality_expression DT_TOK_NEQ relational_expression {
+ $$ = OP2(DT_TOK_NEQ, $1, $3);
+ }
+ ;
+
+and_expression:
+ equality_expression
+ | and_expression DT_TOK_BAND equality_expression {
+ $$ = OP2(DT_TOK_BAND, $1, $3);
+ }
+ ;
+
+exclusive_or_expression:
+ and_expression
+ | exclusive_or_expression DT_TOK_XOR and_expression {
+ $$ = OP2(DT_TOK_XOR, $1, $3);
+ }
+ ;
+
+inclusive_or_expression:
+ exclusive_or_expression
+ | inclusive_or_expression DT_TOK_BOR exclusive_or_expression {
+ $$ = OP2(DT_TOK_BOR, $1, $3);
+ }
+ ;
+
+logical_and_expression:
+ inclusive_or_expression
+ | logical_and_expression DT_TOK_LAND inclusive_or_expression {
+ $$ = OP2(DT_TOK_LAND, $1, $3);
+ }
+ ;
+
+logical_xor_expression:
+ logical_and_expression
+ | logical_xor_expression DT_TOK_LXOR logical_and_expression {
+ $$ = OP2(DT_TOK_LXOR, $1, $3);
+ }
+ ;
+
+logical_or_expression:
+ logical_xor_expression
+ | logical_or_expression DT_TOK_LOR logical_xor_expression {
+ $$ = OP2(DT_TOK_LOR, $1, $3);
+ }
+ ;
+
+constant_expression: conditional_expression
+ ;
+
+conditional_expression:
+ logical_or_expression
+ | logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON
+ conditional_expression { $$ = OP3($1, $3, $5); }
+ ;
+
+assignment_expression:
+ conditional_expression
+ | unary_expression assignment_operator assignment_expression {
+ $$ = OP2($2, $1, $3);
+ }
+ ;
+
+assignment_operator:
+ DT_TOK_ASGN { $$ = DT_TOK_ASGN; }
+ | DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; }
+ | DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; }
+ | DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; }
+ | DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; }
+ | DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; }
+ | DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; }
+ | DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; }
+ | DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; }
+ | DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; }
+ | DT_TOK_OR_EQ { $$ = DT_TOK_OR_EQ; }
+ ;
+
+expression: assignment_expression
+ | expression DT_TOK_COMMA assignment_expression {
+ $$ = OP2(DT_TOK_COMMA, $1, $3);
+ }
+ ;
+
+declaration: declaration_specifiers ';' {
+ $$ = dt_node_decl();
+ dt_decl_free(dt_decl_pop());
+ yybegin(YYS_CLAUSE);
+ }
+ | declaration_specifiers init_declarator_list ';' {
+ $$ = $2;
+ dt_decl_free(dt_decl_pop());
+ yybegin(YYS_CLAUSE);
+ }
+ ;
+
+declaration_specifiers:
+ d_storage_class_specifier
+ | d_storage_class_specifier declaration_specifiers
+ | type_specifier
+ | type_specifier declaration_specifiers
+ | type_qualifier
+ | type_qualifier declaration_specifiers
+ ;
+
+parameter_declaration_specifiers:
+ storage_class_specifier
+ | storage_class_specifier declaration_specifiers
+ | type_specifier
+ | type_specifier declaration_specifiers
+ | type_qualifier
+ | type_qualifier declaration_specifiers
+ ;
+
+storage_class_specifier:
+ DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); }
+ | DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); }
+ | DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); }
+ | DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); }
+ | DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); }
+ ;
+
+d_storage_class_specifier:
+ storage_class_specifier
+ | DT_KEY_SELF { dt_decl_class(DT_DC_SELF); }
+ | DT_KEY_THIS { dt_decl_class(DT_DC_THIS); }
+ ;
+
+type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
+ | DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); }
+ | DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); }
+ | DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); }
+ | DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); }
+ | DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); }
+ | DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
+ | DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
+ | DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
+ | DT_KEY_STRING {
+ $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
+ }
+ | DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); }
+ | struct_or_union_specifier
+ | enum_specifier
+ ;
+
+type_qualifier: DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); }
+ | DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); }
+ | DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); }
+ ;
+
+struct_or_union_specifier:
+ struct_or_union_definition struct_declaration_list '}' {
+ $$ = dt_scope_pop();
+ }
+ | struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); }
+ | struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); }
+ ;
+
+struct_or_union_definition:
+ struct_or_union '{' { dt_decl_sou($1, NULL); }
+ | struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); }
+ | struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); }
+ ;
+
+struct_or_union:
+ DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
+ | DT_KEY_UNION { $$ = CTF_K_UNION; }
+ ;
+
+struct_declaration_list:
+ struct_declaration
+ | struct_declaration_list struct_declaration
+ ;
+
+init_declarator_list:
+ init_declarator
+ | init_declarator_list DT_TOK_COMMA init_declarator {
+ $$ = LINK($1, $3);
+ }
+ ;
+
+init_declarator:
+ declarator {
+ $$ = dt_node_decl();
+ dt_decl_reset();
+ }
+ ;
+
+struct_declaration:
+ specifier_qualifier_list struct_declarator_list ';' {
+ dt_decl_free(dt_decl_pop());
+ }
+ ;
+
+specifier_qualifier_list:
+ type_specifier
+ | type_specifier specifier_qualifier_list { $$ = $2; }
+ | type_qualifier
+ | type_qualifier specifier_qualifier_list { $$ = $2; }
+ ;
+
+struct_declarator_list:
+ struct_declarator
+ | struct_declarator_list DT_TOK_COMMA struct_declarator
+ ;
+
+struct_declarator:
+ declarator { dt_decl_member(NULL); }
+ | DT_TOK_COLON constant_expression { dt_decl_member($2); }
+ | declarator DT_TOK_COLON constant_expression {
+ dt_decl_member($3);
+ }
+ ;
+
+enum_specifier:
+ enum_definition enumerator_list '}' { $$ = dt_scope_pop(); }
+ | DT_KEY_ENUM DT_TOK_IDENT { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
+ | DT_KEY_ENUM DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
+ ;
+
+enum_definition:
+ DT_KEY_ENUM '{' { dt_decl_enum(NULL); }
+ | DT_KEY_ENUM DT_TOK_IDENT '{' { dt_decl_enum($2); }
+ | DT_KEY_ENUM DT_TOK_TNAME '{' { dt_decl_enum($2); }
+ ;
+
+enumerator_list:
+ enumerator
+ | enumerator_list DT_TOK_COMMA enumerator
+ ;
+
+enumerator: DT_TOK_IDENT { dt_decl_enumerator($1, NULL); }
+ | DT_TOK_IDENT DT_TOK_ASGN expression {
+ dt_decl_enumerator($1, $3);
+ }
+ ;
+
+declarator: direct_declarator
+ | pointer direct_declarator
+ ;
+
+direct_declarator:
+ DT_TOK_IDENT { $$ = dt_decl_ident($1); }
+ | lparen declarator DT_TOK_RPAR { $$ = $2; }
+ | direct_declarator array { dt_decl_array($2); }
+ | direct_declarator function { dt_decl_func($1, $2); }
+ ;
+
+lparen: DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
+ ;
+
+pointer: DT_TOK_MUL { $$ = dt_decl_ptr(); }
+ | DT_TOK_MUL type_qualifier_list { $$ = dt_decl_ptr(); }
+ | DT_TOK_MUL pointer { $$ = dt_decl_ptr(); }
+ | DT_TOK_MUL type_qualifier_list pointer { $$ = dt_decl_ptr(); }
+ ;
+
+type_qualifier_list:
+ type_qualifier
+ | type_qualifier_list type_qualifier { $$ = $2; }
+ ;
+
+parameter_type_list:
+ parameter_list
+ | DT_TOK_ELLIPSIS { $$ = dt_node_vatype(); }
+ | parameter_list DT_TOK_COMMA DT_TOK_ELLIPSIS {
+ $$ = LINK($1, dt_node_vatype());
+ }
+ ;
+
+parameter_list: parameter_declaration
+ | parameter_list DT_TOK_COMMA parameter_declaration {
+ $$ = LINK($1, $3);
+ }
+ ;
+
+parameter_declaration:
+ parameter_declaration_specifiers {
+ $$ = dt_node_type(NULL);
+ }
+ | parameter_declaration_specifiers declarator {
+ $$ = dt_node_type(NULL);
+ }
+ | parameter_declaration_specifiers abstract_declarator {
+ $$ = dt_node_type(NULL);
+ }
+ ;
+
+type_name: specifier_qualifier_list {
+ $$ = dt_decl_pop();
+ }
+ | specifier_qualifier_list abstract_declarator {
+ $$ = dt_decl_pop();
+ }
+ ;
+
+abstract_declarator:
+ pointer
+ | direct_abstract_declarator
+ | pointer direct_abstract_declarator
+ ;
+
+direct_abstract_declarator:
+ lparen abstract_declarator DT_TOK_RPAR { $$ = $2; }
+ | direct_abstract_declarator array { dt_decl_array($2); }
+ | array { dt_decl_array($1); $$ = NULL; }
+ | direct_abstract_declarator function { dt_decl_func($1, $2); }
+ | function { dt_decl_func(NULL, $1); }
+ ;
+
+array: DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
+ array_parameters DT_TOK_RBRAC {
+ dt_scope_pop();
+ $$ = $3;
+ }
+ ;
+
+array_parameters:
+ /* empty */ { $$ = NULL; }
+ | constant_expression { $$ = $1; }
+ | parameter_type_list { $$ = $1; }
+ ;
+
+function: DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
+ function_parameters DT_TOK_RPAR {
+ dt_scope_pop();
+ $$ = $3;
+ }
+ ;
+
+function_parameters:
+ /* empty */ { $$ = NULL; }
+ | parameter_type_list { $$ = $1; }
+ ;
+
+%%
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_handle.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_handle.c
new file mode 100644
index 0000000..fe1ec7a
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_handle.c
@@ -0,0 +1,485 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+
+#include <dt_impl.h>
+#include <dt_program.h>
+
+static const char _dt_errprog[] =
+"dtrace:::ERROR"
+"{"
+" trace(arg1);"
+" trace(arg2);"
+" trace(arg3);"
+" trace(arg4);"
+" trace(arg5);"
+"}";
+
+int
+dtrace_handle_err(dtrace_hdl_t *dtp, dtrace_handle_err_f *hdlr, void *arg)
+{
+ dtrace_prog_t *pgp = NULL;
+ dt_stmt_t *stp;
+ dtrace_ecbdesc_t *edp;
+
+ /*
+ * We don't currently support multiple error handlers.
+ */
+ if (dtp->dt_errhdlr != NULL)
+ return (dt_set_errno(dtp, EALREADY));
+
+ /*
+ * If the DTRACEOPT_GRABANON is enabled, the anonymous enabling will
+ * already have a dtrace:::ERROR probe enabled; save 'hdlr' and 'arg'
+ * but do not bother compiling and enabling _dt_errprog.
+ */
+ if (dtp->dt_options[DTRACEOPT_GRABANON] != DTRACEOPT_UNSET)
+ goto out;
+
+ if ((pgp = dtrace_program_strcompile(dtp, _dt_errprog,
+ DTRACE_PROBESPEC_NAME, DTRACE_C_ZDEFS, 0, NULL)) == NULL)
+ return (dt_set_errno(dtp, dtrace_errno(dtp)));
+
+ stp = dt_list_next(&pgp->dp_stmts);
+ assert(stp != NULL);
+
+ edp = stp->ds_desc->dtsd_ecbdesc;
+ assert(edp != NULL);
+ edp->dted_uarg = DT_ECB_ERROR;
+
+out:
+ dtp->dt_errhdlr = hdlr;
+ dtp->dt_errarg = arg;
+ dtp->dt_errprog = pgp;
+
+ return (0);
+}
+
+int
+dtrace_handle_drop(dtrace_hdl_t *dtp, dtrace_handle_drop_f *hdlr, void *arg)
+{
+ if (dtp->dt_drophdlr != NULL)
+ return (dt_set_errno(dtp, EALREADY));
+
+ dtp->dt_drophdlr = hdlr;
+ dtp->dt_droparg = arg;
+
+ return (0);
+}
+
+int
+dtrace_handle_proc(dtrace_hdl_t *dtp, dtrace_handle_proc_f *hdlr, void *arg)
+{
+ if (dtp->dt_prochdlr != NULL)
+ return (dt_set_errno(dtp, EALREADY));
+
+ dtp->dt_prochdlr = hdlr;
+ dtp->dt_procarg = arg;
+
+ return (0);
+}
+
+int
+dtrace_handle_buffered(dtrace_hdl_t *dtp, dtrace_handle_buffered_f *hdlr,
+ void *arg)
+{
+ if (dtp->dt_bufhdlr != NULL)
+ return (dt_set_errno(dtp, EALREADY));
+
+ if (hdlr == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ dtp->dt_bufhdlr = hdlr;
+ dtp->dt_bufarg = arg;
+
+ return (0);
+}
+
+int
+dtrace_handle_setopt(dtrace_hdl_t *dtp, dtrace_handle_setopt_f *hdlr,
+ void *arg)
+{
+ if (hdlr == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ dtp->dt_setopthdlr = hdlr;
+ dtp->dt_setoptarg = arg;
+
+ return (0);
+}
+
+#define DT_REC(type, ndx) *((type *)((uintptr_t)data->dtpda_data + \
+ epd->dtepd_rec[(ndx)].dtrd_offset))
+
+static int
+dt_handle_err(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
+{
+ dtrace_eprobedesc_t *epd = data->dtpda_edesc, *errepd;
+ dtrace_probedesc_t *pd = data->dtpda_pdesc, *errpd;
+ dtrace_errdata_t err;
+ dtrace_epid_t epid;
+
+ char where[30];
+ char details[30];
+ char offinfo[30];
+ const int slop = 80;
+ const char *faultstr;
+ char *str;
+ int len;
+
+ assert(epd->dtepd_uarg == DT_ECB_ERROR);
+
+ if (epd->dtepd_nrecs != 5 || strcmp(pd->dtpd_provider, "dtrace") != 0 ||
+ strcmp(pd->dtpd_name, "ERROR") != 0)
+ return (dt_set_errno(dtp, EDT_BADERROR));
+
+ /*
+ * This is an error. We have the following items here: EPID,
+ * faulting action, DIF offset, fault code and faulting address.
+ */
+ epid = (uint32_t)DT_REC(uint64_t, 0);
+
+ if (dt_epid_lookup(dtp, epid, &errepd, &errpd) != 0)
+ return (dt_set_errno(dtp, EDT_BADERROR));
+
+ err.dteda_edesc = errepd;
+ err.dteda_pdesc = errpd;
+ err.dteda_cpu = data->dtpda_cpu;
+ err.dteda_action = (int)DT_REC(uint64_t, 1);
+ err.dteda_offset = (int)DT_REC(uint64_t, 2);
+ err.dteda_fault = (int)DT_REC(uint64_t, 3);
+ err.dteda_addr = DT_REC(uint64_t, 4);
+
+ faultstr = dtrace_faultstr(dtp, err.dteda_fault);
+ len = sizeof (where) + sizeof (offinfo) + strlen(faultstr) +
+ strlen(errpd->dtpd_provider) + strlen(errpd->dtpd_mod) +
+ strlen(errpd->dtpd_name) + strlen(errpd->dtpd_func) +
+ slop;
+
+ str = (char *)alloca(len);
+
+ if (err.dteda_action == 0) {
+ (void) sprintf(where, "predicate");
+ } else {
+ (void) sprintf(where, "action #%d", err.dteda_action);
+ }
+
+ if (err.dteda_offset != -1) {
+ (void) sprintf(offinfo, " at DIF offset %d", err.dteda_offset);
+ } else {
+ offinfo[0] = 0;
+ }
+
+ switch (err.dteda_fault) {
+ case DTRACEFLT_BADADDR:
+ case DTRACEFLT_BADALIGN:
+ case DTRACEFLT_BADSTACK:
+ (void) sprintf(details, " (0x%llx)",
+ (u_longlong_t)err.dteda_addr);
+ break;
+
+ default:
+ details[0] = 0;
+ }
+
+ (void) snprintf(str, len, "error on enabled probe ID %u "
+ "(ID %u: %s:%s:%s:%s): %s%s in %s%s\n",
+ epid, errpd->dtpd_id, errpd->dtpd_provider,
+ errpd->dtpd_mod, errpd->dtpd_func,
+ errpd->dtpd_name, dtrace_faultstr(dtp, err.dteda_fault),
+ details, where, offinfo);
+
+ err.dteda_msg = str;
+
+ if (dtp->dt_errhdlr == NULL)
+ return (dt_set_errno(dtp, EDT_ERRABORT));
+
+ if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_ERRABORT));
+
+ return (0);
+}
+
+int
+dt_handle_liberr(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
+ const char *faultstr)
+{
+ dtrace_probedesc_t *errpd = data->dtpda_pdesc;
+ dtrace_errdata_t err;
+ const int slop = 80;
+ char *str;
+ int len;
+
+ err.dteda_edesc = data->dtpda_edesc;
+ err.dteda_pdesc = errpd;
+ err.dteda_cpu = data->dtpda_cpu;
+ err.dteda_action = -1;
+ err.dteda_offset = -1;
+ err.dteda_fault = DTRACEFLT_LIBRARY;
+ err.dteda_addr = 0;
+
+ len = strlen(faultstr) +
+ strlen(errpd->dtpd_provider) + strlen(errpd->dtpd_mod) +
+ strlen(errpd->dtpd_name) + strlen(errpd->dtpd_func) +
+ slop;
+
+ str = alloca(len);
+
+ (void) snprintf(str, len, "error on enabled probe ID %u "
+ "(ID %u: %s:%s:%s:%s): %s\n",
+ data->dtpda_edesc->dtepd_epid,
+ errpd->dtpd_id, errpd->dtpd_provider,
+ errpd->dtpd_mod, errpd->dtpd_func,
+ errpd->dtpd_name, faultstr);
+
+ err.dteda_msg = str;
+
+ if (dtp->dt_errhdlr == NULL)
+ return (dt_set_errno(dtp, EDT_ERRABORT));
+
+ if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_ERRABORT));
+
+ return (0);
+}
+
+#define DROPTAG(x) x, #x
+
+static const struct {
+ dtrace_dropkind_t dtdrg_kind;
+ char *dtdrg_tag;
+} _dt_droptags[] = {
+ { DROPTAG(DTRACEDROP_PRINCIPAL) },
+ { DROPTAG(DTRACEDROP_AGGREGATION) },
+ { DROPTAG(DTRACEDROP_DYNAMIC) },
+ { DROPTAG(DTRACEDROP_DYNRINSE) },
+ { DROPTAG(DTRACEDROP_DYNDIRTY) },
+ { DROPTAG(DTRACEDROP_SPEC) },
+ { DROPTAG(DTRACEDROP_SPECBUSY) },
+ { DROPTAG(DTRACEDROP_SPECUNAVAIL) },
+ { DROPTAG(DTRACEDROP_DBLERROR) },
+ { DROPTAG(DTRACEDROP_STKSTROVERFLOW) },
+ { 0, NULL }
+};
+
+static const char *
+dt_droptag(dtrace_dropkind_t kind)
+{
+ int i;
+
+ for (i = 0; _dt_droptags[i].dtdrg_tag != NULL; i++) {
+ if (_dt_droptags[i].dtdrg_kind == kind)
+ return (_dt_droptags[i].dtdrg_tag);
+ }
+
+ return ("DTRACEDROP_UNKNOWN");
+}
+
+int
+dt_handle_cpudrop(dtrace_hdl_t *dtp, processorid_t cpu,
+ dtrace_dropkind_t what, uint64_t howmany)
+{
+ dtrace_dropdata_t drop;
+ char str[80], *s;
+ int size;
+
+ assert(what == DTRACEDROP_PRINCIPAL || what == DTRACEDROP_AGGREGATION);
+
+ bzero(&drop, sizeof (drop));
+ drop.dtdda_handle = dtp;
+ drop.dtdda_cpu = cpu;
+ drop.dtdda_kind = what;
+ drop.dtdda_drops = howmany;
+ drop.dtdda_msg = str;
+
+ if (dtp->dt_droptags) {
+ (void) snprintf(str, sizeof (str), "[%s] ", dt_droptag(what));
+ s = &str[strlen(str)];
+ size = sizeof (str) - (s - str);
+ } else {
+ s = str;
+ size = sizeof (str);
+ }
+
+ (void) snprintf(s, size, "%llu %sdrop%s on CPU %d\n",
+ (u_longlong_t)howmany,
+ what == DTRACEDROP_PRINCIPAL ? "" : "aggregation ",
+ howmany > 1 ? "s" : "", cpu);
+
+ if (dtp->dt_drophdlr == NULL)
+ return (dt_set_errno(dtp, EDT_DROPABORT));
+
+ if ((*dtp->dt_drophdlr)(&drop, dtp->dt_droparg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_DROPABORT));
+
+ return (0);
+}
+
+static const struct {
+ dtrace_dropkind_t dtdrt_kind;
+ uintptr_t dtdrt_offset;
+ const char *dtdrt_str;
+ const char *dtdrt_msg;
+} _dt_droptab[] = {
+ { DTRACEDROP_DYNAMIC,
+ offsetof(dtrace_status_t, dtst_dyndrops),
+ "dynamic variable drop" },
+
+ { DTRACEDROP_DYNRINSE,
+ offsetof(dtrace_status_t, dtst_dyndrops_rinsing),
+ "dynamic variable drop", " with non-empty rinsing list" },
+
+ { DTRACEDROP_DYNDIRTY,
+ offsetof(dtrace_status_t, dtst_dyndrops_dirty),
+ "dynamic variable drop", " with non-empty dirty list" },
+
+ { DTRACEDROP_SPEC,
+ offsetof(dtrace_status_t, dtst_specdrops),
+ "speculative drop" },
+
+ { DTRACEDROP_SPECBUSY,
+ offsetof(dtrace_status_t, dtst_specdrops_busy),
+ "failed speculation", " (available buffer(s) still busy)" },
+
+ { DTRACEDROP_SPECUNAVAIL,
+ offsetof(dtrace_status_t, dtst_specdrops_unavail),
+ "failed speculation", " (no speculative buffer available)" },
+
+ { DTRACEDROP_STKSTROVERFLOW,
+ offsetof(dtrace_status_t, dtst_stkstroverflows),
+ "jstack()/ustack() string table overflow" },
+
+ { DTRACEDROP_DBLERROR,
+ offsetof(dtrace_status_t, dtst_dblerrors),
+ "error", " in ERROR probe enabling" },
+
+ { 0, 0, NULL }
+};
+
+int
+dt_handle_status(dtrace_hdl_t *dtp, dtrace_status_t *old, dtrace_status_t *new)
+{
+ dtrace_dropdata_t drop;
+ char str[80], *s;
+ uintptr_t base = (uintptr_t)new, obase = (uintptr_t)old;
+ int i, size;
+
+ bzero(&drop, sizeof (drop));
+ drop.dtdda_handle = dtp;
+ drop.dtdda_cpu = DTRACE_CPUALL;
+ drop.dtdda_msg = str;
+
+ /*
+ * First, check to see if we've been killed -- in which case we abort.
+ */
+ if (new->dtst_killed && !old->dtst_killed)
+ return (dt_set_errno(dtp, EDT_BRICKED));
+
+ for (i = 0; _dt_droptab[i].dtdrt_str != NULL; i++) {
+ uintptr_t naddr = base + _dt_droptab[i].dtdrt_offset;
+ uintptr_t oaddr = obase + _dt_droptab[i].dtdrt_offset;
+
+ uint64_t nval = *((uint64_t *)naddr);
+ uint64_t oval = *((uint64_t *)oaddr);
+
+ if (nval == oval)
+ continue;
+
+ if (dtp->dt_droptags) {
+ (void) snprintf(str, sizeof (str), "[%s] ",
+ dt_droptag(_dt_droptab[i].dtdrt_kind));
+ s = &str[strlen(str)];
+ size = sizeof (str) - (s - str);
+ } else {
+ s = str;
+ size = sizeof (str);
+ }
+
+ (void) snprintf(s, size, "%llu %s%s%s\n",
+ (u_longlong_t)(nval - oval),
+ _dt_droptab[i].dtdrt_str, (nval - oval > 1) ? "s" : "",
+ _dt_droptab[i].dtdrt_msg != NULL ?
+ _dt_droptab[i].dtdrt_msg : "");
+
+ drop.dtdda_kind = _dt_droptab[i].dtdrt_kind;
+ drop.dtdda_total = nval;
+ drop.dtdda_drops = nval - oval;
+
+ if (dtp->dt_drophdlr == NULL)
+ return (dt_set_errno(dtp, EDT_DROPABORT));
+
+ if ((*dtp->dt_drophdlr)(&drop,
+ dtp->dt_droparg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_DROPABORT));
+ }
+
+ return (0);
+}
+
+int
+dt_handle_setopt(dtrace_hdl_t *dtp, dtrace_setoptdata_t *data)
+{
+ void *arg = dtp->dt_setoptarg;
+
+ if (dtp->dt_setopthdlr == NULL)
+ return (0);
+
+ if ((*dtp->dt_setopthdlr)(data, arg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_DIRABORT));
+
+ return (0);
+}
+
+int
+dt_handle(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
+{
+ dtrace_eprobedesc_t *epd = data->dtpda_edesc;
+ int rval;
+
+ switch (epd->dtepd_uarg) {
+ case DT_ECB_ERROR:
+ rval = dt_handle_err(dtp, data);
+ break;
+
+ default:
+ return (DTRACE_CONSUME_THIS);
+ }
+
+ if (rval == 0)
+ return (DTRACE_CONSUME_NEXT);
+
+ return (DTRACE_CONSUME_ERROR);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
new file mode 100644
index 0000000..13adbb4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
@@ -0,0 +1,1047 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(sun)
+#include <sys/sysmacros.h>
+#endif
+#include <strings.h>
+#include <stdlib.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <assert.h>
+#include <errno.h>
+#include <ctype.h>
+#if defined(sun)
+#include <sys/procfs_isa.h>
+#endif
+#include <limits.h>
+
+#include <dt_ident.h>
+#include <dt_parser.h>
+#include <dt_provider.h>
+#include <dt_strtab.h>
+#include <dt_impl.h>
+
+/*
+ * Common code for cooking an identifier that uses a typed signature list (we
+ * use this for associative arrays and functions). If the argument list is
+ * of the same length and types, then return the return type. Otherwise
+ * print an appropriate compiler error message and abort the compile.
+ */
+static void
+dt_idcook_sign(dt_node_t *dnp, dt_ident_t *idp,
+ int argc, dt_node_t *args, const char *prefix, const char *suffix)
+{
+ dt_idsig_t *isp = idp->di_data;
+ int i, compat, mismatch, arglimit, iskey;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ iskey = idp->di_kind == DT_IDENT_ARRAY || idp->di_kind == DT_IDENT_AGG;
+
+ if (isp->dis_varargs >= 0) {
+ mismatch = argc < isp->dis_varargs;
+ arglimit = isp->dis_varargs;
+ } else if (isp->dis_optargs >= 0) {
+ mismatch = (argc < isp->dis_optargs || argc > isp->dis_argc);
+ arglimit = argc;
+ } else {
+ mismatch = argc != isp->dis_argc;
+ arglimit = isp->dis_argc;
+ }
+
+ if (mismatch) {
+ xyerror(D_PROTO_LEN, "%s%s%s prototype mismatch: %d %s%s"
+ "passed, %s%d expected\n", prefix, idp->di_name, suffix,
+ argc, iskey ? "key" : "arg", argc == 1 ? " " : "s ",
+ isp->dis_optargs >= 0 ? "at least " : "",
+ isp->dis_optargs >= 0 ? isp->dis_optargs : arglimit);
+ }
+
+ for (i = 0; i < arglimit; i++, args = args->dn_list) {
+ if (isp->dis_args[i].dn_ctfp != NULL)
+ compat = dt_node_is_argcompat(&isp->dis_args[i], args);
+ else
+ compat = 1; /* "@" matches any type */
+
+ if (!compat) {
+ xyerror(D_PROTO_ARG,
+ "%s%s%s %s #%d is incompatible with "
+ "prototype:\n\tprototype: %s\n\t%9s: %s\n",
+ prefix, idp->di_name, suffix,
+ iskey ? "key" : "argument", i + 1,
+ dt_node_type_name(&isp->dis_args[i], n1,
+ sizeof (n1)),
+ iskey ? "key" : "argument",
+ dt_node_type_name(args, n2, sizeof (n2)));
+ }
+ }
+
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+}
+
+/*
+ * Cook an associative array identifier. If this is the first time we are
+ * cooking this array, create its signature based on the argument list.
+ * Otherwise validate the argument list against the existing signature.
+ */
+static void
+dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
+{
+ if (idp->di_data == NULL) {
+ dt_idsig_t *isp = idp->di_data = malloc(sizeof (dt_idsig_t));
+ char n[DT_TYPE_NAMELEN];
+ int i;
+
+ if (isp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ isp->dis_varargs = -1;
+ isp->dis_optargs = -1;
+ isp->dis_argc = argc;
+ isp->dis_args = NULL;
+ isp->dis_auxinfo = 0;
+
+ if (argc != 0 && (isp->dis_args = calloc(argc,
+ sizeof (dt_node_t))) == NULL) {
+ idp->di_data = NULL;
+ free(isp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ /*
+ * If this identifier has not been explicitly declared earlier,
+ * set the identifier's base type to be our special type <DYN>.
+ * If this ident is an aggregation, it will remain as is. If
+ * this ident is an associative array, it will be reassigned
+ * based on the result type of the first assignment statement.
+ */
+ if (!(idp->di_flags & DT_IDFLG_DECL)) {
+ idp->di_ctfp = DT_DYN_CTFP(yypcb->pcb_hdl);
+ idp->di_type = DT_DYN_TYPE(yypcb->pcb_hdl);
+ }
+
+ for (i = 0; i < argc; i++, args = args->dn_list) {
+ if (dt_node_is_dynamic(args) || dt_node_is_void(args)) {
+ xyerror(D_KEY_TYPE, "%s expression may not be "
+ "used as %s index: key #%d\n",
+ dt_node_type_name(args, n, sizeof (n)),
+ dt_idkind_name(idp->di_kind), i + 1);
+ }
+
+ dt_node_type_propagate(args, &isp->dis_args[i]);
+ isp->dis_args[i].dn_list = &isp->dis_args[i + 1];
+ }
+
+ if (argc != 0)
+ isp->dis_args[argc - 1].dn_list = NULL;
+
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+
+ } else {
+ dt_idcook_sign(dnp, idp, argc, args,
+ idp->di_kind == DT_IDENT_AGG ? "@" : "", "[ ]");
+ }
+}
+
+/*
+ * Cook a function call. If this is the first time we are cooking this
+ * identifier, create its type signature based on predefined prototype stored
+ * in di_iarg. We then validate the argument list against this signature.
+ */
+static void
+dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
+{
+ if (idp->di_data == NULL) {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_typeinfo_t dtt;
+ dt_idsig_t *isp;
+ char *s, *p1, *p2;
+ int i = 0;
+
+ assert(idp->di_iarg != NULL);
+ s = alloca(strlen(idp->di_iarg) + 1);
+ (void) strcpy(s, idp->di_iarg);
+
+ if ((p2 = strrchr(s, ')')) != NULL)
+ *p2 = '\0'; /* mark end of parameter list string */
+
+ if ((p1 = strchr(s, '(')) != NULL)
+ *p1++ = '\0'; /* mark end of return type string */
+
+ if (p1 == NULL || p2 == NULL) {
+ xyerror(D_UNKNOWN, "internal error: malformed entry "
+ "for built-in function %s\n", idp->di_name);
+ }
+
+ for (p2 = p1; *p2 != '\0'; p2++) {
+ if (!isspace(*p2)) {
+ i++;
+ break;
+ }
+ }
+
+ for (p2 = strchr(p2, ','); p2++ != NULL; i++)
+ p2 = strchr(p2, ',');
+
+ /*
+ * We first allocate a new ident signature structure with the
+ * appropriate number of argument entries, and then look up
+ * the return type and store its CTF data in di_ctfp/type.
+ */
+ if ((isp = idp->di_data = malloc(sizeof (dt_idsig_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ isp->dis_varargs = -1;
+ isp->dis_optargs = -1;
+ isp->dis_argc = i;
+ isp->dis_args = NULL;
+ isp->dis_auxinfo = 0;
+
+ if (i != 0 && (isp->dis_args = calloc(i,
+ sizeof (dt_node_t))) == NULL) {
+ idp->di_data = NULL;
+ free(isp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ if (dt_type_lookup(s, &dtt) == -1) {
+ xyerror(D_UNKNOWN, "failed to resolve type of %s (%s):"
+ " %s\n", idp->di_name, s,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ if (idp->di_kind == DT_IDENT_AGGFUNC) {
+ idp->di_ctfp = DT_DYN_CTFP(dtp);
+ idp->di_type = DT_DYN_TYPE(dtp);
+ } else {
+ idp->di_ctfp = dtt.dtt_ctfp;
+ idp->di_type = dtt.dtt_type;
+ }
+
+ /*
+ * For each comma-delimited parameter in the prototype string,
+ * we look up the corresponding type and store its CTF data in
+ * the corresponding location in dis_args[]. We also recognize
+ * the special type string "@" to indicate that the specified
+ * parameter may be a D expression of *any* type (represented
+ * as a dis_args[] element with ctfp = NULL, type == CTF_ERR).
+ * If a varargs "..." is present, we record the argument index
+ * in dis_varargs for the benefit of dt_idcook_sign(), above.
+ * If the type of an argument is enclosed in square brackets
+ * (e.g. "[int]"), the argument is considered optional: the
+ * argument may be absent, but if it is present, it must be of
+ * the specified type. Note that varargs may not optional,
+ * optional arguments may not follow varargs, and non-optional
+ * arguments may not follow optional arguments.
+ */
+ for (i = 0; i < isp->dis_argc; i++, p1 = p2) {
+ while (isspace(*p1))
+ p1++; /* skip leading whitespace */
+
+ if ((p2 = strchr(p1, ',')) == NULL)
+ p2 = p1 + strlen(p1);
+ else
+ *p2++ = '\0';
+
+ if (strcmp(p1, "@") == 0 || strcmp(p1, "...") == 0) {
+ isp->dis_args[i].dn_ctfp = NULL;
+ isp->dis_args[i].dn_type = CTF_ERR;
+ if (*p1 == '.')
+ isp->dis_varargs = i;
+ continue;
+ }
+
+ if (*p1 == '[' && p1[strlen(p1) - 1] == ']') {
+ if (isp->dis_varargs != -1) {
+ xyerror(D_UNKNOWN, "optional arg#%d "
+ "may not follow variable arg#%d\n",
+ i + 1, isp->dis_varargs + 1);
+ }
+
+ if (isp->dis_optargs == -1)
+ isp->dis_optargs = i;
+
+ p1[strlen(p1) - 1] = '\0';
+ p1++;
+ } else if (isp->dis_optargs != -1) {
+ xyerror(D_UNKNOWN, "required arg#%d may not "
+ "follow optional arg#%d\n", i + 1,
+ isp->dis_optargs + 1);
+ }
+
+ if (dt_type_lookup(p1, &dtt) == -1) {
+ xyerror(D_UNKNOWN, "failed to resolve type of "
+ "%s arg#%d (%s): %s\n", idp->di_name, i + 1,
+ p1, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ dt_node_type_assign(&isp->dis_args[i],
+ dtt.dtt_ctfp, dtt.dtt_type);
+ }
+ }
+
+ dt_idcook_sign(dnp, idp, argc, args, "", "( )");
+}
+
+/*
+ * Cook a reference to the dynamically typed args[] array. We verify that the
+ * reference is using a single integer constant, and then construct a new ident
+ * representing the appropriate type or translation specifically for this node.
+ */
+static void
+dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_probe_t *prp = yypcb->pcb_probe;
+
+ dt_node_t tag, *nnp, *xnp;
+ dt_xlator_t *dxp;
+ dt_ident_t *xidp;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ if (argc != 1) {
+ xyerror(D_PROTO_LEN, "%s[ ] prototype mismatch: %d arg%s"
+ "passed, 1 expected\n", idp->di_name, argc,
+ argc == 1 ? " " : "s ");
+ }
+
+ if (ap->dn_kind != DT_NODE_INT) {
+ xyerror(D_PROTO_ARG, "%s[ ] argument #1 is incompatible with "
+ "prototype:\n\tprototype: %s\n\t argument: %s\n",
+ idp->di_name, "integer constant",
+ dt_type_name(ap->dn_ctfp, ap->dn_type, n1, sizeof (n1)));
+ }
+
+ if (yypcb->pcb_pdesc == NULL) {
+ xyerror(D_ARGS_NONE, "%s[ ] may not be referenced outside "
+ "of a probe clause\n", idp->di_name);
+ }
+
+ if (prp == NULL) {
+ xyerror(D_ARGS_MULTI,
+ "%s[ ] may not be referenced because probe description %s "
+ "matches an unstable set of probes\n", idp->di_name,
+ dtrace_desc2str(yypcb->pcb_pdesc, n1, sizeof (n1)));
+ }
+
+ if (ap->dn_value >= prp->pr_argc) {
+ xyerror(D_ARGS_IDX, "index %lld is out of range for %s %s[ ]\n",
+ (longlong_t)ap->dn_value, dtrace_desc2str(yypcb->pcb_pdesc,
+ n1, sizeof (n1)), idp->di_name);
+ }
+
+ /*
+ * Look up the native and translated argument types for the probe.
+ * If no translation is needed, these will be the same underlying node.
+ * If translation is needed, look up the appropriate translator. Once
+ * we have the appropriate node, create a new dt_ident_t for this node,
+ * assign it the appropriate attributes, and set the type of 'dnp'.
+ */
+ xnp = prp->pr_xargv[ap->dn_value];
+ nnp = prp->pr_nargv[prp->pr_mapping[ap->dn_value]];
+
+ if (xnp->dn_type == CTF_ERR) {
+ xyerror(D_ARGS_TYPE, "failed to resolve translated type for "
+ "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
+ }
+
+ if (nnp->dn_type == CTF_ERR) {
+ xyerror(D_ARGS_TYPE, "failed to resolve native type for "
+ "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
+ }
+
+ if (dtp->dt_xlatemode == DT_XL_STATIC && (
+ nnp == xnp || dt_node_is_argcompat(nnp, xnp))) {
+ dnp->dn_ident = dt_ident_create(idp->di_name, idp->di_kind,
+ idp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
+ idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
+
+ if (dnp->dn_ident == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dt_node_type_assign(dnp,
+ prp->pr_argv[ap->dn_value].dtt_ctfp,
+ prp->pr_argv[ap->dn_value].dtt_type);
+
+ } else if ((dxp = dt_xlator_lookup(dtp,
+ nnp, xnp, DT_XLATE_FUZZY)) != NULL || (
+ dxp = dt_xlator_lookup(dtp, dt_probe_tag(prp, ap->dn_value, &tag),
+ xnp, DT_XLATE_EXACT | DT_XLATE_EXTERN)) != NULL) {
+
+ xidp = dt_xlator_ident(dxp, xnp->dn_ctfp, xnp->dn_type);
+
+ dnp->dn_ident = dt_ident_create(idp->di_name, xidp->di_kind,
+ xidp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
+ idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
+
+ if (dnp->dn_ident == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (dt_xlator_dynamic(dxp))
+ dxp->dx_arg = (int)ap->dn_value;
+
+ /*
+ * Propagate relevant members from the translator's internal
+ * dt_ident_t. This code must be kept in sync with the state
+ * that is initialized for idents in dt_xlator_create().
+ */
+ dnp->dn_ident->di_data = xidp->di_data;
+ dnp->dn_ident->di_ctfp = xidp->di_ctfp;
+ dnp->dn_ident->di_type = xidp->di_type;
+
+ dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+
+ } else {
+ xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s "
+ "is not defined\n", idp->di_name, (longlong_t)ap->dn_value,
+ dt_node_type_name(nnp, n1, sizeof (n1)),
+ dt_node_type_name(xnp, n2, sizeof (n2)));
+ }
+
+ assert(dnp->dn_ident->di_flags & DT_IDFLG_ORPHAN);
+ assert(dnp->dn_ident->di_id == idp->di_id);
+}
+
+static void
+dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
+{
+ dtrace_typeinfo_t dtt;
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ char n[DT_TYPE_NAMELEN];
+
+ if (argc != 1) {
+ xyerror(D_PROTO_LEN, "%s[ ] prototype mismatch: %d arg%s"
+ "passed, 1 expected\n", idp->di_name,
+ argc, argc == 1 ? " " : "s ");
+ }
+
+ if (ap->dn_kind != DT_NODE_INT) {
+ xyerror(D_PROTO_ARG, "%s[ ] argument #1 is incompatible with "
+ "prototype:\n\tprototype: %s\n\t argument: %s\n",
+ idp->di_name, "integer constant",
+ dt_type_name(ap->dn_ctfp, ap->dn_type, n, sizeof (n)));
+ }
+
+ if ((ap->dn_flags & DT_NF_SIGNED) && (int64_t)ap->dn_value < 0) {
+ xyerror(D_REGS_IDX, "index %lld is out of range for array %s\n",
+ (longlong_t)ap->dn_value, idp->di_name);
+ }
+
+ if (dt_type_lookup("uint64_t", &dtt) == -1) {
+ xyerror(D_UNKNOWN, "failed to resolve type of %s: %s\n",
+ idp->di_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ idp->di_ctfp = dtt.dtt_ctfp;
+ idp->di_type = dtt.dtt_type;
+
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+}
+
+/*ARGSUSED*/
+static void
+dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
+{
+ if (idp->di_type == CTF_ERR) {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_typeinfo_t dtt;
+
+ if (dt_type_lookup(idp->di_iarg, &dtt) == -1) {
+ xyerror(D_UNKNOWN,
+ "failed to resolve type %s for identifier %s: %s\n",
+ (const char *)idp->di_iarg, idp->di_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ idp->di_ctfp = dtt.dtt_ctfp;
+ idp->di_type = dtt.dtt_type;
+ }
+
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+}
+
+/*ARGSUSED*/
+static void
+dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
+{
+ if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR)
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+}
+
+static void
+dt_idcook_inline(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
+{
+ if (idp->di_kind == DT_IDENT_ARRAY)
+ dt_idcook_assc(dnp, idp, argc, args);
+ else
+ dt_idcook_thaw(dnp, idp, argc, args);
+}
+
+static void
+dt_iddtor_sign(dt_ident_t *idp)
+{
+ if (idp->di_data != NULL)
+ free(((dt_idsig_t *)idp->di_data)->dis_args);
+ free(idp->di_data);
+}
+
+static void
+dt_iddtor_free(dt_ident_t *idp)
+{
+ free(idp->di_data);
+}
+
+static void
+dt_iddtor_inline(dt_ident_t *idp)
+{
+ dt_idnode_t *inp = idp->di_iarg;
+
+ if (inp != NULL) {
+ dt_node_link_free(&inp->din_list);
+
+ if (inp->din_hash != NULL)
+ dt_idhash_destroy(inp->din_hash);
+
+ free(inp->din_argv);
+ free(inp);
+ }
+
+ if (idp->di_kind == DT_IDENT_ARRAY)
+ dt_iddtor_sign(idp);
+ else
+ dt_iddtor_free(idp);
+}
+
+/*ARGSUSED*/
+static void
+dt_iddtor_none(dt_ident_t *idp)
+{
+ /* do nothing */
+}
+
+static void
+dt_iddtor_probe(dt_ident_t *idp)
+{
+ if (idp->di_data != NULL)
+ dt_probe_destroy(idp->di_data);
+}
+
+static size_t
+dt_idsize_type(dt_ident_t *idp)
+{
+ return (ctf_type_size(idp->di_ctfp, idp->di_type));
+}
+
+/*ARGSUSED*/
+static size_t
+dt_idsize_none(dt_ident_t *idp)
+{
+ return (0);
+}
+
+const dt_idops_t dt_idops_assc = {
+ dt_idcook_assc,
+ dt_iddtor_sign,
+ dt_idsize_none,
+};
+
+const dt_idops_t dt_idops_func = {
+ dt_idcook_func,
+ dt_iddtor_sign,
+ dt_idsize_none,
+};
+
+const dt_idops_t dt_idops_args = {
+ dt_idcook_args,
+ dt_iddtor_none,
+ dt_idsize_none,
+};
+
+const dt_idops_t dt_idops_regs = {
+ dt_idcook_regs,
+ dt_iddtor_free,
+ dt_idsize_none,
+};
+
+const dt_idops_t dt_idops_type = {
+ dt_idcook_type,
+ dt_iddtor_free,
+ dt_idsize_type,
+};
+
+const dt_idops_t dt_idops_thaw = {
+ dt_idcook_thaw,
+ dt_iddtor_free,
+ dt_idsize_type,
+};
+
+const dt_idops_t dt_idops_inline = {
+ dt_idcook_inline,
+ dt_iddtor_inline,
+ dt_idsize_type,
+};
+
+const dt_idops_t dt_idops_probe = {
+ dt_idcook_thaw,
+ dt_iddtor_probe,
+ dt_idsize_none,
+};
+
+static void
+dt_idhash_populate(dt_idhash_t *dhp)
+{
+ const dt_ident_t *idp = dhp->dh_tmpl;
+
+ dhp->dh_tmpl = NULL; /* clear dh_tmpl first to avoid recursion */
+ dt_dprintf("populating %s idhash from %p\n", dhp->dh_name, (void *)idp);
+
+ for (; idp->di_name != NULL; idp++) {
+ if (dt_idhash_insert(dhp, idp->di_name,
+ idp->di_kind, idp->di_flags, idp->di_id, idp->di_attr,
+ idp->di_vers, idp->di_ops ? idp->di_ops : &dt_idops_thaw,
+ idp->di_iarg, 0) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+}
+
+dt_idhash_t *
+dt_idhash_create(const char *name, const dt_ident_t *tmpl,
+ uint_t min, uint_t max)
+{
+ dt_idhash_t *dhp;
+ size_t size;
+
+ assert(min <= max);
+
+ size = sizeof (dt_idhash_t) +
+ sizeof (dt_ident_t *) * (_dtrace_strbuckets - 1);
+
+ if ((dhp = malloc(size)) == NULL)
+ return (NULL);
+
+ bzero(dhp, size);
+ dhp->dh_name = name;
+ dhp->dh_tmpl = tmpl;
+ dhp->dh_nextid = min;
+ dhp->dh_minid = min;
+ dhp->dh_maxid = max;
+ dhp->dh_hashsz = _dtrace_strbuckets;
+
+ return (dhp);
+}
+
+/*
+ * Destroy an entire identifier hash. This must be done using two passes with
+ * an inlined version of dt_ident_destroy() to avoid referencing freed memory.
+ * In the first pass di_dtor() is called for all identifiers; then the second
+ * pass frees the actual dt_ident_t's. These must be done separately because
+ * a di_dtor() may operate on data structures which contain references to other
+ * identifiers inside of this hash itself (e.g. a global inline definition
+ * which contains a parse tree that refers to another global variable).
+ */
+void
+dt_idhash_destroy(dt_idhash_t *dhp)
+{
+ dt_ident_t *idp, *next;
+ ulong_t i;
+
+ for (i = 0; i < dhp->dh_hashsz; i++) {
+ for (idp = dhp->dh_hash[i]; idp != NULL; idp = next) {
+ next = idp->di_next;
+ idp->di_ops->di_dtor(idp);
+ }
+ }
+
+ for (i = 0; i < dhp->dh_hashsz; i++) {
+ for (idp = dhp->dh_hash[i]; idp != NULL; idp = next) {
+ next = idp->di_next;
+ free(idp->di_name);
+ free(idp);
+ }
+ }
+
+ free(dhp);
+}
+
+void
+dt_idhash_update(dt_idhash_t *dhp)
+{
+ uint_t nextid = dhp->dh_minid;
+ dt_ident_t *idp;
+ ulong_t i;
+
+ for (i = 0; i < dhp->dh_hashsz; i++) {
+ for (idp = dhp->dh_hash[i]; idp != NULL; idp = idp->di_next) {
+ /*
+ * Right now we're hard coding which types need to be
+ * reset, but ideally this would be done dynamically.
+ */
+ if (idp->di_kind == DT_IDENT_ARRAY ||
+ idp->di_kind == DT_IDENT_SCALAR ||
+ idp->di_kind == DT_IDENT_AGG)
+ nextid = MAX(nextid, idp->di_id + 1);
+ }
+ }
+
+ dhp->dh_nextid = nextid;
+}
+
+dt_ident_t *
+dt_idhash_lookup(dt_idhash_t *dhp, const char *name)
+{
+ size_t len;
+ ulong_t h = dt_strtab_hash(name, &len) % dhp->dh_hashsz;
+ dt_ident_t *idp;
+
+ if (dhp->dh_tmpl != NULL)
+ dt_idhash_populate(dhp); /* fill hash w/ initial population */
+
+ for (idp = dhp->dh_hash[h]; idp != NULL; idp = idp->di_next) {
+ if (strcmp(idp->di_name, name) == 0)
+ return (idp);
+ }
+
+ return (NULL);
+}
+
+int
+dt_idhash_nextid(dt_idhash_t *dhp, uint_t *p)
+{
+ if (dhp->dh_nextid >= dhp->dh_maxid)
+ return (-1); /* no more id's are free to allocate */
+
+ *p = dhp->dh_nextid++;
+ return (0);
+}
+
+ulong_t
+dt_idhash_size(const dt_idhash_t *dhp)
+{
+ return (dhp->dh_nelems);
+}
+
+const char *
+dt_idhash_name(const dt_idhash_t *dhp)
+{
+ return (dhp->dh_name);
+}
+
+dt_ident_t *
+dt_idhash_insert(dt_idhash_t *dhp, const char *name, ushort_t kind,
+ ushort_t flags, uint_t id, dtrace_attribute_t attr, uint_t vers,
+ const dt_idops_t *ops, void *iarg, ulong_t gen)
+{
+ dt_ident_t *idp;
+ ulong_t h;
+
+ if (dhp->dh_tmpl != NULL)
+ dt_idhash_populate(dhp); /* fill hash w/ initial population */
+
+ idp = dt_ident_create(name, kind, flags, id,
+ attr, vers, ops, iarg, gen);
+
+ if (idp == NULL)
+ return (NULL);
+
+ h = dt_strtab_hash(name, NULL) % dhp->dh_hashsz;
+ idp->di_next = dhp->dh_hash[h];
+
+ dhp->dh_hash[h] = idp;
+ dhp->dh_nelems++;
+
+ if (dhp->dh_defer != NULL)
+ dhp->dh_defer(dhp, idp);
+
+ return (idp);
+}
+
+void
+dt_idhash_xinsert(dt_idhash_t *dhp, dt_ident_t *idp)
+{
+ ulong_t h;
+
+ if (dhp->dh_tmpl != NULL)
+ dt_idhash_populate(dhp); /* fill hash w/ initial population */
+
+ h = dt_strtab_hash(idp->di_name, NULL) % dhp->dh_hashsz;
+ idp->di_next = dhp->dh_hash[h];
+ idp->di_flags &= ~DT_IDFLG_ORPHAN;
+
+ dhp->dh_hash[h] = idp;
+ dhp->dh_nelems++;
+
+ if (dhp->dh_defer != NULL)
+ dhp->dh_defer(dhp, idp);
+}
+
+void
+dt_idhash_delete(dt_idhash_t *dhp, dt_ident_t *key)
+{
+ size_t len;
+ ulong_t h = dt_strtab_hash(key->di_name, &len) % dhp->dh_hashsz;
+ dt_ident_t **pp = &dhp->dh_hash[h];
+ dt_ident_t *idp;
+
+ for (idp = dhp->dh_hash[h]; idp != NULL; idp = idp->di_next) {
+ if (idp == key)
+ break;
+ else
+ pp = &idp->di_next;
+ }
+
+ assert(idp == key);
+ *pp = idp->di_next;
+
+ assert(dhp->dh_nelems != 0);
+ dhp->dh_nelems--;
+
+ if (!(idp->di_flags & DT_IDFLG_ORPHAN))
+ dt_ident_destroy(idp);
+}
+
+static int
+dt_idhash_comp(const void *lp, const void *rp)
+{
+ const dt_ident_t *lhs = *((const dt_ident_t **)lp);
+ const dt_ident_t *rhs = *((const dt_ident_t **)rp);
+
+ if (lhs->di_id != rhs->di_id)
+ return ((int)(lhs->di_id - rhs->di_id));
+ else
+ return (strcmp(lhs->di_name, rhs->di_name));
+}
+
+int
+dt_idhash_iter(dt_idhash_t *dhp, dt_idhash_f *func, void *data)
+{
+ dt_ident_t **ids;
+ dt_ident_t *idp;
+ ulong_t i, j, n;
+ int rv;
+
+ if (dhp->dh_tmpl != NULL)
+ dt_idhash_populate(dhp); /* fill hash w/ initial population */
+
+ n = dhp->dh_nelems;
+ ids = alloca(sizeof (dt_ident_t *) * n);
+
+ for (i = 0, j = 0; i < dhp->dh_hashsz; i++) {
+ for (idp = dhp->dh_hash[i]; idp != NULL; idp = idp->di_next)
+ ids[j++] = idp;
+ }
+
+ qsort(ids, dhp->dh_nelems, sizeof (dt_ident_t *), dt_idhash_comp);
+
+ for (i = 0; i < n; i++) {
+ if ((rv = func(dhp, ids[i], data)) != 0)
+ return (rv);
+ }
+
+ return (0);
+}
+
+dt_ident_t *
+dt_idstack_lookup(dt_idstack_t *sp, const char *name)
+{
+ dt_idhash_t *dhp;
+ dt_ident_t *idp;
+
+ for (dhp = dt_list_prev(&sp->dids_list);
+ dhp != NULL; dhp = dt_list_prev(dhp)) {
+ if ((idp = dt_idhash_lookup(dhp, name)) != NULL)
+ return (idp);
+ }
+
+ return (NULL);
+}
+
+void
+dt_idstack_push(dt_idstack_t *sp, dt_idhash_t *dhp)
+{
+ dt_list_append(&sp->dids_list, dhp);
+}
+
+void
+dt_idstack_pop(dt_idstack_t *sp, dt_idhash_t *dhp)
+{
+ assert(dt_list_prev(&sp->dids_list) == dhp);
+ dt_list_delete(&sp->dids_list, dhp);
+}
+
+dt_ident_t *
+dt_ident_create(const char *name, ushort_t kind, ushort_t flags, uint_t id,
+ dtrace_attribute_t attr, uint_t vers,
+ const dt_idops_t *ops, void *iarg, ulong_t gen)
+{
+ dt_ident_t *idp;
+ char *s = NULL;
+
+ if ((name != NULL && (s = strdup(name)) == NULL) ||
+ (idp = malloc(sizeof (dt_ident_t))) == NULL) {
+ free(s);
+ return (NULL);
+ }
+
+ idp->di_name = s;
+ idp->di_kind = kind;
+ idp->di_flags = flags;
+ idp->di_id = id;
+ idp->di_attr = attr;
+ idp->di_vers = vers;
+ idp->di_ops = ops;
+ idp->di_iarg = iarg;
+ idp->di_data = NULL;
+ idp->di_ctfp = NULL;
+ idp->di_type = CTF_ERR;
+ idp->di_next = NULL;
+ idp->di_gen = gen;
+ idp->di_lineno = yylineno;
+
+ return (idp);
+}
+
+/*
+ * Destroy an individual identifier. This code must be kept in sync with the
+ * dt_idhash_destroy() function below, which separates out the call to di_dtor.
+ */
+void
+dt_ident_destroy(dt_ident_t *idp)
+{
+ idp->di_ops->di_dtor(idp);
+ free(idp->di_name);
+ free(idp);
+}
+
+void
+dt_ident_morph(dt_ident_t *idp, ushort_t kind,
+ const dt_idops_t *ops, void *iarg)
+{
+ idp->di_ops->di_dtor(idp);
+ idp->di_kind = kind;
+ idp->di_ops = ops;
+ idp->di_iarg = iarg;
+ idp->di_data = NULL;
+}
+
+dtrace_attribute_t
+dt_ident_cook(dt_node_t *dnp, dt_ident_t *idp, dt_node_t **pargp)
+{
+ dtrace_attribute_t attr;
+ dt_node_t *args, *argp;
+ int argc = 0;
+
+ attr = dt_node_list_cook(pargp, DT_IDFLG_REF);
+ args = pargp ? *pargp : NULL;
+
+ for (argp = args; argp != NULL; argp = argp->dn_list)
+ argc++;
+
+ idp->di_ops->di_cook(dnp, idp, argc, args);
+
+ if (idp->di_flags & DT_IDFLG_USER)
+ dnp->dn_flags |= DT_NF_USERLAND;
+
+ return (dt_attr_min(attr, idp->di_attr));
+}
+
+void
+dt_ident_type_assign(dt_ident_t *idp, ctf_file_t *fp, ctf_id_t type)
+{
+ idp->di_ctfp = fp;
+ idp->di_type = type;
+}
+
+dt_ident_t *
+dt_ident_resolve(dt_ident_t *idp)
+{
+ while (idp->di_flags & DT_IDFLG_INLINE) {
+ const dt_node_t *dnp = ((dt_idnode_t *)idp->di_iarg)->din_root;
+
+ if (dnp == NULL)
+ break; /* can't resolve any further yet */
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_VAR:
+ case DT_NODE_SYM:
+ case DT_NODE_FUNC:
+ case DT_NODE_AGG:
+ case DT_NODE_INLINE:
+ case DT_NODE_PROBE:
+ idp = dnp->dn_ident;
+ continue;
+ }
+
+ if (dt_node_is_dynamic(dnp))
+ idp = dnp->dn_ident;
+ else
+ break;
+ }
+
+ return (idp);
+}
+
+size_t
+dt_ident_size(dt_ident_t *idp)
+{
+ idp = dt_ident_resolve(idp);
+ return (idp->di_ops->di_size(idp));
+}
+
+int
+dt_ident_unref(const dt_ident_t *idp)
+{
+ return (idp->di_gen == yypcb->pcb_hdl->dt_gen &&
+ (idp->di_flags & (DT_IDFLG_REF|DT_IDFLG_MOD|DT_IDFLG_DECL)) == 0);
+}
+
+const char *
+dt_idkind_name(uint_t kind)
+{
+ switch (kind) {
+ case DT_IDENT_ARRAY: return ("associative array");
+ case DT_IDENT_SCALAR: return ("scalar");
+ case DT_IDENT_PTR: return ("pointer");
+ case DT_IDENT_FUNC: return ("function");
+ case DT_IDENT_AGG: return ("aggregation");
+ case DT_IDENT_AGGFUNC: return ("aggregating function");
+ case DT_IDENT_ACTFUNC: return ("tracing function");
+ case DT_IDENT_XLSOU: return ("translated data");
+ case DT_IDENT_XLPTR: return ("pointer to translated data");
+ case DT_IDENT_SYMBOL: return ("external symbol reference");
+ case DT_IDENT_ENUM: return ("enumerator");
+ case DT_IDENT_PRAGAT: return ("#pragma attributes");
+ case DT_IDENT_PRAGBN: return ("#pragma binding");
+ case DT_IDENT_PROBE: return ("probe definition");
+ default: return ("<?>");
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.h
new file mode 100644
index 0000000..cc80d6e
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.h
@@ -0,0 +1,183 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_IDENT_H
+#define _DT_IDENT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libctf.h>
+#include <dtrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dt_list.h>
+
+struct dt_node;
+struct dt_ident;
+struct dt_idhash;
+struct dt_irlist;
+struct dt_regset;
+
+typedef struct dt_idsig {
+ int dis_varargs; /* argument index of start of varargs (or -1) */
+ int dis_optargs; /* argument index of start of optargs (or -1) */
+ int dis_argc; /* number of types in this signature */
+ struct dt_node *dis_args; /* array of nodes representing formal types */
+ uint64_t dis_auxinfo; /* auxiliary signature information, if any */
+} dt_idsig_t;
+
+typedef struct dt_idnode {
+ struct dt_node *din_list; /* allocation list for parse tree nodes */
+ struct dt_node *din_root; /* root of this identifier's parse tree */
+ struct dt_idhash *din_hash; /* identifiers private to this subtree */
+ struct dt_ident **din_argv; /* identifiers in din_hash for arguments */
+ int din_argc; /* length of din_argv[] array */
+} dt_idnode_t;
+
+typedef struct dt_idops {
+ void (*di_cook)(struct dt_node *, struct dt_ident *,
+ int, struct dt_node *);
+ void (*di_dtor)(struct dt_ident *);
+ size_t (*di_size)(struct dt_ident *);
+} dt_idops_t;
+
+typedef struct dt_ident {
+ char *di_name; /* identifier name */
+ ushort_t di_kind; /* identifier kind (see below) */
+ ushort_t di_flags; /* identifier flags (see below) */
+ uint_t di_id; /* variable or subr id (see <sys/dtrace.h>) */
+ dtrace_attribute_t di_attr; /* identifier stability attributes */
+ uint_t di_vers; /* identifier version number (dt_version_t) */
+ const dt_idops_t *di_ops; /* identifier's class-specific ops vector */
+ void *di_iarg; /* initial argument pointer for ops vector */
+ void *di_data; /* private data pointer for ops vector */
+ ctf_file_t *di_ctfp; /* CTF container for the variable data type */
+ ctf_id_t di_type; /* CTF identifier for the variable data type */
+ struct dt_ident *di_next; /* pointer to next ident in hash chain */
+ ulong_t di_gen; /* generation number (pass that created me) */
+ int di_lineno; /* line number that defined this identifier */
+} dt_ident_t;
+
+#define DT_IDENT_ARRAY 0 /* identifier is an array variable */
+#define DT_IDENT_SCALAR 1 /* identifier is a scalar variable */
+#define DT_IDENT_PTR 2 /* identifier is a magic pointer */
+#define DT_IDENT_FUNC 3 /* identifier is a built-in function */
+#define DT_IDENT_AGG 4 /* identifier is an aggregation */
+#define DT_IDENT_AGGFUNC 5 /* identifier is an aggregating function */
+#define DT_IDENT_ACTFUNC 6 /* identifier is an action function */
+#define DT_IDENT_XLSOU 7 /* identifier is a translated struct or union */
+#define DT_IDENT_XLPTR 8 /* identifier is a translated pointer */
+#define DT_IDENT_SYMBOL 9 /* identifier is an external symbol */
+#define DT_IDENT_ENUM 10 /* identifier is an enumerator */
+#define DT_IDENT_PRAGAT 11 /* identifier is #pragma attributes */
+#define DT_IDENT_PRAGBN 12 /* identifier is #pragma binding */
+#define DT_IDENT_PROBE 13 /* identifier is a probe definition */
+
+#define DT_IDFLG_TLS 0x0001 /* variable is thread-local storage */
+#define DT_IDFLG_LOCAL 0x0002 /* variable is local storage */
+#define DT_IDFLG_WRITE 0x0004 /* variable is writable (can be modified) */
+#define DT_IDFLG_INLINE 0x0008 /* variable is an inline definition */
+#define DT_IDFLG_REF 0x0010 /* variable is referenced by this program */
+#define DT_IDFLG_MOD 0x0020 /* variable is modified by this program */
+#define DT_IDFLG_DIFR 0x0040 /* variable is referenced by current DIFO */
+#define DT_IDFLG_DIFW 0x0080 /* variable is modified by current DIFO */
+#define DT_IDFLG_CGREG 0x0100 /* variable is inlined by code generator */
+#define DT_IDFLG_USER 0x0200 /* variable is associated with userland */
+#define DT_IDFLG_PRIM 0x0400 /* variable is associated with primary object */
+#define DT_IDFLG_DECL 0x0800 /* variable is associated with explicit decl */
+#define DT_IDFLG_ORPHAN 0x1000 /* variable is in a dt_node and not dt_idhash */
+
+typedef struct dt_idhash {
+ dt_list_t dh_list; /* list prev/next pointers for dt_idstack */
+ const char *dh_name; /* name of this hash table */
+ void (*dh_defer)(struct dt_idhash *, dt_ident_t *); /* defer callback */
+ const dt_ident_t *dh_tmpl; /* template for initial ident population */
+ uint_t dh_nextid; /* next id to be returned by idhash_nextid() */
+ uint_t dh_minid; /* min id to be returned by idhash_nextid() */
+ uint_t dh_maxid; /* max id to be returned by idhash_nextid() */
+ ulong_t dh_nelems; /* number of identifiers in hash table */
+ ulong_t dh_hashsz; /* number of entries in dh_buckets array */
+ dt_ident_t *dh_hash[1]; /* array of hash table bucket pointers */
+} dt_idhash_t;
+
+typedef struct dt_idstack {
+ dt_list_t dids_list; /* list meta-data for dt_idhash_t stack */
+} dt_idstack_t;
+
+extern const dt_idops_t dt_idops_assc; /* associative array or aggregation */
+extern const dt_idops_t dt_idops_func; /* function call built-in */
+extern const dt_idops_t dt_idops_args; /* args[] built-in */
+extern const dt_idops_t dt_idops_regs; /* regs[]/uregs[] built-in */
+extern const dt_idops_t dt_idops_type; /* predefined type name string */
+extern const dt_idops_t dt_idops_thaw; /* prefrozen type identifier */
+extern const dt_idops_t dt_idops_inline; /* inline variable */
+extern const dt_idops_t dt_idops_probe; /* probe definition */
+
+extern dt_idhash_t *dt_idhash_create(const char *, const dt_ident_t *,
+ uint_t, uint_t);
+extern void dt_idhash_destroy(dt_idhash_t *);
+extern void dt_idhash_update(dt_idhash_t *);
+extern dt_ident_t *dt_idhash_lookup(dt_idhash_t *, const char *);
+extern int dt_idhash_nextid(dt_idhash_t *, uint_t *);
+extern ulong_t dt_idhash_size(const dt_idhash_t *);
+extern const char *dt_idhash_name(const dt_idhash_t *);
+
+extern dt_ident_t *dt_idhash_insert(dt_idhash_t *, const char *, ushort_t,
+ ushort_t, uint_t, dtrace_attribute_t, uint_t,
+ const dt_idops_t *, void *, ulong_t);
+
+extern void dt_idhash_xinsert(dt_idhash_t *, dt_ident_t *);
+extern void dt_idhash_delete(dt_idhash_t *, dt_ident_t *);
+
+typedef int dt_idhash_f(dt_idhash_t *, dt_ident_t *, void *);
+extern int dt_idhash_iter(dt_idhash_t *, dt_idhash_f *, void *);
+
+extern dt_ident_t *dt_idstack_lookup(dt_idstack_t *, const char *);
+extern void dt_idstack_push(dt_idstack_t *, dt_idhash_t *);
+extern void dt_idstack_pop(dt_idstack_t *, dt_idhash_t *);
+
+extern dt_ident_t *dt_ident_create(const char *, ushort_t, ushort_t, uint_t,
+ dtrace_attribute_t, uint_t, const dt_idops_t *, void *, ulong_t);
+extern void dt_ident_destroy(dt_ident_t *);
+extern void dt_ident_morph(dt_ident_t *, ushort_t, const dt_idops_t *, void *);
+extern dtrace_attribute_t dt_ident_cook(struct dt_node *,
+ dt_ident_t *, struct dt_node **);
+
+extern void dt_ident_type_assign(dt_ident_t *, ctf_file_t *, ctf_id_t);
+extern dt_ident_t *dt_ident_resolve(dt_ident_t *);
+extern size_t dt_ident_size(dt_ident_t *);
+extern int dt_ident_unref(const dt_ident_t *);
+
+extern const char *dt_idkind_name(uint_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_IDENT_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
new file mode 100644
index 0000000..61d901b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
@@ -0,0 +1,706 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#ifndef _DT_IMPL_H
+#define _DT_IMPL_H
+
+#include <sys/param.h>
+#include <sys/objfs.h>
+#if !defined(sun)
+#include <sys/bitmap.h>
+#include <sys/utsname.h>
+#include <sys/ioccom.h>
+#include <sys/time.h>
+#include <string.h>
+#endif
+#include <setjmp.h>
+#include <libctf.h>
+#include <dtrace.h>
+#include <gelf.h>
+#if defined(sun)
+#include <synch.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dt_parser.h>
+#include <dt_regset.h>
+#include <dt_inttab.h>
+#include <dt_strtab.h>
+#include <dt_ident.h>
+#include <dt_list.h>
+#include <dt_decl.h>
+#include <dt_as.h>
+#include <dt_proc.h>
+#include <dt_dof.h>
+#include <dt_pcb.h>
+
+struct dt_module; /* see below */
+struct dt_pfdict; /* see <dt_printf.h> */
+struct dt_arg; /* see below */
+struct dt_provider; /* see <dt_provider.h> */
+struct dt_xlator; /* see <dt_xlator.h> */
+
+typedef struct dt_intrinsic {
+ const char *din_name; /* string name of the intrinsic type */
+ ctf_encoding_t din_data; /* integer or floating-point CTF encoding */
+ uint_t din_kind; /* CTF type kind to instantiate */
+} dt_intrinsic_t;
+
+typedef struct dt_typedef {
+ const char *dty_src; /* string name of typedef source type */
+ const char *dty_dst; /* string name of typedef destination type */
+} dt_typedef_t;
+
+typedef struct dt_intdesc {
+ const char *did_name; /* string name of the integer type */
+ ctf_file_t *did_ctfp; /* CTF container for this type reference */
+ ctf_id_t did_type; /* CTF type reference for this type */
+ uintmax_t did_limit; /* maximum positive value held by type */
+} dt_intdesc_t;
+
+typedef struct dt_modops {
+ uint_t (*do_syminit)(struct dt_module *);
+ void (*do_symsort)(struct dt_module *);
+ GElf_Sym *(*do_symname)(struct dt_module *,
+ const char *, GElf_Sym *, uint_t *);
+ GElf_Sym *(*do_symaddr)(struct dt_module *,
+ GElf_Addr, GElf_Sym *, uint_t *);
+} dt_modops_t;
+
+typedef struct dt_arg {
+ int da_ndx; /* index of this argument */
+ int da_mapping; /* mapping of argument indices to arguments */
+ ctf_id_t da_type; /* type of argument */
+ ctf_file_t *da_ctfp; /* CTF container for type */
+ dt_ident_t *da_xlator; /* translator, if any */
+ struct dt_arg *da_next; /* next argument */
+} dt_arg_t;
+
+typedef struct dt_sym {
+ uint_t ds_symid; /* id of corresponding symbol */
+ uint_t ds_next; /* index of next element in hash chain */
+} dt_sym_t;
+
+typedef struct dt_module {
+ dt_list_t dm_list; /* list forward/back pointers */
+ char dm_name[DTRACE_MODNAMELEN]; /* string name of module */
+ char dm_file[MAXPATHLEN]; /* file path of module (if any) */
+ struct dt_module *dm_next; /* pointer to next module in hash chain */
+ const dt_modops_t *dm_ops; /* pointer to data model's ops vector */
+ Elf *dm_elf; /* libelf handle for module object */
+ objfs_info_t dm_info; /* object filesystem private info */
+ ctf_sect_t dm_symtab; /* symbol table for module */
+ ctf_sect_t dm_strtab; /* string table for module */
+ ctf_sect_t dm_ctdata; /* CTF data for module */
+ ctf_file_t *dm_ctfp; /* CTF container handle */
+ uint_t *dm_symbuckets; /* symbol table hash buckets (chain indices) */
+ dt_sym_t *dm_symchains; /* symbol table hash chains buffer */
+ void *dm_asmap; /* symbol pointers sorted by value */
+ uint_t dm_symfree; /* index of next free hash element */
+ uint_t dm_nsymbuckets; /* number of elements in bucket array */
+ uint_t dm_nsymelems; /* number of elements in hash table */
+ uint_t dm_asrsv; /* actual reserved size of dm_asmap */
+ uint_t dm_aslen; /* number of entries in dm_asmap */
+ uint_t dm_flags; /* module flags (see below) */
+ int dm_modid; /* modinfo(1M) module identifier */
+ GElf_Addr dm_text_va; /* virtual address of text section */
+ GElf_Xword dm_text_size; /* size in bytes of text section */
+ GElf_Addr dm_data_va; /* virtual address of data section */
+ GElf_Xword dm_data_size; /* size in bytes of data section */
+ GElf_Addr dm_bss_va; /* virtual address of BSS */
+ GElf_Xword dm_bss_size; /* size in bytes of BSS */
+ dt_idhash_t *dm_extern; /* external symbol definitions */
+#if !defined(sun)
+ caddr_t dm_reloc_offset; /* Symbol relocation offset. */
+ uintptr_t *dm_sec_offsets;
+#endif
+} dt_module_t;
+
+#define DT_DM_LOADED 0x1 /* module symbol and type data is loaded */
+#define DT_DM_KERNEL 0x2 /* module is associated with a kernel object */
+#define DT_DM_PRIMARY 0x4 /* module is a krtld primary kernel object */
+
+typedef struct dt_provmod {
+ char *dp_name; /* name of provider module */
+ struct dt_provmod *dp_next; /* next module */
+} dt_provmod_t;
+
+typedef struct dt_ahashent {
+ struct dt_ahashent *dtahe_prev; /* prev on hash chain */
+ struct dt_ahashent *dtahe_next; /* next on hash chain */
+ struct dt_ahashent *dtahe_prevall; /* prev on list of all */
+ struct dt_ahashent *dtahe_nextall; /* next on list of all */
+ uint64_t dtahe_hashval; /* hash value */
+ size_t dtahe_size; /* size of data */
+ dtrace_aggdata_t dtahe_data; /* data */
+ void (*dtahe_aggregate)(int64_t *, int64_t *, size_t); /* function */
+} dt_ahashent_t;
+
+typedef struct dt_ahash {
+ dt_ahashent_t **dtah_hash; /* hash table */
+ dt_ahashent_t *dtah_all; /* list of all elements */
+ size_t dtah_size; /* size of hash table */
+} dt_ahash_t;
+
+typedef struct dt_aggregate {
+ dtrace_bufdesc_t dtat_buf; /* buf aggregation snapshot */
+ int dtat_flags; /* aggregate flags */
+ processorid_t dtat_ncpus; /* number of CPUs in aggregate */
+ processorid_t *dtat_cpus; /* CPUs in aggregate */
+ processorid_t dtat_ncpu; /* size of dtat_cpus array */
+ processorid_t dtat_maxcpu; /* maximum number of CPUs */
+ dt_ahash_t dtat_hash; /* aggregate hash table */
+} dt_aggregate_t;
+
+typedef struct dt_print_aggdata {
+ dtrace_hdl_t *dtpa_dtp; /* pointer to libdtrace handle */
+ dtrace_aggvarid_t dtpa_id; /* aggregation variable of interest */
+ FILE *dtpa_fp; /* file pointer */
+ int dtpa_allunprint; /* print only unprinted aggregations */
+} dt_print_aggdata_t;
+
+typedef struct dt_dirpath {
+ dt_list_t dir_list; /* linked-list forward/back pointers */
+ char *dir_path; /* directory pathname */
+} dt_dirpath_t;
+
+typedef struct dt_lib_depend {
+ dt_list_t dtld_deplist; /* linked-list forward/back pointers */
+ char *dtld_library; /* library name */
+ char *dtld_libpath; /* library pathname */
+ uint_t dtld_finish; /* completion time in tsort for lib */
+ uint_t dtld_start; /* starting time in tsort for lib */
+ uint_t dtld_loaded; /* boolean: is this library loaded */
+ dt_list_t dtld_dependencies; /* linked-list of lib dependencies */
+ dt_list_t dtld_dependents; /* linked-list of lib dependents */
+} dt_lib_depend_t;
+
+typedef uint32_t dt_version_t; /* encoded version (see below) */
+
+struct dtrace_hdl {
+ const dtrace_vector_t *dt_vector; /* library vector, if vectored open */
+ void *dt_varg; /* vector argument, if vectored open */
+ dtrace_conf_t dt_conf; /* DTrace driver configuration profile */
+ char dt_errmsg[BUFSIZ]; /* buffer for formatted syntax error msgs */
+ const char *dt_errtag; /* tag used with last call to dt_set_errmsg() */
+ dt_pcb_t *dt_pcb; /* pointer to current parsing control block */
+ ulong_t dt_gen; /* compiler generation number */
+ dt_list_t dt_programs; /* linked list of dtrace_prog_t's */
+ dt_list_t dt_xlators; /* linked list of dt_xlator_t's */
+ struct dt_xlator **dt_xlatormap; /* dt_xlator_t's indexed by dx_id */
+ id_t dt_xlatorid; /* next dt_xlator_t id to assign */
+ dt_ident_t *dt_externs; /* linked list of external symbol identifiers */
+ dt_idhash_t *dt_macros; /* hash table of macro variable identifiers */
+ dt_idhash_t *dt_aggs; /* hash table of aggregation identifiers */
+ dt_idhash_t *dt_globals; /* hash table of global identifiers */
+ dt_idhash_t *dt_tls; /* hash table of thread-local identifiers */
+ dt_list_t dt_modlist; /* linked list of dt_module_t's */
+ dt_module_t **dt_mods; /* hash table of dt_module_t's */
+ uint_t dt_modbuckets; /* number of module hash buckets */
+ uint_t dt_nmods; /* number of modules in hash and list */
+ dt_provmod_t *dt_provmod; /* linked list of provider modules */
+ dt_module_t *dt_exec; /* pointer to executable module */
+ dt_module_t *dt_rtld; /* pointer to run-time linker module */
+ dt_module_t *dt_cdefs; /* pointer to C dynamic type module */
+ dt_module_t *dt_ddefs; /* pointer to D dynamic type module */
+ dt_list_t dt_provlist; /* linked list of dt_provider_t's */
+ struct dt_provider **dt_provs; /* hash table of dt_provider_t's */
+ uint_t dt_provbuckets; /* number of provider hash buckets */
+ uint_t dt_nprovs; /* number of providers in hash and list */
+ dt_proc_hash_t *dt_procs; /* hash table of grabbed process handles */
+ dt_intdesc_t dt_ints[6]; /* cached integer type descriptions */
+ ctf_id_t dt_type_func; /* cached CTF identifier for function type */
+ ctf_id_t dt_type_fptr; /* cached CTF identifier for function pointer */
+ ctf_id_t dt_type_str; /* cached CTF identifier for string type */
+ ctf_id_t dt_type_dyn; /* cached CTF identifier for <DYN> type */
+ ctf_id_t dt_type_stack; /* cached CTF identifier for stack type */
+ ctf_id_t dt_type_symaddr; /* cached CTF identifier for _symaddr type */
+ ctf_id_t dt_type_usymaddr; /* cached CTF ident. for _usymaddr type */
+ size_t dt_maxprobe; /* max enabled probe ID */
+ dtrace_eprobedesc_t **dt_edesc; /* enabled probe descriptions */
+ dtrace_probedesc_t **dt_pdesc; /* probe descriptions for enabled prbs */
+ size_t dt_maxagg; /* max aggregation ID */
+ dtrace_aggdesc_t **dt_aggdesc; /* aggregation descriptions */
+ int dt_maxformat; /* max format ID */
+ void **dt_formats; /* pointer to format array */
+ int dt_maxstrdata; /* max strdata ID */
+ char **dt_strdata; /* pointer to strdata array */
+ dt_aggregate_t dt_aggregate; /* aggregate */
+ dtrace_bufdesc_t dt_buf; /* staging buffer */
+ struct dt_pfdict *dt_pfdict; /* dictionary of printf conversions */
+ dt_version_t dt_vmax; /* optional ceiling on program API binding */
+ dtrace_attribute_t dt_amin; /* optional floor on program attributes */
+ char *dt_cpp_path; /* pathname of cpp(1) to invoke if needed */
+ char **dt_cpp_argv; /* argument vector for exec'ing cpp(1) */
+ int dt_cpp_argc; /* count of initialized cpp(1) arguments */
+ int dt_cpp_args; /* size of dt_cpp_argv[] array */
+ char *dt_ld_path; /* pathname of ld(1) to invoke if needed */
+ dt_list_t dt_lib_path; /* linked-list forming library search path */
+ uint_t dt_lazyload; /* boolean: set via -xlazyload */
+ uint_t dt_droptags; /* boolean: set via -xdroptags */
+ uint_t dt_active; /* boolean: set once tracing is active */
+ uint_t dt_stopped; /* boolean: set once tracing is stopped */
+ processorid_t dt_beganon; /* CPU that executed BEGIN probe (if any) */
+ processorid_t dt_endedon; /* CPU that executed END probe (if any) */
+ uint_t dt_oflags; /* dtrace open-time options (see dtrace.h) */
+ uint_t dt_cflags; /* dtrace compile-time options (see dtrace.h) */
+ uint_t dt_dflags; /* dtrace link-time options (see dtrace.h) */
+ uint_t dt_prcmode; /* dtrace process create mode (see dt_proc.h) */
+ uint_t dt_linkmode; /* dtrace symbol linking mode (see below) */
+ uint_t dt_linktype; /* dtrace link output file type (see below) */
+ uint_t dt_xlatemode; /* dtrace translator linking mode (see below) */
+ uint_t dt_stdcmode; /* dtrace stdc compatibility mode (see below) */
+ uint_t dt_treedump; /* dtrace tree debug bitmap (see below) */
+ uint64_t dt_options[DTRACEOPT_MAX]; /* dtrace run-time options */
+ int dt_version; /* library version requested by client */
+ int dt_ctferr; /* error resulting from last CTF failure */
+ int dt_errno; /* error resulting from last failed operation */
+#if !defined(sun)
+ const char *dt_errfile;
+ int dt_errline;
+#endif
+ int dt_fd; /* file descriptor for dtrace pseudo-device */
+ int dt_ftfd; /* file descriptor for fasttrap pseudo-device */
+ int dt_fterr; /* saved errno from failed open of dt_ftfd */
+ int dt_cdefs_fd; /* file descriptor for C CTF debugging cache */
+ int dt_ddefs_fd; /* file descriptor for D CTF debugging cache */
+#if defined(sun)
+ int dt_stdout_fd; /* file descriptor for saved stdout */
+#else
+ FILE *dt_freopen_fp; /* file pointer for freopened stdout */
+#endif
+ dtrace_handle_err_f *dt_errhdlr; /* error handler, if any */
+ void *dt_errarg; /* error handler argument */
+ dtrace_prog_t *dt_errprog; /* error handler program, if any */
+ dtrace_handle_drop_f *dt_drophdlr; /* drop handler, if any */
+ void *dt_droparg; /* drop handler argument */
+ dtrace_handle_proc_f *dt_prochdlr; /* proc handler, if any */
+ void *dt_procarg; /* proc handler argument */
+ dtrace_handle_setopt_f *dt_setopthdlr; /* setopt handler, if any */
+ void *dt_setoptarg; /* setopt handler argument */
+ dtrace_status_t dt_status[2]; /* status cache */
+ int dt_statusgen; /* current status generation */
+ hrtime_t dt_laststatus; /* last status */
+ hrtime_t dt_lastswitch; /* last switch of buffer data */
+ hrtime_t dt_lastagg; /* last snapshot of aggregation data */
+ char *dt_sprintf_buf; /* buffer for dtrace_sprintf() */
+ int dt_sprintf_buflen; /* length of dtrace_sprintf() buffer */
+ const char *dt_filetag; /* default filetag for dt_set_errmsg() */
+ char *dt_buffered_buf; /* buffer for buffered output */
+ size_t dt_buffered_offs; /* current offset into buffered buffer */
+ size_t dt_buffered_size; /* size of buffered buffer */
+ dtrace_handle_buffered_f *dt_bufhdlr; /* buffered handler, if any */
+ void *dt_bufarg; /* buffered handler argument */
+ dt_dof_t dt_dof; /* DOF generation buffers (see dt_dof.c) */
+ struct utsname dt_uts; /* uname(2) information for system */
+ dt_list_t dt_lib_dep; /* scratch linked-list of lib dependencies */
+ dt_list_t dt_lib_dep_sorted; /* dependency sorted library list */
+};
+
+/*
+ * Values for the user arg of the ECB.
+ */
+#define DT_ECB_DEFAULT 0
+#define DT_ECB_ERROR 1
+
+/*
+ * Values for the dt_linkmode property, which is used by the assembler when
+ * processing external symbol references. User can set using -xlink=<mode>.
+ */
+#define DT_LINK_KERNEL 0 /* kernel syms static, user syms dynamic */
+#define DT_LINK_PRIMARY 1 /* primary kernel syms static, others dynamic */
+#define DT_LINK_DYNAMIC 2 /* all symbols dynamic */
+#define DT_LINK_STATIC 3 /* all symbols static */
+
+/*
+ * Values for the dt_linktype property, which is used by dtrace_program_link()
+ * to determine the type of output file that is desired by the client.
+ */
+#define DT_LTYP_ELF 0 /* produce ELF containing DOF */
+#define DT_LTYP_DOF 1 /* produce stand-alone DOF */
+
+/*
+ * Values for the dt_xlatemode property, which is used to determine whether
+ * references to dynamic translators are permitted. Set using -xlate=<mode>.
+ */
+#define DT_XL_STATIC 0 /* require xlators to be statically defined */
+#define DT_XL_DYNAMIC 1 /* produce references to dynamic translators */
+
+/*
+ * Values for the dt_stdcmode property, which is used by the compiler when
+ * running cpp to determine the presence and setting of the __STDC__ macro.
+ */
+#define DT_STDC_XA 0 /* ISO C + K&R C compat w/o ISO: __STDC__=0 */
+#define DT_STDC_XC 1 /* Strict ISO C: __STDC__=1 */
+#define DT_STDC_XS 2 /* K&R C: __STDC__ not defined */
+#define DT_STDC_XT 3 /* ISO C + K&R C compat with ISO: __STDC__=0 */
+
+/*
+ * Macro to test whether a given pass bit is set in the dt_treedump bit-vector.
+ * If the bit for pass 'p' is set, the D compiler displays the parse tree for
+ * the program by printing it to stderr at the end of compiler pass 'p'.
+ */
+#define DT_TREEDUMP_PASS(dtp, p) ((dtp)->dt_treedump & (1 << ((p) - 1)))
+
+/*
+ * Macros for accessing the cached CTF container and type ID for the common
+ * types "int", "string", and <DYN>, which we need to use frequently in the D
+ * compiler. The DT_INT_* macro relies upon "int" being at index 0 in the
+ * _dtrace_ints_* tables in dt_open.c; the others are also set up there.
+ */
+#define DT_INT_CTFP(dtp) ((dtp)->dt_ints[0].did_ctfp)
+#define DT_INT_TYPE(dtp) ((dtp)->dt_ints[0].did_type)
+
+#define DT_FUNC_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_FUNC_TYPE(dtp) ((dtp)->dt_type_func)
+
+#define DT_FPTR_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_FPTR_TYPE(dtp) ((dtp)->dt_type_fptr)
+
+#define DT_STR_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_STR_TYPE(dtp) ((dtp)->dt_type_str)
+
+#define DT_DYN_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_DYN_TYPE(dtp) ((dtp)->dt_type_dyn)
+
+#define DT_STACK_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_STACK_TYPE(dtp) ((dtp)->dt_type_stack)
+
+#define DT_SYMADDR_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_SYMADDR_TYPE(dtp) ((dtp)->dt_type_symaddr)
+
+#define DT_USYMADDR_CTFP(dtp) ((dtp)->dt_ddefs->dm_ctfp)
+#define DT_USYMADDR_TYPE(dtp) ((dtp)->dt_type_usymaddr)
+
+/*
+ * Actions and subroutines are both DT_NODE_FUNC nodes; to avoid confusing
+ * an action for a subroutine (or vice versa), we assure that the DT_ACT_*
+ * constants and the DIF_SUBR_* constants occupy non-overlapping ranges by
+ * starting the DT_ACT_* constants at DIF_SUBR_MAX + 1.
+ */
+#define DT_ACT_BASE DIF_SUBR_MAX + 1
+#define DT_ACT(n) (DT_ACT_BASE + (n))
+
+#define DT_ACT_PRINTF DT_ACT(0) /* printf() action */
+#define DT_ACT_TRACE DT_ACT(1) /* trace() action */
+#define DT_ACT_TRACEMEM DT_ACT(2) /* tracemem() action */
+#define DT_ACT_STACK DT_ACT(3) /* stack() action */
+#define DT_ACT_STOP DT_ACT(4) /* stop() action */
+#define DT_ACT_BREAKPOINT DT_ACT(5) /* breakpoint() action */
+#define DT_ACT_PANIC DT_ACT(6) /* panic() action */
+#define DT_ACT_SPECULATE DT_ACT(7) /* speculate() action */
+#define DT_ACT_COMMIT DT_ACT(8) /* commit() action */
+#define DT_ACT_DISCARD DT_ACT(9) /* discard() action */
+#define DT_ACT_CHILL DT_ACT(10) /* chill() action */
+#define DT_ACT_EXIT DT_ACT(11) /* exit() action */
+#define DT_ACT_USTACK DT_ACT(12) /* ustack() action */
+#define DT_ACT_PRINTA DT_ACT(13) /* printa() action */
+#define DT_ACT_RAISE DT_ACT(14) /* raise() action */
+#define DT_ACT_CLEAR DT_ACT(15) /* clear() action */
+#define DT_ACT_NORMALIZE DT_ACT(16) /* normalize() action */
+#define DT_ACT_DENORMALIZE DT_ACT(17) /* denormalize() action */
+#define DT_ACT_TRUNC DT_ACT(18) /* trunc() action */
+#define DT_ACT_SYSTEM DT_ACT(19) /* system() action */
+#define DT_ACT_JSTACK DT_ACT(20) /* jstack() action */
+#define DT_ACT_FTRUNCATE DT_ACT(21) /* ftruncate() action */
+#define DT_ACT_FREOPEN DT_ACT(22) /* freopen() action */
+#define DT_ACT_SYM DT_ACT(23) /* sym()/func() actions */
+#define DT_ACT_MOD DT_ACT(24) /* mod() action */
+#define DT_ACT_USYM DT_ACT(25) /* usym()/ufunc() actions */
+#define DT_ACT_UMOD DT_ACT(26) /* umod() action */
+#define DT_ACT_UADDR DT_ACT(27) /* uaddr() action */
+#define DT_ACT_SETOPT DT_ACT(28) /* setopt() action */
+#define DT_ACT_PRINT DT_ACT(29) /* print() action */
+#define DT_ACT_PRINTM DT_ACT(30) /* printm() action */
+#define DT_ACT_PRINTT DT_ACT(31) /* printt() action */
+
+/*
+ * Sentinel to tell freopen() to restore the saved stdout. This must not
+ * be ever valid for opening for write access via freopen(3C), which of
+ * course, "." never is.
+ */
+#define DT_FREOPEN_RESTORE "."
+
+#define EDT_BASE 1000 /* base value for libdtrace errnos */
+
+enum {
+ EDT_VERSION = EDT_BASE, /* client is requesting unsupported version */
+ EDT_VERSINVAL, /* version string is invalid or overflows */
+ EDT_VERSUNDEF, /* requested API version is not defined */
+ EDT_VERSREDUCED, /* requested API version has been reduced */
+ EDT_CTF, /* libctf called failed (dt_ctferr has more) */
+ EDT_COMPILER, /* error in D program compilation */
+ EDT_NOREG, /* register allocation failure */
+ EDT_NOTUPREG, /* tuple register allocation failure */
+ EDT_NOMEM, /* memory allocation failure */
+ EDT_INT2BIG, /* integer limit exceeded */
+ EDT_STR2BIG, /* string limit exceeded */
+ EDT_NOMOD, /* unknown module name */
+ EDT_NOPROV, /* unknown provider name */
+ EDT_NOPROBE, /* unknown probe name */
+ EDT_NOSYM, /* unknown symbol name */
+ EDT_NOSYMADDR, /* no symbol corresponds to address */
+ EDT_NOTYPE, /* unknown type name */
+ EDT_NOVAR, /* unknown variable name */
+ EDT_NOAGG, /* unknown aggregation name */
+ EDT_BADSCOPE, /* improper use of type name scoping operator */
+ EDT_BADSPEC, /* overspecified probe description */
+ EDT_BADSPCV, /* bad macro variable in probe description */
+ EDT_BADID, /* invalid probe identifier */
+ EDT_NOTLOADED, /* module is not currently loaded */
+ EDT_NOCTF, /* module does not contain any CTF data */
+ EDT_DATAMODEL, /* module and program data models don't match */
+ EDT_DIFVERS, /* library has newer DIF version than driver */
+ EDT_BADAGG, /* unrecognized aggregating action */
+ EDT_FIO, /* file i/o error */
+ EDT_DIFINVAL, /* invalid DIF program */
+ EDT_DIFSIZE, /* invalid DIF size */
+ EDT_DIFFAULT, /* failed to copyin DIF program */
+ EDT_BADPROBE, /* bad probe description */
+ EDT_BADPGLOB, /* bad probe description globbing pattern */
+ EDT_NOSCOPE, /* declaration scope stack underflow */
+ EDT_NODECL, /* declaration stack underflow */
+ EDT_DMISMATCH, /* record list does not match statement */
+ EDT_DOFFSET, /* record data offset error */
+ EDT_DALIGN, /* record data alignment error */
+ EDT_BADOPTNAME, /* invalid dtrace_setopt option name */
+ EDT_BADOPTVAL, /* invalid dtrace_setopt option value */
+ EDT_BADOPTCTX, /* invalid dtrace_setopt option context */
+ EDT_CPPFORK, /* failed to fork preprocessor */
+ EDT_CPPEXEC, /* failed to exec preprocessor */
+ EDT_CPPENT, /* preprocessor not found */
+ EDT_CPPERR, /* unknown preprocessor error */
+ EDT_SYMOFLOW, /* external symbol table overflow */
+ EDT_ACTIVE, /* operation illegal when tracing is active */
+ EDT_DESTRUCTIVE, /* destructive actions not allowed */
+ EDT_NOANON, /* no anonymous tracing state */
+ EDT_ISANON, /* can't claim anon state and enable probes */
+ EDT_ENDTOOBIG, /* END enablings exceed size of prncpl buffer */
+ EDT_NOCONV, /* failed to load type for printf conversion */
+ EDT_BADCONV, /* incomplete printf conversion */
+ EDT_BADERROR, /* invalid library ERROR action */
+ EDT_ERRABORT, /* abort due to error */
+ EDT_DROPABORT, /* abort due to drop */
+ EDT_DIRABORT, /* abort explicitly directed */
+ EDT_BADRVAL, /* invalid return value from callback */
+ EDT_BADNORMAL, /* invalid normalization */
+ EDT_BUFTOOSMALL, /* enabling exceeds size of buffer */
+ EDT_BADTRUNC, /* invalid truncation */
+ EDT_BUSY, /* device busy (active kernel debugger) */
+ EDT_ACCESS, /* insufficient privileges to use DTrace */
+ EDT_NOENT, /* dtrace device not available */
+ EDT_BRICKED, /* abort due to systemic unresponsiveness */
+ EDT_HARDWIRE, /* failed to load hard-wired definitions */
+ EDT_ELFVERSION, /* libelf is out-of-date w.r.t libdtrace */
+ EDT_NOBUFFERED, /* attempt to buffer output without handler */
+ EDT_UNSTABLE, /* description matched unstable set of probes */
+ EDT_BADSETOPT, /* invalid setopt library action */
+ EDT_BADSTACKPC, /* invalid stack program counter size */
+ EDT_BADAGGVAR, /* invalid aggregation variable identifier */
+ EDT_OVERSION, /* client is requesting deprecated version */
+ EDT_ENABLING_ERR /* failed to enable probe */
+};
+
+/*
+ * Interfaces for parsing and comparing DTrace attribute tuples, which describe
+ * stability and architectural binding information. The dtrace_attribute_t
+ * structure and associated constant definitions are found in <sys/dtrace.h>.
+ */
+extern dtrace_attribute_t dt_attr_min(dtrace_attribute_t, dtrace_attribute_t);
+extern dtrace_attribute_t dt_attr_max(dtrace_attribute_t, dtrace_attribute_t);
+extern char *dt_attr_str(dtrace_attribute_t, char *, size_t);
+extern int dt_attr_cmp(dtrace_attribute_t, dtrace_attribute_t);
+
+/*
+ * Interfaces for parsing and handling DTrace version strings. Version binding
+ * is a feature of the D compiler that is handled completely independently of
+ * the DTrace kernel infrastructure, so the definitions are here in libdtrace.
+ * Version strings are compiled into an encoded uint32_t which can be compared
+ * using C comparison operators. Version definitions are found in dt_open.c.
+ */
+#define DT_VERSION_STRMAX 16 /* enough for "255.4095.4095\0" */
+#define DT_VERSION_MAJMAX 0xFF /* maximum major version number */
+#define DT_VERSION_MINMAX 0xFFF /* maximum minor version number */
+#define DT_VERSION_MICMAX 0xFFF /* maximum micro version number */
+
+#define DT_VERSION_NUMBER(M, m, u) \
+ ((((M) & 0xFF) << 24) | (((m) & 0xFFF) << 12) | ((u) & 0xFFF))
+
+#define DT_VERSION_MAJOR(v) (((v) & 0xFF000000) >> 24)
+#define DT_VERSION_MINOR(v) (((v) & 0x00FFF000) >> 12)
+#define DT_VERSION_MICRO(v) ((v) & 0x00000FFF)
+
+extern char *dt_version_num2str(dt_version_t, char *, size_t);
+extern int dt_version_str2num(const char *, dt_version_t *);
+extern int dt_version_defined(dt_version_t);
+
+/*
+ * Miscellaneous internal libdtrace interfaces. The definitions below are for
+ * libdtrace routines that do not yet merit their own separate header file.
+ */
+extern char *dt_cpp_add_arg(dtrace_hdl_t *, const char *);
+extern char *dt_cpp_pop_arg(dtrace_hdl_t *);
+
+#if defined(sun)
+extern int dt_set_errno(dtrace_hdl_t *, int);
+#else
+int _dt_set_errno(dtrace_hdl_t *, int, const char *, int);
+void dt_get_errloc(dtrace_hdl_t *, const char **, int *);
+#define dt_set_errno(_a,_b) _dt_set_errno(_a,_b,__FILE__,__LINE__)
+#endif
+extern void dt_set_errmsg(dtrace_hdl_t *, const char *, const char *,
+ const char *, int, const char *, va_list);
+
+#if defined(sun)
+extern int dt_ioctl(dtrace_hdl_t *, int, void *);
+#else
+extern int dt_ioctl(dtrace_hdl_t *, u_long, void *);
+#endif
+extern int dt_status(dtrace_hdl_t *, processorid_t);
+extern long dt_sysconf(dtrace_hdl_t *, int);
+extern ssize_t dt_write(dtrace_hdl_t *, int, const void *, size_t);
+extern int dt_printf(dtrace_hdl_t *, FILE *, const char *, ...);
+
+extern void *dt_zalloc(dtrace_hdl_t *, size_t);
+extern void *dt_alloc(dtrace_hdl_t *, size_t);
+extern void dt_free(dtrace_hdl_t *, void *);
+extern void dt_difo_free(dtrace_hdl_t *, dtrace_difo_t *);
+
+extern int dt_gmatch(const char *, const char *);
+extern char *dt_basename(char *);
+
+extern ulong_t dt_popc(ulong_t);
+extern ulong_t dt_popcb(const ulong_t *, ulong_t);
+
+extern int dt_buffered_enable(dtrace_hdl_t *);
+extern int dt_buffered_flush(dtrace_hdl_t *, dtrace_probedata_t *,
+ const dtrace_recdesc_t *, const dtrace_aggdata_t *, uint32_t flags);
+extern void dt_buffered_disable(dtrace_hdl_t *);
+extern void dt_buffered_destroy(dtrace_hdl_t *);
+
+extern uint64_t dt_stddev(uint64_t *, uint64_t);
+
+extern int dt_rw_read_held(pthread_rwlock_t *);
+extern int dt_rw_write_held(pthread_rwlock_t *);
+extern int dt_mutex_held(pthread_mutex_t *);
+extern int dt_options_load(dtrace_hdl_t *);
+
+#define DT_RW_READ_HELD(x) dt_rw_read_held(x)
+#define DT_RW_WRITE_HELD(x) dt_rw_write_held(x)
+#define DT_RW_LOCK_HELD(x) (DT_RW_READ_HELD(x) || DT_RW_WRITE_HELD(x))
+#define DT_MUTEX_HELD(x) dt_mutex_held(x)
+
+extern void dt_dprintf(const char *, ...);
+
+extern void dt_setcontext(dtrace_hdl_t *, dtrace_probedesc_t *);
+extern void dt_endcontext(dtrace_hdl_t *);
+
+extern void dt_pragma(dt_node_t *);
+extern int dt_reduce(dtrace_hdl_t *, dt_version_t);
+extern void dt_cg(dt_pcb_t *, dt_node_t *);
+extern dtrace_difo_t *dt_as(dt_pcb_t *);
+extern void dt_dis(const dtrace_difo_t *, FILE *);
+
+extern int dt_aggregate_go(dtrace_hdl_t *);
+extern int dt_aggregate_init(dtrace_hdl_t *);
+extern void dt_aggregate_destroy(dtrace_hdl_t *);
+
+extern int dt_epid_lookup(dtrace_hdl_t *, dtrace_epid_t,
+ dtrace_eprobedesc_t **, dtrace_probedesc_t **);
+extern void dt_epid_destroy(dtrace_hdl_t *);
+extern int dt_aggid_lookup(dtrace_hdl_t *, dtrace_aggid_t, dtrace_aggdesc_t **);
+extern void dt_aggid_destroy(dtrace_hdl_t *);
+
+extern void *dt_format_lookup(dtrace_hdl_t *, int);
+extern void dt_format_destroy(dtrace_hdl_t *);
+
+extern const char *dt_strdata_lookup(dtrace_hdl_t *, int);
+extern void dt_strdata_destroy(dtrace_hdl_t *);
+
+extern int dt_print_quantize(dtrace_hdl_t *, FILE *,
+ const void *, size_t, uint64_t);
+extern int dt_print_lquantize(dtrace_hdl_t *, FILE *,
+ const void *, size_t, uint64_t);
+extern int dt_print_llquantize(dtrace_hdl_t *, FILE *,
+ const void *, size_t, uint64_t);
+extern int dt_print_agg(const dtrace_aggdata_t *, void *);
+
+extern int dt_handle(dtrace_hdl_t *, dtrace_probedata_t *);
+extern int dt_handle_liberr(dtrace_hdl_t *,
+ const dtrace_probedata_t *, const char *);
+extern int dt_handle_cpudrop(dtrace_hdl_t *, processorid_t,
+ dtrace_dropkind_t, uint64_t);
+extern int dt_handle_status(dtrace_hdl_t *,
+ dtrace_status_t *, dtrace_status_t *);
+extern int dt_handle_setopt(dtrace_hdl_t *, dtrace_setoptdata_t *);
+
+extern int dt_lib_depend_add(dtrace_hdl_t *, dt_list_t *, const char *);
+extern dt_lib_depend_t *dt_lib_depend_lookup(dt_list_t *, const char *);
+
+extern dt_pcb_t *yypcb; /* pointer to current parser control block */
+extern char yyintprefix; /* int token prefix for macros (+/-) */
+extern char yyintsuffix[4]; /* int token suffix ([uUlL]*) */
+extern int yyintdecimal; /* int token is decimal (1) or octal/hex (0) */
+extern char yytext[]; /* lex input buffer */
+extern int yylineno; /* lex line number */
+extern int yydebug; /* lex debugging */
+extern dt_node_t *yypragma; /* lex token list for control lines */
+
+extern const dtrace_attribute_t _dtrace_maxattr; /* maximum attributes */
+extern const dtrace_attribute_t _dtrace_defattr; /* default attributes */
+extern const dtrace_attribute_t _dtrace_symattr; /* symbol ref attributes */
+extern const dtrace_attribute_t _dtrace_typattr; /* type ref attributes */
+extern const dtrace_attribute_t _dtrace_prvattr; /* provider attributes */
+extern const dtrace_pattr_t _dtrace_prvdesc; /* provider attribute bundle */
+
+extern const dt_version_t _dtrace_versions[]; /* array of valid versions */
+extern const char *const _dtrace_version; /* current version string */
+
+extern int _dtrace_strbuckets; /* number of hash buckets for strings */
+extern int _dtrace_intbuckets; /* number of hash buckets for ints */
+extern uint_t _dtrace_stkindent; /* default indent for stack/ustack */
+extern uint_t _dtrace_pidbuckets; /* number of hash buckets for pids */
+extern uint_t _dtrace_pidlrulim; /* number of proc handles to cache */
+extern int _dtrace_debug; /* debugging messages enabled */
+extern size_t _dtrace_bufsize; /* default dt_buf_create() size */
+extern int _dtrace_argmax; /* default maximum probe arguments */
+
+extern const char *_dtrace_libdir; /* default library directory */
+extern const char *_dtrace_moddir; /* default kernel module directory */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_IMPL_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.c
new file mode 100644
index 0000000..a6ac589
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.c
@@ -0,0 +1,115 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <assert.h>
+
+#include <dt_inttab.h>
+#include <dt_impl.h>
+
+dt_inttab_t *
+dt_inttab_create(dtrace_hdl_t *dtp)
+{
+ uint_t len = _dtrace_intbuckets;
+ dt_inttab_t *ip;
+
+ assert((len & (len - 1)) == 0);
+
+ if ((ip = dt_zalloc(dtp, sizeof (dt_inttab_t))) == NULL ||
+ (ip->int_hash = dt_zalloc(dtp, sizeof (void *) * len)) == NULL) {
+ dt_free(dtp, ip);
+ return (NULL);
+ }
+
+ ip->int_hdl = dtp;
+ ip->int_hashlen = len;
+
+ return (ip);
+}
+
+void
+dt_inttab_destroy(dt_inttab_t *ip)
+{
+ dt_inthash_t *hp, *np;
+
+ for (hp = ip->int_head; hp != NULL; hp = np) {
+ np = hp->inh_next;
+ dt_free(ip->int_hdl, hp);
+ }
+
+ dt_free(ip->int_hdl, ip->int_hash);
+ dt_free(ip->int_hdl, ip);
+}
+
+int
+dt_inttab_insert(dt_inttab_t *ip, uint64_t value, uint_t flags)
+{
+ uint_t h = value & (ip->int_hashlen - 1);
+ dt_inthash_t *hp;
+
+ if (flags & DT_INT_SHARED) {
+ for (hp = ip->int_hash[h]; hp != NULL; hp = hp->inh_hash) {
+ if (hp->inh_value == value && hp->inh_flags == flags)
+ return (hp->inh_index);
+ }
+ }
+
+ if ((hp = dt_alloc(ip->int_hdl, sizeof (dt_inthash_t))) == NULL)
+ return (-1);
+
+ hp->inh_hash = ip->int_hash[h];
+ hp->inh_next = NULL;
+ hp->inh_value = value;
+ hp->inh_index = ip->int_index++;
+ hp->inh_flags = flags;
+
+ ip->int_hash[h] = hp;
+ ip->int_nelems++;
+
+ if (ip->int_head == NULL)
+ ip->int_head = hp;
+ else
+ ip->int_tail->inh_next = hp;
+
+ ip->int_tail = hp;
+ return (hp->inh_index);
+}
+
+uint_t
+dt_inttab_size(const dt_inttab_t *ip)
+{
+ return (ip->int_nelems);
+}
+
+void
+dt_inttab_write(const dt_inttab_t *ip, uint64_t *dst)
+{
+ const dt_inthash_t *hp;
+
+ for (hp = ip->int_head; hp != NULL; hp = hp->inh_next)
+ *dst++ = hp->inh_value;
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.h
new file mode 100644
index 0000000..c1e86e3
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_inttab.h
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_INTTAB_H
+#define _DT_INTTAB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dtrace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_inthash {
+ struct dt_inthash *inh_hash; /* next dt_inthash in hash chain */
+ struct dt_inthash *inh_next; /* next dt_inthash in output table */
+ uint64_t inh_value; /* value associated with this element */
+ uint_t inh_index; /* index associated with this element */
+ uint_t inh_flags; /* flags (see below) */
+} dt_inthash_t;
+
+typedef struct dt_inttab {
+ dtrace_hdl_t *int_hdl; /* pointer back to library handle */
+ dt_inthash_t **int_hash; /* array of hash buckets */
+ uint_t int_hashlen; /* size of hash bucket array */
+ uint_t int_nelems; /* number of elements hashed */
+ dt_inthash_t *int_head; /* head of table in index order */
+ dt_inthash_t *int_tail; /* tail of table in index order */
+ uint_t int_index; /* next index to hand out */
+} dt_inttab_t;
+
+#define DT_INT_PRIVATE 0 /* only a single ref for this entry */
+#define DT_INT_SHARED 1 /* multiple refs can share entry */
+
+extern dt_inttab_t *dt_inttab_create(dtrace_hdl_t *);
+extern void dt_inttab_destroy(dt_inttab_t *);
+extern int dt_inttab_insert(dt_inttab_t *, uint64_t, uint_t);
+extern uint_t dt_inttab_size(const dt_inttab_t *);
+extern void dt_inttab_write(const dt_inttab_t *, uint64_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_INTTAB_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
new file mode 100644
index 0000000..b31933e
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
@@ -0,0 +1,872 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <dt_impl.h>
+#include <dt_grammar.h>
+#include <dt_parser.h>
+#include <dt_string.h>
+
+/*
+ * We need to undefine lex's input and unput macros so that references to these
+ * call the functions provided at the end of this source file.
+ */
+#if defined(sun)
+#undef input
+#undef unput
+#else
+/*
+ * Define YY_INPUT for flex since input() can't be re-defined.
+ */
+#define YY_INPUT(buf,result,max_size) \
+ if (yypcb->pcb_fileptr != NULL) { \
+ if (((result = fread(buf, 1, max_size, yypcb->pcb_fileptr)) == 0) \
+ && ferror(yypcb->pcb_fileptr)) \
+ longjmp(yypcb->pcb_jmpbuf, EDT_FIO); \
+ } else { \
+ int n; \
+ for (n = 0; n < max_size && \
+ yypcb->pcb_strptr < yypcb->pcb_string + yypcb->pcb_strlen; n++) \
+ buf[n] = *yypcb->pcb_strptr++; \
+ result = n; \
+ }
+/*
+ * Do not EOF let tokens to be put back. This does not work with flex.
+ * On the other hand, leaving current buffer in same state it was when
+ * last EOF was received guarantees that input() will keep returning EOF
+ * for all subsequent invocations, which is the effect desired.
+ */
+#undef unput
+#define unput(c) \
+ do { \
+ int _c = c; \
+ if (_c != EOF) \
+ yyunput(_c, yytext_ptr); \
+ } while(0)
+#endif
+
+static int id_or_type(const char *);
+#if defined(sun)
+static int input(void);
+static void unput(int);
+#endif
+
+/*
+ * We first define a set of labeled states for use in the D lexer and then a
+ * set of regular expressions to simplify things below. The lexer states are:
+ *
+ * S0 - D program clause and expression lexing
+ * S1 - D comments (i.e. skip everything until end of comment)
+ * S2 - D program outer scope (probe specifiers and declarations)
+ * S3 - D control line parsing (i.e. after ^# is seen but before \n)
+ * S4 - D control line scan (locate control directives only and invoke S3)
+ */
+%}
+
+%e 1500 /* maximum nodes */
+%p 3700 /* maximum positions */
+%n 600 /* maximum states */
+
+%s S0 S1 S2 S3 S4
+
+RGX_AGG "@"[a-zA-Z_][0-9a-zA-Z_]*
+RGX_PSPEC [-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]*
+RGX_IDENT [a-zA-Z_`][0-9a-zA-Z_`]*
+RGX_INT ([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]?
+RGX_FP ([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]?
+RGX_WS [\f\n\r\t\v ]
+RGX_STR ([^"\\\n]|\\[^"\n]|\\\")*
+RGX_CHR ([^'\\\n]|\\[^'\n]|\\')*
+RGX_INTERP ^[\f\t\v ]*#!.*
+RGX_CTL ^[\f\t\v ]*#
+
+%%
+
+%{
+
+/*
+ * We insert a special prologue into yylex() itself: if the pcb contains a
+ * context token, we return that prior to running the normal lexer. This
+ * allows libdtrace to force yacc into one of our three parsing contexts: D
+ * expression (DT_CTX_DEXPR), D program (DT_CTX_DPROG) or D type (DT_CTX_DTYPE).
+ * Once the token is returned, we clear it so this only happens once.
+ */
+if (yypcb->pcb_token != 0) {
+ int tok = yypcb->pcb_token;
+ yypcb->pcb_token = 0;
+ return (tok);
+}
+
+%}
+
+<S0>auto return (DT_KEY_AUTO);
+<S0>break return (DT_KEY_BREAK);
+<S0>case return (DT_KEY_CASE);
+<S0>char return (DT_KEY_CHAR);
+<S0>const return (DT_KEY_CONST);
+<S0>continue return (DT_KEY_CONTINUE);
+<S0>counter return (DT_KEY_COUNTER);
+<S0>default return (DT_KEY_DEFAULT);
+<S0>do return (DT_KEY_DO);
+<S0>double return (DT_KEY_DOUBLE);
+<S0>else return (DT_KEY_ELSE);
+<S0>enum return (DT_KEY_ENUM);
+<S0>extern return (DT_KEY_EXTERN);
+<S0>float return (DT_KEY_FLOAT);
+<S0>for return (DT_KEY_FOR);
+<S0>goto return (DT_KEY_GOTO);
+<S0>if return (DT_KEY_IF);
+<S0>import return (DT_KEY_IMPORT);
+<S0>inline return (DT_KEY_INLINE);
+<S0>int return (DT_KEY_INT);
+<S0>long return (DT_KEY_LONG);
+<S0>offsetof return (DT_TOK_OFFSETOF);
+<S0>probe return (DT_KEY_PROBE);
+<S0>provider return (DT_KEY_PROVIDER);
+<S0>register return (DT_KEY_REGISTER);
+<S0>restrict return (DT_KEY_RESTRICT);
+<S0>return return (DT_KEY_RETURN);
+<S0>self return (DT_KEY_SELF);
+<S0>short return (DT_KEY_SHORT);
+<S0>signed return (DT_KEY_SIGNED);
+<S0>sizeof return (DT_TOK_SIZEOF);
+<S0>static return (DT_KEY_STATIC);
+<S0>string return (DT_KEY_STRING);
+<S0>stringof return (DT_TOK_STRINGOF);
+<S0>struct return (DT_KEY_STRUCT);
+<S0>switch return (DT_KEY_SWITCH);
+<S0>this return (DT_KEY_THIS);
+<S0>translator return (DT_KEY_XLATOR);
+<S0>typedef return (DT_KEY_TYPEDEF);
+<S0>union return (DT_KEY_UNION);
+<S0>unsigned return (DT_KEY_UNSIGNED);
+<S0>void return (DT_KEY_VOID);
+<S0>volatile return (DT_KEY_VOLATILE);
+<S0>while return (DT_KEY_WHILE);
+<S0>xlate return (DT_TOK_XLATE);
+
+<S2>auto { yybegin(YYS_EXPR); return (DT_KEY_AUTO); }
+<S2>char { yybegin(YYS_EXPR); return (DT_KEY_CHAR); }
+<S2>const { yybegin(YYS_EXPR); return (DT_KEY_CONST); }
+<S2>counter { yybegin(YYS_DEFINE); return (DT_KEY_COUNTER); }
+<S2>double { yybegin(YYS_EXPR); return (DT_KEY_DOUBLE); }
+<S2>enum { yybegin(YYS_EXPR); return (DT_KEY_ENUM); }
+<S2>extern { yybegin(YYS_EXPR); return (DT_KEY_EXTERN); }
+<S2>float { yybegin(YYS_EXPR); return (DT_KEY_FLOAT); }
+<S2>import { yybegin(YYS_EXPR); return (DT_KEY_IMPORT); }
+<S2>inline { yybegin(YYS_DEFINE); return (DT_KEY_INLINE); }
+<S2>int { yybegin(YYS_EXPR); return (DT_KEY_INT); }
+<S2>long { yybegin(YYS_EXPR); return (DT_KEY_LONG); }
+<S2>provider { yybegin(YYS_DEFINE); return (DT_KEY_PROVIDER); }
+<S2>register { yybegin(YYS_EXPR); return (DT_KEY_REGISTER); }
+<S2>restrict { yybegin(YYS_EXPR); return (DT_KEY_RESTRICT); }
+<S2>self { yybegin(YYS_EXPR); return (DT_KEY_SELF); }
+<S2>short { yybegin(YYS_EXPR); return (DT_KEY_SHORT); }
+<S2>signed { yybegin(YYS_EXPR); return (DT_KEY_SIGNED); }
+<S2>static { yybegin(YYS_EXPR); return (DT_KEY_STATIC); }
+<S2>string { yybegin(YYS_EXPR); return (DT_KEY_STRING); }
+<S2>struct { yybegin(YYS_EXPR); return (DT_KEY_STRUCT); }
+<S2>this { yybegin(YYS_EXPR); return (DT_KEY_THIS); }
+<S2>translator { yybegin(YYS_DEFINE); return (DT_KEY_XLATOR); }
+<S2>typedef { yybegin(YYS_EXPR); return (DT_KEY_TYPEDEF); }
+<S2>union { yybegin(YYS_EXPR); return (DT_KEY_UNION); }
+<S2>unsigned { yybegin(YYS_EXPR); return (DT_KEY_UNSIGNED); }
+<S2>void { yybegin(YYS_EXPR); return (DT_KEY_VOID); }
+<S2>volatile { yybegin(YYS_EXPR); return (DT_KEY_VOLATILE); }
+
+<S0>"$$"[0-9]+ {
+ int i = atoi(yytext + 2);
+ char *v = "";
+
+ /*
+ * A macro argument reference substitutes the text of
+ * an argument in place of the current token. When we
+ * see $$<d> we fetch the saved string from pcb_sargv
+ * (or use the default argument if the option has been
+ * set and the argument hasn't been specified) and
+ * return a token corresponding to this string.
+ */
+ if (i < 0 || (i >= yypcb->pcb_sargc &&
+ !(yypcb->pcb_cflags & DTRACE_C_DEFARG))) {
+ xyerror(D_MACRO_UNDEF, "macro argument %s is "
+ "not defined\n", yytext);
+ }
+
+ if (i < yypcb->pcb_sargc) {
+ v = yypcb->pcb_sargv[i]; /* get val from pcb */
+ yypcb->pcb_sflagv[i] |= DT_IDFLG_REF;
+ }
+
+ if ((yylval.l_str = strdup(v)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ (void) stresc2chr(yylval.l_str);
+ return (DT_TOK_STRING);
+ }
+
+<S0>"$"[0-9]+ {
+ int i = atoi(yytext + 1);
+ char *p, *v = "0";
+
+ /*
+ * A macro argument reference substitutes the text of
+ * one identifier or integer pattern for another. When
+ * we see $<d> we fetch the saved string from pcb_sargv
+ * (or use the default argument if the option has been
+ * set and the argument hasn't been specified) and
+ * return a token corresponding to this string.
+ */
+ if (i < 0 || (i >= yypcb->pcb_sargc &&
+ !(yypcb->pcb_cflags & DTRACE_C_DEFARG))) {
+ xyerror(D_MACRO_UNDEF, "macro argument %s is "
+ "not defined\n", yytext);
+ }
+
+ if (i < yypcb->pcb_sargc) {
+ v = yypcb->pcb_sargv[i]; /* get val from pcb */
+ yypcb->pcb_sflagv[i] |= DT_IDFLG_REF;
+ }
+
+ /*
+ * If the macro text is not a valid integer or ident,
+ * then we treat it as a string. The string may be
+ * optionally enclosed in quotes, which we strip.
+ */
+ if (strbadidnum(v)) {
+ size_t len = strlen(v);
+
+ if (len != 1 && *v == '"' && v[len - 1] == '"')
+ yylval.l_str = strndup(v + 1, len - 2);
+ else
+ yylval.l_str = strndup(v, len);
+
+ if (yylval.l_str == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ (void) stresc2chr(yylval.l_str);
+ return (DT_TOK_STRING);
+ }
+
+ /*
+ * If the macro text is not a string an begins with a
+ * digit or a +/- sign, process it as an integer token.
+ */
+ if (isdigit(v[0]) || v[0] == '-' || v[0] == '+') {
+ if (isdigit(v[0]))
+ yyintprefix = 0;
+ else
+ yyintprefix = *v++;
+
+ errno = 0;
+ yylval.l_int = strtoull(v, &p, 0);
+ (void) strncpy(yyintsuffix, p,
+ sizeof (yyintsuffix));
+ yyintdecimal = *v != '0';
+
+ if (errno == ERANGE) {
+ xyerror(D_MACRO_OFLOW, "macro argument"
+ " %s constant %s results in integer"
+ " overflow\n", yytext, v);
+ }
+
+ return (DT_TOK_INT);
+ }
+
+ return (id_or_type(v));
+ }
+
+<S0>"$$"{RGX_IDENT} {
+ dt_ident_t *idp = dt_idhash_lookup(
+ yypcb->pcb_hdl->dt_macros, yytext + 2);
+
+ char s[16]; /* enough for UINT_MAX + \0 */
+
+ if (idp == NULL) {
+ xyerror(D_MACRO_UNDEF, "macro variable %s "
+ "is not defined\n", yytext);
+ }
+
+ /*
+ * For the moment, all current macro variables are of
+ * type id_t (refer to dtrace_update() for details).
+ */
+ (void) snprintf(s, sizeof (s), "%u", idp->di_id);
+ if ((yylval.l_str = strdup(s)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ return (DT_TOK_STRING);
+ }
+
+<S0>"$"{RGX_IDENT} {
+ dt_ident_t *idp = dt_idhash_lookup(
+ yypcb->pcb_hdl->dt_macros, yytext + 1);
+
+ if (idp == NULL) {
+ xyerror(D_MACRO_UNDEF, "macro variable %s "
+ "is not defined\n", yytext);
+ }
+
+ /*
+ * For the moment, all current macro variables are of
+ * type id_t (refer to dtrace_update() for details).
+ */
+ yylval.l_int = (intmax_t)(int)idp->di_id;
+ yyintprefix = 0;
+ yyintsuffix[0] = '\0';
+ yyintdecimal = 1;
+
+ return (DT_TOK_INT);
+ }
+
+<S0>{RGX_IDENT} {
+ return (id_or_type(yytext));
+ }
+
+<S0>{RGX_AGG} {
+ if ((yylval.l_str = strdup(yytext)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ return (DT_TOK_AGG);
+ }
+
+<S0>"@" {
+ if ((yylval.l_str = strdup("@_")) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ return (DT_TOK_AGG);
+ }
+
+<S0>{RGX_INT} |
+<S2>{RGX_INT} |
+<S3>{RGX_INT} {
+ char *p;
+
+ errno = 0;
+ yylval.l_int = strtoull(yytext, &p, 0);
+ yyintprefix = 0;
+ (void) strncpy(yyintsuffix, p, sizeof (yyintsuffix));
+ yyintdecimal = yytext[0] != '0';
+
+ if (errno == ERANGE) {
+ xyerror(D_INT_OFLOW, "constant %s results in "
+ "integer overflow\n", yytext);
+ }
+
+ if (*p != '\0' && strchr("uUlL", *p) == NULL) {
+ xyerror(D_INT_DIGIT, "constant %s contains "
+ "invalid digit %c\n", yytext, *p);
+ }
+
+ if ((YYSTATE) != S3)
+ return (DT_TOK_INT);
+
+ yypragma = dt_node_link(yypragma,
+ dt_node_int(yylval.l_int));
+ }
+
+<S0>{RGX_FP} yyerror("floating-point constants are not permitted\n");
+
+<S0>\"{RGX_STR}$ |
+<S3>\"{RGX_STR}$ xyerror(D_STR_NL, "newline encountered in string literal");
+
+<S0>\"{RGX_STR}\" |
+<S3>\"{RGX_STR}\" {
+ /*
+ * Quoted string -- convert C escape sequences and
+ * return the string as a token.
+ */
+ yylval.l_str = strndup(yytext + 1, yyleng - 2);
+
+ if (yylval.l_str == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ (void) stresc2chr(yylval.l_str);
+ if ((YYSTATE) != S3)
+ return (DT_TOK_STRING);
+
+ yypragma = dt_node_link(yypragma,
+ dt_node_string(yylval.l_str));
+ }
+
+<S0>'{RGX_CHR}$ xyerror(D_CHR_NL, "newline encountered in character constant");
+
+<S0>'{RGX_CHR}' {
+ char *s, *p, *q;
+ size_t nbytes;
+
+ /*
+ * Character constant -- convert C escape sequences and
+ * return the character as an integer immediate value.
+ */
+ if (yyleng == 2)
+ xyerror(D_CHR_NULL, "empty character constant");
+
+ s = yytext + 1;
+ yytext[yyleng - 1] = '\0';
+ nbytes = stresc2chr(s);
+ yylval.l_int = 0;
+ yyintprefix = 0;
+ yyintsuffix[0] = '\0';
+ yyintdecimal = 1;
+
+ if (nbytes > sizeof (yylval.l_int)) {
+ xyerror(D_CHR_OFLOW, "character constant is "
+ "too long");
+ }
+#if BYTE_ORDER == _LITTLE_ENDIAN
+ p = ((char *)&yylval.l_int) + nbytes - 1;
+ for (q = s; nbytes != 0; nbytes--)
+ *p-- = *q++;
+#else
+ bcopy(s, ((char *)&yylval.l_int) +
+ sizeof (yylval.l_int) - nbytes, nbytes);
+#endif
+ return (DT_TOK_INT);
+ }
+
+<S0>"/*" |
+<S2>"/*" {
+ yypcb->pcb_cstate = (YYSTATE);
+ BEGIN(S1);
+ }
+
+<S0>{RGX_INTERP} |
+<S2>{RGX_INTERP} ; /* discard any #! lines */
+
+<S0>{RGX_CTL} |
+<S2>{RGX_CTL} |
+<S4>{RGX_CTL} {
+ assert(yypragma == NULL);
+ yypcb->pcb_cstate = (YYSTATE);
+ BEGIN(S3);
+ }
+
+<S4>. ; /* discard */
+<S4>"\n" ; /* discard */
+
+<S0>"/" {
+ int c, tok;
+
+ /*
+ * The use of "/" as the predicate delimiter and as the
+ * integer division symbol requires special lookahead
+ * to avoid a shift/reduce conflict in the D grammar.
+ * We look ahead to the next non-whitespace character.
+ * If we encounter EOF, ";", "{", or "/", then this "/"
+ * closes the predicate and we return DT_TOK_EPRED.
+ * If we encounter anything else, it's DT_TOK_DIV.
+ */
+ while ((c = input()) != 0) {
+ if (strchr("\f\n\r\t\v ", c) == NULL)
+ break;
+ }
+
+ if (c == 0 || c == ';' || c == '{' || c == '/') {
+ if (yypcb->pcb_parens != 0) {
+ yyerror("closing ) expected in "
+ "predicate before /\n");
+ }
+ if (yypcb->pcb_brackets != 0) {
+ yyerror("closing ] expected in "
+ "predicate before /\n");
+ }
+ tok = DT_TOK_EPRED;
+ } else
+ tok = DT_TOK_DIV;
+
+ unput(c);
+ return (tok);
+ }
+
+<S0>"(" {
+ yypcb->pcb_parens++;
+ return (DT_TOK_LPAR);
+ }
+
+<S0>")" {
+ if (--yypcb->pcb_parens < 0)
+ yyerror("extra ) in input stream\n");
+ return (DT_TOK_RPAR);
+ }
+
+<S0>"[" {
+ yypcb->pcb_brackets++;
+ return (DT_TOK_LBRAC);
+ }
+
+<S0>"]" {
+ if (--yypcb->pcb_brackets < 0)
+ yyerror("extra ] in input stream\n");
+ return (DT_TOK_RBRAC);
+ }
+
+<S0>"{" |
+<S2>"{" {
+ yypcb->pcb_braces++;
+ return ('{');
+ }
+
+<S0>"}" {
+ if (--yypcb->pcb_braces < 0)
+ yyerror("extra } in input stream\n");
+ return ('}');
+ }
+
+<S0>"|" return (DT_TOK_BOR);
+<S0>"^" return (DT_TOK_XOR);
+<S0>"&" return (DT_TOK_BAND);
+<S0>"&&" return (DT_TOK_LAND);
+<S0>"^^" return (DT_TOK_LXOR);
+<S0>"||" return (DT_TOK_LOR);
+<S0>"==" return (DT_TOK_EQU);
+<S0>"!=" return (DT_TOK_NEQ);
+<S0>"<" return (DT_TOK_LT);
+<S0>"<=" return (DT_TOK_LE);
+<S0>">" return (DT_TOK_GT);
+<S0>">=" return (DT_TOK_GE);
+<S0>"<<" return (DT_TOK_LSH);
+<S0>">>" return (DT_TOK_RSH);
+<S0>"+" return (DT_TOK_ADD);
+<S0>"-" return (DT_TOK_SUB);
+<S0>"*" return (DT_TOK_MUL);
+<S0>"%" return (DT_TOK_MOD);
+<S0>"~" return (DT_TOK_BNEG);
+<S0>"!" return (DT_TOK_LNEG);
+<S0>"?" return (DT_TOK_QUESTION);
+<S0>":" return (DT_TOK_COLON);
+<S0>"." return (DT_TOK_DOT);
+<S0>"->" return (DT_TOK_PTR);
+<S0>"=" return (DT_TOK_ASGN);
+<S0>"+=" return (DT_TOK_ADD_EQ);
+<S0>"-=" return (DT_TOK_SUB_EQ);
+<S0>"*=" return (DT_TOK_MUL_EQ);
+<S0>"/=" return (DT_TOK_DIV_EQ);
+<S0>"%=" return (DT_TOK_MOD_EQ);
+<S0>"&=" return (DT_TOK_AND_EQ);
+<S0>"^=" return (DT_TOK_XOR_EQ);
+<S0>"|=" return (DT_TOK_OR_EQ);
+<S0>"<<=" return (DT_TOK_LSH_EQ);
+<S0>">>=" return (DT_TOK_RSH_EQ);
+<S0>"++" return (DT_TOK_ADDADD);
+<S0>"--" return (DT_TOK_SUBSUB);
+<S0>"..." return (DT_TOK_ELLIPSIS);
+<S0>"," return (DT_TOK_COMMA);
+<S0>";" return (';');
+<S0>{RGX_WS} ; /* discard */
+<S0>"\\"\n ; /* discard */
+<S0>. yyerror("syntax error near \"%c\"\n", yytext[0]);
+
+<S1>"/*" yyerror("/* encountered inside a comment\n");
+<S1>"*/" BEGIN(yypcb->pcb_cstate);
+<S1>.|\n ; /* discard */
+
+<S2>{RGX_PSPEC} {
+ /*
+ * S2 has an ambiguity because RGX_PSPEC includes '*'
+ * as a glob character and '*' also can be DT_TOK_STAR.
+ * Since lex always matches the longest token, this
+ * rule can be matched by an input string like "int*",
+ * which could begin a global variable declaration such
+ * as "int*x;" or could begin a RGX_PSPEC with globbing
+ * such as "int* { trace(timestamp); }". If C_PSPEC is
+ * not set, we must resolve the ambiguity in favor of
+ * the type and perform lexer pushback if the fragment
+ * before '*' or entire fragment matches a type name.
+ * If C_PSPEC is set, we always return a PSPEC token.
+ * If C_PSPEC is off, the user can avoid ambiguity by
+ * including a ':' delimiter in the specifier, which
+ * they should be doing anyway to specify the provider.
+ */
+ if (!(yypcb->pcb_cflags & DTRACE_C_PSPEC) &&
+ strchr(yytext, ':') == NULL) {
+
+ char *p = strchr(yytext, '*');
+ char *q = yytext + yyleng - 1;
+
+ if (p != NULL && p > yytext)
+ *p = '\0'; /* prune yytext */
+
+ if (dt_type_lookup(yytext, NULL) == 0) {
+ yylval.l_str = strdup(yytext);
+
+ if (yylval.l_str == NULL) {
+ longjmp(yypcb->pcb_jmpbuf,
+ EDT_NOMEM);
+ }
+
+ if (p != NULL && p > yytext) {
+ for (*p = '*'; q >= p; q--)
+ unput(*q);
+ }
+
+ yybegin(YYS_EXPR);
+ return (DT_TOK_TNAME);
+ }
+
+ if (p != NULL && p > yytext)
+ *p = '*'; /* restore yytext */
+ }
+
+ if ((yylval.l_str = strdup(yytext)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ return (DT_TOK_PSPEC);
+ }
+
+<S2>"/" return (DT_TOK_DIV);
+<S2>"," return (DT_TOK_COMMA);
+
+<S2>{RGX_WS} ; /* discard */
+<S2>. yyerror("syntax error near \"%c\"\n", yytext[0]);
+
+<S3>\n {
+ dt_pragma(yypragma);
+ yypragma = NULL;
+ BEGIN(yypcb->pcb_cstate);
+ }
+
+<S3>[\f\t\v ]+ ; /* discard */
+
+<S3>[^\f\n\t\v "]+ {
+ dt_node_t *dnp;
+
+ if ((yylval.l_str = strdup(yytext)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * We want to call dt_node_ident() here, but we can't
+ * because it will expand inlined identifiers, which we
+ * don't want to do from #pragma context in order to
+ * support pragmas that apply to the ident itself. We
+ * call dt_node_string() and then reset dn_op instead.
+ */
+ dnp = dt_node_string(yylval.l_str);
+ dnp->dn_kind = DT_NODE_IDENT;
+ dnp->dn_op = DT_TOK_IDENT;
+ yypragma = dt_node_link(yypragma, dnp);
+ }
+
+<S3>. yyerror("syntax error near \"%c\"\n", yytext[0]);
+
+%%
+
+/*
+ * yybegin provides a wrapper for use from C code around the lex BEGIN() macro.
+ * We use two main states for lexing because probe descriptions use a syntax
+ * that is incompatible with the normal D tokens (e.g. names can contain "-").
+ * yybegin also handles the job of switching between two lists of dt_nodes
+ * as we allocate persistent definitions, like inlines, and transient nodes
+ * that will be freed once we are done parsing the current program file.
+ */
+void
+yybegin(yystate_t state)
+{
+#ifdef YYDEBUG
+ yydebug = _dtrace_debug;
+#endif
+ if (yypcb->pcb_yystate == state)
+ return; /* nothing to do if we're in the state already */
+
+ if (yypcb->pcb_yystate == YYS_DEFINE) {
+ yypcb->pcb_list = yypcb->pcb_hold;
+ yypcb->pcb_hold = NULL;
+ }
+
+ switch (state) {
+ case YYS_CLAUSE:
+ BEGIN(S2);
+ break;
+ case YYS_DEFINE:
+ assert(yypcb->pcb_hold == NULL);
+ yypcb->pcb_hold = yypcb->pcb_list;
+ yypcb->pcb_list = NULL;
+ /*FALLTHRU*/
+ case YYS_EXPR:
+ BEGIN(S0);
+ break;
+ case YYS_DONE:
+ break;
+ case YYS_CONTROL:
+ BEGIN(S4);
+ break;
+ default:
+ xyerror(D_UNKNOWN, "internal error -- bad yystate %d\n", state);
+ }
+
+ yypcb->pcb_yystate = state;
+}
+
+void
+yyinit(dt_pcb_t *pcb)
+{
+ yypcb = pcb;
+ yylineno = 1;
+ yypragma = NULL;
+#if defined(sun)
+ yysptr = yysbuf;
+#endif
+}
+
+/*
+ * Given a lexeme 's' (typically yytext), set yylval and return an appropriate
+ * token to the parser indicating either an identifier or a typedef name.
+ * User-defined global variables always take precedence over types, but we do
+ * use some heuristics because D programs can look at an ever-changing set of
+ * kernel types and also can implicitly instantiate variables by assignment,
+ * unlike in C. The code here is ordered carefully as lookups are not cheap.
+ */
+static int
+id_or_type(const char *s)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
+ int c0, c1, ttok = DT_TOK_TNAME;
+ dt_ident_t *idp;
+
+ if ((s = yylval.l_str = strdup(s)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * If the lexeme is a global variable or likely identifier or *not* a
+ * type_name, then it is an identifier token.
+ */
+ if (dt_idstack_lookup(&yypcb->pcb_globals, s) != NULL ||
+ dt_idhash_lookup(yypcb->pcb_idents, s) != NULL ||
+ dt_type_lookup(s, NULL) != 0)
+ return (DT_TOK_IDENT);
+
+ /*
+ * If we're in the midst of parsing a declaration and a type_specifier
+ * has already been shifted, then return DT_TOK_IDENT instead of TNAME.
+ * This semantic is necessary to permit valid ISO C code such as:
+ *
+ * typedef int foo;
+ * struct s { foo foo; };
+ *
+ * without causing shift/reduce conflicts in the direct_declarator part
+ * of the grammar. The result is that we must check for conflicting
+ * redeclarations of the same identifier as part of dt_node_decl().
+ */
+ if (ddp != NULL && ddp->dd_name != NULL)
+ return (DT_TOK_IDENT);
+
+ /*
+ * If the lexeme is a type name and we are not in a program clause,
+ * then always interpret it as a type and return DT_TOK_TNAME.
+ */
+ if ((YYSTATE) != S0)
+ return (DT_TOK_TNAME);
+
+ /*
+ * If the lexeme matches a type name but is in a program clause, then
+ * it could be a type or it could be an undefined variable. Peek at
+ * the next token to decide. If we see ++, --, [, or =, we know there
+ * might be an assignment that is trying to create a global variable,
+ * so we optimistically return DT_TOK_IDENT. There is no harm in being
+ * wrong: a type_name followed by ++, --, [, or = is a syntax error.
+ */
+ while ((c0 = input()) != 0) {
+ if (strchr("\f\n\r\t\v ", c0) == NULL)
+ break;
+ }
+
+ switch (c0) {
+ case '+':
+ case '-':
+ if ((c1 = input()) == c0)
+ ttok = DT_TOK_IDENT;
+ unput(c1);
+ break;
+
+ case '=':
+ if ((c1 = input()) != c0)
+ ttok = DT_TOK_IDENT;
+ unput(c1);
+ break;
+ case '[':
+ ttok = DT_TOK_IDENT;
+ break;
+ }
+
+ if (ttok == DT_TOK_IDENT) {
+ idp = dt_idhash_insert(yypcb->pcb_idents, s, DT_IDENT_SCALAR, 0,
+ 0, _dtrace_defattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ unput(c0);
+ return (ttok);
+}
+
+#if defined(sun)
+static int
+input(void)
+{
+ int c;
+
+ if (yysptr > yysbuf)
+ c = *--yysptr;
+ else if (yypcb->pcb_fileptr != NULL)
+ c = fgetc(yypcb->pcb_fileptr);
+ else if (yypcb->pcb_strptr < yypcb->pcb_string + yypcb->pcb_strlen)
+ c = *(unsigned char *)(yypcb->pcb_strptr++);
+ else
+ c = EOF;
+
+ if (c == '\n')
+ yylineno++;
+
+ if (c != EOF)
+ return (c);
+
+ if ((YYSTATE) == S1)
+ yyerror("end-of-file encountered before matching */\n");
+
+ if ((YYSTATE) == S3)
+ yyerror("end-of-file encountered before end of control line\n");
+
+ if (yypcb->pcb_fileptr != NULL && ferror(yypcb->pcb_fileptr))
+ longjmp(yypcb->pcb_jmpbuf, EDT_FIO);
+
+ return (0); /* EOF */
+}
+
+static void
+unput(int c)
+{
+ if (c == '\n')
+ yylineno--;
+
+ *yysptr++ = c;
+ yytchar = c;
+}
+#endif
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
new file mode 100644
index 0000000..2d0428a
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -0,0 +1,1972 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define ELF_TARGET_ALL
+#include <elf.h>
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/sysmacros.h>
+#else
+#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
+#endif
+
+#include <unistd.h>
+#include <strings.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#if defined(sun)
+#include <wait.h>
+#else
+#include <sys/wait.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <sys/mman.h>
+#endif
+#include <assert.h>
+#include <sys/ipc.h>
+
+#include <dt_impl.h>
+#include <dt_provider.h>
+#include <dt_program.h>
+#include <dt_string.h>
+
+#define ESHDR_NULL 0
+#define ESHDR_SHSTRTAB 1
+#define ESHDR_DOF 2
+#define ESHDR_STRTAB 3
+#define ESHDR_SYMTAB 4
+#define ESHDR_REL 5
+#define ESHDR_NUM 6
+
+#define PWRITE_SCN(index, data) \
+ (lseek64(fd, (off64_t)elf_file.shdr[(index)].sh_offset, SEEK_SET) != \
+ (off64_t)elf_file.shdr[(index)].sh_offset || \
+ dt_write(dtp, fd, (data), elf_file.shdr[(index)].sh_size) != \
+ elf_file.shdr[(index)].sh_size)
+
+static const char DTRACE_SHSTRTAB32[] = "\0"
+".shstrtab\0" /* 1 */
+".SUNW_dof\0" /* 11 */
+".strtab\0" /* 21 */
+".symtab\0" /* 29 */
+#ifdef __sparc
+".rela.SUNW_dof"; /* 37 */
+#else
+".rel.SUNW_dof"; /* 37 */
+#endif
+
+static const char DTRACE_SHSTRTAB64[] = "\0"
+".shstrtab\0" /* 1 */
+".SUNW_dof\0" /* 11 */
+".strtab\0" /* 21 */
+".symtab\0" /* 29 */
+".rela.SUNW_dof"; /* 37 */
+
+static const char DOFSTR[] = "__SUNW_dof";
+static const char DOFLAZYSTR[] = "___SUNW_dof";
+
+typedef struct dt_link_pair {
+ struct dt_link_pair *dlp_next; /* next pair in linked list */
+ void *dlp_str; /* buffer for string table */
+ void *dlp_sym; /* buffer for symbol table */
+} dt_link_pair_t;
+
+typedef struct dof_elf32 {
+ uint32_t de_nrel; /* relocation count */
+#ifdef __sparc
+ Elf32_Rela *de_rel; /* array of relocations for sparc */
+#else
+ Elf32_Rel *de_rel; /* array of relocations for x86 */
+#endif
+ uint32_t de_nsym; /* symbol count */
+ Elf32_Sym *de_sym; /* array of symbols */
+ uint32_t de_strlen; /* size of of string table */
+ char *de_strtab; /* string table */
+ uint32_t de_global; /* index of the first global symbol */
+} dof_elf32_t;
+
+static int
+prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
+{
+ dof_sec_t *dofs, *s;
+ dof_relohdr_t *dofrh;
+ dof_relodesc_t *dofr;
+ char *strtab;
+ int i, j, nrel;
+ size_t strtabsz = 1;
+ uint32_t count = 0;
+ size_t base;
+ Elf32_Sym *sym;
+#ifdef __sparc
+ Elf32_Rela *rel;
+#else
+ Elf32_Rel *rel;
+#endif
+
+ /*LINTED*/
+ dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff);
+
+ /*
+ * First compute the size of the string table and the number of
+ * relocations present in the DOF.
+ */
+ for (i = 0; i < dof->dofh_secnum; i++) {
+ if (dofs[i].dofs_type != DOF_SECT_URELHDR)
+ continue;
+
+ /*LINTED*/
+ dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
+
+ s = &dofs[dofrh->dofr_strtab];
+ strtab = (char *)dof + s->dofs_offset;
+ assert(strtab[0] == '\0');
+ strtabsz += s->dofs_size - 1;
+
+ s = &dofs[dofrh->dofr_relsec];
+ /*LINTED*/
+ dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
+ count += s->dofs_size / s->dofs_entsize;
+ }
+
+ dep->de_strlen = strtabsz;
+ dep->de_nrel = count;
+ dep->de_nsym = count + 1; /* the first symbol is always null */
+
+ if (dtp->dt_lazyload) {
+ dep->de_strlen += sizeof (DOFLAZYSTR);
+ dep->de_nsym++;
+ } else {
+ dep->de_strlen += sizeof (DOFSTR);
+ dep->de_nsym++;
+ }
+
+ if ((dep->de_rel = calloc(dep->de_nrel,
+ sizeof (dep->de_rel[0]))) == NULL) {
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf32_Sym))) == NULL) {
+ free(dep->de_rel);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) {
+ free(dep->de_rel);
+ free(dep->de_sym);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ count = 0;
+ strtabsz = 1;
+ dep->de_strtab[0] = '\0';
+ rel = dep->de_rel;
+ sym = dep->de_sym;
+ dep->de_global = 1;
+
+ /*
+ * The first symbol table entry must be zeroed and is always ignored.
+ */
+ bzero(sym, sizeof (Elf32_Sym));
+ sym++;
+
+ /*
+ * Take a second pass through the DOF sections filling in the
+ * memory we allocated.
+ */
+ for (i = 0; i < dof->dofh_secnum; i++) {
+ if (dofs[i].dofs_type != DOF_SECT_URELHDR)
+ continue;
+
+ /*LINTED*/
+ dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
+
+ s = &dofs[dofrh->dofr_strtab];
+ strtab = (char *)dof + s->dofs_offset;
+ bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size);
+ base = strtabsz;
+ strtabsz += s->dofs_size - 1;
+
+ s = &dofs[dofrh->dofr_relsec];
+ /*LINTED*/
+ dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
+ nrel = s->dofs_size / s->dofs_entsize;
+
+ s = &dofs[dofrh->dofr_tgtsec];
+
+ for (j = 0; j < nrel; j++) {
+#if defined(__arm__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#elif defined(__ia64__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#elif defined(__i386) || defined(__amd64)
+ rel->r_offset = s->dofs_offset +
+ dofr[j].dofr_offset;
+ rel->r_info = ELF32_R_INFO(count + dep->de_global,
+ R_386_32);
+#elif defined(__mips__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#elif defined(__powerpc__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#elif defined(__sparc)
+ /*
+ * Add 4 bytes to hit the low half of this 64-bit
+ * big-endian address.
+ */
+ rel->r_offset = s->dofs_offset +
+ dofr[j].dofr_offset + 4;
+ rel->r_info = ELF32_R_INFO(count + dep->de_global,
+ R_SPARC_32);
+#else
+#error unknown ISA
+#endif
+
+ sym->st_name = base + dofr[j].dofr_name - 1;
+ sym->st_value = 0;
+ sym->st_size = 0;
+ sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
+ sym->st_other = 0;
+ sym->st_shndx = SHN_UNDEF;
+
+ rel++;
+ sym++;
+ count++;
+ }
+ }
+
+ /*
+ * Add a symbol for the DOF itself. We use a different symbol for
+ * lazily and actively loaded DOF to make them easy to distinguish.
+ */
+ sym->st_name = strtabsz;
+ sym->st_value = 0;
+ sym->st_size = dof->dofh_filesz;
+ sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
+ sym->st_other = 0;
+ sym->st_shndx = ESHDR_DOF;
+ sym++;
+
+ if (dtp->dt_lazyload) {
+ bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz,
+ sizeof (DOFLAZYSTR));
+ strtabsz += sizeof (DOFLAZYSTR);
+ } else {
+ bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR));
+ strtabsz += sizeof (DOFSTR);
+ }
+
+ assert(count == dep->de_nrel);
+ assert(strtabsz == dep->de_strlen);
+
+ return (0);
+}
+
+
+typedef struct dof_elf64 {
+ uint32_t de_nrel;
+ Elf64_Rela *de_rel;
+ uint32_t de_nsym;
+ Elf64_Sym *de_sym;
+
+ uint32_t de_strlen;
+ char *de_strtab;
+
+ uint32_t de_global;
+} dof_elf64_t;
+
+static int
+prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
+{
+ dof_sec_t *dofs, *s;
+ dof_relohdr_t *dofrh;
+ dof_relodesc_t *dofr;
+ char *strtab;
+ int i, j, nrel;
+ size_t strtabsz = 1;
+ uint32_t count = 0;
+ size_t base;
+ Elf64_Sym *sym;
+ Elf64_Rela *rel;
+
+ /*LINTED*/
+ dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff);
+
+ /*
+ * First compute the size of the string table and the number of
+ * relocations present in the DOF.
+ */
+ for (i = 0; i < dof->dofh_secnum; i++) {
+ if (dofs[i].dofs_type != DOF_SECT_URELHDR)
+ continue;
+
+ /*LINTED*/
+ dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
+
+ s = &dofs[dofrh->dofr_strtab];
+ strtab = (char *)dof + s->dofs_offset;
+ assert(strtab[0] == '\0');
+ strtabsz += s->dofs_size - 1;
+
+ s = &dofs[dofrh->dofr_relsec];
+ /*LINTED*/
+ dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
+ count += s->dofs_size / s->dofs_entsize;
+ }
+
+ dep->de_strlen = strtabsz;
+ dep->de_nrel = count;
+ dep->de_nsym = count + 1; /* the first symbol is always null */
+
+ if (dtp->dt_lazyload) {
+ dep->de_strlen += sizeof (DOFLAZYSTR);
+ dep->de_nsym++;
+ } else {
+ dep->de_strlen += sizeof (DOFSTR);
+ dep->de_nsym++;
+ }
+
+ if ((dep->de_rel = calloc(dep->de_nrel,
+ sizeof (dep->de_rel[0]))) == NULL) {
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf64_Sym))) == NULL) {
+ free(dep->de_rel);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) {
+ free(dep->de_rel);
+ free(dep->de_sym);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ count = 0;
+ strtabsz = 1;
+ dep->de_strtab[0] = '\0';
+ rel = dep->de_rel;
+ sym = dep->de_sym;
+ dep->de_global = 1;
+
+ /*
+ * The first symbol table entry must be zeroed and is always ignored.
+ */
+ bzero(sym, sizeof (Elf64_Sym));
+ sym++;
+
+ /*
+ * Take a second pass through the DOF sections filling in the
+ * memory we allocated.
+ */
+ for (i = 0; i < dof->dofh_secnum; i++) {
+ if (dofs[i].dofs_type != DOF_SECT_URELHDR)
+ continue;
+
+ /*LINTED*/
+ dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
+
+ s = &dofs[dofrh->dofr_strtab];
+ strtab = (char *)dof + s->dofs_offset;
+ bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size);
+ base = strtabsz;
+ strtabsz += s->dofs_size - 1;
+
+ s = &dofs[dofrh->dofr_relsec];
+ /*LINTED*/
+ dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
+ nrel = s->dofs_size / s->dofs_entsize;
+
+ s = &dofs[dofrh->dofr_tgtsec];
+
+ for (j = 0; j < nrel; j++) {
+#ifdef DOODAD
+#if defined(__arm__)
+/* XXX */
+#elif defined(__ia64__)
+/* XXX */
+#elif defined(__mips__)
+/* XXX */
+#elif defined(__powerpc__)
+/* XXX */
+#elif defined(__i386) || defined(__amd64)
+ rel->r_offset = s->dofs_offset +
+ dofr[j].dofr_offset;
+ rel->r_info = ELF64_R_INFO(count + dep->de_global,
+ R_AMD64_64);
+#elif defined(__sparc)
+ rel->r_offset = s->dofs_offset +
+ dofr[j].dofr_offset;
+ rel->r_info = ELF64_R_INFO(count + dep->de_global,
+ R_SPARC_64);
+#else
+#error unknown ISA
+#endif
+#endif
+
+ sym->st_name = base + dofr[j].dofr_name - 1;
+ sym->st_value = 0;
+ sym->st_size = 0;
+ sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC);
+ sym->st_other = 0;
+ sym->st_shndx = SHN_UNDEF;
+
+ rel++;
+ sym++;
+ count++;
+ }
+ }
+
+ /*
+ * Add a symbol for the DOF itself. We use a different symbol for
+ * lazily and actively loaded DOF to make them easy to distinguish.
+ */
+ sym->st_name = strtabsz;
+ sym->st_value = 0;
+ sym->st_size = dof->dofh_filesz;
+ sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
+ sym->st_other = 0;
+ sym->st_shndx = ESHDR_DOF;
+ sym++;
+
+ if (dtp->dt_lazyload) {
+ bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz,
+ sizeof (DOFLAZYSTR));
+ strtabsz += sizeof (DOFLAZYSTR);
+ } else {
+ bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR));
+ strtabsz += sizeof (DOFSTR);
+ }
+
+ assert(count == dep->de_nrel);
+ assert(strtabsz == dep->de_strlen);
+
+ return (0);
+}
+
+/*
+ * Write out an ELF32 file prologue consisting of a header, section headers,
+ * and a section header string table. The DOF data will follow this prologue
+ * and complete the contents of the given ELF file.
+ */
+static int
+dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
+{
+ struct {
+ Elf32_Ehdr ehdr;
+ Elf32_Shdr shdr[ESHDR_NUM];
+ } elf_file;
+
+ Elf32_Shdr *shp;
+ Elf32_Off off;
+ dof_elf32_t de;
+ int ret = 0;
+ uint_t nshdr;
+
+ if (prepare_elf32(dtp, dof, &de) != 0)
+ return (-1); /* errno is set for us */
+
+ /*
+ * If there are no relocations, we only need enough sections for
+ * the shstrtab and the DOF.
+ */
+ nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM;
+
+ bzero(&elf_file, sizeof (elf_file));
+
+ elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0;
+ elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1;
+ elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2;
+ elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3;
+ elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+ elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32;
+#if BYTE_ORDER == _BIG_ENDIAN
+ elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
+#else
+ elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+#endif
+#if defined(__FreeBSD__)
+ elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+ elf_file.ehdr.e_type = ET_REL;
+#if defined(__arm__)
+ elf_file.ehdr.e_machine = EM_ARM;
+#elif defined(__ia64__)
+ elf_file.ehdr.e_machine = EM_IA_64;
+#elif defined(__mips__)
+ elf_file.ehdr.e_machine = EM_MIPS;
+#elif defined(__powerpc__)
+ elf_file.ehdr.e_machine = EM_PPC;
+#elif defined(__sparc)
+ elf_file.ehdr.e_machine = EM_SPARC;
+#elif defined(__i386) || defined(__amd64)
+ elf_file.ehdr.e_machine = EM_386;
+#endif
+ elf_file.ehdr.e_version = EV_CURRENT;
+ elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr);
+ elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr);
+ elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr);
+ elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr);
+ elf_file.ehdr.e_shnum = nshdr;
+ elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB;
+ off = sizeof (elf_file) + nshdr * sizeof (Elf32_Shdr);
+
+ shp = &elf_file.shdr[ESHDR_SHSTRTAB];
+ shp->sh_name = 1; /* DTRACE_SHSTRTAB32[1] = ".shstrtab" */
+ shp->sh_type = SHT_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_size = sizeof (DTRACE_SHSTRTAB32);
+ shp->sh_addralign = sizeof (char);
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
+
+ shp = &elf_file.shdr[ESHDR_DOF];
+ shp->sh_name = 11; /* DTRACE_SHSTRTAB32[11] = ".SUNW_dof" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_SUNW_dof;
+ shp->sh_offset = off;
+ shp->sh_size = dof->dofh_filesz;
+ shp->sh_addralign = 8;
+ off = shp->sh_offset + shp->sh_size;
+
+ shp = &elf_file.shdr[ESHDR_STRTAB];
+ shp->sh_name = 21; /* DTRACE_SHSTRTAB32[21] = ".strtab" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_size = de.de_strlen;
+ shp->sh_addralign = sizeof (char);
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4);
+
+ shp = &elf_file.shdr[ESHDR_SYMTAB];
+ shp->sh_name = 29; /* DTRACE_SHSTRTAB32[29] = ".symtab" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_SYMTAB;
+ shp->sh_entsize = sizeof (Elf32_Sym);
+ shp->sh_link = ESHDR_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_info = de.de_global;
+ shp->sh_size = de.de_nsym * sizeof (Elf32_Sym);
+ shp->sh_addralign = 4;
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4);
+
+ if (de.de_nrel == 0) {
+ if (dt_write(dtp, fd, &elf_file,
+ sizeof (elf_file)) != sizeof (elf_file) ||
+ PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) ||
+ PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
+ PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
+ PWRITE_SCN(ESHDR_DOF, dof)) {
+ ret = dt_set_errno(dtp, errno);
+ }
+ } else {
+ shp = &elf_file.shdr[ESHDR_REL];
+ shp->sh_name = 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */
+ shp->sh_flags = SHF_ALLOC;
+#ifdef __sparc
+ shp->sh_type = SHT_RELA;
+#else
+ shp->sh_type = SHT_REL;
+#endif
+ shp->sh_entsize = sizeof (de.de_rel[0]);
+ shp->sh_link = ESHDR_SYMTAB;
+ shp->sh_info = ESHDR_DOF;
+ shp->sh_offset = off;
+ shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]);
+ shp->sh_addralign = 4;
+
+ if (dt_write(dtp, fd, &elf_file,
+ sizeof (elf_file)) != sizeof (elf_file) ||
+ PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) ||
+ PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
+ PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
+ PWRITE_SCN(ESHDR_REL, de.de_rel) ||
+ PWRITE_SCN(ESHDR_DOF, dof)) {
+ ret = dt_set_errno(dtp, errno);
+ }
+ }
+
+ free(de.de_strtab);
+ free(de.de_sym);
+ free(de.de_rel);
+
+ return (ret);
+}
+
+/*
+ * Write out an ELF64 file prologue consisting of a header, section headers,
+ * and a section header string table. The DOF data will follow this prologue
+ * and complete the contents of the given ELF file.
+ */
+static int
+dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
+{
+ struct {
+ Elf64_Ehdr ehdr;
+ Elf64_Shdr shdr[ESHDR_NUM];
+ } elf_file;
+
+ Elf64_Shdr *shp;
+ Elf64_Off off;
+ dof_elf64_t de;
+ int ret = 0;
+ uint_t nshdr;
+
+ if (prepare_elf64(dtp, dof, &de) != 0)
+ return (-1); /* errno is set for us */
+
+ /*
+ * If there are no relocations, we only need enough sections for
+ * the shstrtab and the DOF.
+ */
+ nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM;
+
+ bzero(&elf_file, sizeof (elf_file));
+
+ elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0;
+ elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1;
+ elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2;
+ elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3;
+ elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+ elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+#if BYTE_ORDER == _BIG_ENDIAN
+ elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
+#else
+ elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+#endif
+#if defined(__FreeBSD__)
+ elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+ elf_file.ehdr.e_type = ET_REL;
+#if defined(__arm__)
+ elf_file.ehdr.e_machine = EM_ARM;
+#elif defined(__ia64__)
+ elf_file.ehdr.e_machine = EM_IA_64;
+#elif defined(__mips__)
+ elf_file.ehdr.e_machine = EM_MIPS;
+#elif defined(__powerpc__)
+ elf_file.ehdr.e_machine = EM_PPC;
+#elif defined(__sparc)
+ elf_file.ehdr.e_machine = EM_SPARCV9;
+#elif defined(__i386) || defined(__amd64)
+ elf_file.ehdr.e_machine = EM_AMD64;
+#endif
+ elf_file.ehdr.e_version = EV_CURRENT;
+ elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr);
+ elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr);
+ elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr);
+ elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr);
+ elf_file.ehdr.e_shnum = nshdr;
+ elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB;
+ off = sizeof (elf_file) + nshdr * sizeof (Elf64_Shdr);
+
+ shp = &elf_file.shdr[ESHDR_SHSTRTAB];
+ shp->sh_name = 1; /* DTRACE_SHSTRTAB64[1] = ".shstrtab" */
+ shp->sh_type = SHT_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_size = sizeof (DTRACE_SHSTRTAB64);
+ shp->sh_addralign = sizeof (char);
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
+
+ shp = &elf_file.shdr[ESHDR_DOF];
+ shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_SUNW_dof;
+ shp->sh_offset = off;
+ shp->sh_size = dof->dofh_filesz;
+ shp->sh_addralign = 8;
+ off = shp->sh_offset + shp->sh_size;
+
+ shp = &elf_file.shdr[ESHDR_STRTAB];
+ shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_size = de.de_strlen;
+ shp->sh_addralign = sizeof (char);
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
+
+ shp = &elf_file.shdr[ESHDR_SYMTAB];
+ shp->sh_name = 29; /* DTRACE_SHSTRTAB64[29] = ".symtab" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_SYMTAB;
+ shp->sh_entsize = sizeof (Elf64_Sym);
+ shp->sh_link = ESHDR_STRTAB;
+ shp->sh_offset = off;
+ shp->sh_info = de.de_global;
+ shp->sh_size = de.de_nsym * sizeof (Elf64_Sym);
+ shp->sh_addralign = 8;
+ off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
+
+ if (de.de_nrel == 0) {
+ if (dt_write(dtp, fd, &elf_file,
+ sizeof (elf_file)) != sizeof (elf_file) ||
+ PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) ||
+ PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
+ PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
+ PWRITE_SCN(ESHDR_DOF, dof)) {
+ ret = dt_set_errno(dtp, errno);
+ }
+ } else {
+ shp = &elf_file.shdr[ESHDR_REL];
+ shp->sh_name = 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */
+ shp->sh_flags = SHF_ALLOC;
+ shp->sh_type = SHT_RELA;
+ shp->sh_entsize = sizeof (de.de_rel[0]);
+ shp->sh_link = ESHDR_SYMTAB;
+ shp->sh_info = ESHDR_DOF;
+ shp->sh_offset = off;
+ shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]);
+ shp->sh_addralign = 8;
+
+ if (dt_write(dtp, fd, &elf_file,
+ sizeof (elf_file)) != sizeof (elf_file) ||
+ PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) ||
+ PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
+ PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
+ PWRITE_SCN(ESHDR_REL, de.de_rel) ||
+ PWRITE_SCN(ESHDR_DOF, dof)) {
+ ret = dt_set_errno(dtp, errno);
+ }
+ }
+
+ free(de.de_strtab);
+ free(de.de_sym);
+ free(de.de_rel);
+
+ return (ret);
+}
+
+static int
+dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
+ GElf_Sym *sym)
+{
+ int i, ret = -1;
+ GElf_Sym s;
+
+ for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
+ if (GELF_ST_TYPE(sym->st_info) == STT_FUNC &&
+ shn == sym->st_shndx &&
+ sym->st_value <= addr &&
+ addr < sym->st_value + sym->st_size) {
+ if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
+ return (0);
+
+ ret = 0;
+ s = *sym;
+ }
+ }
+
+ if (ret == 0)
+ *sym = s;
+ return (ret);
+}
+
+#if defined(__arm__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+ return (0);
+}
+#elif defined(__ia64__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+ return (0);
+}
+#elif defined(__mips__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+ return (0);
+}
+#elif defined(__powerpc__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+ return (0);
+}
+
+#elif defined(__sparc)
+
+#define DT_OP_RET 0x81c7e008
+#define DT_OP_NOP 0x01000000
+#define DT_OP_CALL 0x40000000
+#define DT_OP_CLR_O0 0x90102000
+
+#define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000)
+#define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000)
+#define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008)
+
+#define DT_RS2(inst) ((inst) & 0x1f)
+#define DT_MAKE_RETL(reg) (0x81c02008 | ((reg) << 14))
+
+/*ARGSUSED*/
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+ uint32_t *ip;
+
+ if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0)
+ return (-1);
+
+ /*LINTED*/
+ ip = (uint32_t *)(p + rela->r_offset);
+
+ /*
+ * We only know about some specific relocation types.
+ */
+ if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 &&
+ GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30)
+ return (-1);
+
+ /*
+ * We may have already processed this object file in an earlier linker
+ * invocation. Check to see if the present instruction sequence matches
+ * the one we would install below.
+ */
+ if (isenabled) {
+ if (ip[0] == DT_OP_NOP) {
+ (*off) += sizeof (ip[0]);
+ return (0);
+ }
+ } else {
+ if (DT_IS_RESTORE(ip[1])) {
+ if (ip[0] == DT_OP_RET) {
+ (*off) += sizeof (ip[0]);
+ return (0);
+ }
+ } else if (DT_IS_MOV_O7(ip[1])) {
+ if (DT_IS_RETL(ip[0]))
+ return (0);
+ } else {
+ if (ip[0] == DT_OP_NOP) {
+ (*off) += sizeof (ip[0]);
+ return (0);
+ }
+ }
+ }
+
+ /*
+ * We only expect call instructions with a displacement of 0.
+ */
+ if (ip[0] != DT_OP_CALL) {
+ dt_dprintf("found %x instead of a call instruction at %llx\n",
+ ip[0], (u_longlong_t)rela->r_offset);
+ return (-1);
+ }
+
+ if (isenabled) {
+ /*
+ * It would necessarily indicate incorrect usage if an is-
+ * enabled probe were tail-called so flag that as an error.
+ * It's also potentially (very) tricky to handle gracefully,
+ * but could be done if this were a desired use scenario.
+ */
+ if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) {
+ dt_dprintf("tail call to is-enabled probe at %llx\n",
+ (u_longlong_t)rela->r_offset);
+ return (-1);
+ }
+
+
+ /*
+ * On SPARC, we take advantage of the fact that the first
+ * argument shares the same register as for the return value.
+ * The macro handles the work of zeroing that register so we
+ * don't need to do anything special here. We instrument the
+ * instruction in the delay slot as we'll need to modify the
+ * return register after that instruction has been emulated.
+ */
+ ip[0] = DT_OP_NOP;
+ (*off) += sizeof (ip[0]);
+ } else {
+ /*
+ * If the call is followed by a restore, it's a tail call so
+ * change the call to a ret. If the call if followed by a mov
+ * of a register into %o7, it's a tail call in leaf context
+ * so change the call to a retl-like instruction that returns
+ * to that register value + 8 (rather than the typical %o7 +
+ * 8); the delay slot instruction is left, but should have no
+ * effect. Otherwise we change the call to be a nop. We
+ * identify the subsequent instruction as the probe point in
+ * all but the leaf tail-call case to ensure that arguments to
+ * the probe are complete and consistent. An astute, though
+ * largely hypothetical, observer would note that there is the
+ * possibility of a false-positive probe firing if the function
+ * contained a branch to the instruction in the delay slot of
+ * the call. Fixing this would require significant in-kernel
+ * modifications, and isn't worth doing until we see it in the
+ * wild.
+ */
+ if (DT_IS_RESTORE(ip[1])) {
+ ip[0] = DT_OP_RET;
+ (*off) += sizeof (ip[0]);
+ } else if (DT_IS_MOV_O7(ip[1])) {
+ ip[0] = DT_MAKE_RETL(DT_RS2(ip[1]));
+ } else {
+ ip[0] = DT_OP_NOP;
+ (*off) += sizeof (ip[0]);
+ }
+ }
+
+ return (0);
+}
+
+#elif defined(__i386) || defined(__amd64)
+
+#define DT_OP_NOP 0x90
+#define DT_OP_RET 0xc3
+#define DT_OP_CALL 0xe8
+#define DT_OP_JMP32 0xe9
+#define DT_OP_REX_RAX 0x48
+#define DT_OP_XOR_EAX_0 0x33
+#define DT_OP_XOR_EAX_1 0xc0
+
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+ uint32_t *off)
+{
+ uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1);
+ uint8_t ret;
+
+ /*
+ * On x86, the first byte of the instruction is the call opcode and
+ * the next four bytes are the 32-bit address; the relocation is for
+ * the address operand. We back up the offset to the first byte of
+ * the instruction. For is-enabled probes, we later advance the offset
+ * so that it hits the first nop in the instruction sequence.
+ */
+ (*off) -= 1;
+
+ /*
+ * We only know about some specific relocation types. Luckily
+ * these types have the same values on both 32-bit and 64-bit
+ * x86 architectures.
+ */
+ if (GELF_R_TYPE(rela->r_info) != R_386_PC32 &&
+ GELF_R_TYPE(rela->r_info) != R_386_PLT32)
+ return (-1);
+
+ /*
+ * We may have already processed this object file in an earlier linker
+ * invocation. Check to see if the present instruction sequence matches
+ * the one we would install. For is-enabled probes, we advance the
+ * offset to the first nop instruction in the sequence to match the
+ * text modification code below.
+ */
+ if (!isenabled) {
+ if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) &&
+ ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP &&
+ ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP)
+ return (0);
+ } else if (dtp->dt_oflags & DTRACE_O_LP64) {
+ if (ip[0] == DT_OP_REX_RAX &&
+ ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 &&
+ (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) &&
+ ip[4] == DT_OP_NOP) {
+ (*off) += 3;
+ return (0);
+ }
+ } else {
+ if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 &&
+ (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) &&
+ ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) {
+ (*off) += 2;
+ return (0);
+ }
+ }
+
+ /*
+ * We expect either a call instrution with a 32-bit displacement or a
+ * jmp instruction with a 32-bit displacement acting as a tail-call.
+ */
+ if (ip[0] != DT_OP_CALL && ip[0] != DT_OP_JMP32) {
+ dt_dprintf("found %x instead of a call or jmp instruction at "
+ "%llx\n", ip[0], (u_longlong_t)rela->r_offset);
+ return (-1);
+ }
+
+ ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP;
+
+ /*
+ * Establish the instruction sequence -- all nops for probes, and an
+ * instruction to clear the return value register (%eax/%rax) followed
+ * by nops for is-enabled probes. For is-enabled probes, we advance
+ * the offset to the first nop. This isn't stricly necessary but makes
+ * for more readable disassembly when the probe is enabled.
+ */
+ if (!isenabled) {
+ ip[0] = ret;
+ ip[1] = DT_OP_NOP;
+ ip[2] = DT_OP_NOP;
+ ip[3] = DT_OP_NOP;
+ ip[4] = DT_OP_NOP;
+ } else if (dtp->dt_oflags & DTRACE_O_LP64) {
+ ip[0] = DT_OP_REX_RAX;
+ ip[1] = DT_OP_XOR_EAX_0;
+ ip[2] = DT_OP_XOR_EAX_1;
+ ip[3] = ret;
+ ip[4] = DT_OP_NOP;
+ (*off) += 3;
+ } else {
+ ip[0] = DT_OP_XOR_EAX_0;
+ ip[1] = DT_OP_XOR_EAX_1;
+ ip[2] = ret;
+ ip[3] = DT_OP_NOP;
+ ip[4] = DT_OP_NOP;
+ (*off) += 2;
+ }
+
+ return (0);
+}
+
+#else
+#error unknown ISA
+#endif
+
+/*PRINTFLIKE5*/
+static int
+dt_link_error(dtrace_hdl_t *dtp, Elf *elf, int fd, dt_link_pair_t *bufs,
+ const char *format, ...)
+{
+ va_list ap;
+ dt_link_pair_t *pair;
+
+ va_start(ap, format);
+ dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
+ va_end(ap);
+
+ if (elf != NULL)
+ (void) elf_end(elf);
+
+ if (fd >= 0)
+ (void) close(fd);
+
+ while ((pair = bufs) != NULL) {
+ bufs = pair->dlp_next;
+ dt_free(dtp, pair->dlp_str);
+ dt_free(dtp, pair->dlp_sym);
+ dt_free(dtp, pair);
+ }
+
+ return (dt_set_errno(dtp, EDT_COMPILER));
+}
+
+static int
+process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
+{
+ static const char dt_prefix[] = "__dtrace";
+ static const char dt_enabled[] = "enabled";
+ static const char dt_symprefix[] = "$dtrace";
+ static const char dt_symfmt[] = "%s%ld.%s";
+ int fd, i, ndx, eprobe, mod = 0;
+ Elf *elf = NULL;
+ GElf_Ehdr ehdr;
+ Elf_Scn *scn_rel, *scn_sym, *scn_str, *scn_tgt;
+ Elf_Data *data_rel, *data_sym, *data_str, *data_tgt;
+ GElf_Shdr shdr_rel, shdr_sym, shdr_str, shdr_tgt;
+ GElf_Sym rsym, fsym, dsym;
+ GElf_Rela rela;
+ char *s, *p, *r;
+ char pname[DTRACE_PROVNAMELEN];
+ dt_provider_t *pvp;
+ dt_probe_t *prp;
+ uint32_t off, eclass, emachine1, emachine2;
+ size_t symsize, nsym, isym, istr, len;
+ key_t objkey;
+ dt_link_pair_t *pair, *bufs = NULL;
+ dt_strtab_t *strtab;
+
+ if ((fd = open64(obj, O_RDWR)) == -1) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "failed to open %s: %s", obj, strerror(errno)));
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "failed to process %s: %s", obj, elf_errmsg(elf_errno())));
+ }
+
+ switch (elf_kind(elf)) {
+ case ELF_K_ELF:
+ break;
+ case ELF_K_AR:
+ return (dt_link_error(dtp, elf, fd, bufs, "archives are not "
+ "permitted; use the contents of the archive instead: %s",
+ obj));
+ default:
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "invalid file type: %s", obj));
+ }
+
+ if (gelf_getehdr(elf, &ehdr) == NULL) {
+ return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s",
+ obj));
+ }
+
+ if (dtp->dt_oflags & DTRACE_O_LP64) {
+ eclass = ELFCLASS64;
+#if defined(__ia64__)
+ emachine1 = emachine2 = EM_IA_64;
+#elif defined(__mips__)
+ emachine1 = emachine2 = EM_MIPS;
+#elif defined(__powerpc__)
+ emachine1 = emachine2 = EM_PPC64;
+#elif defined(__sparc)
+ emachine1 = emachine2 = EM_SPARCV9;
+#elif defined(__i386) || defined(__amd64)
+ emachine1 = emachine2 = EM_AMD64;
+#endif
+ symsize = sizeof (Elf64_Sym);
+ } else {
+ eclass = ELFCLASS32;
+#if defined(__arm__)
+ emachine1 = emachine2 = EM_ARM;
+#elif defined(__mips__)
+ emachine1 = emachine2 = EM_MIPS;
+#elif defined(__powerpc__)
+ emachine1 = emachine2 = EM_PPC;
+#elif defined(__sparc)
+ emachine1 = EM_SPARC;
+ emachine2 = EM_SPARC32PLUS;
+#elif defined(__i386) || defined(__amd64) || defined(__ia64__)
+ emachine1 = emachine2 = EM_386;
+#endif
+ symsize = sizeof (Elf32_Sym);
+ }
+
+ if (ehdr.e_ident[EI_CLASS] != eclass) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "incorrect ELF class for object file: %s", obj));
+ }
+
+ if (ehdr.e_machine != emachine1 && ehdr.e_machine != emachine2) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "incorrect ELF machine type for object file: %s", obj));
+ }
+
+ /*
+ * We use this token as a relatively unique handle for this file on the
+ * system in order to disambiguate potential conflicts between files of
+ * the same name which contain identially named local symbols.
+ */
+ if ((objkey = ftok(obj, 0)) == (key_t)-1) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "failed to generate unique key for object file: %s", obj));
+ }
+
+ scn_rel = NULL;
+ while ((scn_rel = elf_nextscn(elf, scn_rel)) != NULL) {
+ if (gelf_getshdr(scn_rel, &shdr_rel) == NULL)
+ goto err;
+
+ /*
+ * Skip any non-relocation sections.
+ */
+ if (shdr_rel.sh_type != SHT_RELA && shdr_rel.sh_type != SHT_REL)
+ continue;
+
+ if ((data_rel = elf_getdata(scn_rel, NULL)) == NULL)
+ goto err;
+
+ /*
+ * Grab the section, section header and section data for the
+ * symbol table that this relocation section references.
+ */
+ if ((scn_sym = elf_getscn(elf, shdr_rel.sh_link)) == NULL ||
+ gelf_getshdr(scn_sym, &shdr_sym) == NULL ||
+ (data_sym = elf_getdata(scn_sym, NULL)) == NULL)
+ goto err;
+
+ /*
+ * Ditto for that symbol table's string table.
+ */
+ if ((scn_str = elf_getscn(elf, shdr_sym.sh_link)) == NULL ||
+ gelf_getshdr(scn_str, &shdr_str) == NULL ||
+ (data_str = elf_getdata(scn_str, NULL)) == NULL)
+ goto err;
+
+ /*
+ * Grab the section, section header and section data for the
+ * target section for the relocations. For the relocations
+ * we're looking for -- this will typically be the text of the
+ * object file.
+ */
+ if ((scn_tgt = elf_getscn(elf, shdr_rel.sh_info)) == NULL ||
+ gelf_getshdr(scn_tgt, &shdr_tgt) == NULL ||
+ (data_tgt = elf_getdata(scn_tgt, NULL)) == NULL)
+ goto err;
+
+ /*
+ * We're looking for relocations to symbols matching this form:
+ *
+ * __dtrace[enabled]_<prov>___<probe>
+ *
+ * For the generated object, we need to record the location
+ * identified by the relocation, and create a new relocation
+ * in the generated object that will be resolved at link time
+ * to the location of the function in which the probe is
+ * embedded. In the target object, we change the matched symbol
+ * so that it will be ignored at link time, and we modify the
+ * target (text) section to replace the call instruction with
+ * one or more nops.
+ *
+ * If the function containing the probe is locally scoped
+ * (static), we create an alias used by the relocation in the
+ * generated object. The alias, a new symbol, will be global
+ * (so that the relocation from the generated object can be
+ * resolved), and hidden (so that it is converted to a local
+ * symbol at link time). Such aliases have this form:
+ *
+ * $dtrace<key>.<function>
+ *
+ * We take a first pass through all the relocations to
+ * populate our string table and count the number of extra
+ * symbols we'll require.
+ */
+ strtab = dt_strtab_create(1);
+ nsym = 0;
+ isym = data_sym->d_size / symsize;
+ istr = data_str->d_size;
+
+ for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
+
+ if (shdr_rel.sh_type == SHT_RELA) {
+ if (gelf_getrela(data_rel, i, &rela) == NULL)
+ continue;
+ } else {
+ GElf_Rel rel;
+ if (gelf_getrel(data_rel, i, &rel) == NULL)
+ continue;
+ rela.r_offset = rel.r_offset;
+ rela.r_info = rel.r_info;
+ rela.r_addend = 0;
+ }
+
+ if (gelf_getsym(data_sym, GELF_R_SYM(rela.r_info),
+ &rsym) == NULL) {
+ dt_strtab_destroy(strtab);
+ goto err;
+ }
+
+ s = (char *)data_str->d_buf + rsym.st_name;
+
+ if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
+ continue;
+
+ if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
+ shdr_rel.sh_info, &fsym) != 0) {
+ dt_strtab_destroy(strtab);
+ goto err;
+ }
+
+ if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL)
+ continue;
+
+ if (fsym.st_name > data_str->d_size) {
+ dt_strtab_destroy(strtab);
+ goto err;
+ }
+
+ s = (char *)data_str->d_buf + fsym.st_name;
+
+ /*
+ * If this symbol isn't of type function, we've really
+ * driven off the rails or the object file is corrupt.
+ */
+ if (GELF_ST_TYPE(fsym.st_info) != STT_FUNC) {
+ dt_strtab_destroy(strtab);
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "expected %s to be of type function", s));
+ }
+
+ len = snprintf(NULL, 0, dt_symfmt, dt_symprefix,
+ objkey, s) + 1;
+ if ((p = dt_alloc(dtp, len)) == NULL) {
+ dt_strtab_destroy(strtab);
+ goto err;
+ }
+ (void) snprintf(p, len, dt_symfmt, dt_symprefix,
+ objkey, s);
+
+ if (dt_strtab_index(strtab, p) == -1) {
+ nsym++;
+ (void) dt_strtab_insert(strtab, p);
+ }
+
+ dt_free(dtp, p);
+ }
+
+ /*
+ * If needed, allocate the additional space for the symbol
+ * table and string table copying the old data into the new
+ * buffers, and marking the buffers as dirty. We inject those
+ * newly allocated buffers into the libelf data structures, but
+ * are still responsible for freeing them once we're done with
+ * the elf handle.
+ */
+ if (nsym > 0) {
+ /*
+ * The first byte of the string table is reserved for
+ * the \0 entry.
+ */
+ len = dt_strtab_size(strtab) - 1;
+
+ assert(len > 0);
+ assert(dt_strtab_index(strtab, "") == 0);
+
+ dt_strtab_destroy(strtab);
+
+ if ((pair = dt_alloc(dtp, sizeof (*pair))) == NULL)
+ goto err;
+
+ if ((pair->dlp_str = dt_alloc(dtp, data_str->d_size +
+ len)) == NULL) {
+ dt_free(dtp, pair);
+ goto err;
+ }
+
+ if ((pair->dlp_sym = dt_alloc(dtp, data_sym->d_size +
+ nsym * symsize)) == NULL) {
+ dt_free(dtp, pair->dlp_str);
+ dt_free(dtp, pair);
+ goto err;
+ }
+
+ pair->dlp_next = bufs;
+ bufs = pair;
+
+ bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size);
+ data_str->d_buf = pair->dlp_str;
+ data_str->d_size += len;
+ (void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY);
+
+ shdr_str.sh_size += len;
+ (void) gelf_update_shdr(scn_str, &shdr_str);
+
+ bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size);
+ data_sym->d_buf = pair->dlp_sym;
+ data_sym->d_size += nsym * symsize;
+ (void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY);
+
+ shdr_sym.sh_size += nsym * symsize;
+ (void) gelf_update_shdr(scn_sym, &shdr_sym);
+
+ nsym += isym;
+ } else {
+ dt_strtab_destroy(strtab);
+ }
+
+ /*
+ * Now that the tables have been allocated, perform the
+ * modifications described above.
+ */
+ for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
+
+ if (shdr_rel.sh_type == SHT_RELA) {
+ if (gelf_getrela(data_rel, i, &rela) == NULL)
+ continue;
+ } else {
+ GElf_Rel rel;
+ if (gelf_getrel(data_rel, i, &rel) == NULL)
+ continue;
+ rela.r_offset = rel.r_offset;
+ rela.r_info = rel.r_info;
+ rela.r_addend = 0;
+ }
+
+ ndx = GELF_R_SYM(rela.r_info);
+
+ if (gelf_getsym(data_sym, ndx, &rsym) == NULL ||
+ rsym.st_name > data_str->d_size)
+ goto err;
+
+ s = (char *)data_str->d_buf + rsym.st_name;
+
+ if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
+ continue;
+
+ s += sizeof (dt_prefix) - 1;
+
+ /*
+ * Check to see if this is an 'is-enabled' check as
+ * opposed to a normal probe.
+ */
+ if (strncmp(s, dt_enabled,
+ sizeof (dt_enabled) - 1) == 0) {
+ s += sizeof (dt_enabled) - 1;
+ eprobe = 1;
+ *eprobesp = 1;
+ dt_dprintf("is-enabled probe\n");
+ } else {
+ eprobe = 0;
+ dt_dprintf("normal probe\n");
+ }
+
+ if (*s++ != '_')
+ goto err;
+
+ if ((p = strstr(s, "___")) == NULL ||
+ p - s >= sizeof (pname))
+ goto err;
+
+ bcopy(s, pname, p - s);
+ pname[p - s] = '\0';
+
+ p = strhyphenate(p + 3); /* strlen("___") */
+
+ if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
+ shdr_rel.sh_info, &fsym) != 0)
+ goto err;
+
+ if (fsym.st_name > data_str->d_size)
+ goto err;
+
+ assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC);
+
+ /*
+ * If a NULL relocation name is passed to
+ * dt_probe_define(), the function name is used for the
+ * relocation. The relocation needs to use a mangled
+ * name if the symbol is locally scoped; the function
+ * name may need to change if we've found the global
+ * alias for the locally scoped symbol (we prefer
+ * global symbols to locals in dt_symtab_lookup()).
+ */
+ s = (char *)data_str->d_buf + fsym.st_name;
+ r = NULL;
+
+ if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) {
+ dsym = fsym;
+ dsym.st_name = istr;
+ dsym.st_info = GELF_ST_INFO(STB_GLOBAL,
+ STT_FUNC);
+ dsym.st_other =
+ ELF64_ST_VISIBILITY(STV_ELIMINATE);
+ (void) gelf_update_sym(data_sym, isym, &dsym);
+
+ r = (char *)data_str->d_buf + istr;
+ istr += 1 + sprintf(r, dt_symfmt,
+ dt_symprefix, objkey, s);
+ isym++;
+ assert(isym <= nsym);
+
+ } else if (strncmp(s, dt_symprefix,
+ strlen(dt_symprefix)) == 0) {
+ r = s;
+ if ((s = strchr(s, '.')) == NULL)
+ goto err;
+ s++;
+ }
+
+ if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "no such provider %s", pname));
+ }
+
+ if ((prp = dt_probe_lookup(pvp, p)) == NULL) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "no such probe %s", p));
+ }
+
+ assert(fsym.st_value <= rela.r_offset);
+
+ off = rela.r_offset - fsym.st_value;
+ if (dt_modtext(dtp, data_tgt->d_buf, eprobe,
+ &rela, &off) != 0)
+ goto err;
+
+ if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0) {
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "failed to allocate space for probe"));
+ }
+#if !defined(sun)
+ /*
+ * Our linker doesn't understand the SUNW_IGNORE ndx and
+ * will try to use this relocation when we build the
+ * final executable. Since we are done processing this
+ * relocation, mark it as inexistant and let libelf
+ * remove it from the file.
+ * If this wasn't done, we would have garbage added to
+ * the executable file as the symbol is going to be
+ * change from UND to ABS.
+ */
+ rela.r_offset = 0;
+ rela.r_info = 0;
+ rela.r_addend = 0;
+ (void) gelf_update_rela(data_rel, i, &rela);
+#endif
+
+ mod = 1;
+ (void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY);
+
+ /*
+ * This symbol may already have been marked to
+ * be ignored by another relocation referencing
+ * the same symbol or if this object file has
+ * already been processed by an earlier link
+ * invocation.
+ */
+#if !defined(sun)
+#define SHN_SUNW_IGNORE SHN_ABS
+#endif
+ if (rsym.st_shndx != SHN_SUNW_IGNORE) {
+ rsym.st_shndx = SHN_SUNW_IGNORE;
+ (void) gelf_update_sym(data_sym, ndx, &rsym);
+ }
+ }
+ }
+
+ if (mod && elf_update(elf, ELF_C_WRITE) == -1)
+ goto err;
+
+ (void) elf_end(elf);
+ (void) close(fd);
+
+#if !defined(sun)
+ if (nsym > 0)
+#endif
+ while ((pair = bufs) != NULL) {
+ bufs = pair->dlp_next;
+ dt_free(dtp, pair->dlp_str);
+ dt_free(dtp, pair->dlp_sym);
+ dt_free(dtp, pair);
+ }
+
+ return (0);
+
+err:
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "an error was encountered while processing %s", obj));
+}
+
+int
+dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
+ const char *file, int objc, char *const objv[])
+{
+#if !defined(sun)
+ char tfile[PATH_MAX];
+ Elf *e;
+ Elf_Scn *scn;
+ Elf_Data *data;
+ GElf_Shdr shdr;
+ int efd;
+ size_t stridx;
+ unsigned char *buf;
+ char *s;
+ int loc;
+ GElf_Ehdr ehdr;
+ Elf_Scn *scn0;
+ GElf_Shdr shdr0;
+ uint64_t off, rc;
+#endif
+ char drti[PATH_MAX];
+ dof_hdr_t *dof;
+ int fd, status, i, cur;
+ char *cmd, tmp;
+ size_t len;
+ int eprobes = 0, ret = 0;
+
+#if !defined(sun)
+ if (access(file, R_OK) == 0) {
+ fprintf(stderr, "dtrace: target object (%s) already exists. "
+ "Please remove the target\ndtrace: object and rebuild all "
+ "the source objects if you wish to run the DTrace\n"
+ "dtrace: linking process again\n", file);
+ /*
+ * Several build infrastructures run DTrace twice (e.g.
+ * postgres) and we don't want the build to fail. Return
+ * 0 here since this isn't really a fatal error.
+ */
+ return (0);
+ }
+ /* XXX Should get a temp file name here. */
+ snprintf(tfile, sizeof(tfile), "%s.tmp", file);
+#endif
+
+ /*
+ * A NULL program indicates a special use in which we just link
+ * together a bunch of object files specified in objv and then
+ * unlink(2) those object files.
+ */
+ if (pgp == NULL) {
+ const char *fmt = "%s -o %s -r";
+
+ len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file) + 1;
+
+ for (i = 0; i < objc; i++)
+ len += strlen(objv[i]) + 1;
+
+ cmd = alloca(len);
+
+ cur = snprintf(cmd, len, fmt, dtp->dt_ld_path, file);
+
+ for (i = 0; i < objc; i++)
+ cur += snprintf(cmd + cur, len - cur, " %s", objv[i]);
+
+ if ((status = system(cmd)) == -1) {
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to run %s: %s", dtp->dt_ld_path,
+ strerror(errno)));
+ }
+
+ if (WIFSIGNALED(status)) {
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to link %s: %s failed due to signal %d",
+ file, dtp->dt_ld_path, WTERMSIG(status)));
+ }
+
+ if (WEXITSTATUS(status) != 0) {
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to link %s: %s exited with status %d\n",
+ file, dtp->dt_ld_path, WEXITSTATUS(status)));
+ }
+
+ for (i = 0; i < objc; i++) {
+ if (strcmp(objv[i], file) != 0)
+ (void) unlink(objv[i]);
+ }
+
+ return (0);
+ }
+
+ for (i = 0; i < objc; i++) {
+ if (process_obj(dtp, objv[i], &eprobes) != 0)
+ return (-1); /* errno is set for us */
+ }
+
+ /*
+ * If there are is-enabled probes then we need to force use of DOF
+ * version 2.
+ */
+ if (eprobes && pgp->dp_dofversion < DOF_VERSION_2)
+ pgp->dp_dofversion = DOF_VERSION_2;
+
+ if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL)
+ return (-1); /* errno is set for us */
+
+#if defined(sun)
+ /*
+ * Create a temporary file and then unlink it if we're going to
+ * combine it with drti.o later. We can still refer to it in child
+ * processes as /dev/fd/<fd>.
+ */
+ if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to open %s: %s", file, strerror(errno)));
+ }
+#else
+ if ((fd = open(tfile, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1)
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to open %s: %s", tfile, strerror(errno)));
+#endif
+
+ /*
+ * If -xlinktype=DOF has been selected, just write out the DOF.
+ * Otherwise proceed to the default of generating and linking ELF.
+ */
+ switch (dtp->dt_linktype) {
+ case DT_LTYP_DOF:
+ if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz)
+ ret = errno;
+
+ if (close(fd) != 0 && ret == 0)
+ ret = errno;
+
+ if (ret != 0) {
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to write %s: %s", file, strerror(ret)));
+ }
+
+ return (0);
+
+ case DT_LTYP_ELF:
+ break; /* fall through to the rest of dtrace_program_link() */
+
+ default:
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "invalid link type %u\n", dtp->dt_linktype));
+ }
+
+
+#if defined(sun)
+ if (!dtp->dt_lazyload)
+ (void) unlink(file);
+#endif
+
+#if defined(sun)
+ if (dtp->dt_oflags & DTRACE_O_LP64)
+ status = dump_elf64(dtp, dof, fd);
+ else
+ status = dump_elf32(dtp, dof, fd);
+
+ if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
+#else
+ /* We don't write the ELF header, just the DOF section */
+ if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) {
+#endif
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to write %s: %s", file, strerror(errno)));
+ }
+
+ if (!dtp->dt_lazyload) {
+#if defined(sun)
+ const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s";
+
+ if (dtp->dt_oflags & DTRACE_O_LP64) {
+ (void) snprintf(drti, sizeof (drti),
+ "%s/64/drti.o", _dtrace_libdir);
+ } else {
+ (void) snprintf(drti, sizeof (drti),
+ "%s/drti.o", _dtrace_libdir);
+ }
+
+ len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd,
+ drti) + 1;
+
+ cmd = alloca(len);
+
+ (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti);
+#else
+ const char *fmt = "%s -o %s -r %s";
+
+#if defined(__amd64__)
+ /*
+ * Arches which default to 64-bit need to explicitly use
+ * the 32-bit library path.
+ */
+ int use_32 = !(dtp->dt_oflags & DTRACE_O_LP64);
+#else
+ /*
+ * Arches which are 32-bit only just use the normal
+ * library path.
+ */
+ int use_32 = 0;
+#endif
+
+ (void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o",
+ use_32 ? "32":"");
+
+ len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
+ drti) + 1;
+
+#if !defined(sun)
+ len *= 2;
+#endif
+ cmd = alloca(len);
+
+ (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file,
+ drti);
+#endif
+ if ((status = system(cmd)) == -1) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to run %s: %s", dtp->dt_ld_path,
+ strerror(errno));
+ goto done;
+ }
+
+ if (WIFSIGNALED(status)) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to link %s: %s failed due to signal %d",
+ file, dtp->dt_ld_path, WTERMSIG(status));
+ goto done;
+ }
+
+ if (WEXITSTATUS(status) != 0) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to link %s: %s exited with status %d\n",
+ file, dtp->dt_ld_path, WEXITSTATUS(status));
+ goto done;
+ }
+#if !defined(sun)
+#define BROKEN_LIBELF
+ /*
+ * FreeBSD's ld(1) is not instructed to interpret and add
+ * correctly the SUNW_dof section present in tfile.
+ * We use libelf to add this section manually and hope the next
+ * ld invocation won't remove it.
+ */
+ elf_version(EV_CURRENT);
+ if ((efd = open(file, O_RDWR, 0)) < 0) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to open file %s: %s",
+ file, strerror(errno));
+ goto done;
+ }
+ if ((e = elf_begin(efd, ELF_C_RDWR, NULL)) == NULL) {
+ close(efd);
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to open elf file: %s",
+ elf_errmsg(elf_errno()));
+ goto done;
+ }
+ /*
+ * Add the string '.SUWN_dof' to the shstrtab section.
+ */
+#ifdef BROKEN_LIBELF
+ elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+#endif
+ elf_getshdrstrndx(e, &stridx);
+ scn = elf_getscn(e, stridx);
+ gelf_getshdr(scn, &shdr);
+ data = elf_newdata(scn);
+ data->d_off = shdr.sh_size;
+ data->d_buf = ".SUNW_dof";
+ data->d_size = 10;
+ data->d_type = ELF_T_BYTE;
+ loc = shdr.sh_size;
+ shdr.sh_size += data->d_size;
+ gelf_update_shdr(scn, &shdr);
+#ifdef BROKEN_LIBELF
+ off = shdr.sh_offset;
+ rc = shdr.sh_offset + shdr.sh_size;
+ gelf_getehdr(e, &ehdr);
+ if (ehdr.e_shoff > off) {
+ off = ehdr.e_shoff + ehdr.e_shnum * ehdr.e_shentsize;
+ rc = roundup(rc, 8);
+ ehdr.e_shoff = rc;
+ gelf_update_ehdr(e, &ehdr);
+ rc += ehdr.e_shnum * ehdr.e_shentsize;
+ }
+ for (;;) {
+ scn0 = NULL;
+ scn = NULL;
+ while ((scn = elf_nextscn(e, scn)) != NULL) {
+ gelf_getshdr(scn, &shdr);
+ if (shdr.sh_type == SHT_NOBITS ||
+ shdr.sh_offset < off)
+ continue;
+ /* Find the immediately adjcent section. */
+ if (scn0 == NULL ||
+ shdr.sh_offset < shdr0.sh_offset) {
+ scn0 = scn;
+ gelf_getshdr(scn0, &shdr0);
+ }
+ }
+ if (scn0 == NULL)
+ break;
+ /* Load section data to work around another bug */
+ elf_getdata(scn0, NULL);
+ /* Update section header, assure section alignment */
+ off = shdr0.sh_offset + shdr0.sh_size;
+ rc = roundup(rc, shdr0.sh_addralign);
+ shdr0.sh_offset = rc;
+ gelf_update_shdr(scn0, &shdr0);
+ rc += shdr0.sh_size;
+ }
+ if (elf_update(e, ELF_C_WRITE) < 0) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to add append the shstrtab section: %s",
+ elf_errmsg(elf_errno()));
+ elf_end(e);
+ close(efd);
+ goto done;
+ }
+ elf_end(e);
+ e = elf_begin(efd, ELF_C_RDWR, NULL);
+#endif
+ /*
+ * Construct the .SUNW_dof section.
+ */
+ scn = elf_newscn(e);
+ data = elf_newdata(scn);
+ buf = mmap(NULL, dof->dofh_filesz, PROT_READ, MAP_SHARED,
+ fd, 0);
+ if (buf == MAP_FAILED) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to mmap buffer %s", strerror(errno));
+ elf_end(e);
+ close(efd);
+ goto done;
+ }
+ data->d_buf = buf;
+ data->d_align = 4;
+ data->d_size = dof->dofh_filesz;
+ data->d_version = EV_CURRENT;
+ gelf_getshdr(scn, &shdr);
+ shdr.sh_name = loc;
+ shdr.sh_flags = SHF_ALLOC;
+ /*
+ * Actually this should be SHT_SUNW_dof, but FreeBSD's ld(1)
+ * will remove this 'unknown' section when we try to create an
+ * executable using the object we are modifying, so we stop
+ * playing by the rules and use SHT_PROGBITS.
+ * Also, note that our drti has modifications to handle this.
+ */
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_addralign = 4;
+ gelf_update_shdr(scn, &shdr);
+ if (elf_update(e, ELF_C_WRITE) < 0) {
+ ret = dt_link_error(dtp, NULL, -1, NULL,
+ "failed to add the SUNW_dof section: %s",
+ elf_errmsg(elf_errno()));
+ munmap(buf, dof->dofh_filesz);
+ elf_end(e);
+ close(efd);
+ goto done;
+ }
+ munmap(buf, dof->dofh_filesz);
+ elf_end(e);
+ close(efd);
+#endif
+ (void) close(fd); /* release temporary file */
+ } else {
+ (void) close(fd);
+ }
+
+done:
+ dtrace_dof_destroy(dtp, dof);
+
+#if !defined(sun)
+ unlink(tfile);
+#endif
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.c
new file mode 100644
index 0000000..32279e9
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.c
@@ -0,0 +1,111 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Simple doubly-linked list implementation. This implementation assumes that
+ * each list element contains an embedded dt_list_t (previous and next
+ * pointers), which is typically the first member of the element struct.
+ * An additional dt_list_t is used to store the head (dl_next) and tail
+ * (dl_prev) pointers. The current head and tail list elements have their
+ * previous and next pointers set to NULL, respectively.
+ */
+
+#include <unistd.h>
+#include <assert.h>
+#include <dt_list.h>
+
+void
+dt_list_append(dt_list_t *dlp, void *new)
+{
+ dt_list_t *p = dlp->dl_prev; /* p = tail list element */
+ dt_list_t *q = new; /* q = new list element */
+
+ dlp->dl_prev = q;
+ q->dl_prev = p;
+ q->dl_next = NULL;
+
+ if (p != NULL) {
+ assert(p->dl_next == NULL);
+ p->dl_next = q;
+ } else {
+ assert(dlp->dl_next == NULL);
+ dlp->dl_next = q;
+ }
+}
+
+void
+dt_list_prepend(dt_list_t *dlp, void *new)
+{
+ dt_list_t *p = new; /* p = new list element */
+ dt_list_t *q = dlp->dl_next; /* q = head list element */
+
+ dlp->dl_next = p;
+ p->dl_prev = NULL;
+ p->dl_next = q;
+
+ if (q != NULL) {
+ assert(q->dl_prev == NULL);
+ q->dl_prev = p;
+ } else {
+ assert(dlp->dl_prev == NULL);
+ dlp->dl_prev = p;
+ }
+}
+
+void
+dt_list_insert(dt_list_t *dlp, void *after_me, void *new)
+{
+ dt_list_t *p = after_me;
+ dt_list_t *q = new;
+
+ if (p == NULL || p->dl_next == NULL) {
+ dt_list_append(dlp, new);
+ return;
+ }
+
+ q->dl_next = p->dl_next;
+ q->dl_prev = p;
+ p->dl_next = q;
+ q->dl_next->dl_prev = q;
+}
+
+void
+dt_list_delete(dt_list_t *dlp, void *existing)
+{
+ dt_list_t *p = existing;
+
+ if (p->dl_prev != NULL)
+ p->dl_prev->dl_next = p->dl_next;
+ else
+ dlp->dl_next = p->dl_next;
+
+ if (p->dl_next != NULL)
+ p->dl_next->dl_prev = p->dl_prev;
+ else
+ dlp->dl_prev = p->dl_prev;
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.h
new file mode 100644
index 0000000..348d18a
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_list.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_LIST_H
+#define _DT_LIST_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_list {
+ struct dt_list *dl_prev;
+ struct dt_list *dl_next;
+} dt_list_t;
+
+#define dt_list_prev(elem) ((void *)(((dt_list_t *)(elem))->dl_prev))
+#define dt_list_next(elem) ((void *)(((dt_list_t *)(elem))->dl_next))
+
+extern void dt_list_append(dt_list_t *, void *);
+extern void dt_list_prepend(dt_list_t *, void *);
+extern void dt_list_insert(dt_list_t *, void *, void *);
+extern void dt_list_delete(dt_list_t *, void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_LIST_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c
new file mode 100644
index 0000000..c6d92c8
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_map.c
@@ -0,0 +1,492 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <dt_impl.h>
+#include <dt_printf.h>
+
+static int
+dt_strdata_add(dtrace_hdl_t *dtp, dtrace_recdesc_t *rec, void ***data, int *max)
+{
+ int maxformat;
+ dtrace_fmtdesc_t fmt;
+ void *result;
+
+ if (rec->dtrd_format == 0)
+ return (0);
+
+ if (rec->dtrd_format <= *max &&
+ (*data)[rec->dtrd_format - 1] != NULL) {
+ return (0);
+ }
+
+ bzero(&fmt, sizeof (fmt));
+ fmt.dtfd_format = rec->dtrd_format;
+ fmt.dtfd_string = NULL;
+ fmt.dtfd_length = 0;
+
+ if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ if ((fmt.dtfd_string = dt_alloc(dtp, fmt.dtfd_length)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
+ free(fmt.dtfd_string);
+ return (dt_set_errno(dtp, errno));
+ }
+
+ while (rec->dtrd_format > (maxformat = *max)) {
+ int new_max = maxformat ? (maxformat << 1) : 1;
+ size_t nsize = new_max * sizeof (void *);
+ size_t osize = maxformat * sizeof (void *);
+ void **new_data = dt_zalloc(dtp, nsize);
+
+ if (new_data == NULL) {
+ dt_free(dtp, fmt.dtfd_string);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bcopy(*data, new_data, osize);
+ free(*data);
+
+ *data = new_data;
+ *max = new_max;
+ }
+
+ switch (rec->dtrd_action) {
+ case DTRACEACT_DIFEXPR:
+ result = fmt.dtfd_string;
+ break;
+ case DTRACEACT_PRINTA:
+ result = dtrace_printa_create(dtp, fmt.dtfd_string);
+ dt_free(dtp, fmt.dtfd_string);
+ break;
+ default:
+ result = dtrace_printf_create(dtp, fmt.dtfd_string);
+ dt_free(dtp, fmt.dtfd_string);
+ break;
+ }
+
+ if (result == NULL)
+ return (-1);
+
+ (*data)[rec->dtrd_format - 1] = result;
+
+ return (0);
+}
+
+static int
+dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
+{
+ dtrace_id_t max;
+ int rval, i;
+ dtrace_eprobedesc_t *enabled, *nenabled;
+ dtrace_probedesc_t *probe;
+
+ while (id >= (max = dtp->dt_maxprobe) || dtp->dt_pdesc == NULL) {
+ dtrace_id_t new_max = max ? (max << 1) : 1;
+ size_t nsize = new_max * sizeof (void *);
+ dtrace_probedesc_t **new_pdesc;
+ dtrace_eprobedesc_t **new_edesc;
+
+ if ((new_pdesc = malloc(nsize)) == NULL ||
+ (new_edesc = malloc(nsize)) == NULL) {
+ free(new_pdesc);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bzero(new_pdesc, nsize);
+ bzero(new_edesc, nsize);
+
+ if (dtp->dt_pdesc != NULL) {
+ size_t osize = max * sizeof (void *);
+
+ bcopy(dtp->dt_pdesc, new_pdesc, osize);
+ free(dtp->dt_pdesc);
+
+ bcopy(dtp->dt_edesc, new_edesc, osize);
+ free(dtp->dt_edesc);
+ }
+
+ dtp->dt_pdesc = new_pdesc;
+ dtp->dt_edesc = new_edesc;
+ dtp->dt_maxprobe = new_max;
+ }
+
+ if (dtp->dt_pdesc[id] != NULL)
+ return (0);
+
+ if ((enabled = malloc(sizeof (dtrace_eprobedesc_t))) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ bzero(enabled, sizeof (dtrace_eprobedesc_t));
+ enabled->dtepd_epid = id;
+ enabled->dtepd_nrecs = 1;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled) == -1) {
+#endif
+ rval = dt_set_errno(dtp, errno);
+ free(enabled);
+ return (rval);
+ }
+
+ if (DTRACE_SIZEOF_EPROBEDESC(enabled) != sizeof (*enabled)) {
+ /*
+ * There must be more than one action. Allocate the
+ * appropriate amount of space and try again.
+ */
+ if ((nenabled =
+ malloc(DTRACE_SIZEOF_EPROBEDESC(enabled))) != NULL)
+ bcopy(enabled, nenabled, sizeof (*enabled));
+
+ free(enabled);
+
+ if ((enabled = nenabled) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+#if defined(sun)
+ rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled);
+#else
+ rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled);
+#endif
+
+ if (rval == -1) {
+ rval = dt_set_errno(dtp, errno);
+ free(enabled);
+ return (rval);
+ }
+ }
+
+ if ((probe = malloc(sizeof (dtrace_probedesc_t))) == NULL) {
+ free(enabled);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ probe->dtpd_id = enabled->dtepd_probeid;
+
+ if (dt_ioctl(dtp, DTRACEIOC_PROBES, probe) == -1) {
+ rval = dt_set_errno(dtp, errno);
+ goto err;
+ }
+
+ for (i = 0; i < enabled->dtepd_nrecs; i++) {
+ dtrace_recdesc_t *rec = &enabled->dtepd_rec[i];
+
+ if (DTRACEACT_ISPRINTFLIKE(rec->dtrd_action)) {
+ if (dt_strdata_add(dtp, rec, &dtp->dt_formats,
+ &dtp->dt_maxformat) != 0) {
+ rval = -1;
+ goto err;
+ }
+ } else if (rec->dtrd_action == DTRACEACT_DIFEXPR) {
+ if (dt_strdata_add(dtp, rec,
+ (void ***)&dtp->dt_strdata,
+ &dtp->dt_maxstrdata) != 0) {
+ rval = -1;
+ goto err;
+ }
+ }
+
+ }
+
+ dtp->dt_pdesc[id] = probe;
+ dtp->dt_edesc[id] = enabled;
+
+ return (0);
+
+err:
+ /*
+ * If we failed, free our allocated probes. Note that if we failed
+ * while allocating formats, we aren't going to free formats that
+ * we have already allocated. This is okay; these formats are
+ * hanging off of dt_formats and will therefore not be leaked.
+ */
+ free(enabled);
+ free(probe);
+ return (rval);
+}
+
+int
+dt_epid_lookup(dtrace_hdl_t *dtp, dtrace_epid_t epid,
+ dtrace_eprobedesc_t **epdp, dtrace_probedesc_t **pdp)
+{
+ int rval;
+
+ if (epid >= dtp->dt_maxprobe || dtp->dt_pdesc[epid] == NULL) {
+ if ((rval = dt_epid_add(dtp, epid)) != 0)
+ return (rval);
+ }
+
+ assert(epid < dtp->dt_maxprobe);
+ assert(dtp->dt_edesc[epid] != NULL);
+ assert(dtp->dt_pdesc[epid] != NULL);
+ *epdp = dtp->dt_edesc[epid];
+ *pdp = dtp->dt_pdesc[epid];
+
+ return (0);
+}
+
+void
+dt_epid_destroy(dtrace_hdl_t *dtp)
+{
+ size_t i;
+
+ assert((dtp->dt_pdesc != NULL && dtp->dt_edesc != NULL &&
+ dtp->dt_maxprobe > 0) || (dtp->dt_pdesc == NULL &&
+ dtp->dt_edesc == NULL && dtp->dt_maxprobe == 0));
+
+ if (dtp->dt_pdesc == NULL)
+ return;
+
+ for (i = 0; i < dtp->dt_maxprobe; i++) {
+ if (dtp->dt_edesc[i] == NULL) {
+ assert(dtp->dt_pdesc[i] == NULL);
+ continue;
+ }
+
+ assert(dtp->dt_pdesc[i] != NULL);
+ free(dtp->dt_edesc[i]);
+ free(dtp->dt_pdesc[i]);
+ }
+
+ free(dtp->dt_pdesc);
+ dtp->dt_pdesc = NULL;
+
+ free(dtp->dt_edesc);
+ dtp->dt_edesc = NULL;
+ dtp->dt_maxprobe = 0;
+}
+
+void *
+dt_format_lookup(dtrace_hdl_t *dtp, int format)
+{
+ if (format == 0 || format > dtp->dt_maxformat)
+ return (NULL);
+
+ if (dtp->dt_formats == NULL)
+ return (NULL);
+
+ return (dtp->dt_formats[format - 1]);
+}
+
+void
+dt_format_destroy(dtrace_hdl_t *dtp)
+{
+ int i;
+
+ for (i = 0; i < dtp->dt_maxformat; i++) {
+ if (dtp->dt_formats[i] != NULL)
+ dt_printf_destroy(dtp->dt_formats[i]);
+ }
+
+ free(dtp->dt_formats);
+ dtp->dt_formats = NULL;
+}
+
+static int
+dt_aggid_add(dtrace_hdl_t *dtp, dtrace_aggid_t id)
+{
+ dtrace_id_t max;
+ dtrace_epid_t epid;
+ int rval;
+
+ while (id >= (max = dtp->dt_maxagg) || dtp->dt_aggdesc == NULL) {
+ dtrace_id_t new_max = max ? (max << 1) : 1;
+ size_t nsize = new_max * sizeof (void *);
+ dtrace_aggdesc_t **new_aggdesc;
+
+ if ((new_aggdesc = malloc(nsize)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ bzero(new_aggdesc, nsize);
+
+ if (dtp->dt_aggdesc != NULL) {
+ bcopy(dtp->dt_aggdesc, new_aggdesc,
+ max * sizeof (void *));
+ free(dtp->dt_aggdesc);
+ }
+
+ dtp->dt_aggdesc = new_aggdesc;
+ dtp->dt_maxagg = new_max;
+ }
+
+ if (dtp->dt_aggdesc[id] == NULL) {
+ dtrace_aggdesc_t *agg, *nagg;
+
+ if ((agg = malloc(sizeof (dtrace_aggdesc_t))) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ bzero(agg, sizeof (dtrace_aggdesc_t));
+ agg->dtagd_id = id;
+ agg->dtagd_nrecs = 1;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg) == -1) {
+#endif
+ rval = dt_set_errno(dtp, errno);
+ free(agg);
+ return (rval);
+ }
+
+ if (DTRACE_SIZEOF_AGGDESC(agg) != sizeof (*agg)) {
+ /*
+ * There must be more than one action. Allocate the
+ * appropriate amount of space and try again.
+ */
+ if ((nagg = malloc(DTRACE_SIZEOF_AGGDESC(agg))) != NULL)
+ bcopy(agg, nagg, sizeof (*agg));
+
+ free(agg);
+
+ if ((agg = nagg) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+#if defined(sun)
+ rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg);
+#else
+ rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg);
+#endif
+
+ if (rval == -1) {
+ rval = dt_set_errno(dtp, errno);
+ free(agg);
+ return (rval);
+ }
+ }
+
+ /*
+ * If we have a uarg, it's a pointer to the compiler-generated
+ * statement; we'll use this value to get the name and
+ * compiler-generated variable ID for the aggregation. If
+ * we're grabbing an anonymous enabling, this pointer value
+ * is obviously meaningless -- and in this case, we can't
+ * provide the compiler-generated aggregation information.
+ */
+ if (dtp->dt_options[DTRACEOPT_GRABANON] == DTRACEOPT_UNSET &&
+ agg->dtagd_rec[0].dtrd_uarg != 0) {
+ dtrace_stmtdesc_t *sdp;
+ dt_ident_t *aid;
+
+ sdp = (dtrace_stmtdesc_t *)(uintptr_t)
+ agg->dtagd_rec[0].dtrd_uarg;
+ aid = sdp->dtsd_aggdata;
+ agg->dtagd_name = aid->di_name;
+ agg->dtagd_varid = aid->di_id;
+ } else {
+ agg->dtagd_varid = DTRACE_AGGVARIDNONE;
+ }
+
+ if ((epid = agg->dtagd_epid) >= dtp->dt_maxprobe ||
+ dtp->dt_pdesc[epid] == NULL) {
+ if ((rval = dt_epid_add(dtp, epid)) != 0) {
+ free(agg);
+ return (rval);
+ }
+ }
+
+ dtp->dt_aggdesc[id] = agg;
+ }
+
+ return (0);
+}
+
+int
+dt_aggid_lookup(dtrace_hdl_t *dtp, dtrace_aggid_t aggid,
+ dtrace_aggdesc_t **adp)
+{
+ int rval;
+
+ if (aggid >= dtp->dt_maxagg || dtp->dt_aggdesc[aggid] == NULL) {
+ if ((rval = dt_aggid_add(dtp, aggid)) != 0)
+ return (rval);
+ }
+
+ assert(aggid < dtp->dt_maxagg);
+ assert(dtp->dt_aggdesc[aggid] != NULL);
+ *adp = dtp->dt_aggdesc[aggid];
+
+ return (0);
+}
+
+void
+dt_aggid_destroy(dtrace_hdl_t *dtp)
+{
+ size_t i;
+
+ assert((dtp->dt_aggdesc != NULL && dtp->dt_maxagg != 0) ||
+ (dtp->dt_aggdesc == NULL && dtp->dt_maxagg == 0));
+
+ if (dtp->dt_aggdesc == NULL)
+ return;
+
+ for (i = 0; i < dtp->dt_maxagg; i++) {
+ if (dtp->dt_aggdesc[i] != NULL)
+ free(dtp->dt_aggdesc[i]);
+ }
+
+ free(dtp->dt_aggdesc);
+ dtp->dt_aggdesc = NULL;
+ dtp->dt_maxagg = 0;
+}
+
+const char *
+dt_strdata_lookup(dtrace_hdl_t *dtp, int idx)
+{
+ if (idx == 0 || idx > dtp->dt_maxstrdata)
+ return (NULL);
+
+ if (dtp->dt_strdata == NULL)
+ return (NULL);
+
+ return (dtp->dt_strdata[idx - 1]);
+}
+
+void
+dt_strdata_destroy(dtrace_hdl_t *dtp)
+{
+ int i;
+
+ for (i = 0; i < dtp->dt_maxstrdata; i++) {
+ free(dtp->dt_strdata[i]);
+ }
+
+ free(dtp->dt_strdata);
+ dtp->dt_strdata = NULL;
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
new file mode 100644
index 0000000..497faa9
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
@@ -0,0 +1,1467 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/modctl.h>
+#include <sys/kobj.h>
+#include <sys/kobj_impl.h>
+#include <sys/sysmacros.h>
+#include <sys/elf.h>
+#include <sys/task.h>
+#else
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/stat.h>
+#endif
+
+#include <unistd.h>
+#if defined(sun)
+#include <project.h>
+#endif
+#include <strings.h>
+#include <stdlib.h>
+#include <libelf.h>
+#include <limits.h>
+#include <assert.h>
+#include <errno.h>
+#include <dirent.h>
+#if !defined(sun)
+#include <fcntl.h>
+#endif
+
+#include <dt_strtab.h>
+#include <dt_module.h>
+#include <dt_impl.h>
+
+static const char *dt_module_strtab; /* active strtab for qsort callbacks */
+
+static void
+dt_module_symhash_insert(dt_module_t *dmp, const char *name, uint_t id)
+{
+ dt_sym_t *dsp = &dmp->dm_symchains[dmp->dm_symfree];
+ uint_t h;
+
+ assert(dmp->dm_symfree < dmp->dm_nsymelems + 1);
+
+ dsp->ds_symid = id;
+ h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
+ dsp->ds_next = dmp->dm_symbuckets[h];
+ dmp->dm_symbuckets[h] = dmp->dm_symfree++;
+}
+
+static uint_t
+dt_module_syminit32(dt_module_t *dmp)
+{
+#if STT_NUM != (STT_TLS + 1)
+#error "STT_NUM has grown. update dt_module_syminit32()"
+#endif
+
+ Elf32_Sym *sym = dmp->dm_symtab.cts_data;
+ const char *base = dmp->dm_strtab.cts_data;
+ size_t ss_size = dmp->dm_strtab.cts_size;
+ uint_t i, n = dmp->dm_nsymelems;
+ uint_t asrsv = 0;
+
+#if defined(__FreeBSD__)
+ GElf_Ehdr ehdr;
+ int is_elf_obj;
+
+ gelf_getehdr(dmp->dm_elf, &ehdr);
+ is_elf_obj = (ehdr.e_type == ET_REL);
+#endif
+
+ for (i = 0; i < n; i++, sym++) {
+ const char *name = base + sym->st_name;
+ uchar_t type = ELF32_ST_TYPE(sym->st_info);
+
+ if (type >= STT_NUM || type == STT_SECTION)
+ continue; /* skip sections and unknown types */
+
+ if (sym->st_name == 0 || sym->st_name >= ss_size)
+ continue; /* skip null or invalid names */
+
+ if (sym->st_value != 0 &&
+ (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) {
+ asrsv++; /* reserve space in the address map */
+
+#if defined(__FreeBSD__)
+ sym->st_value += (Elf_Addr) dmp->dm_reloc_offset;
+ if (is_elf_obj && sym->st_shndx != SHN_UNDEF &&
+ sym->st_shndx < ehdr.e_shnum)
+ sym->st_value +=
+ dmp->dm_sec_offsets[sym->st_shndx];
+#endif
+ }
+
+ dt_module_symhash_insert(dmp, name, i);
+ }
+
+ return (asrsv);
+}
+
+static uint_t
+dt_module_syminit64(dt_module_t *dmp)
+{
+#if STT_NUM != (STT_TLS + 1)
+#error "STT_NUM has grown. update dt_module_syminit64()"
+#endif
+
+ Elf64_Sym *sym = dmp->dm_symtab.cts_data;
+ const char *base = dmp->dm_strtab.cts_data;
+ size_t ss_size = dmp->dm_strtab.cts_size;
+ uint_t i, n = dmp->dm_nsymelems;
+ uint_t asrsv = 0;
+
+#if defined(__FreeBSD__)
+ GElf_Ehdr ehdr;
+ int is_elf_obj;
+
+ gelf_getehdr(dmp->dm_elf, &ehdr);
+ is_elf_obj = (ehdr.e_type == ET_REL);
+#endif
+
+ for (i = 0; i < n; i++, sym++) {
+ const char *name = base + sym->st_name;
+ uchar_t type = ELF64_ST_TYPE(sym->st_info);
+
+ if (type >= STT_NUM || type == STT_SECTION)
+ continue; /* skip sections and unknown types */
+
+ if (sym->st_name == 0 || sym->st_name >= ss_size)
+ continue; /* skip null or invalid names */
+
+ if (sym->st_value != 0 &&
+ (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) {
+ asrsv++; /* reserve space in the address map */
+#if defined(__FreeBSD__)
+ sym->st_value += (Elf_Addr) dmp->dm_reloc_offset;
+ if (is_elf_obj && sym->st_shndx != SHN_UNDEF &&
+ sym->st_shndx < ehdr.e_shnum)
+ sym->st_value +=
+ dmp->dm_sec_offsets[sym->st_shndx];
+#endif
+ }
+
+ dt_module_symhash_insert(dmp, name, i);
+ }
+
+ return (asrsv);
+}
+
+/*
+ * Sort comparison function for 32-bit symbol address-to-name lookups. We sort
+ * symbols by value. If values are equal, we prefer the symbol that is
+ * non-zero sized, typed, not weak, or lexically first, in that order.
+ */
+static int
+dt_module_symcomp32(const void *lp, const void *rp)
+{
+ Elf32_Sym *lhs = *((Elf32_Sym **)lp);
+ Elf32_Sym *rhs = *((Elf32_Sym **)rp);
+
+ if (lhs->st_value != rhs->st_value)
+ return (lhs->st_value > rhs->st_value ? 1 : -1);
+
+ if ((lhs->st_size == 0) != (rhs->st_size == 0))
+ return (lhs->st_size == 0 ? 1 : -1);
+
+ if ((ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
+ (ELF32_ST_TYPE(rhs->st_info) == STT_NOTYPE))
+ return (ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
+
+ if ((ELF32_ST_BIND(lhs->st_info) == STB_WEAK) !=
+ (ELF32_ST_BIND(rhs->st_info) == STB_WEAK))
+ return (ELF32_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
+
+ return (strcmp(dt_module_strtab + lhs->st_name,
+ dt_module_strtab + rhs->st_name));
+}
+
+/*
+ * Sort comparison function for 64-bit symbol address-to-name lookups. We sort
+ * symbols by value. If values are equal, we prefer the symbol that is
+ * non-zero sized, typed, not weak, or lexically first, in that order.
+ */
+static int
+dt_module_symcomp64(const void *lp, const void *rp)
+{
+ Elf64_Sym *lhs = *((Elf64_Sym **)lp);
+ Elf64_Sym *rhs = *((Elf64_Sym **)rp);
+
+ if (lhs->st_value != rhs->st_value)
+ return (lhs->st_value > rhs->st_value ? 1 : -1);
+
+ if ((lhs->st_size == 0) != (rhs->st_size == 0))
+ return (lhs->st_size == 0 ? 1 : -1);
+
+ if ((ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
+ (ELF64_ST_TYPE(rhs->st_info) == STT_NOTYPE))
+ return (ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
+
+ if ((ELF64_ST_BIND(lhs->st_info) == STB_WEAK) !=
+ (ELF64_ST_BIND(rhs->st_info) == STB_WEAK))
+ return (ELF64_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
+
+ return (strcmp(dt_module_strtab + lhs->st_name,
+ dt_module_strtab + rhs->st_name));
+}
+
+static void
+dt_module_symsort32(dt_module_t *dmp)
+{
+ Elf32_Sym *symtab = (Elf32_Sym *)dmp->dm_symtab.cts_data;
+ Elf32_Sym **sympp = (Elf32_Sym **)dmp->dm_asmap;
+ const dt_sym_t *dsp = dmp->dm_symchains + 1;
+ uint_t i, n = dmp->dm_symfree;
+
+ for (i = 1; i < n; i++, dsp++) {
+ Elf32_Sym *sym = symtab + dsp->ds_symid;
+ if (sym->st_value != 0 &&
+ (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
+ *sympp++ = sym;
+ }
+
+ dmp->dm_aslen = (uint_t)(sympp - (Elf32_Sym **)dmp->dm_asmap);
+ assert(dmp->dm_aslen <= dmp->dm_asrsv);
+
+ dt_module_strtab = dmp->dm_strtab.cts_data;
+ qsort(dmp->dm_asmap, dmp->dm_aslen,
+ sizeof (Elf32_Sym *), dt_module_symcomp32);
+ dt_module_strtab = NULL;
+}
+
+static void
+dt_module_symsort64(dt_module_t *dmp)
+{
+ Elf64_Sym *symtab = (Elf64_Sym *)dmp->dm_symtab.cts_data;
+ Elf64_Sym **sympp = (Elf64_Sym **)dmp->dm_asmap;
+ const dt_sym_t *dsp = dmp->dm_symchains + 1;
+ uint_t i, n = dmp->dm_symfree;
+
+ for (i = 1; i < n; i++, dsp++) {
+ Elf64_Sym *sym = symtab + dsp->ds_symid;
+ if (sym->st_value != 0 &&
+ (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
+ *sympp++ = sym;
+ }
+
+ dmp->dm_aslen = (uint_t)(sympp - (Elf64_Sym **)dmp->dm_asmap);
+ assert(dmp->dm_aslen <= dmp->dm_asrsv);
+
+ dt_module_strtab = dmp->dm_strtab.cts_data;
+ qsort(dmp->dm_asmap, dmp->dm_aslen,
+ sizeof (Elf64_Sym *), dt_module_symcomp64);
+ dt_module_strtab = NULL;
+}
+
+static GElf_Sym *
+dt_module_symgelf32(const Elf32_Sym *src, GElf_Sym *dst)
+{
+ if (dst != NULL) {
+ dst->st_name = src->st_name;
+ dst->st_info = src->st_info;
+ dst->st_other = src->st_other;
+ dst->st_shndx = src->st_shndx;
+ dst->st_value = src->st_value;
+ dst->st_size = src->st_size;
+ }
+
+ return (dst);
+}
+
+static GElf_Sym *
+dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst)
+{
+ if (dst != NULL)
+ bcopy(src, dst, sizeof (GElf_Sym));
+
+ return (dst);
+}
+
+static GElf_Sym *
+dt_module_symname32(dt_module_t *dmp, const char *name,
+ GElf_Sym *symp, uint_t *idp)
+{
+ const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
+ const char *strtab = dmp->dm_strtab.cts_data;
+
+ const Elf32_Sym *sym;
+ const dt_sym_t *dsp;
+ uint_t i, h;
+
+ if (dmp->dm_nsymelems == 0)
+ return (NULL);
+
+ h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
+
+ for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
+ dsp = &dmp->dm_symchains[i];
+ sym = symtab + dsp->ds_symid;
+
+ if (strcmp(name, strtab + sym->st_name) == 0) {
+ if (idp != NULL)
+ *idp = dsp->ds_symid;
+ return (dt_module_symgelf32(sym, symp));
+ }
+ }
+
+ return (NULL);
+}
+
+static GElf_Sym *
+dt_module_symname64(dt_module_t *dmp, const char *name,
+ GElf_Sym *symp, uint_t *idp)
+{
+ const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
+ const char *strtab = dmp->dm_strtab.cts_data;
+
+ const Elf64_Sym *sym;
+ const dt_sym_t *dsp;
+ uint_t i, h;
+
+ if (dmp->dm_nsymelems == 0)
+ return (NULL);
+
+ h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
+
+ for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
+ dsp = &dmp->dm_symchains[i];
+ sym = symtab + dsp->ds_symid;
+
+ if (strcmp(name, strtab + sym->st_name) == 0) {
+ if (idp != NULL)
+ *idp = dsp->ds_symid;
+ return (dt_module_symgelf64(sym, symp));
+ }
+ }
+
+ return (NULL);
+}
+
+static GElf_Sym *
+dt_module_symaddr32(dt_module_t *dmp, GElf_Addr addr,
+ GElf_Sym *symp, uint_t *idp)
+{
+ const Elf32_Sym **asmap = (const Elf32_Sym **)dmp->dm_asmap;
+ const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
+ const Elf32_Sym *sym;
+
+ uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
+ Elf32_Addr v;
+
+ if (dmp->dm_aslen == 0)
+ return (NULL);
+
+ while (hi - lo > 1) {
+ mid = (lo + hi) / 2;
+ if (addr >= asmap[mid]->st_value)
+ lo = mid;
+ else
+ hi = mid;
+ }
+
+ i = addr < asmap[hi]->st_value ? lo : hi;
+ sym = asmap[i];
+ v = sym->st_value;
+
+ /*
+ * If the previous entry has the same value, improve our choice. The
+ * order of equal-valued symbols is determined by the comparison func.
+ */
+ while (i-- != 0 && asmap[i]->st_value == v)
+ sym = asmap[i];
+
+ if (addr - sym->st_value < MAX(sym->st_size, 1)) {
+ if (idp != NULL)
+ *idp = (uint_t)(sym - symtab);
+ return (dt_module_symgelf32(sym, symp));
+ }
+
+ return (NULL);
+}
+
+static GElf_Sym *
+dt_module_symaddr64(dt_module_t *dmp, GElf_Addr addr,
+ GElf_Sym *symp, uint_t *idp)
+{
+ const Elf64_Sym **asmap = (const Elf64_Sym **)dmp->dm_asmap;
+ const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
+ const Elf64_Sym *sym;
+
+ uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
+ Elf64_Addr v;
+
+ if (dmp->dm_aslen == 0)
+ return (NULL);
+
+ while (hi - lo > 1) {
+ mid = (lo + hi) / 2;
+ if (addr >= asmap[mid]->st_value)
+ lo = mid;
+ else
+ hi = mid;
+ }
+
+ i = addr < asmap[hi]->st_value ? lo : hi;
+ sym = asmap[i];
+ v = sym->st_value;
+
+ /*
+ * If the previous entry has the same value, improve our choice. The
+ * order of equal-valued symbols is determined by the comparison func.
+ */
+ while (i-- != 0 && asmap[i]->st_value == v)
+ sym = asmap[i];
+
+ if (addr - sym->st_value < MAX(sym->st_size, 1)) {
+ if (idp != NULL)
+ *idp = (uint_t)(sym - symtab);
+ return (dt_module_symgelf64(sym, symp));
+ }
+
+ return (NULL);
+}
+
+static const dt_modops_t dt_modops_32 = {
+ dt_module_syminit32,
+ dt_module_symsort32,
+ dt_module_symname32,
+ dt_module_symaddr32
+};
+
+static const dt_modops_t dt_modops_64 = {
+ dt_module_syminit64,
+ dt_module_symsort64,
+ dt_module_symname64,
+ dt_module_symaddr64
+};
+
+dt_module_t *
+dt_module_create(dtrace_hdl_t *dtp, const char *name)
+{
+ uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
+ dt_module_t *dmp;
+
+ for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
+ if (strcmp(dmp->dm_name, name) == 0)
+ return (dmp);
+ }
+
+ if ((dmp = malloc(sizeof (dt_module_t))) == NULL)
+ return (NULL); /* caller must handle allocation failure */
+
+ bzero(dmp, sizeof (dt_module_t));
+ (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name));
+ dt_list_append(&dtp->dt_modlist, dmp);
+ dmp->dm_next = dtp->dt_mods[h];
+ dtp->dt_mods[h] = dmp;
+ dtp->dt_nmods++;
+
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
+ dmp->dm_ops = &dt_modops_64;
+ else
+ dmp->dm_ops = &dt_modops_32;
+
+ return (dmp);
+}
+
+dt_module_t *
+dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
+{
+ uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
+ dt_module_t *dmp;
+
+ for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
+ if (strcmp(dmp->dm_name, name) == 0)
+ return (dmp);
+ }
+
+ return (NULL);
+}
+
+/*ARGSUSED*/
+dt_module_t *
+dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp)
+{
+ return (ctfp ? ctf_getspecific(ctfp) : NULL);
+}
+
+static int
+dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
+{
+ const char *s;
+ size_t shstrs;
+ GElf_Shdr sh;
+ Elf_Data *dp;
+ Elf_Scn *sp;
+
+ if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
+ return (dt_set_errno(dtp, EDT_NOTLOADED));
+
+ for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
+ if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
+ (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
+ continue; /* skip any malformed sections */
+
+ if (sh.sh_type == ctsp->cts_type &&
+ sh.sh_entsize == ctsp->cts_entsize &&
+ strcmp(s, ctsp->cts_name) == 0)
+ break; /* section matches specification */
+ }
+
+ /*
+ * If the section isn't found, return success but leave cts_data set
+ * to NULL and cts_size set to zero for our caller.
+ */
+ if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
+ return (0);
+
+#if defined(sun)
+ ctsp->cts_data = dp->d_buf;
+#else
+ if ((ctsp->cts_data = malloc(dp->d_size)) == NULL)
+ return (0);
+ memcpy(ctsp->cts_data, dp->d_buf, dp->d_size);
+#endif
+ ctsp->cts_size = dp->d_size;
+
+ dt_dprintf("loaded %s [%s] (%lu bytes)\n",
+ dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);
+
+ return (0);
+}
+
+int
+dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ if (dmp->dm_flags & DT_DM_LOADED)
+ return (0); /* module is already loaded */
+
+ dmp->dm_ctdata.cts_name = ".SUNW_ctf";
+ dmp->dm_ctdata.cts_type = SHT_PROGBITS;
+ dmp->dm_ctdata.cts_flags = 0;
+ dmp->dm_ctdata.cts_data = NULL;
+ dmp->dm_ctdata.cts_size = 0;
+ dmp->dm_ctdata.cts_entsize = 0;
+ dmp->dm_ctdata.cts_offset = 0;
+
+ dmp->dm_symtab.cts_name = ".symtab";
+ dmp->dm_symtab.cts_type = SHT_SYMTAB;
+ dmp->dm_symtab.cts_flags = 0;
+ dmp->dm_symtab.cts_data = NULL;
+ dmp->dm_symtab.cts_size = 0;
+ dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?
+ sizeof (Elf64_Sym) : sizeof (Elf32_Sym);
+ dmp->dm_symtab.cts_offset = 0;
+
+ dmp->dm_strtab.cts_name = ".strtab";
+ dmp->dm_strtab.cts_type = SHT_STRTAB;
+ dmp->dm_strtab.cts_flags = 0;
+ dmp->dm_strtab.cts_data = NULL;
+ dmp->dm_strtab.cts_size = 0;
+ dmp->dm_strtab.cts_entsize = 0;
+ dmp->dm_strtab.cts_offset = 0;
+
+ /*
+ * Attempt to load the module's CTF section, symbol table section, and
+ * string table section. Note that modules may not contain CTF data:
+ * this will result in a successful load_sect but data of size zero.
+ * We will then fail if dt_module_getctf() is called, as shown below.
+ */
+ if (dt_module_load_sect(dtp, dmp, &dmp->dm_ctdata) == -1 ||
+ dt_module_load_sect(dtp, dmp, &dmp->dm_symtab) == -1 ||
+ dt_module_load_sect(dtp, dmp, &dmp->dm_strtab) == -1) {
+ dt_module_unload(dtp, dmp);
+ return (-1); /* dt_errno is set for us */
+ }
+
+ /*
+ * Allocate the hash chains and hash buckets for symbol name lookup.
+ * This is relatively simple since the symbol table is of fixed size
+ * and is known in advance. We allocate one extra element since we
+ * use element indices instead of pointers and zero is our sentinel.
+ */
+ dmp->dm_nsymelems =
+ dmp->dm_symtab.cts_size / dmp->dm_symtab.cts_entsize;
+
+ dmp->dm_nsymbuckets = _dtrace_strbuckets;
+ dmp->dm_symfree = 1; /* first free element is index 1 */
+
+ dmp->dm_symbuckets = malloc(sizeof (uint_t) * dmp->dm_nsymbuckets);
+ dmp->dm_symchains = malloc(sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);
+
+ if (dmp->dm_symbuckets == NULL || dmp->dm_symchains == NULL) {
+ dt_module_unload(dtp, dmp);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bzero(dmp->dm_symbuckets, sizeof (uint_t) * dmp->dm_nsymbuckets);
+ bzero(dmp->dm_symchains, sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);
+
+ /*
+ * Iterate over the symbol table data buffer and insert each symbol
+ * name into the name hash if the name and type are valid. Then
+ * allocate the address map, fill it in, and sort it.
+ */
+ dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);
+
+ dt_dprintf("hashed %s [%s] (%u symbols)\n",
+ dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);
+
+ if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {
+ dt_module_unload(dtp, dmp);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dmp->dm_ops->do_symsort(dmp);
+
+ dt_dprintf("sorted %s [%s] (%u symbols)\n",
+ dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);
+
+ dmp->dm_flags |= DT_DM_LOADED;
+ return (0);
+}
+
+ctf_file_t *
+dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ const char *parent;
+ dt_module_t *pmp;
+ ctf_file_t *pfp;
+ int model;
+
+ if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
+ return (dmp->dm_ctfp);
+
+ if (dmp->dm_ops == &dt_modops_64)
+ model = CTF_MODEL_LP64;
+ else
+ model = CTF_MODEL_ILP32;
+
+ /*
+ * If the data model of the module does not match our program data
+ * model, then do not permit CTF from this module to be opened and
+ * returned to the compiler. If we support mixed data models in the
+ * future for combined kernel/user tracing, this can be removed.
+ */
+ if (dtp->dt_conf.dtc_ctfmodel != model) {
+ (void) dt_set_errno(dtp, EDT_DATAMODEL);
+ return (NULL);
+ }
+
+ if (dmp->dm_ctdata.cts_size == 0) {
+ (void) dt_set_errno(dtp, EDT_NOCTF);
+ return (NULL);
+ }
+
+ dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
+ &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);
+
+ if (dmp->dm_ctfp == NULL) {
+ (void) dt_set_errno(dtp, EDT_CTF);
+ return (NULL);
+ }
+
+ (void) ctf_setmodel(dmp->dm_ctfp, model);
+ ctf_setspecific(dmp->dm_ctfp, dmp);
+
+ if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
+ if ((pmp = dt_module_create(dtp, parent)) == NULL ||
+ (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
+ if (pmp == NULL)
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ goto err;
+ }
+
+ if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
+ dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
+ (void) dt_set_errno(dtp, EDT_CTF);
+ goto err;
+ }
+ }
+
+ dt_dprintf("loaded CTF container for %s (%p)\n",
+ dmp->dm_name, (void *)dmp->dm_ctfp);
+
+ return (dmp->dm_ctfp);
+
+err:
+ ctf_close(dmp->dm_ctfp);
+ dmp->dm_ctfp = NULL;
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ ctf_close(dmp->dm_ctfp);
+ dmp->dm_ctfp = NULL;
+
+#if !defined(sun)
+ if (dmp->dm_ctdata.cts_data != NULL) {
+ free(dmp->dm_ctdata.cts_data);
+ }
+ if (dmp->dm_symtab.cts_data != NULL) {
+ free(dmp->dm_symtab.cts_data);
+ }
+ if (dmp->dm_strtab.cts_data != NULL) {
+ free(dmp->dm_strtab.cts_data);
+ }
+#endif
+
+ bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
+ bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
+ bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
+
+ if (dmp->dm_symbuckets != NULL) {
+ free(dmp->dm_symbuckets);
+ dmp->dm_symbuckets = NULL;
+ }
+
+ if (dmp->dm_symchains != NULL) {
+ free(dmp->dm_symchains);
+ dmp->dm_symchains = NULL;
+ }
+
+ if (dmp->dm_asmap != NULL) {
+ free(dmp->dm_asmap);
+ dmp->dm_asmap = NULL;
+ }
+#if defined(__FreeBSD__)
+ if (dmp->dm_sec_offsets != NULL) {
+ free(dmp->dm_sec_offsets);
+ dmp->dm_sec_offsets = NULL;
+ }
+#endif
+ dmp->dm_symfree = 0;
+ dmp->dm_nsymbuckets = 0;
+ dmp->dm_nsymelems = 0;
+ dmp->dm_asrsv = 0;
+ dmp->dm_aslen = 0;
+
+ dmp->dm_text_va = 0;
+ dmp->dm_text_size = 0;
+ dmp->dm_data_va = 0;
+ dmp->dm_data_size = 0;
+ dmp->dm_bss_va = 0;
+ dmp->dm_bss_size = 0;
+
+ if (dmp->dm_extern != NULL) {
+ dt_idhash_destroy(dmp->dm_extern);
+ dmp->dm_extern = NULL;
+ }
+
+ (void) elf_end(dmp->dm_elf);
+ dmp->dm_elf = NULL;
+
+ dmp->dm_flags &= ~DT_DM_LOADED;
+}
+
+void
+dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets;
+ dt_module_t **dmpp = &dtp->dt_mods[h];
+
+ dt_list_delete(&dtp->dt_modlist, dmp);
+ assert(dtp->dt_nmods != 0);
+ dtp->dt_nmods--;
+
+ /*
+ * Now remove this module from its hash chain. We expect to always
+ * find the module on its hash chain, so in this loop we assert that
+ * we don't run off the end of the list.
+ */
+ while (*dmpp != dmp) {
+ dmpp = &((*dmpp)->dm_next);
+ assert(*dmpp != NULL);
+ }
+
+ *dmpp = dmp->dm_next;
+
+ dt_module_unload(dtp, dmp);
+ free(dmp);
+}
+
+/*
+ * Insert a new external symbol reference into the specified module. The new
+ * symbol will be marked as undefined and is assigned a symbol index beyond
+ * any existing cached symbols from this module. We use the ident's di_data
+ * field to store a pointer to a copy of the dtrace_syminfo_t for this symbol.
+ */
+dt_ident_t *
+dt_module_extern(dtrace_hdl_t *dtp, dt_module_t *dmp,
+ const char *name, const dtrace_typeinfo_t *tip)
+{
+ dtrace_syminfo_t *sip;
+ dt_ident_t *idp;
+ uint_t id;
+
+ if (dmp->dm_extern == NULL && (dmp->dm_extern = dt_idhash_create(
+ "extern", NULL, dmp->dm_nsymelems, UINT_MAX)) == NULL) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ if (dt_idhash_nextid(dmp->dm_extern, &id) == -1) {
+ (void) dt_set_errno(dtp, EDT_SYMOFLOW);
+ return (NULL);
+ }
+
+ if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ idp = dt_idhash_insert(dmp->dm_extern, name, DT_IDENT_SYMBOL, 0, id,
+ _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
+
+ if (idp == NULL) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ free(sip);
+ return (NULL);
+ }
+
+ sip->dts_object = dmp->dm_name;
+ sip->dts_name = idp->di_name;
+ sip->dts_id = idp->di_id;
+
+ idp->di_data = sip;
+ idp->di_ctfp = tip->dtt_ctfp;
+ idp->di_type = tip->dtt_type;
+
+ return (idp);
+}
+
+const char *
+dt_module_modelname(dt_module_t *dmp)
+{
+ if (dmp->dm_ops == &dt_modops_64)
+ return ("64-bit");
+ else
+ return ("32-bit");
+}
+
+/*
+ * Update our module cache by adding an entry for the specified module 'name'.
+ * We create the dt_module_t and populate it using /system/object/<name>/.
+ *
+ * On FreeBSD, the module name is passed as the full module file name,
+ * including the path.
+ */
+static void
+#if defined(sun)
+dt_module_update(dtrace_hdl_t *dtp, const char *name)
+#else
+dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
+#endif
+{
+ char fname[MAXPATHLEN];
+ struct stat64 st;
+ int fd, err, bits;
+
+ dt_module_t *dmp;
+ const char *s;
+ size_t shstrs;
+ GElf_Shdr sh;
+ Elf_Data *dp;
+ Elf_Scn *sp;
+
+#if defined(sun)
+ (void) snprintf(fname, sizeof (fname),
+ "%s/%s/object", OBJFS_ROOT, name);
+#else
+ GElf_Ehdr ehdr;
+ GElf_Phdr ph;
+ char name[MAXPATHLEN];
+ uintptr_t mapbase, alignmask;
+ int i = 0;
+ int is_elf_obj;
+
+ (void) strlcpy(name, k_stat->name, sizeof(name));
+ (void) strlcpy(fname, k_stat->pathname, sizeof(fname));
+#endif
+
+ if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 ||
+ (dmp = dt_module_create(dtp, name)) == NULL) {
+ dt_dprintf("failed to open %s: %s\n", fname, strerror(errno));
+ (void) close(fd);
+ return;
+ }
+
+ /*
+ * Since the module can unload out from under us (and /system/object
+ * will return ENOENT), tell libelf to cook the entire file now and
+ * then close the underlying file descriptor immediately. If this
+ * succeeds, we know that we can continue safely using dmp->dm_elf.
+ */
+ dmp->dm_elf = elf_begin(fd, ELF_C_READ, NULL);
+ err = elf_cntl(dmp->dm_elf, ELF_C_FDREAD);
+ (void) close(fd);
+
+ if (dmp->dm_elf == NULL || err == -1 ||
+ elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) {
+ dt_dprintf("failed to load %s: %s\n",
+ fname, elf_errmsg(elf_errno()));
+ dt_module_destroy(dtp, dmp);
+ return;
+ }
+
+ switch (gelf_getclass(dmp->dm_elf)) {
+ case ELFCLASS32:
+ dmp->dm_ops = &dt_modops_32;
+ bits = 32;
+ break;
+ case ELFCLASS64:
+ dmp->dm_ops = &dt_modops_64;
+ bits = 64;
+ break;
+ default:
+ dt_dprintf("failed to load %s: unknown ELF class\n", fname);
+ dt_module_destroy(dtp, dmp);
+ return;
+ }
+#if defined(__FreeBSD__)
+ mapbase = (uintptr_t)k_stat->address;
+ gelf_getehdr(dmp->dm_elf, &ehdr);
+ is_elf_obj = (ehdr.e_type == ET_REL);
+ if (is_elf_obj) {
+ dmp->dm_sec_offsets =
+ malloc(ehdr.e_shnum * sizeof(*dmp->dm_sec_offsets));
+ if (dmp->dm_sec_offsets == NULL) {
+ dt_dprintf("failed to allocate memory\n");
+ dt_module_destroy(dtp, dmp);
+ return;
+ }
+ }
+#endif
+ /*
+ * Iterate over the section headers locating various sections of
+ * interest and use their attributes to flesh out the dt_module_t.
+ */
+ for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
+ if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
+ (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
+ continue; /* skip any malformed sections */
+#if defined(__FreeBSD__)
+ if (sh.sh_size == 0)
+ continue;
+ if (is_elf_obj && (sh.sh_type == SHT_PROGBITS ||
+ sh.sh_type == SHT_NOBITS)) {
+ alignmask = sh.sh_addralign - 1;
+ mapbase += alignmask;
+ mapbase &= ~alignmask;
+ sh.sh_addr = mapbase;
+ dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr;
+ mapbase += sh.sh_size;
+ }
+#endif
+ if (strcmp(s, ".text") == 0) {
+ dmp->dm_text_size = sh.sh_size;
+ dmp->dm_text_va = sh.sh_addr;
+ } else if (strcmp(s, ".data") == 0) {
+ dmp->dm_data_size = sh.sh_size;
+ dmp->dm_data_va = sh.sh_addr;
+ } else if (strcmp(s, ".bss") == 0) {
+ dmp->dm_bss_size = sh.sh_size;
+ dmp->dm_bss_va = sh.sh_addr;
+ } else if (strcmp(s, ".info") == 0 &&
+ (dp = elf_getdata(sp, NULL)) != NULL) {
+ bcopy(dp->d_buf, &dmp->dm_info,
+ MIN(sh.sh_size, sizeof (dmp->dm_info)));
+ } else if (strcmp(s, ".filename") == 0 &&
+ (dp = elf_getdata(sp, NULL)) != NULL) {
+ (void) strlcpy(dmp->dm_file,
+ dp->d_buf, sizeof (dmp->dm_file));
+ }
+ }
+
+ dmp->dm_flags |= DT_DM_KERNEL;
+#if defined(sun)
+ dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);
+#else
+ /*
+ * Include .rodata and special sections into .text.
+ * This depends on default section layout produced by GNU ld
+ * for ELF objects and libraries:
+ * [Text][R/O data][R/W data][Dynamic][BSS][Non loadable]
+ */
+ dmp->dm_text_size = dmp->dm_data_va - dmp->dm_text_va;
+#if defined(__i386__)
+ /*
+ * Find the first load section and figure out the relocation
+ * offset for the symbols. The kernel module will not need
+ * relocation, but the kernel linker modules will.
+ */
+ for (i = 0; gelf_getphdr(dmp->dm_elf, i, &ph) != NULL; i++) {
+ if (ph.p_type == PT_LOAD) {
+ dmp->dm_reloc_offset = k_stat->address - ph.p_vaddr;
+ break;
+ }
+ }
+#endif
+#endif
+
+ if (dmp->dm_info.objfs_info_primary)
+ dmp->dm_flags |= DT_DM_PRIMARY;
+
+ dt_dprintf("opened %d-bit module %s (%s) [%d]\n",
+ bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid);
+}
+
+/*
+ * Unload all the loaded modules and then refresh the module cache with the
+ * latest list of loaded modules and their address ranges.
+ */
+void
+dtrace_update(dtrace_hdl_t *dtp)
+{
+ dt_module_t *dmp;
+ DIR *dirp;
+#if defined(__FreeBSD__)
+ int fileid;
+#endif
+
+ for (dmp = dt_list_next(&dtp->dt_modlist);
+ dmp != NULL; dmp = dt_list_next(dmp))
+ dt_module_unload(dtp, dmp);
+
+#if defined(sun)
+ /*
+ * Open /system/object and attempt to create a libdtrace module for
+ * each kernel module that is loaded on the current system.
+ */
+ if (!(dtp->dt_oflags & DTRACE_O_NOSYS) &&
+ (dirp = opendir(OBJFS_ROOT)) != NULL) {
+ struct dirent *dp;
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_name[0] != '.')
+ dt_module_update(dtp, dp->d_name);
+ }
+
+ (void) closedir(dirp);
+ }
+#elif defined(__FreeBSD__)
+ /*
+ * Use FreeBSD's kernel loader interface to discover what kernel
+ * modules are loaded and create a libdtrace module for each one.
+ */
+ for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
+ struct kld_file_stat k_stat;
+ k_stat.version = sizeof(k_stat);
+ if (kldstat(fileid, &k_stat) == 0)
+ dt_module_update(dtp, &k_stat);
+ }
+#endif
+
+ /*
+ * Look up all the macro identifiers and set di_id to the latest value.
+ * This code collaborates with dt_lex.l on the use of di_id. We will
+ * need to implement something fancier if we need to support non-ints.
+ */
+ dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid();
+ dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid();
+ dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid();
+ dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();
+ dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);
+ dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();
+#if defined(sun)
+ dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();
+#endif
+ dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);
+#if defined(sun)
+ dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();
+#endif
+ dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();
+
+ /*
+ * Cache the pointers to the modules representing the base executable
+ * and the run-time linker in the dtrace client handle. Note that on
+ * x86 krtld is folded into unix, so if we don't find it, use unix
+ * instead.
+ */
+ dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");
+ dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");
+ if (dtp->dt_rtld == NULL)
+ dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix");
+
+ /*
+ * If this is the first time we are initializing the module list,
+ * remove the module for genunix from the module list and then move it
+ * to the front of the module list. We do this so that type and symbol
+ * queries encounter genunix and thereby optimize for the common case
+ * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below.
+ */
+ if (dtp->dt_exec != NULL &&
+ dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) {
+ dt_list_delete(&dtp->dt_modlist, dtp->dt_exec);
+ dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec);
+ }
+}
+
+static dt_module_t *
+dt_module_from_object(dtrace_hdl_t *dtp, const char *object)
+{
+ int err = EDT_NOMOD;
+ dt_module_t *dmp;
+
+ switch ((uintptr_t)object) {
+ case (uintptr_t)DTRACE_OBJ_EXEC:
+ dmp = dtp->dt_exec;
+ break;
+ case (uintptr_t)DTRACE_OBJ_RTLD:
+ dmp = dtp->dt_rtld;
+ break;
+ case (uintptr_t)DTRACE_OBJ_CDEFS:
+ dmp = dtp->dt_cdefs;
+ break;
+ case (uintptr_t)DTRACE_OBJ_DDEFS:
+ dmp = dtp->dt_ddefs;
+ break;
+ default:
+ dmp = dt_module_create(dtp, object);
+ err = EDT_NOMEM;
+ }
+
+ if (dmp == NULL)
+ (void) dt_set_errno(dtp, err);
+
+ return (dmp);
+}
+
+/*
+ * Exported interface to look up a symbol by name. We return the GElf_Sym and
+ * complete symbol information for the matching symbol.
+ */
+int
+dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
+ GElf_Sym *symp, dtrace_syminfo_t *sip)
+{
+ dt_module_t *dmp;
+ dt_ident_t *idp;
+ uint_t n, id;
+ GElf_Sym sym;
+
+ uint_t mask = 0; /* mask of dt_module flags to match */
+ uint_t bits = 0; /* flag bits that must be present */
+
+ if (object != DTRACE_OBJ_EVERY &&
+ object != DTRACE_OBJ_KMODS &&
+ object != DTRACE_OBJ_UMODS) {
+ if ((dmp = dt_module_from_object(dtp, object)) == NULL)
+ return (-1); /* dt_errno is set for us */
+
+ if (dt_module_load(dtp, dmp) == -1)
+ return (-1); /* dt_errno is set for us */
+ n = 1;
+
+ } else {
+ if (object == DTRACE_OBJ_KMODS)
+ mask = bits = DT_DM_KERNEL;
+ else if (object == DTRACE_OBJ_UMODS)
+ mask = DT_DM_KERNEL;
+
+ dmp = dt_list_next(&dtp->dt_modlist);
+ n = dtp->dt_nmods;
+ }
+
+ if (symp == NULL)
+ symp = &sym;
+
+ for (; n > 0; n--, dmp = dt_list_next(dmp)) {
+ if ((dmp->dm_flags & mask) != bits)
+ continue; /* failed to match required attributes */
+
+ if (dt_module_load(dtp, dmp) == -1)
+ continue; /* failed to load symbol table */
+
+ if (dmp->dm_ops->do_symname(dmp, name, symp, &id) != NULL) {
+ if (sip != NULL) {
+ sip->dts_object = dmp->dm_name;
+ sip->dts_name = (const char *)
+ dmp->dm_strtab.cts_data + symp->st_name;
+ sip->dts_id = id;
+ }
+ return (0);
+ }
+
+ if (dmp->dm_extern != NULL &&
+ (idp = dt_idhash_lookup(dmp->dm_extern, name)) != NULL) {
+ if (symp != &sym) {
+ symp->st_name = (uintptr_t)idp->di_name;
+ symp->st_info =
+ GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
+ symp->st_other = 0;
+ symp->st_shndx = SHN_UNDEF;
+ symp->st_value = 0;
+ symp->st_size =
+ ctf_type_size(idp->di_ctfp, idp->di_type);
+ }
+
+ if (sip != NULL) {
+ sip->dts_object = dmp->dm_name;
+ sip->dts_name = idp->di_name;
+ sip->dts_id = idp->di_id;
+ }
+
+ return (0);
+ }
+ }
+
+ return (dt_set_errno(dtp, EDT_NOSYM));
+}
+
+/*
+ * Exported interface to look up a symbol by address. We return the GElf_Sym
+ * and complete symbol information for the matching symbol.
+ */
+int
+dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,
+ GElf_Sym *symp, dtrace_syminfo_t *sip)
+{
+ dt_module_t *dmp;
+ uint_t id;
+ const dtrace_vector_t *v = dtp->dt_vector;
+
+ if (v != NULL)
+ return (v->dtv_lookup_by_addr(dtp->dt_varg, addr, symp, sip));
+
+ for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;
+ dmp = dt_list_next(dmp)) {
+ if (addr - dmp->dm_text_va < dmp->dm_text_size ||
+ addr - dmp->dm_data_va < dmp->dm_data_size ||
+ addr - dmp->dm_bss_va < dmp->dm_bss_size)
+ break;
+ }
+
+ if (dmp == NULL)
+ return (dt_set_errno(dtp, EDT_NOSYMADDR));
+
+ if (dt_module_load(dtp, dmp) == -1)
+ return (-1); /* dt_errno is set for us */
+
+ if (symp != NULL) {
+ if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)
+ return (dt_set_errno(dtp, EDT_NOSYMADDR));
+ }
+
+ if (sip != NULL) {
+ sip->dts_object = dmp->dm_name;
+
+ if (symp != NULL) {
+ sip->dts_name = (const char *)
+ dmp->dm_strtab.cts_data + symp->st_name;
+ sip->dts_id = id;
+ } else {
+ sip->dts_name = NULL;
+ sip->dts_id = 0;
+ }
+ }
+
+ return (0);
+}
+
+int
+dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
+ dtrace_typeinfo_t *tip)
+{
+ dtrace_typeinfo_t ti;
+ dt_module_t *dmp;
+ int found = 0;
+ ctf_id_t id;
+ uint_t n;
+ int justone;
+
+ uint_t mask = 0; /* mask of dt_module flags to match */
+ uint_t bits = 0; /* flag bits that must be present */
+
+ if (object != DTRACE_OBJ_EVERY &&
+ object != DTRACE_OBJ_KMODS &&
+ object != DTRACE_OBJ_UMODS) {
+ if ((dmp = dt_module_from_object(dtp, object)) == NULL)
+ return (-1); /* dt_errno is set for us */
+
+ if (dt_module_load(dtp, dmp) == -1)
+ return (-1); /* dt_errno is set for us */
+ n = 1;
+ justone = 1;
+
+ } else {
+ if (object == DTRACE_OBJ_KMODS)
+ mask = bits = DT_DM_KERNEL;
+ else if (object == DTRACE_OBJ_UMODS)
+ mask = DT_DM_KERNEL;
+
+ dmp = dt_list_next(&dtp->dt_modlist);
+ n = dtp->dt_nmods;
+ justone = 0;
+ }
+
+ if (tip == NULL)
+ tip = &ti;
+
+ for (; n > 0; n--, dmp = dt_list_next(dmp)) {
+ if ((dmp->dm_flags & mask) != bits)
+ continue; /* failed to match required attributes */
+
+ /*
+ * If we can't load the CTF container, continue on to the next
+ * module. If our search was scoped to only one module then
+ * return immediately leaving dt_errno unmodified.
+ */
+ if (dt_module_getctf(dtp, dmp) == NULL) {
+ if (justone)
+ return (-1);
+ continue;
+ }
+
+ /*
+ * Look up the type in the module's CTF container. If our
+ * match is a forward declaration tag, save this choice in
+ * 'tip' and keep going in the hope that we will locate the
+ * underlying structure definition. Otherwise just return.
+ */
+ if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) {
+ tip->dtt_object = dmp->dm_name;
+ tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_type = id;
+
+ if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(
+ dmp->dm_ctfp, id)) != CTF_K_FORWARD)
+ return (0);
+
+ found++;
+ }
+ }
+
+ if (found == 0)
+ return (dt_set_errno(dtp, EDT_NOTYPE));
+
+ return (0);
+}
+
+int
+dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
+ const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
+{
+ dt_module_t *dmp;
+
+ tip->dtt_object = NULL;
+ tip->dtt_ctfp = NULL;
+ tip->dtt_type = CTF_ERR;
+
+ if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMOD));
+
+ if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
+ dt_ident_t *idp =
+ dt_idhash_lookup(dmp->dm_extern, sip->dts_name);
+
+ if (idp == NULL)
+ return (dt_set_errno(dtp, EDT_NOSYM));
+
+ tip->dtt_ctfp = idp->di_ctfp;
+ tip->dtt_type = idp->di_type;
+
+ } else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
+ if (dt_module_getctf(dtp, dmp) == NULL)
+ return (-1); /* errno is set for us */
+
+ tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);
+
+ if (tip->dtt_type == CTF_ERR) {
+ dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp);
+ return (dt_set_errno(dtp, EDT_CTF));
+ }
+
+ } else {
+ tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
+ tip->dtt_type = DT_FPTR_TYPE(dtp);
+ }
+
+ tip->dtt_object = dmp->dm_name;
+ return (0);
+}
+
+static dtrace_objinfo_t *
+dt_module_info(const dt_module_t *dmp, dtrace_objinfo_t *dto)
+{
+ dto->dto_name = dmp->dm_name;
+ dto->dto_file = dmp->dm_file;
+ dto->dto_id = dmp->dm_modid;
+ dto->dto_flags = 0;
+
+ if (dmp->dm_flags & DT_DM_KERNEL)
+ dto->dto_flags |= DTRACE_OBJ_F_KERNEL;
+ if (dmp->dm_flags & DT_DM_PRIMARY)
+ dto->dto_flags |= DTRACE_OBJ_F_PRIMARY;
+
+ dto->dto_text_va = dmp->dm_text_va;
+ dto->dto_text_size = dmp->dm_text_size;
+ dto->dto_data_va = dmp->dm_data_va;
+ dto->dto_data_size = dmp->dm_data_size;
+ dto->dto_bss_va = dmp->dm_bss_va;
+ dto->dto_bss_size = dmp->dm_bss_size;
+
+ return (dto);
+}
+
+int
+dtrace_object_iter(dtrace_hdl_t *dtp, dtrace_obj_f *func, void *data)
+{
+ const dt_module_t *dmp = dt_list_next(&dtp->dt_modlist);
+ dtrace_objinfo_t dto;
+ int rv;
+
+ for (; dmp != NULL; dmp = dt_list_next(dmp)) {
+ if ((rv = (*func)(dtp, dt_module_info(dmp, &dto), data)) != 0)
+ return (rv);
+ }
+
+ return (0);
+}
+
+int
+dtrace_object_info(dtrace_hdl_t *dtp, const char *object, dtrace_objinfo_t *dto)
+{
+ dt_module_t *dmp;
+
+ if (object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS ||
+ object == DTRACE_OBJ_UMODS || dto == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ if ((dmp = dt_module_from_object(dtp, object)) == NULL)
+ return (-1); /* dt_errno is set for us */
+
+ if (dt_module_load(dtp, dmp) == -1)
+ return (-1); /* dt_errno is set for us */
+
+ (void) dt_module_info(dmp, dto);
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h
new file mode 100644
index 0000000..8334a2b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_MODULE_H
+#define _DT_MODULE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dt_impl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern dt_module_t *dt_module_create(dtrace_hdl_t *, const char *);
+extern int dt_module_load(dtrace_hdl_t *, dt_module_t *);
+extern void dt_module_unload(dtrace_hdl_t *, dt_module_t *);
+extern void dt_module_destroy(dtrace_hdl_t *, dt_module_t *);
+
+extern dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *, const char *);
+extern dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *, ctf_file_t *);
+
+extern ctf_file_t *dt_module_getctf(dtrace_hdl_t *, dt_module_t *);
+extern dt_ident_t *dt_module_extern(dtrace_hdl_t *, dt_module_t *,
+ const char *, const dtrace_typeinfo_t *);
+
+extern const char *dt_module_modelname(dt_module_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_MODULE_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
new file mode 100644
index 0000000..6c6e41b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -0,0 +1,1674 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/modctl.h>
+#include <sys/systeminfo.h>
+#endif
+#include <sys/resource.h>
+
+#include <libelf.h>
+#include <strings.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+#define _POSIX_PTHREAD_SEMANTICS
+#include <dirent.h>
+#undef _POSIX_PTHREAD_SEMANTICS
+
+#include <dt_impl.h>
+#include <dt_program.h>
+#include <dt_module.h>
+#include <dt_printf.h>
+#include <dt_string.h>
+#include <dt_provider.h>
+#if !defined(sun)
+#include <sys/sysctl.h>
+#include <string.h>
+#endif
+#if defined(__i386__)
+#include <ieeefp.h>
+#endif
+
+/*
+ * Stability and versioning definitions. These #defines are used in the tables
+ * of identifiers below to fill in the attribute and version fields associated
+ * with each identifier. The DT_ATTR_* macros are a convenience to permit more
+ * concise declarations of common attributes such as Stable/Stable/Common. The
+ * DT_VERS_* macros declare the encoded integer values of all versions used so
+ * far. DT_VERS_LATEST must correspond to the latest version value among all
+ * versions exported by the D compiler. DT_VERS_STRING must be an ASCII string
+ * that contains DT_VERS_LATEST within it along with any suffixes (e.g. Beta).
+ * You must update DT_VERS_LATEST and DT_VERS_STRING when adding a new version,
+ * and then add the new version to the _dtrace_versions[] array declared below.
+ * Refer to the Solaris Dynamic Tracing Guide Stability and Versioning chapters
+ * respectively for an explanation of these DTrace features and their values.
+ *
+ * NOTE: Although the DTrace versioning scheme supports the labeling and
+ * introduction of incompatible changes (e.g. dropping an interface in a
+ * major release), the libdtrace code does not currently support this.
+ * All versions are assumed to strictly inherit from one another. If
+ * we ever need to provide divergent interfaces, this will need work.
+ */
+#define DT_ATTR_STABCMN { DTRACE_STABILITY_STABLE, \
+ DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }
+
+#define DT_ATTR_EVOLCMN { DTRACE_STABILITY_EVOLVING, \
+ DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON \
+}
+
+/*
+ * The version number should be increased for every customer visible release
+ * of Solaris. The major number should be incremented when a fundamental
+ * change has been made that would affect all consumers, and would reflect
+ * sweeping changes to DTrace or the D language. The minor number should be
+ * incremented when a change is introduced that could break scripts that had
+ * previously worked; for example, adding a new built-in variable could break
+ * a script which was already using that identifier. The micro number should
+ * be changed when introducing functionality changes or major bug fixes that
+ * do not affect backward compatibility -- this is merely to make capabilities
+ * easily determined from the version number. Minor bugs do not require any
+ * modification to the version number.
+ */
+#define DT_VERS_1_0 DT_VERSION_NUMBER(1, 0, 0)
+#define DT_VERS_1_1 DT_VERSION_NUMBER(1, 1, 0)
+#define DT_VERS_1_2 DT_VERSION_NUMBER(1, 2, 0)
+#define DT_VERS_1_2_1 DT_VERSION_NUMBER(1, 2, 1)
+#define DT_VERS_1_2_2 DT_VERSION_NUMBER(1, 2, 2)
+#define DT_VERS_1_3 DT_VERSION_NUMBER(1, 3, 0)
+#define DT_VERS_1_4 DT_VERSION_NUMBER(1, 4, 0)
+#define DT_VERS_1_4_1 DT_VERSION_NUMBER(1, 4, 1)
+#define DT_VERS_1_5 DT_VERSION_NUMBER(1, 5, 0)
+#define DT_VERS_1_6 DT_VERSION_NUMBER(1, 6, 0)
+#define DT_VERS_1_6_1 DT_VERSION_NUMBER(1, 6, 1)
+#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
+#define DT_VERS_1_6_3 DT_VERSION_NUMBER(1, 6, 3)
+#define DT_VERS_1_7 DT_VERSION_NUMBER(1, 7, 0)
+#define DT_VERS_1_7_1 DT_VERSION_NUMBER(1, 7, 1)
+#define DT_VERS_1_8 DT_VERSION_NUMBER(1, 8, 0)
+#define DT_VERS_1_8_1 DT_VERSION_NUMBER(1, 8, 1)
+#define DT_VERS_1_9 DT_VERSION_NUMBER(1, 9, 0)
+#define DT_VERS_LATEST DT_VERS_1_9
+#define DT_VERS_STRING "Sun D 1.9"
+
+const dt_version_t _dtrace_versions[] = {
+ DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
+ DT_VERS_1_1, /* D API 1.1.0 Solaris Express 6/05 */
+ DT_VERS_1_2, /* D API 1.2.0 Solaris 10 Update 1 */
+ DT_VERS_1_2_1, /* D API 1.2.1 Solaris Express 4/06 */
+ DT_VERS_1_2_2, /* D API 1.2.2 Solaris Express 6/06 */
+ DT_VERS_1_3, /* D API 1.3 Solaris Express 10/06 */
+ DT_VERS_1_4, /* D API 1.4 Solaris Express 2/07 */
+ DT_VERS_1_4_1, /* D API 1.4.1 Solaris Express 4/07 */
+ DT_VERS_1_5, /* D API 1.5 Solaris Express 7/07 */
+ DT_VERS_1_6, /* D API 1.6 */
+ DT_VERS_1_6_1, /* D API 1.6.1 */
+ DT_VERS_1_6_2, /* D API 1.6.2 */
+ DT_VERS_1_6_3, /* D API 1.6.3 */
+ DT_VERS_1_7, /* D API 1.7 */
+ DT_VERS_1_7_1, /* D API 1.7.1 */
+ DT_VERS_1_8, /* D API 1.8 */
+ DT_VERS_1_8_1, /* D API 1.8.1 */
+ DT_VERS_1_9, /* D API 1.9 */
+ 0
+};
+
+/*
+ * Global variables that are formatted on FreeBSD based on the kernel file name.
+ */
+#if !defined(sun)
+static char curthread_str[MAXPATHLEN];
+static char intmtx_str[MAXPATHLEN];
+static char threadmtx_str[MAXPATHLEN];
+static char rwlock_str[MAXPATHLEN];
+static char sxlock_str[MAXPATHLEN];
+#endif
+
+/*
+ * Table of global identifiers. This is used to populate the global identifier
+ * hash when a new dtrace client open occurs. For more info see dt_ident.h.
+ * The global identifiers that represent functions use the dt_idops_func ops
+ * and specify the private data pointer as a prototype string which is parsed
+ * when the identifier is first encountered. These prototypes look like ANSI
+ * C function prototypes except that the special symbol "@" can be used as a
+ * wildcard to represent a single parameter of any type (i.e. any dt_node_t).
+ * The standard "..." notation can also be used to represent varargs. An empty
+ * parameter list is taken to mean void (that is, no arguments are permitted).
+ * A parameter enclosed in square brackets (e.g. "[int]") denotes an optional
+ * argument.
+ */
+static const dt_ident_t _dtrace_globals[] = {
+{ "alloca", DT_IDENT_FUNC, 0, DIF_SUBR_ALLOCA, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void *(size_t)" },
+{ "arg0", DT_IDENT_SCALAR, 0, DIF_VAR_ARG0, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg1", DT_IDENT_SCALAR, 0, DIF_VAR_ARG1, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg2", DT_IDENT_SCALAR, 0, DIF_VAR_ARG2, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg3", DT_IDENT_SCALAR, 0, DIF_VAR_ARG3, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg4", DT_IDENT_SCALAR, 0, DIF_VAR_ARG4, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg5", DT_IDENT_SCALAR, 0, DIF_VAR_ARG5, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg6", DT_IDENT_SCALAR, 0, DIF_VAR_ARG6, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg7", DT_IDENT_SCALAR, 0, DIF_VAR_ARG7, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg8", DT_IDENT_SCALAR, 0, DIF_VAR_ARG8, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "arg9", DT_IDENT_SCALAR, 0, DIF_VAR_ARG9, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+{ "args", DT_IDENT_ARRAY, 0, DIF_VAR_ARGS, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_args, NULL },
+{ "avg", DT_IDENT_AGGFUNC, 0, DTRACEAGG_AVG, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@)" },
+{ "basename", DT_IDENT_FUNC, 0, DIF_SUBR_BASENAME, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(const char *)" },
+{ "bcopy", DT_IDENT_FUNC, 0, DIF_SUBR_BCOPY, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(void *, void *, size_t)" },
+{ "breakpoint", DT_IDENT_ACTFUNC, 0, DT_ACT_BREAKPOINT,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void()" },
+{ "caller", DT_IDENT_SCALAR, 0, DIF_VAR_CALLER, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uintptr_t" },
+{ "chill", DT_IDENT_ACTFUNC, 0, DT_ACT_CHILL, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "cleanpath", DT_IDENT_FUNC, 0, DIF_SUBR_CLEANPATH, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "string(const char *)" },
+{ "clear", DT_IDENT_ACTFUNC, 0, DT_ACT_CLEAR, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(...)" },
+{ "commit", DT_IDENT_ACTFUNC, 0, DT_ACT_COMMIT, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "copyin", DT_IDENT_FUNC, 0, DIF_SUBR_COPYIN, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void *(uintptr_t, size_t)" },
+{ "copyinstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINSTR,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(uintptr_t, [size_t])" },
+{ "copyinto", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINTO, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "void(uintptr_t, size_t, void *)" },
+{ "copyout", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUT, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(void *, uintptr_t, size_t)" },
+{ "copyoutstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUTSTR,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(char *, uintptr_t, size_t)" },
+{ "count", DT_IDENT_AGGFUNC, 0, DTRACEAGG_COUNT, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void()" },
+{ "curthread", DT_IDENT_SCALAR, 0, DIF_VAR_CURTHREAD,
+ { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_PRIVATE,
+ DTRACE_CLASS_COMMON }, DT_VERS_1_0,
+#if defined(sun)
+ &dt_idops_type, "genunix`kthread_t *" },
+#else
+ &dt_idops_type, curthread_str },
+#endif
+{ "ddi_pathname", DT_IDENT_FUNC, 0, DIF_SUBR_DDI_PATHNAME,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(void *, int64_t)" },
+{ "denormalize", DT_IDENT_ACTFUNC, 0, DT_ACT_DENORMALIZE, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "void(...)" },
+{ "dirname", DT_IDENT_FUNC, 0, DIF_SUBR_DIRNAME, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(const char *)" },
+{ "discard", DT_IDENT_ACTFUNC, 0, DT_ACT_DISCARD, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "epid", DT_IDENT_SCALAR, 0, DIF_VAR_EPID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint_t" },
+{ "errno", DT_IDENT_SCALAR, 0, DIF_VAR_ERRNO, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int" },
+{ "execargs", DT_IDENT_SCALAR, 0, DIF_VAR_EXECARGS,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "execname", DT_IDENT_SCALAR, 0, DIF_VAR_EXECNAME,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "exit", DT_IDENT_ACTFUNC, 0, DT_ACT_EXIT, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "freopen", DT_IDENT_ACTFUNC, 0, DT_ACT_FREOPEN, DT_ATTR_STABCMN,
+ DT_VERS_1_1, &dt_idops_func, "void(@, ...)" },
+{ "ftruncate", DT_IDENT_ACTFUNC, 0, DT_ACT_FTRUNCATE, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "void()" },
+{ "func", DT_IDENT_ACTFUNC, 0, DT_ACT_SYM, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
+{ "getmajor", DT_IDENT_FUNC, 0, DIF_SUBR_GETMAJOR,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "genunix`major_t(genunix`dev_t)" },
+{ "getminor", DT_IDENT_FUNC, 0, DIF_SUBR_GETMINOR,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "genunix`minor_t(genunix`dev_t)" },
+{ "htonl", DT_IDENT_FUNC, 0, DIF_SUBR_HTONL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint32_t(uint32_t)" },
+{ "htonll", DT_IDENT_FUNC, 0, DIF_SUBR_HTONLL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint64_t(uint64_t)" },
+{ "htons", DT_IDENT_FUNC, 0, DIF_SUBR_HTONS, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint16_t(uint16_t)" },
+{ "gid", DT_IDENT_SCALAR, 0, DIF_VAR_GID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "gid_t" },
+{ "id", DT_IDENT_SCALAR, 0, DIF_VAR_ID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint_t" },
+{ "index", DT_IDENT_FUNC, 0, DIF_SUBR_INDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "int(const char *, const char *, [int])" },
+{ "inet_ntoa", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA, DT_ATTR_STABCMN,
+#if defined(sun)
+ DT_VERS_1_5, &dt_idops_func, "string(ipaddr_t *)" },
+#else
+ DT_VERS_1_5, &dt_idops_func, "string(in_addr_t *)" },
+#endif
+{ "inet_ntoa6", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA6, DT_ATTR_STABCMN,
+#if defined(sun)
+ DT_VERS_1_5, &dt_idops_func, "string(in6_addr_t *)" },
+#else
+ DT_VERS_1_5, &dt_idops_func, "string(struct in6_addr *)" },
+#endif
+{ "inet_ntop", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOP, DT_ATTR_STABCMN,
+ DT_VERS_1_5, &dt_idops_func, "string(int, void *)" },
+{ "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint_t" },
+{ "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "stack(...)" },
+{ "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(int64_t, [int])" },
+{ "llquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LLQUANTIZE, DT_ATTR_STABCMN,
+ DT_VERS_1_7, &dt_idops_func,
+ "void(@, int32_t, int32_t, int32_t, int32_t, ...)" },
+{ "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, int32_t, int32_t, ...)" },
+{ "max", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MAX, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@)" },
+{ "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "uintptr_t *(void *, size_t)" },
+{ "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@)" },
+{ "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
+{ "msgdsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGDSIZE,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "size_t(mblk_t *)" },
+{ "msgsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGSIZE,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "size_t(mblk_t *)" },
+#if defined(sun)
+{ "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`kmutex_t *)" },
+{ "mutex_owner", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNER,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "genunix`kthread_t *(genunix`kmutex_t *)" },
+{ "mutex_type_adaptive", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_ADAPTIVE,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`kmutex_t *)" },
+{ "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`kmutex_t *)" },
+#else
+{ "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, intmtx_str },
+{ "mutex_owner", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNER,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, threadmtx_str },
+{ "mutex_type_adaptive", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_ADAPTIVE,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, intmtx_str },
+{ "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, intmtx_str },
+#endif
+{ "ntohl", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint32_t(uint32_t)" },
+{ "ntohll", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHLL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint64_t(uint64_t)" },
+{ "ntohs", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHS, DT_ATTR_EVOLCMN, DT_VERS_1_3,
+ &dt_idops_func, "uint16_t(uint16_t)" },
+{ "normalize", DT_IDENT_ACTFUNC, 0, DT_ACT_NORMALIZE, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "void(...)" },
+{ "panic", DT_IDENT_ACTFUNC, 0, DT_ACT_PANIC, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void()" },
+{ "pid", DT_IDENT_SCALAR, 0, DIF_VAR_PID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "pid_t" },
+{ "ppid", DT_IDENT_SCALAR, 0, DIF_VAR_PPID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "pid_t" },
+{ "print", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINT, DT_ATTR_STABCMN, DT_VERS_1_9,
+ &dt_idops_func, "void(@)" },
+{ "printa", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTA, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, ...)" },
+{ "printf", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTF, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, ...)" },
+{ "printm", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTM, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(size_t, uintptr_t *)" },
+{ "printt", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTT, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(size_t, uintptr_t *)" },
+{ "probefunc", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEFUNC,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "probemod", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEMOD,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "probename", DT_IDENT_SCALAR, 0, DIF_VAR_PROBENAME,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "probeprov", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEPROV,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+{ "progenyof", DT_IDENT_FUNC, 0, DIF_SUBR_PROGENYOF,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(pid_t)" },
+{ "quantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_QUANTIZE,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, ...)" },
+{ "raise", DT_IDENT_ACTFUNC, 0, DT_ACT_RAISE, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "rand", DT_IDENT_FUNC, 0, DIF_SUBR_RAND, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "int()" },
+{ "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "int(const char *, const char *, [int])" },
+#if defined(sun)
+{ "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`krwlock_t *)" },
+{ "rw_read_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_READ_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`krwlock_t *)" },
+{ "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, "int(genunix`krwlock_t *)" },
+#else
+{ "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, rwlock_str },
+{ "rw_read_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_READ_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, rwlock_str },
+{ "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, rwlock_str },
+#endif
+{ "self", DT_IDENT_PTR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "void" },
+{ "setopt", DT_IDENT_ACTFUNC, 0, DT_ACT_SETOPT, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "void(const char *, [const char *])" },
+{ "speculate", DT_IDENT_ACTFUNC, 0, DT_ACT_SPECULATE,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(int)" },
+{ "speculation", DT_IDENT_FUNC, 0, DIF_SUBR_SPECULATION,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "int()" },
+{ "stack", DT_IDENT_ACTFUNC, 0, DT_ACT_STACK, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "stack(...)" },
+{ "stackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_STACKDEPTH,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint32_t" },
+{ "stddev", DT_IDENT_AGGFUNC, 0, DTRACEAGG_STDDEV, DT_ATTR_STABCMN,
+ DT_VERS_1_6, &dt_idops_func, "void(@)" },
+{ "stop", DT_IDENT_ACTFUNC, 0, DT_ACT_STOP, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void()" },
+{ "strchr", DT_IDENT_FUNC, 0, DIF_SUBR_STRCHR, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "string(const char *, char)" },
+{ "strlen", DT_IDENT_FUNC, 0, DIF_SUBR_STRLEN, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "size_t(const char *)" },
+{ "strjoin", DT_IDENT_FUNC, 0, DIF_SUBR_STRJOIN, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "string(const char *, const char *)" },
+{ "strrchr", DT_IDENT_FUNC, 0, DIF_SUBR_STRRCHR, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "string(const char *, char)" },
+{ "strstr", DT_IDENT_FUNC, 0, DIF_SUBR_STRSTR, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "string(const char *, const char *)" },
+{ "strtok", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOK, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "string(const char *, const char *)" },
+{ "substr", DT_IDENT_FUNC, 0, DIF_SUBR_SUBSTR, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "string(const char *, int, [int])" },
+{ "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@)" },
+#if !defined(sun)
+{ "sx_isexclusive", DT_IDENT_FUNC, 0, DIF_SUBR_SX_ISEXCLUSIVE,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, sxlock_str },
+{ "sx_shared_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_SHARED_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, sxlock_str },
+{ "sx_exclusive_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_EXCLUSIVE_HELD,
+ DT_ATTR_EVOLCMN, DT_VERS_1_0,
+ &dt_idops_func, sxlock_str },
+#endif
+{ "sym", DT_IDENT_ACTFUNC, 0, DT_ACT_SYM, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
+{ "system", DT_IDENT_ACTFUNC, 0, DT_ACT_SYSTEM, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, ...)" },
+{ "this", DT_IDENT_PTR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "void" },
+{ "tid", DT_IDENT_SCALAR, 0, DIF_VAR_TID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "id_t" },
+{ "timestamp", DT_IDENT_SCALAR, 0, DIF_VAR_TIMESTAMP,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint64_t" },
+{ "tolower", DT_IDENT_FUNC, 0, DIF_SUBR_TOLOWER, DT_ATTR_STABCMN, DT_VERS_1_8,
+ &dt_idops_func, "string(const char *)" },
+{ "toupper", DT_IDENT_FUNC, 0, DIF_SUBR_TOUPPER, DT_ATTR_STABCMN, DT_VERS_1_8,
+ &dt_idops_func, "string(const char *)" },
+{ "trace", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACE, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@)" },
+{ "tracemem", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACEMEM,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void(@, size_t, ...)" },
+{ "trunc", DT_IDENT_ACTFUNC, 0, DT_ACT_TRUNC, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_func, "void(...)" },
+{ "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1,
+ &dt_idops_func, "uintptr_t *(void *, size_t, string, size_t)" },
+#if defined(sun)
+{ "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
+#endif
+{ "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_type, "uint64_t" },
+#if defined(sun)
+{ "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
+#endif
+{ "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uid_t" },
+#if defined(sun)
+{ "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
+#endif
+{ "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_regs, NULL },
+{ "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "stack(...)" },
+{ "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,
+ DT_ATTR_STABCMN, DT_VERS_1_2,
+ &dt_idops_type, "uint32_t" },
+#if defined(sun)
+{ "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
+ DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
+#endif
+{ "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "uint64_t" },
+{ "walltimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_WALLTIMESTAMP,
+ DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_type, "int64_t" },
+#if defined(sun)
+{ "zonename", DT_IDENT_SCALAR, 0, DIF_VAR_ZONENAME,
+ DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
+#endif
+
+#if !defined(sun)
+{ "cpu", DT_IDENT_SCALAR, 0, DIF_VAR_CPU,
+ DT_ATTR_STABCMN, DT_VERS_1_6_3, &dt_idops_type, "int" },
+#endif
+
+{ NULL, 0, 0, 0, { 0, 0, 0 }, 0, NULL, NULL }
+};
+
+/*
+ * Tables of ILP32 intrinsic integer and floating-point type templates to use
+ * to populate the dynamic "C" CTF type container.
+ */
+static const dt_intrinsic_t _dtrace_intrinsics_32[] = {
+{ "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
+{ "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
+{ "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
+{ "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
+{ "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "signed long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
+{ "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
+{ "unsigned long", { 0, 0, 32 }, CTF_K_INTEGER },
+{ "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
+{ "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
+{ "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
+{ "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
+{ "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
+{ "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
+{ "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
+{ "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
+{ "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
+{ "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
+{ "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
+{ NULL, { 0, 0, 0 }, 0 }
+};
+
+/*
+ * Tables of LP64 intrinsic integer and floating-point type templates to use
+ * to populate the dynamic "C" CTF type container.
+ */
+static const dt_intrinsic_t _dtrace_intrinsics_64[] = {
+{ "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
+{ "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
+{ "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
+{ "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
+{ "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
+{ "signed long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
+{ "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
+{ "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
+{ "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
+{ "unsigned long", { 0, 0, 64 }, CTF_K_INTEGER },
+{ "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
+{ "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
+{ "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
+{ "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
+{ "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
+{ "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
+{ "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
+{ "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
+{ "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
+{ "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
+{ "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
+{ NULL, { 0, 0, 0 }, 0 }
+};
+
+/*
+ * Tables of ILP32 typedefs to use to populate the dynamic "D" CTF container.
+ * These aliases ensure that D definitions can use typical <sys/types.h> names.
+ */
+static const dt_typedef_t _dtrace_typedefs_32[] = {
+{ "char", "int8_t" },
+{ "short", "int16_t" },
+{ "int", "int32_t" },
+{ "long long", "int64_t" },
+{ "int", "intptr_t" },
+{ "int", "ssize_t" },
+{ "unsigned char", "uint8_t" },
+{ "unsigned short", "uint16_t" },
+{ "unsigned", "uint32_t" },
+{ "unsigned long long", "uint64_t" },
+{ "unsigned char", "uchar_t" },
+{ "unsigned short", "ushort_t" },
+{ "unsigned", "uint_t" },
+{ "unsigned long", "ulong_t" },
+{ "unsigned long long", "u_longlong_t" },
+{ "int", "ptrdiff_t" },
+{ "unsigned", "uintptr_t" },
+{ "unsigned", "size_t" },
+{ "long", "id_t" },
+{ "long", "pid_t" },
+{ NULL, NULL }
+};
+
+/*
+ * Tables of LP64 typedefs to use to populate the dynamic "D" CTF container.
+ * These aliases ensure that D definitions can use typical <sys/types.h> names.
+ */
+static const dt_typedef_t _dtrace_typedefs_64[] = {
+{ "char", "int8_t" },
+{ "short", "int16_t" },
+{ "int", "int32_t" },
+{ "long", "int64_t" },
+{ "long", "intptr_t" },
+{ "long", "ssize_t" },
+{ "unsigned char", "uint8_t" },
+{ "unsigned short", "uint16_t" },
+{ "unsigned", "uint32_t" },
+{ "unsigned long", "uint64_t" },
+{ "unsigned char", "uchar_t" },
+{ "unsigned short", "ushort_t" },
+{ "unsigned", "uint_t" },
+{ "unsigned long", "ulong_t" },
+{ "unsigned long long", "u_longlong_t" },
+{ "long", "ptrdiff_t" },
+{ "unsigned long", "uintptr_t" },
+{ "unsigned long", "size_t" },
+{ "int", "id_t" },
+{ "int", "pid_t" },
+{ NULL, NULL }
+};
+
+/*
+ * Tables of ILP32 integer type templates used to populate the dtp->dt_ints[]
+ * cache when a new dtrace client open occurs. Values are set by dtrace_open().
+ */
+static const dt_intdesc_t _dtrace_ints_32[] = {
+{ "int", NULL, CTF_ERR, 0x7fffffffULL },
+{ "unsigned int", NULL, CTF_ERR, 0xffffffffULL },
+{ "long", NULL, CTF_ERR, 0x7fffffffULL },
+{ "unsigned long", NULL, CTF_ERR, 0xffffffffULL },
+{ "long long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
+{ "unsigned long long", NULL, CTF_ERR, 0xffffffffffffffffULL }
+};
+
+/*
+ * Tables of LP64 integer type templates used to populate the dtp->dt_ints[]
+ * cache when a new dtrace client open occurs. Values are set by dtrace_open().
+ */
+static const dt_intdesc_t _dtrace_ints_64[] = {
+{ "int", NULL, CTF_ERR, 0x7fffffffULL },
+{ "unsigned int", NULL, CTF_ERR, 0xffffffffULL },
+{ "long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
+{ "unsigned long", NULL, CTF_ERR, 0xffffffffffffffffULL },
+{ "long long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
+{ "unsigned long long", NULL, CTF_ERR, 0xffffffffffffffffULL }
+};
+
+/*
+ * Table of macro variable templates used to populate the macro identifier hash
+ * when a new dtrace client open occurs. Values are set by dtrace_update().
+ */
+static const dt_ident_t _dtrace_macros[] = {
+{ "egid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "euid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "gid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "pid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "pgid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "ppid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "projid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "sid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "taskid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "target", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ "uid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
+{ NULL, 0, 0, 0, { 0, 0, 0 }, 0 }
+};
+
+/*
+ * Hard-wired definition string to be compiled and cached every time a new
+ * DTrace library handle is initialized. This string should only be used to
+ * contain definitions that should be present regardless of DTRACE_O_NOLIBS.
+ */
+static const char _dtrace_hardwire[] = "\
+inline long NULL = 0; \n\
+#pragma D binding \"1.0\" NULL\n\
+";
+
+/*
+ * Default DTrace configuration to use when opening libdtrace DTRACE_O_NODEV.
+ * If DTRACE_O_NODEV is not set, we load the configuration from the kernel.
+ * The use of CTF_MODEL_NATIVE is more subtle than it might appear: we are
+ * relying on the fact that when running dtrace(1M), isaexec will invoke the
+ * binary with the same bitness as the kernel, which is what we want by default
+ * when generating our DIF. The user can override the choice using oflags.
+ */
+static const dtrace_conf_t _dtrace_conf = {
+ DIF_VERSION, /* dtc_difversion */
+ DIF_DIR_NREGS, /* dtc_difintregs */
+ DIF_DTR_NREGS, /* dtc_diftupregs */
+ CTF_MODEL_NATIVE /* dtc_ctfmodel */
+};
+
+const dtrace_attribute_t _dtrace_maxattr = {
+ DTRACE_STABILITY_MAX,
+ DTRACE_STABILITY_MAX,
+ DTRACE_CLASS_MAX
+};
+
+const dtrace_attribute_t _dtrace_defattr = {
+ DTRACE_STABILITY_STABLE,
+ DTRACE_STABILITY_STABLE,
+ DTRACE_CLASS_COMMON
+};
+
+const dtrace_attribute_t _dtrace_symattr = {
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_CLASS_UNKNOWN
+};
+
+const dtrace_attribute_t _dtrace_typattr = {
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_CLASS_UNKNOWN
+};
+
+const dtrace_attribute_t _dtrace_prvattr = {
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_STABILITY_PRIVATE,
+ DTRACE_CLASS_UNKNOWN
+};
+
+const dtrace_pattr_t _dtrace_prvdesc = {
+{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
+};
+
+#if defined(sun)
+const char *_dtrace_defcpp = "/usr/ccs/lib/cpp"; /* default cpp(1) to invoke */
+const char *_dtrace_defld = "/usr/ccs/bin/ld"; /* default ld(1) to invoke */
+#else
+const char *_dtrace_defcpp = "cpp"; /* default cpp(1) to invoke */
+const char *_dtrace_defld = "ld"; /* default ld(1) to invoke */
+#endif
+
+const char *_dtrace_libdir = "/usr/lib/dtrace"; /* default library directory */
+#if defined(sun)
+const char *_dtrace_provdir = "/dev/dtrace/provider"; /* provider directory */
+#else
+const char *_dtrace_provdir = "/dev/dtrace"; /* provider directory */
+#endif
+
+int _dtrace_strbuckets = 211; /* default number of hash buckets (prime) */
+int _dtrace_intbuckets = 256; /* default number of integer buckets (Pof2) */
+uint_t _dtrace_strsize = 256; /* default size of string intrinsic type */
+uint_t _dtrace_stkindent = 14; /* default whitespace indent for stack/ustack */
+uint_t _dtrace_pidbuckets = 64; /* default number of pid hash buckets */
+uint_t _dtrace_pidlrulim = 8; /* default number of pid handles to cache */
+size_t _dtrace_bufsize = 512; /* default dt_buf_create() size */
+int _dtrace_argmax = 32; /* default maximum number of probe arguments */
+
+int _dtrace_debug = 0; /* debug messages enabled (off) */
+const char *const _dtrace_version = DT_VERS_STRING; /* API version string */
+int _dtrace_rdvers = RD_VERSION; /* rtld_db feature version */
+
+typedef struct dt_fdlist {
+ int *df_fds; /* array of provider driver file descriptors */
+ uint_t df_ents; /* number of valid elements in df_fds[] */
+ uint_t df_size; /* size of df_fds[] */
+} dt_fdlist_t;
+
+#if defined(sun)
+#pragma init(_dtrace_init)
+#else
+void _dtrace_init(void) __attribute__ ((constructor));
+#endif
+void
+_dtrace_init(void)
+{
+ _dtrace_debug = getenv("DTRACE_DEBUG") != NULL;
+
+ for (; _dtrace_rdvers > 0; _dtrace_rdvers--) {
+ if (rd_init(_dtrace_rdvers) == RD_OK)
+ break;
+ }
+#if defined(__i386__)
+ /* make long doubles 64 bits -sson */
+ (void) fpsetprec(FP_PE);
+#endif
+}
+
+static dtrace_hdl_t *
+set_open_errno(dtrace_hdl_t *dtp, int *errp, int err)
+{
+ if (dtp != NULL)
+ dtrace_close(dtp);
+ if (errp != NULL)
+ *errp = err;
+ return (NULL);
+}
+
+static void
+dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
+{
+ dt_provmod_t *prov;
+ char path[PATH_MAX];
+ int fd;
+#if defined(sun)
+ struct dirent *dp, *ep;
+ DIR *dirp;
+
+ if ((dirp = opendir(_dtrace_provdir)) == NULL)
+ return; /* failed to open directory; just skip it */
+
+ ep = alloca(sizeof (struct dirent) + PATH_MAX + 1);
+ bzero(ep, sizeof (struct dirent) + PATH_MAX + 1);
+
+ while (readdir_r(dirp, ep, &dp) == 0 && dp != NULL) {
+ if (dp->d_name[0] == '.')
+ continue; /* skip "." and ".." */
+
+ if (dfp->df_ents == dfp->df_size) {
+ uint_t size = dfp->df_size ? dfp->df_size * 2 : 16;
+ int *fds = realloc(dfp->df_fds, size * sizeof (int));
+
+ if (fds == NULL)
+ break; /* skip the rest of this directory */
+
+ dfp->df_fds = fds;
+ dfp->df_size = size;
+ }
+
+ (void) snprintf(path, sizeof (path), "%s/%s",
+ _dtrace_provdir, dp->d_name);
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ continue; /* failed to open driver; just skip it */
+
+ if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
+ (prov->dp_name = malloc(strlen(dp->d_name) + 1)) == NULL) {
+ free(prov);
+ (void) close(fd);
+ break;
+ }
+
+ (void) strcpy(prov->dp_name, dp->d_name);
+ prov->dp_next = *provmod;
+ *provmod = prov;
+
+ dt_dprintf("opened provider %s\n", dp->d_name);
+ dfp->df_fds[dfp->df_ents++] = fd;
+ }
+
+ (void) closedir(dirp);
+#else
+ char *p;
+ char *p1;
+ char *p_providers = NULL;
+ int error;
+ size_t len = 0;
+
+ /*
+ * Loop to allocate/reallocate memory for the string of provider
+ * names and retry:
+ */
+ while(1) {
+ /*
+ * The first time around, get the string length. The next time,
+ * hopefully we've allocated enough memory.
+ */
+ error = sysctlbyname("debug.dtrace.providers",p_providers,&len,NULL,0);
+ if (len == 0)
+ /* No providers? That's strange. Where's dtrace? */
+ break;
+ else if (error == 0 && p_providers == NULL) {
+ /*
+ * Allocate the initial memory which should be enough
+ * unless another provider loads before we have
+ * time to go back and get the string.
+ */
+ if ((p_providers = malloc(len)) == NULL)
+ /* How do we report errors here? */
+ return;
+ } else if (error == -1 && errno == ENOMEM) {
+ /*
+ * The current buffer isn't large enough, so
+ * reallocate it. We normally won't need to do this
+ * because providers aren't being loaded all the time.
+ */
+ if ((p = realloc(p_providers,len)) == NULL)
+ /* How do we report errors here? */
+ return;
+ p_providers = p;
+ } else
+ break;
+ }
+
+ /* Check if we got a string of provider names: */
+ if (error == 0 && len > 0 && p_providers != NULL) {
+ p = p_providers;
+
+ /*
+ * Parse the string containing the space separated
+ * provider names.
+ */
+ while ((p1 = strsep(&p," ")) != NULL) {
+ if (dfp->df_ents == dfp->df_size) {
+ uint_t size = dfp->df_size ? dfp->df_size * 2 : 16;
+ int *fds = realloc(dfp->df_fds, size * sizeof (int));
+
+ if (fds == NULL)
+ break;
+
+ dfp->df_fds = fds;
+ dfp->df_size = size;
+ }
+
+ (void) snprintf(path, sizeof (path), "/dev/dtrace/%s", p1);
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ continue; /* failed to open driver; just skip it */
+
+ if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
+ (prov->dp_name = malloc(strlen(p1) + 1)) == NULL) {
+ free(prov);
+ (void) close(fd);
+ break;
+ }
+
+ (void) strcpy(prov->dp_name, p1);
+ prov->dp_next = *provmod;
+ *provmod = prov;
+
+ dt_dprintf("opened provider %s\n", p1);
+ dfp->df_fds[dfp->df_ents++] = fd;
+ }
+ }
+ if (p_providers != NULL)
+ free(p_providers);
+#endif
+}
+
+static void
+dt_provmod_destroy(dt_provmod_t **provmod)
+{
+ dt_provmod_t *next, *current;
+
+ for (current = *provmod; current != NULL; current = next) {
+ next = current->dp_next;
+ free(current->dp_name);
+ free(current);
+ }
+
+ *provmod = NULL;
+}
+
+#if defined(sun)
+static const char *
+dt_get_sysinfo(int cmd, char *buf, size_t len)
+{
+ ssize_t rv = sysinfo(cmd, buf, len);
+ char *p = buf;
+
+ if (rv < 0 || rv > len)
+ (void) snprintf(buf, len, "%s", "Unknown");
+
+ while ((p = strchr(p, '.')) != NULL)
+ *p++ = '_';
+
+ return (buf);
+}
+#endif
+
+static dtrace_hdl_t *
+dt_vopen(int version, int flags, int *errp,
+ const dtrace_vector_t *vector, void *arg)
+{
+ dtrace_hdl_t *dtp = NULL;
+ int dtfd = -1, ftfd = -1, fterr = 0;
+ dtrace_prog_t *pgp;
+ dt_module_t *dmp;
+ dt_provmod_t *provmod = NULL;
+ int i, err;
+ struct rlimit rl;
+
+ const dt_intrinsic_t *dinp;
+ const dt_typedef_t *dtyp;
+ const dt_ident_t *idp;
+
+ dtrace_typeinfo_t dtt;
+ ctf_funcinfo_t ctc;
+ ctf_arinfo_t ctr;
+
+ dt_fdlist_t df = { NULL, 0, 0 };
+
+ char isadef[32], utsdef[32];
+ char s1[64], s2[64];
+
+ if (version <= 0)
+ return (set_open_errno(dtp, errp, EINVAL));
+
+ if (version > DTRACE_VERSION)
+ return (set_open_errno(dtp, errp, EDT_VERSION));
+
+ if (version < DTRACE_VERSION) {
+ /*
+ * Currently, increasing the library version number is used to
+ * denote a binary incompatible change. That is, a consumer
+ * of the library cannot run on a version of the library with
+ * a higher DTRACE_VERSION number than the consumer compiled
+ * against. Once the library API has been committed to,
+ * backwards binary compatibility will be required; at that
+ * time, this check should change to return EDT_OVERSION only
+ * if the specified version number is less than the version
+ * number at the time of interface commitment.
+ */
+ return (set_open_errno(dtp, errp, EDT_OVERSION));
+ }
+
+ if (flags & ~DTRACE_O_MASK)
+ return (set_open_errno(dtp, errp, EINVAL));
+
+ if ((flags & DTRACE_O_LP64) && (flags & DTRACE_O_ILP32))
+ return (set_open_errno(dtp, errp, EINVAL));
+
+ if (vector == NULL && arg != NULL)
+ return (set_open_errno(dtp, errp, EINVAL));
+
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ return (set_open_errno(dtp, errp, EDT_ELFVERSION));
+
+ if (vector != NULL || (flags & DTRACE_O_NODEV))
+ goto alloc; /* do not attempt to open dtrace device */
+
+ /*
+ * Before we get going, crank our limit on file descriptors up to the
+ * hard limit. This is to allow for the fact that libproc keeps file
+ * descriptors to objects open for the lifetime of the proc handle;
+ * without raising our hard limit, we would have an acceptably small
+ * bound on the number of processes that we could concurrently
+ * instrument with the pid provider.
+ */
+ if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
+ rl.rlim_cur = rl.rlim_max;
+ (void) setrlimit(RLIMIT_NOFILE, &rl);
+ }
+
+ /*
+ * Get the device path of each of the providers. We hold them open
+ * in the df.df_fds list until we open the DTrace driver itself,
+ * allowing us to see all of the probes provided on this system. Once
+ * we have the DTrace driver open, we can safely close all the providers
+ * now that they have registered with the framework.
+ */
+ dt_provmod_open(&provmod, &df);
+
+ dtfd = open("/dev/dtrace/dtrace", O_RDWR);
+ err = errno; /* save errno from opening dtfd */
+
+#if defined(sun)
+ ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
+#else
+ ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
+#endif
+ fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
+
+ while (df.df_ents-- != 0)
+ (void) close(df.df_fds[df.df_ents]);
+
+ free(df.df_fds);
+
+ /*
+ * If we failed to open the dtrace device, fail dtrace_open().
+ * We convert some kernel errnos to custom libdtrace errnos to
+ * improve the resulting message from the usual strerror().
+ */
+ if (dtfd == -1) {
+ dt_provmod_destroy(&provmod);
+ switch (err) {
+ case ENOENT:
+ err = EDT_NOENT;
+ break;
+ case EBUSY:
+ err = EDT_BUSY;
+ break;
+ case EACCES:
+ err = EDT_ACCESS;
+ break;
+ }
+ return (set_open_errno(dtp, errp, err));
+ }
+
+ (void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);
+ (void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);
+
+alloc:
+ if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ bzero(dtp, sizeof (dtrace_hdl_t));
+ dtp->dt_oflags = flags;
+#if defined(sun)
+ dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
+#else
+ dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
+#endif
+ dtp->dt_linkmode = DT_LINK_KERNEL;
+ dtp->dt_linktype = DT_LTYP_ELF;
+ dtp->dt_xlatemode = DT_XL_STATIC;
+ dtp->dt_stdcmode = DT_STDC_XA;
+ dtp->dt_version = version;
+ dtp->dt_fd = dtfd;
+ dtp->dt_ftfd = ftfd;
+ dtp->dt_fterr = fterr;
+ dtp->dt_cdefs_fd = -1;
+ dtp->dt_ddefs_fd = -1;
+#if defined(sun)
+ dtp->dt_stdout_fd = -1;
+#else
+ dtp->dt_freopen_fp = NULL;
+#endif
+ dtp->dt_modbuckets = _dtrace_strbuckets;
+ dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *));
+ dtp->dt_provbuckets = _dtrace_strbuckets;
+ dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *));
+ dt_proc_hash_create(dtp);
+ dtp->dt_vmax = DT_VERS_LATEST;
+ dtp->dt_cpp_path = strdup(_dtrace_defcpp);
+ dtp->dt_cpp_argv = malloc(sizeof (char *));
+ dtp->dt_cpp_argc = 1;
+ dtp->dt_cpp_args = 1;
+ dtp->dt_ld_path = strdup(_dtrace_defld);
+ dtp->dt_provmod = provmod;
+ dtp->dt_vector = vector;
+ dtp->dt_varg = arg;
+ dt_dof_init(dtp);
+ (void) uname(&dtp->dt_uts);
+
+ if (dtp->dt_mods == NULL || dtp->dt_provs == NULL ||
+ dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||
+ dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ for (i = 0; i < DTRACEOPT_MAX; i++)
+ dtp->dt_options[i] = DTRACEOPT_UNSET;
+
+ dtp->dt_cpp_argv[0] = (char *)strbasename(dtp->dt_cpp_path);
+
+#if defined(sun)
+ (void) snprintf(isadef, sizeof (isadef), "-D__SUNW_D_%u",
+ (uint_t)(sizeof (void *) * NBBY));
+
+ (void) snprintf(utsdef, sizeof (utsdef), "-D__%s_%s",
+ dt_get_sysinfo(SI_SYSNAME, s1, sizeof (s1)),
+ dt_get_sysinfo(SI_RELEASE, s2, sizeof (s2)));
+
+ if (dt_cpp_add_arg(dtp, "-D__sun") == NULL ||
+ dt_cpp_add_arg(dtp, "-D__unix") == NULL ||
+ dt_cpp_add_arg(dtp, "-D__SVR4") == NULL ||
+ dt_cpp_add_arg(dtp, "-D__SUNW_D=1") == NULL ||
+ dt_cpp_add_arg(dtp, isadef) == NULL ||
+ dt_cpp_add_arg(dtp, utsdef) == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+#endif
+
+ if (flags & DTRACE_O_NODEV)
+ bcopy(&_dtrace_conf, &dtp->dt_conf, sizeof (_dtrace_conf));
+ else if (dt_ioctl(dtp, DTRACEIOC_CONF, &dtp->dt_conf) != 0)
+ return (set_open_errno(dtp, errp, errno));
+
+ if (flags & DTRACE_O_LP64)
+ dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_LP64;
+ else if (flags & DTRACE_O_ILP32)
+ dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_ILP32;
+
+#ifdef __sparc
+ /*
+ * On SPARC systems, __sparc is always defined for <sys/isa_defs.h>
+ * and __sparcv9 is defined if we are doing a 64-bit compile.
+ */
+ if (dt_cpp_add_arg(dtp, "-D__sparc") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64 &&
+ dt_cpp_add_arg(dtp, "-D__sparcv9") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+#endif
+
+#if defined(sun)
+#ifdef __x86
+ /*
+ * On x86 systems, __i386 is defined for <sys/isa_defs.h> for 32-bit
+ * compiles and __amd64 is defined for 64-bit compiles. Unlike SPARC,
+ * they are defined exclusive of one another (see PSARC 2004/619).
+ */
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) {
+ if (dt_cpp_add_arg(dtp, "-D__amd64") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+ } else {
+ if (dt_cpp_add_arg(dtp, "-D__i386") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+ }
+#endif
+#else
+#if defined(__amd64__) || defined(__i386__)
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) {
+ if (dt_cpp_add_arg(dtp, "-m64") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+ } else {
+ if (dt_cpp_add_arg(dtp, "-m32") == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+ }
+#endif
+#endif
+
+ if (dtp->dt_conf.dtc_difversion < DIF_VERSION)
+ return (set_open_errno(dtp, errp, EDT_DIFVERS));
+
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32)
+ bcopy(_dtrace_ints_32, dtp->dt_ints, sizeof (_dtrace_ints_32));
+ else
+ bcopy(_dtrace_ints_64, dtp->dt_ints, sizeof (_dtrace_ints_64));
+
+ /*
+ * On FreeBSD the kernel module name can't be hard-coded. The
+ * 'kern.bootfile' sysctl value tells us exactly which file is being
+ * used as the kernel.
+ */
+#if !defined(sun)
+ {
+ char bootfile[MAXPATHLEN];
+ char *p;
+ int i;
+ size_t len = sizeof(bootfile);
+
+ /* This call shouldn't fail, but use a default just in case. */
+ if (sysctlbyname("kern.bootfile", bootfile, &len, NULL, 0) != 0)
+ strlcpy(bootfile, "kernel", sizeof(bootfile));
+
+ if ((p = strrchr(bootfile, '/')) != NULL)
+ p++;
+ else
+ p = bootfile;
+
+ /*
+ * Format the global variables based on the kernel module name.
+ */
+ snprintf(curthread_str, sizeof(curthread_str), "%s`struct thread *",p);
+ snprintf(intmtx_str, sizeof(intmtx_str), "int(%s`struct mtx *)",p);
+ snprintf(threadmtx_str, sizeof(threadmtx_str), "struct thread *(%s`struct mtx *)",p);
+ snprintf(rwlock_str, sizeof(rwlock_str), "int(%s`struct rwlock *)",p);
+ snprintf(sxlock_str, sizeof(sxlock_str), "int(%s`struct sxlock *)",p);
+ }
+#endif
+
+ dtp->dt_macros = dt_idhash_create("macro", NULL, 0, UINT_MAX);
+ dtp->dt_aggs = dt_idhash_create("aggregation", NULL,
+ DTRACE_AGGVARIDNONE + 1, UINT_MAX);
+
+ dtp->dt_globals = dt_idhash_create("global", _dtrace_globals,
+ DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
+
+ dtp->dt_tls = dt_idhash_create("thread local", NULL,
+ DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
+
+ if (dtp->dt_macros == NULL || dtp->dt_aggs == NULL ||
+ dtp->dt_globals == NULL || dtp->dt_tls == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ /*
+ * Populate the dt_macros identifier hash table by hand: we can't use
+ * the dt_idhash_populate() mechanism because we're not yet compiling
+ * and dtrace_update() needs to immediately reference these idents.
+ */
+ for (idp = _dtrace_macros; idp->di_name != NULL; idp++) {
+ if (dt_idhash_insert(dtp->dt_macros, idp->di_name,
+ idp->di_kind, idp->di_flags, idp->di_id, idp->di_attr,
+ idp->di_vers, idp->di_ops ? idp->di_ops : &dt_idops_thaw,
+ idp->di_iarg, 0) == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+ }
+
+ /*
+ * Update the module list using /system/object and load the values for
+ * the macro variable definitions according to the current process.
+ */
+ dtrace_update(dtp);
+
+ /*
+ * Select the intrinsics and typedefs we want based on the data model.
+ * The intrinsics are under "C". The typedefs are added under "D".
+ */
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32) {
+ dinp = _dtrace_intrinsics_32;
+ dtyp = _dtrace_typedefs_32;
+ } else {
+ dinp = _dtrace_intrinsics_64;
+ dtyp = _dtrace_typedefs_64;
+ }
+
+ /*
+ * Create a dynamic CTF container under the "C" scope for intrinsic
+ * types and types defined in ANSI-C header files that are included.
+ */
+ if ((dmp = dtp->dt_cdefs = dt_module_create(dtp, "C")) == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ if ((dmp->dm_ctfp = ctf_create(&dtp->dt_ctferr)) == NULL)
+ return (set_open_errno(dtp, errp, EDT_CTF));
+
+ dt_dprintf("created CTF container for %s (%p)\n",
+ dmp->dm_name, (void *)dmp->dm_ctfp);
+
+ (void) ctf_setmodel(dmp->dm_ctfp, dtp->dt_conf.dtc_ctfmodel);
+ ctf_setspecific(dmp->dm_ctfp, dmp);
+
+ dmp->dm_flags = DT_DM_LOADED; /* fake up loaded bit */
+ dmp->dm_modid = -1; /* no module ID */
+
+ /*
+ * Fill the dynamic "C" CTF container with all of the intrinsic
+ * integer and floating-point types appropriate for this data model.
+ */
+ for (; dinp->din_name != NULL; dinp++) {
+ if (dinp->din_kind == CTF_K_INTEGER) {
+ err = ctf_add_integer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ dinp->din_name, &dinp->din_data);
+ } else {
+ err = ctf_add_float(dmp->dm_ctfp, CTF_ADD_ROOT,
+ dinp->din_name, &dinp->din_data);
+ }
+
+ if (err == CTF_ERR) {
+ dt_dprintf("failed to add %s to C container: %s\n",
+ dinp->din_name, ctf_errmsg(
+ ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+ }
+
+ if (ctf_update(dmp->dm_ctfp) != 0) {
+ dt_dprintf("failed to update C container: %s\n",
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+
+ /*
+ * Add intrinsic pointer types that are needed to initialize printf
+ * format dictionary types (see table in dt_printf.c).
+ */
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ ctf_lookup_by_name(dmp->dm_ctfp, "void"));
+
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ ctf_lookup_by_name(dmp->dm_ctfp, "char"));
+
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ ctf_lookup_by_name(dmp->dm_ctfp, "int"));
+
+ if (ctf_update(dmp->dm_ctfp) != 0) {
+ dt_dprintf("failed to update C container: %s\n",
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+
+ /*
+ * Create a dynamic CTF container under the "D" scope for types that
+ * are defined by the D program itself or on-the-fly by the D compiler.
+ * The "D" CTF container is a child of the "C" CTF container.
+ */
+ if ((dmp = dtp->dt_ddefs = dt_module_create(dtp, "D")) == NULL)
+ return (set_open_errno(dtp, errp, EDT_NOMEM));
+
+ if ((dmp->dm_ctfp = ctf_create(&dtp->dt_ctferr)) == NULL)
+ return (set_open_errno(dtp, errp, EDT_CTF));
+
+ dt_dprintf("created CTF container for %s (%p)\n",
+ dmp->dm_name, (void *)dmp->dm_ctfp);
+
+ (void) ctf_setmodel(dmp->dm_ctfp, dtp->dt_conf.dtc_ctfmodel);
+ ctf_setspecific(dmp->dm_ctfp, dmp);
+
+ dmp->dm_flags = DT_DM_LOADED; /* fake up loaded bit */
+ dmp->dm_modid = -1; /* no module ID */
+
+ if (ctf_import(dmp->dm_ctfp, dtp->dt_cdefs->dm_ctfp) == CTF_ERR) {
+ dt_dprintf("failed to import D parent container: %s\n",
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+
+ /*
+ * Fill the dynamic "D" CTF container with all of the built-in typedefs
+ * that we need to use for our D variable and function definitions.
+ * This ensures that basic inttypes.h names are always available to us.
+ */
+ for (; dtyp->dty_src != NULL; dtyp++) {
+ if (ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ dtyp->dty_dst, ctf_lookup_by_name(dmp->dm_ctfp,
+ dtyp->dty_src)) == CTF_ERR) {
+ dt_dprintf("failed to add typedef %s %s to D "
+ "container: %s", dtyp->dty_src, dtyp->dty_dst,
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+ }
+
+ /*
+ * Insert a CTF ID corresponding to a pointer to a type of kind
+ * CTF_K_FUNCTION we can use in the compiler for function pointers.
+ * CTF treats all function pointers as "int (*)()" so we only need one.
+ */
+ ctc.ctc_return = ctf_lookup_by_name(dmp->dm_ctfp, "int");
+ ctc.ctc_argc = 0;
+ ctc.ctc_flags = 0;
+
+ dtp->dt_type_func = ctf_add_function(dmp->dm_ctfp,
+ CTF_ADD_ROOT, &ctc, NULL);
+
+ dtp->dt_type_fptr = ctf_add_pointer(dmp->dm_ctfp,
+ CTF_ADD_ROOT, dtp->dt_type_func);
+
+ /*
+ * We also insert CTF definitions for the special D intrinsic types
+ * string and <DYN> into the D container. The string type is added
+ * as a typedef of char[n]. The <DYN> type is an alias for void.
+ * We compare types to these special CTF ids throughout the compiler.
+ */
+ ctr.ctr_contents = ctf_lookup_by_name(dmp->dm_ctfp, "char");
+ ctr.ctr_index = ctf_lookup_by_name(dmp->dm_ctfp, "long");
+ ctr.ctr_nelems = _dtrace_strsize;
+
+ dtp->dt_type_str = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ "string", ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &ctr));
+
+ dtp->dt_type_dyn = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ "<DYN>", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
+
+ dtp->dt_type_stack = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ "stack", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
+
+ dtp->dt_type_symaddr = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ "_symaddr", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
+
+ dtp->dt_type_usymaddr = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
+ "_usymaddr", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
+
+ if (dtp->dt_type_func == CTF_ERR || dtp->dt_type_fptr == CTF_ERR ||
+ dtp->dt_type_str == CTF_ERR || dtp->dt_type_dyn == CTF_ERR ||
+ dtp->dt_type_stack == CTF_ERR || dtp->dt_type_symaddr == CTF_ERR ||
+ dtp->dt_type_usymaddr == CTF_ERR) {
+ dt_dprintf("failed to add intrinsic to D container: %s\n",
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+
+ if (ctf_update(dmp->dm_ctfp) != 0) {
+ dt_dprintf("failed update D container: %s\n",
+ ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ return (set_open_errno(dtp, errp, EDT_CTF));
+ }
+
+ /*
+ * Initialize the integer description table used to convert integer
+ * constants to the appropriate types. Refer to the comments above
+ * dt_node_int() for a complete description of how this table is used.
+ */
+ for (i = 0; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i++) {
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY,
+ dtp->dt_ints[i].did_name, &dtt) != 0) {
+ dt_dprintf("failed to lookup integer type %s: %s\n",
+ dtp->dt_ints[i].did_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ return (set_open_errno(dtp, errp, dtp->dt_errno));
+ }
+ dtp->dt_ints[i].did_ctfp = dtt.dtt_ctfp;
+ dtp->dt_ints[i].did_type = dtt.dtt_type;
+ }
+
+ /*
+ * Now that we've created the "C" and "D" containers, move them to the
+ * start of the module list so that these types and symbols are found
+ * first (for stability) when iterating through the module list.
+ */
+ dt_list_delete(&dtp->dt_modlist, dtp->dt_ddefs);
+ dt_list_prepend(&dtp->dt_modlist, dtp->dt_ddefs);
+
+ dt_list_delete(&dtp->dt_modlist, dtp->dt_cdefs);
+ dt_list_prepend(&dtp->dt_modlist, dtp->dt_cdefs);
+
+ if (dt_pfdict_create(dtp) == -1)
+ return (set_open_errno(dtp, errp, dtp->dt_errno));
+
+ /*
+ * If we are opening libdtrace DTRACE_O_NODEV enable C_ZDEFS by default
+ * because without /dev/dtrace open, we will not be able to load the
+ * names and attributes of any providers or probes from the kernel.
+ */
+ if (flags & DTRACE_O_NODEV)
+ dtp->dt_cflags |= DTRACE_C_ZDEFS;
+
+ /*
+ * Load hard-wired inlines into the definition cache by calling the
+ * compiler on the raw definition string defined above.
+ */
+ if ((pgp = dtrace_program_strcompile(dtp, _dtrace_hardwire,
+ DTRACE_PROBESPEC_NONE, DTRACE_C_EMPTY, 0, NULL)) == NULL) {
+ dt_dprintf("failed to load hard-wired definitions: %s\n",
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ return (set_open_errno(dtp, errp, EDT_HARDWIRE));
+ }
+
+ dt_program_destroy(dtp, pgp);
+
+ /*
+ * Set up the default DTrace library path. Once set, the next call to
+ * dt_compile() will compile all the libraries. We intentionally defer
+ * library processing to improve overhead for clients that don't ever
+ * compile, and to provide better error reporting (because the full
+ * reporting of compiler errors requires dtrace_open() to succeed).
+ */
+ if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)
+ return (set_open_errno(dtp, errp, dtp->dt_errno));
+
+ return (dtp);
+}
+
+dtrace_hdl_t *
+dtrace_open(int version, int flags, int *errp)
+{
+ return (dt_vopen(version, flags, errp, NULL, NULL));
+}
+
+dtrace_hdl_t *
+dtrace_vopen(int version, int flags, int *errp,
+ const dtrace_vector_t *vector, void *arg)
+{
+ return (dt_vopen(version, flags, errp, vector, arg));
+}
+
+void
+dtrace_close(dtrace_hdl_t *dtp)
+{
+ dt_ident_t *idp, *ndp;
+ dt_module_t *dmp;
+ dt_provider_t *pvp;
+ dtrace_prog_t *pgp;
+ dt_xlator_t *dxp;
+ dt_dirpath_t *dirp;
+ int i;
+
+ if (dtp->dt_procs != NULL)
+ dt_proc_hash_destroy(dtp);
+
+ while ((pgp = dt_list_next(&dtp->dt_programs)) != NULL)
+ dt_program_destroy(dtp, pgp);
+
+ while ((dxp = dt_list_next(&dtp->dt_xlators)) != NULL)
+ dt_xlator_destroy(dtp, dxp);
+
+ dt_free(dtp, dtp->dt_xlatormap);
+
+ for (idp = dtp->dt_externs; idp != NULL; idp = ndp) {
+ ndp = idp->di_next;
+ dt_ident_destroy(idp);
+ }
+
+ if (dtp->dt_macros != NULL)
+ dt_idhash_destroy(dtp->dt_macros);
+ if (dtp->dt_aggs != NULL)
+ dt_idhash_destroy(dtp->dt_aggs);
+ if (dtp->dt_globals != NULL)
+ dt_idhash_destroy(dtp->dt_globals);
+ if (dtp->dt_tls != NULL)
+ dt_idhash_destroy(dtp->dt_tls);
+
+ while ((dmp = dt_list_next(&dtp->dt_modlist)) != NULL)
+ dt_module_destroy(dtp, dmp);
+
+ while ((pvp = dt_list_next(&dtp->dt_provlist)) != NULL)
+ dt_provider_destroy(dtp, pvp);
+
+ if (dtp->dt_fd != -1)
+ (void) close(dtp->dt_fd);
+ if (dtp->dt_ftfd != -1)
+ (void) close(dtp->dt_ftfd);
+ if (dtp->dt_cdefs_fd != -1)
+ (void) close(dtp->dt_cdefs_fd);
+ if (dtp->dt_ddefs_fd != -1)
+ (void) close(dtp->dt_ddefs_fd);
+#if defined(sun)
+ if (dtp->dt_stdout_fd != -1)
+ (void) close(dtp->dt_stdout_fd);
+#else
+ if (dtp->dt_freopen_fp != NULL)
+ (void) fclose(dtp->dt_freopen_fp);
+#endif
+
+ dt_epid_destroy(dtp);
+ dt_aggid_destroy(dtp);
+ dt_format_destroy(dtp);
+ dt_strdata_destroy(dtp);
+ dt_buffered_destroy(dtp);
+ dt_aggregate_destroy(dtp);
+ free(dtp->dt_buf.dtbd_data);
+ dt_pfdict_destroy(dtp);
+ dt_provmod_destroy(&dtp->dt_provmod);
+ dt_dof_fini(dtp);
+
+ for (i = 1; i < dtp->dt_cpp_argc; i++)
+ free(dtp->dt_cpp_argv[i]);
+
+ while ((dirp = dt_list_next(&dtp->dt_lib_path)) != NULL) {
+ dt_list_delete(&dtp->dt_lib_path, dirp);
+ free(dirp->dir_path);
+ free(dirp);
+ }
+
+ free(dtp->dt_cpp_argv);
+ free(dtp->dt_cpp_path);
+ free(dtp->dt_ld_path);
+
+ free(dtp->dt_mods);
+ free(dtp->dt_provs);
+ free(dtp);
+}
+
+int
+dtrace_provider_modules(dtrace_hdl_t *dtp, const char **mods, int nmods)
+{
+ dt_provmod_t *prov;
+ int i = 0;
+
+ for (prov = dtp->dt_provmod; prov != NULL; prov = prov->dp_next, i++) {
+ if (i < nmods)
+ mods[i] = prov->dp_name;
+ }
+
+ return (i);
+}
+
+int
+dtrace_ctlfd(dtrace_hdl_t *dtp)
+{
+ return (dtp->dt_fd);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
new file mode 100644
index 0000000..fa1407f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
@@ -0,0 +1,1031 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/resource.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <strings.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+
+#include <dt_impl.h>
+#include <dt_string.h>
+
+static int
+dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ agp->dtat_flags |= option;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char str[DTRACE_ATTR2STR_MAX];
+ dtrace_attribute_t attr;
+
+ if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dt_dprintf("set compiler attribute minimum to %s\n",
+ dtrace_attr2str(attr, str, sizeof (str)));
+
+ if (dtp->dt_pcb != NULL) {
+ dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
+ dtp->dt_pcb->pcb_amin = attr;
+ } else {
+ dtp->dt_cflags |= DTRACE_C_EATTR;
+ dtp->dt_amin = attr;
+ }
+
+ return (0);
+}
+
+static void
+dt_coredump(void)
+{
+ const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
+
+ struct sigaction act;
+ struct rlimit lim;
+
+ (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
+
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+
+ (void) sigemptyset(&act.sa_mask);
+ (void) sigaction(SIGABRT, &act, NULL);
+
+ lim.rlim_cur = RLIM_INFINITY;
+ lim.rlim_max = RLIM_INFINITY;
+
+ (void) setrlimit(RLIMIT_CORE, &lim);
+ abort();
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ static int enabled = 0;
+
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (enabled++ || atexit(dt_coredump) == 0)
+ return (0);
+
+ return (dt_set_errno(dtp, errno));
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ if (dt_cpp_add_arg(dtp, "-H") == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char *cpp;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ if ((cpp = strdup(arg)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
+ free(dtp->dt_cpp_path);
+ dtp->dt_cpp_path = cpp;
+
+ return (0);
+}
+
+static int
+dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char *buf;
+ size_t len;
+ const char *opt = (const char *)option;
+
+ if (opt == NULL || arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ len = strlen(opt) + strlen(arg) + 1;
+ buf = alloca(len);
+
+ (void) strcpy(buf, opt);
+ (void) strcat(buf, arg);
+
+ if (dt_cpp_add_arg(dtp, buf) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int fd;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ (void) close(dtp->dt_cdefs_fd);
+ dtp->dt_cdefs_fd = fd;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtp->dt_droptags = 1;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int fd;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ (void) close(dtp->dt_ddefs_fd);
+ dtp->dt_ddefs_fd = fd;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ _dtrace_debug = 1;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int n;
+
+ if (arg == NULL || (n = atoi(arg)) <= 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_conf.dtc_difintregs = n;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtp->dt_lazyload = 1;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char *ld;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ if ((ld = strdup(arg)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ free(dtp->dt_ld_path);
+ dtp->dt_ld_path = ld;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dt_dirpath_t *dp;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
+ (dp->dir_path = strdup(arg)) == NULL) {
+ free(dp);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dt_list_append(&dtp->dt_lib_path, dp);
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (strcmp(arg, "kernel") == 0)
+ dtp->dt_linkmode = DT_LINK_KERNEL;
+ else if (strcmp(arg, "primary") == 0)
+ dtp->dt_linkmode = DT_LINK_PRIMARY;
+ else if (strcmp(arg, "dynamic") == 0)
+ dtp->dt_linkmode = DT_LINK_DYNAMIC;
+ else if (strcmp(arg, "static") == 0)
+ dtp->dt_linkmode = DT_LINK_STATIC;
+ else
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (strcasecmp(arg, "elf") == 0)
+ dtp->dt_linktype = DT_LTYP_ELF;
+ else if (strcasecmp(arg, "dof") == 0)
+ dtp->dt_linktype = DT_LTYP_DOF;
+ else
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (strcmp(arg, "exec") == 0)
+ dtp->dt_prcmode = DT_PROC_STOP_CREATE;
+ else if (strcmp(arg, "preinit") == 0)
+ dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
+ else if (strcmp(arg, "postinit") == 0)
+ dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
+ else if (strcmp(arg, "main") == 0)
+ dtp->dt_prcmode = DT_PROC_STOP_MAIN;
+ else
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int n;
+
+ if (arg == NULL || (n = atoi(arg)) < 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_procs->dph_lrulim = n;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+ if (strcmp(arg, "a") == 0)
+ dtp->dt_stdcmode = DT_STDC_XA;
+ else if (strcmp(arg, "c") == 0)
+ dtp->dt_stdcmode = DT_STDC_XC;
+ else if (strcmp(arg, "s") == 0)
+ dtp->dt_stdcmode = DT_STDC_XS;
+ else if (strcmp(arg, "t") == 0)
+ dtp->dt_stdcmode = DT_STDC_XT;
+ else
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
+ char *path;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if ((path = strdup(arg)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ free(dp->dir_path);
+ dp->dir_path = path;
+
+ return (0);
+}
+
+
+/*ARGSUSED*/
+static int
+dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int m;
+
+ if (arg == NULL || (m = atoi(arg)) <= 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_treedump = m;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ int n;
+
+ if (arg == NULL || (n = atoi(arg)) <= 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_conf.dtc_diftupregs = n;
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (strcmp(arg, "dynamic") == 0)
+ dtp->dt_xlatemode = DT_XL_DYNAMIC;
+ else if (strcmp(arg, "static") == 0)
+ dtp->dt_xlatemode = DT_XL_STATIC;
+ else
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ dtp->dt_pcb->pcb_cflags |= option;
+ else
+ dtp->dt_cflags |= option;
+
+ return (0);
+}
+
+static int
+dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_dflags |= option;
+ return (0);
+}
+
+static int
+dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg != NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dtp->dt_pcb != NULL)
+ dtp->dt_pcb->pcb_cflags &= ~option;
+ else
+ dtp->dt_cflags &= ~option;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dt_version_t v;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (dt_version_str2num(arg, &v) == -1)
+ return (dt_set_errno(dtp, EDT_VERSINVAL));
+
+ if (!dt_version_defined(v))
+ return (dt_set_errno(dtp, EDT_VERSUNDEF));
+
+ return (dt_reduce(dtp, v));
+}
+
+static int
+dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char *end;
+ dtrace_optval_t val = 0;
+ int i;
+
+ const struct {
+ char *positive;
+ char *negative;
+ } couples[] = {
+ { "yes", "no" },
+ { "enable", "disable" },
+ { "enabled", "disabled" },
+ { "true", "false" },
+ { "on", "off" },
+ { "set", "unset" },
+ { NULL }
+ };
+
+ if (arg != NULL) {
+ if (arg[0] == '\0') {
+ val = DTRACEOPT_UNSET;
+ goto out;
+ }
+
+ for (i = 0; couples[i].positive != NULL; i++) {
+ if (strcasecmp(couples[i].positive, arg) == 0) {
+ val = 1;
+ goto out;
+ }
+
+ if (strcasecmp(couples[i].negative, arg) == 0) {
+ val = DTRACEOPT_UNSET;
+ goto out;
+ }
+ }
+
+ errno = 0;
+ val = strtoull(arg, &end, 0);
+
+ if (*end != '\0' || errno != 0 || val < 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+ }
+
+out:
+ dtp->dt_options[option] = val;
+ return (0);
+}
+
+static int
+dt_optval_parse(const char *arg, dtrace_optval_t *rval)
+{
+ dtrace_optval_t mul = 1;
+ size_t len;
+ char *end;
+
+ len = strlen(arg);
+ errno = 0;
+
+ switch (arg[len - 1]) {
+ case 't':
+ case 'T':
+ mul *= 1024;
+ /*FALLTHRU*/
+ case 'g':
+ case 'G':
+ mul *= 1024;
+ /*FALLTHRU*/
+ case 'm':
+ case 'M':
+ mul *= 1024;
+ /*FALLTHRU*/
+ case 'k':
+ case 'K':
+ mul *= 1024;
+ /*FALLTHRU*/
+ default:
+ break;
+ }
+
+ errno = 0;
+ *rval = strtoull(arg, &end, 0) * mul;
+
+ if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
+ *rval < 0 || errno != 0)
+ return (-1);
+
+ return (0);
+}
+
+static int
+dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtrace_optval_t val = 0;
+
+ if (arg != NULL && dt_optval_parse(arg, &val) != 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_options[option] = val;
+ return (0);
+}
+
+static int
+dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ char *end;
+ int i;
+ dtrace_optval_t mul = 1, val = 0;
+
+ const struct {
+ char *name;
+ hrtime_t mul;
+ } suffix[] = {
+ { "ns", NANOSEC / NANOSEC },
+ { "nsec", NANOSEC / NANOSEC },
+ { "us", NANOSEC / MICROSEC },
+ { "usec", NANOSEC / MICROSEC },
+ { "ms", NANOSEC / MILLISEC },
+ { "msec", NANOSEC / MILLISEC },
+ { "s", NANOSEC / SEC },
+ { "sec", NANOSEC / SEC },
+ { "m", NANOSEC * (hrtime_t)60 },
+ { "min", NANOSEC * (hrtime_t)60 },
+ { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
+ { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
+ { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
+ { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
+ { "hz", 0 },
+ { NULL }
+ };
+
+ if (arg != NULL) {
+ errno = 0;
+ val = strtoull(arg, &end, 0);
+
+ for (i = 0; suffix[i].name != NULL; i++) {
+ if (strcasecmp(suffix[i].name, end) == 0) {
+ mul = suffix[i].mul;
+ break;
+ }
+ }
+
+ if (suffix[i].name == NULL && *end != '\0' || val < 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (mul == 0) {
+ /*
+ * The rate has been specified in frequency-per-second.
+ */
+ if (val != 0)
+ val = NANOSEC / val;
+ } else {
+ val *= mul;
+ }
+ }
+
+ dtp->dt_options[option] = val;
+ return (0);
+}
+
+/*
+ * When setting the strsize option, set the option in the dt_options array
+ * using dt_opt_size() as usual, and then update the definition of the CTF
+ * type for the D intrinsic "string" to be an array of the corresponding size.
+ * If any errors occur, reset dt_options[option] to its previous value.
+ */
+static int
+dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtrace_optval_t val = dtp->dt_options[option];
+ ctf_file_t *fp = DT_STR_CTFP(dtp);
+ ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
+ ctf_arinfo_t r;
+
+ if (dt_opt_size(dtp, arg, option) != 0)
+ return (-1); /* dt_errno is set for us */
+
+ if (dtp->dt_options[option] > UINT_MAX) {
+ dtp->dt_options[option] = val;
+ return (dt_set_errno(dtp, EOVERFLOW));
+ }
+
+ if (ctf_array_info(fp, type, &r) == CTF_ERR) {
+ dtp->dt_options[option] = val;
+ dtp->dt_ctferr = ctf_errno(fp);
+ return (dt_set_errno(dtp, EDT_CTF));
+ }
+
+ r.ctr_nelems = (uint_t)dtp->dt_options[option];
+
+ if (ctf_set_array(fp, type, &r) == CTF_ERR ||
+ ctf_update(fp) == CTF_ERR) {
+ dtp->dt_options[option] = val;
+ dtp->dt_ctferr = ctf_errno(fp);
+ return (dt_set_errno(dtp, EDT_CTF));
+ }
+
+ return (0);
+}
+
+static const struct {
+ const char *dtbp_name;
+ int dtbp_policy;
+} _dtrace_bufpolicies[] = {
+ { "ring", DTRACEOPT_BUFPOLICY_RING },
+ { "fill", DTRACEOPT_BUFPOLICY_FILL },
+ { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
+ { NULL, 0 }
+};
+
+/*ARGSUSED*/
+static int
+dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtrace_optval_t policy = DTRACEOPT_UNSET;
+ int i;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
+ if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
+ policy = _dtrace_bufpolicies[i].dtbp_policy;
+ break;
+ }
+ }
+
+ if (policy == DTRACEOPT_UNSET)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
+
+ return (0);
+}
+
+static const struct {
+ const char *dtbr_name;
+ int dtbr_policy;
+} _dtrace_bufresize[] = {
+ { "auto", DTRACEOPT_BUFRESIZE_AUTO },
+ { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
+ { NULL, 0 }
+};
+
+/*ARGSUSED*/
+static int
+dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtrace_optval_t policy = DTRACEOPT_UNSET;
+ int i;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
+ if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
+ policy = _dtrace_bufresize[i].dtbr_policy;
+ break;
+ }
+ }
+
+ if (policy == DTRACEOPT_UNSET)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
+
+ return (0);
+}
+
+int
+dt_options_load(dtrace_hdl_t *dtp)
+{
+ dof_hdr_t hdr, *dof;
+ dof_sec_t *sec;
+ size_t offs;
+ int i;
+
+ /*
+ * To load the option values, we need to ask the kernel to provide its
+ * DOF, which we'll sift through to look for OPTDESC sections.
+ */
+ bzero(&hdr, sizeof (dof_hdr_t));
+ hdr.dofh_loadsz = sizeof (dof_hdr_t);
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
+#else
+ dof = &hdr;
+ if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
+#endif
+ return (dt_set_errno(dtp, errno));
+
+ if (hdr.dofh_loadsz < sizeof (dof_hdr_t))
+ return (dt_set_errno(dtp, EINVAL));
+
+ dof = alloca(hdr.dofh_loadsz);
+ bzero(dof, sizeof (dof_hdr_t));
+ dof->dofh_loadsz = hdr.dofh_loadsz;
+
+ for (i = 0; i < DTRACEOPT_MAX; i++)
+ dtp->dt_options[i] = DTRACEOPT_UNSET;
+
+#if defined(sun)
+ if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
+#endif
+ return (dt_set_errno(dtp, errno));
+
+ for (i = 0; i < dof->dofh_secnum; i++) {
+ sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
+ dof->dofh_secoff + i * dof->dofh_secsize);
+
+ if (sec->dofs_type != DOF_SECT_OPTDESC)
+ continue;
+
+ break;
+ }
+
+ for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
+ dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
+ ((uintptr_t)dof + sec->dofs_offset + offs);
+
+ if (opt->dofo_strtab != DOF_SECIDX_NONE)
+ continue;
+
+ if (opt->dofo_option >= DTRACEOPT_MAX)
+ continue;
+
+ dtp->dt_options[opt->dofo_option] = opt->dofo_value;
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ dtrace_optval_t size;
+ void *p;
+
+ if (arg == NULL || dt_optval_parse(arg, &size) != 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (size > SIZE_MAX)
+ size = SIZE_MAX;
+
+ if ((p = dt_zalloc(dtp, size)) == NULL) {
+ do {
+ size /= 2;
+ } while ((p = dt_zalloc(dtp, size)) == NULL);
+ }
+
+ dt_free(dtp, p);
+
+ return (0);
+}
+
+typedef struct dt_option {
+ const char *o_name;
+ int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
+ uintptr_t o_option;
+} dt_option_t;
+
+/*
+ * Compile-time options.
+ */
+static const dt_option_t _dtrace_ctoptions[] = {
+ { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
+ { "amin", dt_opt_amin },
+ { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
+ { "core", dt_opt_core },
+ { "cpp", dt_opt_cflags, DTRACE_C_CPP },
+ { "cpphdrs", dt_opt_cpp_hdrs },
+ { "cpppath", dt_opt_cpp_path },
+ { "ctypes", dt_opt_ctypes },
+ { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
+ { "dtypes", dt_opt_dtypes },
+ { "debug", dt_opt_debug },
+ { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
+ { "droptags", dt_opt_droptags },
+ { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
+ { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
+ { "evaltime", dt_opt_evaltime },
+ { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
+ { "iregs", dt_opt_iregs },
+ { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
+ { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
+ { "late", dt_opt_xlate },
+ { "lazyload", dt_opt_lazyload },
+ { "ldpath", dt_opt_ld_path },
+ { "libdir", dt_opt_libdir },
+ { "linkmode", dt_opt_linkmode },
+ { "linktype", dt_opt_linktype },
+ { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
+ { "pgmax", dt_opt_pgmax },
+ { "preallocate", dt_opt_preallocate },
+ { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
+ { "stdc", dt_opt_stdc },
+ { "strip", dt_opt_dflags, DTRACE_D_STRIP },
+ { "syslibdir", dt_opt_syslibdir },
+ { "tree", dt_opt_tree },
+ { "tregs", dt_opt_tregs },
+ { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
+ { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
+ { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
+ { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
+ { "version", dt_opt_version },
+ { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
+ { NULL, NULL, 0 }
+};
+
+/*
+ * Run-time options.
+ */
+static const dt_option_t _dtrace_rtoptions[] = {
+ { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
+ { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
+ { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
+ { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
+ { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
+ { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
+ { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
+ { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
+ { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
+ { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
+ { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
+ { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
+ { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
+ { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
+ { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
+ { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
+ { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
+ { NULL, NULL, 0 }
+};
+
+/*
+ * Dynamic run-time options.
+ */
+static const dt_option_t _dtrace_drtoptions[] = {
+ { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
+ { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
+ { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
+ { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
+ { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
+ { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
+ { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
+ { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
+ { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
+ { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
+ { NULL, NULL, 0 }
+};
+
+int
+dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
+{
+ const dt_option_t *op;
+
+ if (opt == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ /*
+ * We only need to search the run-time options -- it's not legal
+ * to get the values of compile-time options.
+ */
+ for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
+ if (strcmp(op->o_name, opt) == 0) {
+ *val = dtp->dt_options[op->o_option];
+ return (0);
+ }
+ }
+
+ for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
+ if (strcmp(op->o_name, opt) == 0) {
+ *val = dtp->dt_options[op->o_option];
+ return (0);
+ }
+ }
+
+ return (dt_set_errno(dtp, EDT_BADOPTNAME));
+}
+
+int
+dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
+{
+ const dt_option_t *op;
+
+ if (opt == NULL)
+ return (dt_set_errno(dtp, EINVAL));
+
+ for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
+ if (strcmp(op->o_name, opt) == 0)
+ return (op->o_func(dtp, val, op->o_option));
+ }
+
+ for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
+ if (strcmp(op->o_name, opt) == 0)
+ return (op->o_func(dtp, val, op->o_option));
+ }
+
+ for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
+ if (strcmp(op->o_name, opt) == 0) {
+ /*
+ * Only dynamic run-time options may be set while
+ * tracing is active.
+ */
+ if (dtp->dt_active)
+ return (dt_set_errno(dtp, EDT_ACTIVE));
+
+ return (op->o_func(dtp, val, op->o_option));
+ }
+ }
+
+ return (dt_set_errno(dtp, EDT_BADOPTNAME));
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
new file mode 100644
index 0000000..aafe647
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -0,0 +1,4900 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * DTrace D Language Parser
+ *
+ * The D Parser is a lex/yacc parser consisting of the lexer dt_lex.l, the
+ * parsing grammar dt_grammar.y, and this file, dt_parser.c, which handles
+ * the construction of the parse tree nodes and their syntactic validation.
+ * The parse tree is constructed of dt_node_t structures (see <dt_parser.h>)
+ * that are built in two passes: (1) the "create" pass, where the parse tree
+ * nodes are allocated by calls from the grammar to dt_node_*() subroutines,
+ * and (2) the "cook" pass, where nodes are coalesced, assigned D types, and
+ * validated according to the syntactic rules of the language.
+ *
+ * All node allocations are performed using dt_node_alloc(). All node frees
+ * during the parsing phase are performed by dt_node_free(), which frees node-
+ * internal state but does not actually free the nodes. All final node frees
+ * are done as part of the end of dt_compile() or as part of destroying
+ * persistent identifiers or translators which have embedded nodes.
+ *
+ * The dt_node_* routines that implement pass (1) may allocate new nodes. The
+ * dt_cook_* routines that implement pass (2) may *not* allocate new nodes.
+ * They may free existing nodes using dt_node_free(), but they may not actually
+ * deallocate any dt_node_t's. Currently dt_cook_op2() is an exception to this
+ * rule: see the comments therein for how this issue is resolved.
+ *
+ * The dt_cook_* routines are responsible for (at minimum) setting the final
+ * node type (dn_ctfp/dn_type) and attributes (dn_attr). If dn_ctfp/dn_type
+ * are set manually (i.e. not by one of the type assignment functions), then
+ * the DT_NF_COOKED flag must be set manually on the node.
+ *
+ * The cooking pass can be applied to the same parse tree more than once (used
+ * in the case of a comma-separated list of probe descriptions). As such, the
+ * cook routines must not perform any parse tree transformations which would
+ * be invalid if the tree were subsequently cooked using a different context.
+ *
+ * The dn_ctfp and dn_type fields form the type of the node. This tuple can
+ * take on the following set of values, which form our type invariants:
+ *
+ * 1. dn_ctfp = NULL, dn_type = CTF_ERR
+ *
+ * In this state, the node has unknown type and is not yet cooked. The
+ * DT_NF_COOKED flag is not yet set on the node.
+ *
+ * 2. dn_ctfp = DT_DYN_CTFP(dtp), dn_type = DT_DYN_TYPE(dtp)
+ *
+ * In this state, the node is a dynamic D type. This means that generic
+ * operations are not valid on this node and only code that knows how to
+ * examine the inner details of the node can operate on it. A <DYN> node
+ * must have dn_ident set to point to an identifier describing the object
+ * and its type. The DT_NF_REF flag is set for all nodes of type <DYN>.
+ * At present, the D compiler uses the <DYN> type for:
+ *
+ * - associative arrays that do not yet have a value type defined
+ * - translated data (i.e. the result of the xlate operator)
+ * - aggregations
+ *
+ * 3. dn_ctfp = DT_STR_CTFP(dtp), dn_type = DT_STR_TYPE(dtp)
+ *
+ * In this state, the node is of type D string. The string type is really
+ * a char[0] typedef, but requires special handling throughout the compiler.
+ *
+ * 4. dn_ctfp != NULL, dn_type = any other type ID
+ *
+ * In this state, the node is of some known D/CTF type. The normal libctf
+ * APIs can be used to learn more about the type name or structure. When
+ * the type is assigned, the DT_NF_SIGNED, DT_NF_REF, and DT_NF_BITFIELD
+ * flags cache the corresponding attributes of the underlying CTF type.
+ */
+
+#include <sys/param.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <strings.h>
+#include <assert.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <dt_impl.h>
+#include <dt_grammar.h>
+#include <dt_module.h>
+#include <dt_provider.h>
+#include <dt_string.h>
+#include <dt_as.h>
+
+dt_pcb_t *yypcb; /* current control block for parser */
+dt_node_t *yypragma; /* lex token list for control lines */
+char yyintprefix; /* int token macro prefix (+/-) */
+char yyintsuffix[4]; /* int token suffix string [uU][lL] */
+int yyintdecimal; /* int token format flag (1=decimal, 0=octal/hex) */
+
+static const char *
+opstr(int op)
+{
+ switch (op) {
+ case DT_TOK_COMMA: return (",");
+ case DT_TOK_ELLIPSIS: return ("...");
+ case DT_TOK_ASGN: return ("=");
+ case DT_TOK_ADD_EQ: return ("+=");
+ case DT_TOK_SUB_EQ: return ("-=");
+ case DT_TOK_MUL_EQ: return ("*=");
+ case DT_TOK_DIV_EQ: return ("/=");
+ case DT_TOK_MOD_EQ: return ("%=");
+ case DT_TOK_AND_EQ: return ("&=");
+ case DT_TOK_XOR_EQ: return ("^=");
+ case DT_TOK_OR_EQ: return ("|=");
+ case DT_TOK_LSH_EQ: return ("<<=");
+ case DT_TOK_RSH_EQ: return (">>=");
+ case DT_TOK_QUESTION: return ("?");
+ case DT_TOK_COLON: return (":");
+ case DT_TOK_LOR: return ("||");
+ case DT_TOK_LXOR: return ("^^");
+ case DT_TOK_LAND: return ("&&");
+ case DT_TOK_BOR: return ("|");
+ case DT_TOK_XOR: return ("^");
+ case DT_TOK_BAND: return ("&");
+ case DT_TOK_EQU: return ("==");
+ case DT_TOK_NEQ: return ("!=");
+ case DT_TOK_LT: return ("<");
+ case DT_TOK_LE: return ("<=");
+ case DT_TOK_GT: return (">");
+ case DT_TOK_GE: return (">=");
+ case DT_TOK_LSH: return ("<<");
+ case DT_TOK_RSH: return (">>");
+ case DT_TOK_ADD: return ("+");
+ case DT_TOK_SUB: return ("-");
+ case DT_TOK_MUL: return ("*");
+ case DT_TOK_DIV: return ("/");
+ case DT_TOK_MOD: return ("%");
+ case DT_TOK_LNEG: return ("!");
+ case DT_TOK_BNEG: return ("~");
+ case DT_TOK_ADDADD: return ("++");
+ case DT_TOK_PREINC: return ("++");
+ case DT_TOK_POSTINC: return ("++");
+ case DT_TOK_SUBSUB: return ("--");
+ case DT_TOK_PREDEC: return ("--");
+ case DT_TOK_POSTDEC: return ("--");
+ case DT_TOK_IPOS: return ("+");
+ case DT_TOK_INEG: return ("-");
+ case DT_TOK_DEREF: return ("*");
+ case DT_TOK_ADDROF: return ("&");
+ case DT_TOK_OFFSETOF: return ("offsetof");
+ case DT_TOK_SIZEOF: return ("sizeof");
+ case DT_TOK_STRINGOF: return ("stringof");
+ case DT_TOK_XLATE: return ("xlate");
+ case DT_TOK_LPAR: return ("(");
+ case DT_TOK_RPAR: return (")");
+ case DT_TOK_LBRAC: return ("[");
+ case DT_TOK_RBRAC: return ("]");
+ case DT_TOK_PTR: return ("->");
+ case DT_TOK_DOT: return (".");
+ case DT_TOK_STRING: return ("<string>");
+ case DT_TOK_IDENT: return ("<ident>");
+ case DT_TOK_TNAME: return ("<type>");
+ case DT_TOK_INT: return ("<int>");
+ default: return ("<?>");
+ }
+}
+
+int
+dt_type_lookup(const char *s, dtrace_typeinfo_t *tip)
+{
+ static const char delimiters[] = " \t\n\r\v\f*`";
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ const char *p, *q, *end, *obj;
+
+ for (p = s, end = s + strlen(s); *p != '\0'; p = q) {
+ while (isspace(*p))
+ p++; /* skip leading whitespace prior to token */
+
+ if (p == end || (q = strpbrk(p + 1, delimiters)) == NULL)
+ break; /* empty string or single token remaining */
+
+ if (*q == '`') {
+ char *object = alloca((size_t)(q - p) + 1);
+ char *type = alloca((size_t)(end - s) + 1);
+
+ /*
+ * Copy from the start of the token (p) to the location
+ * backquote (q) to extract the nul-terminated object.
+ */
+ bcopy(p, object, (size_t)(q - p));
+ object[(size_t)(q - p)] = '\0';
+
+ /*
+ * Copy the original string up to the start of this
+ * token (p) into type, and then concatenate everything
+ * after q. This is the type name without the object.
+ */
+ bcopy(s, type, (size_t)(p - s));
+ bcopy(q + 1, type + (size_t)(p - s), strlen(q + 1) + 1);
+
+ if (strchr(q + 1, '`') != NULL)
+ return (dt_set_errno(dtp, EDT_BADSCOPE));
+
+ return (dtrace_lookup_by_type(dtp, object, type, tip));
+ }
+ }
+
+ if (yypcb->pcb_idepth != 0)
+ obj = DTRACE_OBJ_CDEFS;
+ else
+ obj = DTRACE_OBJ_EVERY;
+
+ return (dtrace_lookup_by_type(dtp, obj, s, tip));
+}
+
+/*
+ * When we parse type expressions or parse an expression with unary "&", we
+ * need to find a type that is a pointer to a previously known type.
+ * Unfortunately CTF is limited to a per-container view, so ctf_type_pointer()
+ * alone does not suffice for our needs. We provide a more intelligent wrapper
+ * for the compiler that attempts to compute a pointer to either the given type
+ * or its base (that is, we try both "foo_t *" and "struct foo *"), and also
+ * to potentially construct the required type on-the-fly.
+ */
+int
+dt_type_pointer(dtrace_typeinfo_t *tip)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ ctf_file_t *ctfp = tip->dtt_ctfp;
+ ctf_id_t type = tip->dtt_type;
+ ctf_id_t base = ctf_type_resolve(ctfp, type);
+
+ dt_module_t *dmp;
+ ctf_id_t ptr;
+
+ if ((ptr = ctf_type_pointer(ctfp, type)) != CTF_ERR ||
+ (ptr = ctf_type_pointer(ctfp, base)) != CTF_ERR) {
+ tip->dtt_type = ptr;
+ return (0);
+ }
+
+ if (yypcb->pcb_idepth != 0)
+ dmp = dtp->dt_cdefs;
+ else
+ dmp = dtp->dt_ddefs;
+
+ if (ctfp != dmp->dm_ctfp && ctfp != ctf_parent_file(dmp->dm_ctfp) &&
+ (type = ctf_add_type(dmp->dm_ctfp, ctfp, type)) == CTF_ERR) {
+ dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
+ return (dt_set_errno(dtp, EDT_CTF));
+ }
+
+ ptr = ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, type);
+
+ if (ptr == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
+ dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
+ return (dt_set_errno(dtp, EDT_CTF));
+ }
+
+ tip->dtt_object = dmp->dm_name;
+ tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_type = ptr;
+
+ return (0);
+}
+
+const char *
+dt_type_name(ctf_file_t *ctfp, ctf_id_t type, char *buf, size_t len)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ if (ctfp == DT_FPTR_CTFP(dtp) && type == DT_FPTR_TYPE(dtp))
+ (void) snprintf(buf, len, "function pointer");
+ else if (ctfp == DT_FUNC_CTFP(dtp) && type == DT_FUNC_TYPE(dtp))
+ (void) snprintf(buf, len, "function");
+ else if (ctfp == DT_DYN_CTFP(dtp) && type == DT_DYN_TYPE(dtp))
+ (void) snprintf(buf, len, "dynamic variable");
+ else if (ctfp == NULL)
+ (void) snprintf(buf, len, "<none>");
+ else if (ctf_type_name(ctfp, type, buf, len) == NULL)
+ (void) snprintf(buf, len, "unknown");
+
+ return (buf);
+}
+
+/*
+ * Perform the "usual arithmetic conversions" to determine which of the two
+ * input operand types should be promoted and used as a result type. The
+ * rules for this are described in ISOC[6.3.1.8] and K&R[A6.5].
+ */
+static void
+dt_type_promote(dt_node_t *lp, dt_node_t *rp, ctf_file_t **ofp, ctf_id_t *otype)
+{
+ ctf_file_t *lfp = lp->dn_ctfp;
+ ctf_id_t ltype = lp->dn_type;
+
+ ctf_file_t *rfp = rp->dn_ctfp;
+ ctf_id_t rtype = rp->dn_type;
+
+ ctf_id_t lbase = ctf_type_resolve(lfp, ltype);
+ uint_t lkind = ctf_type_kind(lfp, lbase);
+
+ ctf_id_t rbase = ctf_type_resolve(rfp, rtype);
+ uint_t rkind = ctf_type_kind(rfp, rbase);
+
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ ctf_encoding_t le, re;
+ uint_t lrank, rrank;
+
+ assert(lkind == CTF_K_INTEGER || lkind == CTF_K_ENUM);
+ assert(rkind == CTF_K_INTEGER || rkind == CTF_K_ENUM);
+
+ if (lkind == CTF_K_ENUM) {
+ lfp = DT_INT_CTFP(dtp);
+ ltype = lbase = DT_INT_TYPE(dtp);
+ }
+
+ if (rkind == CTF_K_ENUM) {
+ rfp = DT_INT_CTFP(dtp);
+ rtype = rbase = DT_INT_TYPE(dtp);
+ }
+
+ if (ctf_type_encoding(lfp, lbase, &le) == CTF_ERR) {
+ yypcb->pcb_hdl->dt_ctferr = ctf_errno(lfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+
+ if (ctf_type_encoding(rfp, rbase, &re) == CTF_ERR) {
+ yypcb->pcb_hdl->dt_ctferr = ctf_errno(rfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ }
+
+ /*
+ * Compute an integer rank based on the size and unsigned status.
+ * If rank is identical, pick the "larger" of the equivalent types
+ * which we define as having a larger base ctf_id_t. If rank is
+ * different, pick the type with the greater rank.
+ */
+ lrank = le.cte_bits + ((le.cte_format & CTF_INT_SIGNED) == 0);
+ rrank = re.cte_bits + ((re.cte_format & CTF_INT_SIGNED) == 0);
+
+ if (lrank == rrank) {
+ if (lbase - rbase < 0)
+ goto return_rtype;
+ else
+ goto return_ltype;
+ } else if (lrank > rrank) {
+ goto return_ltype;
+ } else
+ goto return_rtype;
+
+return_ltype:
+ *ofp = lfp;
+ *otype = ltype;
+ return;
+
+return_rtype:
+ *ofp = rfp;
+ *otype = rtype;
+}
+
+void
+dt_node_promote(dt_node_t *lp, dt_node_t *rp, dt_node_t *dnp)
+{
+ dt_type_promote(lp, rp, &dnp->dn_ctfp, &dnp->dn_type);
+ dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type);
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+}
+
+const char *
+dt_node_name(const dt_node_t *dnp, char *buf, size_t len)
+{
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ const char *prefix = "", *suffix = "";
+ const dtrace_syminfo_t *dts;
+ char *s;
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_INT:
+ (void) snprintf(buf, len, "integer constant 0x%llx",
+ (u_longlong_t)dnp->dn_value);
+ break;
+ case DT_NODE_STRING:
+ s = strchr2esc(dnp->dn_string, strlen(dnp->dn_string));
+ (void) snprintf(buf, len, "string constant \"%s\"",
+ s != NULL ? s : dnp->dn_string);
+ free(s);
+ break;
+ case DT_NODE_IDENT:
+ (void) snprintf(buf, len, "identifier %s", dnp->dn_string);
+ break;
+ case DT_NODE_VAR:
+ case DT_NODE_FUNC:
+ case DT_NODE_AGG:
+ case DT_NODE_INLINE:
+ switch (dnp->dn_ident->di_kind) {
+ case DT_IDENT_FUNC:
+ case DT_IDENT_AGGFUNC:
+ case DT_IDENT_ACTFUNC:
+ suffix = "( )";
+ break;
+ case DT_IDENT_AGG:
+ prefix = "@";
+ break;
+ }
+ (void) snprintf(buf, len, "%s %s%s%s",
+ dt_idkind_name(dnp->dn_ident->di_kind),
+ prefix, dnp->dn_ident->di_name, suffix);
+ break;
+ case DT_NODE_SYM:
+ dts = dnp->dn_ident->di_data;
+ (void) snprintf(buf, len, "symbol %s`%s",
+ dts->dts_object, dts->dts_name);
+ break;
+ case DT_NODE_TYPE:
+ (void) snprintf(buf, len, "type %s",
+ dt_node_type_name(dnp, n1, sizeof (n1)));
+ break;
+ case DT_NODE_OP1:
+ case DT_NODE_OP2:
+ case DT_NODE_OP3:
+ (void) snprintf(buf, len, "operator %s", opstr(dnp->dn_op));
+ break;
+ case DT_NODE_DEXPR:
+ case DT_NODE_DFUNC:
+ if (dnp->dn_expr)
+ return (dt_node_name(dnp->dn_expr, buf, len));
+ (void) snprintf(buf, len, "%s", "statement");
+ break;
+ case DT_NODE_PDESC:
+ if (dnp->dn_desc->dtpd_id == 0) {
+ (void) snprintf(buf, len,
+ "probe description %s:%s:%s:%s",
+ dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod,
+ dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name);
+ } else {
+ (void) snprintf(buf, len, "probe description %u",
+ dnp->dn_desc->dtpd_id);
+ }
+ break;
+ case DT_NODE_CLAUSE:
+ (void) snprintf(buf, len, "%s", "clause");
+ break;
+ case DT_NODE_MEMBER:
+ (void) snprintf(buf, len, "member %s", dnp->dn_membname);
+ break;
+ case DT_NODE_XLATOR:
+ (void) snprintf(buf, len, "translator <%s> (%s)",
+ dt_type_name(dnp->dn_xlator->dx_dst_ctfp,
+ dnp->dn_xlator->dx_dst_type, n1, sizeof (n1)),
+ dt_type_name(dnp->dn_xlator->dx_src_ctfp,
+ dnp->dn_xlator->dx_src_type, n2, sizeof (n2)));
+ break;
+ case DT_NODE_PROG:
+ (void) snprintf(buf, len, "%s", "program");
+ break;
+ default:
+ (void) snprintf(buf, len, "node <%u>", dnp->dn_kind);
+ break;
+ }
+
+ return (buf);
+}
+
+/*
+ * dt_node_xalloc() can be used to create new parse nodes from any libdtrace
+ * caller. The caller is responsible for assigning dn_link appropriately.
+ */
+dt_node_t *
+dt_node_xalloc(dtrace_hdl_t *dtp, int kind)
+{
+ dt_node_t *dnp = dt_alloc(dtp, sizeof (dt_node_t));
+
+ if (dnp == NULL)
+ return (NULL);
+
+ dnp->dn_ctfp = NULL;
+ dnp->dn_type = CTF_ERR;
+ dnp->dn_kind = (uchar_t)kind;
+ dnp->dn_flags = 0;
+ dnp->dn_op = 0;
+ dnp->dn_line = -1;
+ dnp->dn_reg = -1;
+ dnp->dn_attr = _dtrace_defattr;
+ dnp->dn_list = NULL;
+ dnp->dn_link = NULL;
+ bzero(&dnp->dn_u, sizeof (dnp->dn_u));
+
+ return (dnp);
+}
+
+/*
+ * dt_node_alloc() is used to create new parse nodes from the parser. It
+ * assigns the node location based on the current lexer line number and places
+ * the new node on the default allocation list. If allocation fails, we
+ * automatically longjmp the caller back to the enclosing compilation call.
+ */
+static dt_node_t *
+dt_node_alloc(int kind)
+{
+ dt_node_t *dnp = dt_node_xalloc(yypcb->pcb_hdl, kind);
+
+ if (dnp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dnp->dn_line = yylineno;
+ dnp->dn_link = yypcb->pcb_list;
+ yypcb->pcb_list = dnp;
+
+ return (dnp);
+}
+
+void
+dt_node_free(dt_node_t *dnp)
+{
+ uchar_t kind = dnp->dn_kind;
+
+ dnp->dn_kind = DT_NODE_FREE;
+
+ switch (kind) {
+ case DT_NODE_STRING:
+ case DT_NODE_IDENT:
+ case DT_NODE_TYPE:
+ free(dnp->dn_string);
+ dnp->dn_string = NULL;
+ break;
+
+ case DT_NODE_VAR:
+ case DT_NODE_FUNC:
+ case DT_NODE_PROBE:
+ if (dnp->dn_ident != NULL) {
+ if (dnp->dn_ident->di_flags & DT_IDFLG_ORPHAN)
+ dt_ident_destroy(dnp->dn_ident);
+ dnp->dn_ident = NULL;
+ }
+ dt_node_list_free(&dnp->dn_args);
+ break;
+
+ case DT_NODE_OP1:
+ if (dnp->dn_child != NULL) {
+ dt_node_free(dnp->dn_child);
+ dnp->dn_child = NULL;
+ }
+ break;
+
+ case DT_NODE_OP3:
+ if (dnp->dn_expr != NULL) {
+ dt_node_free(dnp->dn_expr);
+ dnp->dn_expr = NULL;
+ }
+ /*FALLTHRU*/
+ case DT_NODE_OP2:
+ if (dnp->dn_left != NULL) {
+ dt_node_free(dnp->dn_left);
+ dnp->dn_left = NULL;
+ }
+ if (dnp->dn_right != NULL) {
+ dt_node_free(dnp->dn_right);
+ dnp->dn_right = NULL;
+ }
+ break;
+
+ case DT_NODE_DEXPR:
+ case DT_NODE_DFUNC:
+ if (dnp->dn_expr != NULL) {
+ dt_node_free(dnp->dn_expr);
+ dnp->dn_expr = NULL;
+ }
+ break;
+
+ case DT_NODE_AGG:
+ if (dnp->dn_aggfun != NULL) {
+ dt_node_free(dnp->dn_aggfun);
+ dnp->dn_aggfun = NULL;
+ }
+ dt_node_list_free(&dnp->dn_aggtup);
+ break;
+
+ case DT_NODE_PDESC:
+ free(dnp->dn_spec);
+ dnp->dn_spec = NULL;
+ free(dnp->dn_desc);
+ dnp->dn_desc = NULL;
+ break;
+
+ case DT_NODE_CLAUSE:
+ if (dnp->dn_pred != NULL)
+ dt_node_free(dnp->dn_pred);
+ if (dnp->dn_locals != NULL)
+ dt_idhash_destroy(dnp->dn_locals);
+ dt_node_list_free(&dnp->dn_pdescs);
+ dt_node_list_free(&dnp->dn_acts);
+ break;
+
+ case DT_NODE_MEMBER:
+ free(dnp->dn_membname);
+ dnp->dn_membname = NULL;
+ if (dnp->dn_membexpr != NULL) {
+ dt_node_free(dnp->dn_membexpr);
+ dnp->dn_membexpr = NULL;
+ }
+ break;
+
+ case DT_NODE_PROVIDER:
+ dt_node_list_free(&dnp->dn_probes);
+ free(dnp->dn_provname);
+ dnp->dn_provname = NULL;
+ break;
+
+ case DT_NODE_PROG:
+ dt_node_list_free(&dnp->dn_list);
+ break;
+ }
+}
+
+void
+dt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr)
+{
+ if ((yypcb->pcb_cflags & DTRACE_C_EATTR) &&
+ (dt_attr_cmp(attr, yypcb->pcb_amin) < 0)) {
+ char a[DTRACE_ATTR2STR_MAX];
+ char s[BUFSIZ];
+
+ dnerror(dnp, D_ATTR_MIN, "attributes for %s (%s) are less than "
+ "predefined minimum\n", dt_node_name(dnp, s, sizeof (s)),
+ dtrace_attr2str(attr, a, sizeof (a)));
+ }
+
+ dnp->dn_attr = attr;
+}
+
+void
+dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type)
+{
+ ctf_id_t base = ctf_type_resolve(fp, type);
+ uint_t kind = ctf_type_kind(fp, base);
+ ctf_encoding_t e;
+
+ dnp->dn_flags &=
+ ~(DT_NF_SIGNED | DT_NF_REF | DT_NF_BITFIELD | DT_NF_USERLAND);
+
+ if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, base, &e) == 0) {
+ size_t size = e.cte_bits / NBBY;
+
+ if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)))
+ dnp->dn_flags |= DT_NF_BITFIELD;
+
+ if (e.cte_format & CTF_INT_SIGNED)
+ dnp->dn_flags |= DT_NF_SIGNED;
+ }
+
+ if (kind == CTF_K_FLOAT && ctf_type_encoding(fp, base, &e) == 0) {
+ if (e.cte_bits / NBBY > sizeof (uint64_t))
+ dnp->dn_flags |= DT_NF_REF;
+ }
+
+ if (kind == CTF_K_STRUCT || kind == CTF_K_UNION ||
+ kind == CTF_K_FORWARD ||
+ kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION)
+ dnp->dn_flags |= DT_NF_REF;
+ else if (yypcb != NULL && fp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
+ type == DT_DYN_TYPE(yypcb->pcb_hdl))
+ dnp->dn_flags |= DT_NF_REF;
+
+ dnp->dn_flags |= DT_NF_COOKED;
+ dnp->dn_ctfp = fp;
+ dnp->dn_type = type;
+}
+
+void
+dt_node_type_propagate(const dt_node_t *src, dt_node_t *dst)
+{
+ assert(src->dn_flags & DT_NF_COOKED);
+ dst->dn_flags = src->dn_flags & ~DT_NF_LVALUE;
+ dst->dn_ctfp = src->dn_ctfp;
+ dst->dn_type = src->dn_type;
+}
+
+const char *
+dt_node_type_name(const dt_node_t *dnp, char *buf, size_t len)
+{
+ if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) {
+ (void) snprintf(buf, len, "%s",
+ dt_idkind_name(dt_ident_resolve(dnp->dn_ident)->di_kind));
+ return (buf);
+ }
+
+ if (dnp->dn_flags & DT_NF_USERLAND) {
+ size_t n = snprintf(buf, len, "userland ");
+ len = len > n ? len - n : 0;
+ (void) dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf + n, len);
+ return (buf);
+ }
+
+ return (dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf, len));
+}
+
+size_t
+dt_node_type_size(const dt_node_t *dnp)
+{
+ ctf_id_t base;
+
+ if (dnp->dn_kind == DT_NODE_STRING)
+ return (strlen(dnp->dn_string) + 1);
+
+ if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL)
+ return (dt_ident_size(dnp->dn_ident));
+
+ base = ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type);
+
+ if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_FORWARD)
+ return (0);
+
+ return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type));
+}
+
+/*
+ * Determine if the specified parse tree node references an identifier of the
+ * specified kind, and if so return a pointer to it; otherwise return NULL.
+ * This function resolves the identifier itself, following through any inlines.
+ */
+dt_ident_t *
+dt_node_resolve(const dt_node_t *dnp, uint_t idkind)
+{
+ dt_ident_t *idp;
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_VAR:
+ case DT_NODE_SYM:
+ case DT_NODE_FUNC:
+ case DT_NODE_AGG:
+ case DT_NODE_INLINE:
+ case DT_NODE_PROBE:
+ idp = dt_ident_resolve(dnp->dn_ident);
+ return (idp->di_kind == idkind ? idp : NULL);
+ }
+
+ if (dt_node_is_dynamic(dnp)) {
+ idp = dt_ident_resolve(dnp->dn_ident);
+ return (idp->di_kind == idkind ? idp : NULL);
+ }
+
+ return (NULL);
+}
+
+size_t
+dt_node_sizeof(const dt_node_t *dnp)
+{
+ dtrace_syminfo_t *sip;
+ GElf_Sym sym;
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ /*
+ * The size of the node as used for the sizeof() operator depends on
+ * the kind of the node. If the node is a SYM, the size is obtained
+ * from the symbol table; if it is not a SYM, the size is determined
+ * from the node's type. This is slightly different from C's sizeof()
+ * operator in that (for example) when applied to a function, sizeof()
+ * will evaluate to the length of the function rather than the size of
+ * the function type.
+ */
+ if (dnp->dn_kind != DT_NODE_SYM)
+ return (dt_node_type_size(dnp));
+
+ sip = dnp->dn_ident->di_data;
+
+ if (dtrace_lookup_by_name(dtp, sip->dts_object,
+ sip->dts_name, &sym, NULL) == -1)
+ return (0);
+
+ return (sym.st_size);
+}
+
+int
+dt_node_is_integer(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+ kind = ctf_type_kind(fp, type);
+
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e))
+ return (0); /* void integer */
+
+ return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM);
+}
+
+int
+dt_node_is_float(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+ kind = ctf_type_kind(fp, type);
+
+ return (kind == CTF_K_FLOAT &&
+ ctf_type_encoding(dnp->dn_ctfp, type, &e) == 0 && (
+ e.cte_format == CTF_FP_SINGLE || e.cte_format == CTF_FP_DOUBLE ||
+ e.cte_format == CTF_FP_LDOUBLE));
+}
+
+int
+dt_node_is_scalar(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+ kind = ctf_type_kind(fp, type);
+
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e))
+ return (0); /* void cannot be used as a scalar */
+
+ return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM ||
+ kind == CTF_K_POINTER);
+}
+
+int
+dt_node_is_arith(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+ kind = ctf_type_kind(fp, type);
+
+ if (kind == CTF_K_INTEGER)
+ return (ctf_type_encoding(fp, type, &e) == 0 && !IS_VOID(e));
+ else
+ return (kind == CTF_K_ENUM);
+}
+
+int
+dt_node_is_vfptr(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+ if (ctf_type_kind(fp, type) != CTF_K_POINTER)
+ return (0); /* type is not a pointer */
+
+ type = ctf_type_resolve(fp, ctf_type_reference(fp, type));
+ kind = ctf_type_kind(fp, type);
+
+ return (kind == CTF_K_FUNCTION || (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)));
+}
+
+int
+dt_node_is_dynamic(const dt_node_t *dnp)
+{
+ if (dnp->dn_kind == DT_NODE_VAR &&
+ (dnp->dn_ident->di_flags & DT_IDFLG_INLINE)) {
+ const dt_idnode_t *inp = dnp->dn_ident->di_iarg;
+ return (inp->din_root ? dt_node_is_dynamic(inp->din_root) : 0);
+ }
+
+ return (dnp->dn_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
+ dnp->dn_type == DT_DYN_TYPE(yypcb->pcb_hdl));
+}
+
+int
+dt_node_is_string(const dt_node_t *dnp)
+{
+ return (dnp->dn_ctfp == DT_STR_CTFP(yypcb->pcb_hdl) &&
+ dnp->dn_type == DT_STR_TYPE(yypcb->pcb_hdl));
+}
+
+int
+dt_node_is_stack(const dt_node_t *dnp)
+{
+ return (dnp->dn_ctfp == DT_STACK_CTFP(yypcb->pcb_hdl) &&
+ dnp->dn_type == DT_STACK_TYPE(yypcb->pcb_hdl));
+}
+
+int
+dt_node_is_symaddr(const dt_node_t *dnp)
+{
+ return (dnp->dn_ctfp == DT_SYMADDR_CTFP(yypcb->pcb_hdl) &&
+ dnp->dn_type == DT_SYMADDR_TYPE(yypcb->pcb_hdl));
+}
+
+int
+dt_node_is_usymaddr(const dt_node_t *dnp)
+{
+ return (dnp->dn_ctfp == DT_USYMADDR_CTFP(yypcb->pcb_hdl) &&
+ dnp->dn_type == DT_USYMADDR_TYPE(yypcb->pcb_hdl));
+}
+
+int
+dt_node_is_strcompat(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_arinfo_t r;
+ ctf_id_t base;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ base = ctf_type_resolve(fp, dnp->dn_type);
+ kind = ctf_type_kind(fp, base);
+
+ if (kind == CTF_K_POINTER &&
+ (base = ctf_type_reference(fp, base)) != CTF_ERR &&
+ (base = ctf_type_resolve(fp, base)) != CTF_ERR &&
+ ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e))
+ return (1); /* promote char pointer to string */
+
+ if (kind == CTF_K_ARRAY && ctf_array_info(fp, base, &r) == 0 &&
+ (base = ctf_type_resolve(fp, r.ctr_contents)) != CTF_ERR &&
+ ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e))
+ return (1); /* promote char array to string */
+
+ return (0);
+}
+
+int
+dt_node_is_pointer(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ uint_t kind;
+
+ assert(dnp->dn_flags & DT_NF_COOKED);
+
+ if (dt_node_is_string(dnp))
+ return (0); /* string are pass-by-ref but act like structs */
+
+ kind = ctf_type_kind(fp, ctf_type_resolve(fp, dnp->dn_type));
+ return (kind == CTF_K_POINTER || kind == CTF_K_ARRAY);
+}
+
+int
+dt_node_is_void(const dt_node_t *dnp)
+{
+ ctf_file_t *fp = dnp->dn_ctfp;
+ ctf_encoding_t e;
+ ctf_id_t type;
+
+ if (dt_node_is_dynamic(dnp))
+ return (0); /* <DYN> is an alias for void but not the same */
+
+ if (dt_node_is_stack(dnp))
+ return (0);
+
+ if (dt_node_is_symaddr(dnp) || dt_node_is_usymaddr(dnp))
+ return (0);
+
+ type = ctf_type_resolve(fp, dnp->dn_type);
+
+ return (ctf_type_kind(fp, type) == CTF_K_INTEGER &&
+ ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e));
+}
+
+int
+dt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp,
+ ctf_file_t **fpp, ctf_id_t *tp)
+{
+ ctf_file_t *lfp = lp->dn_ctfp;
+ ctf_file_t *rfp = rp->dn_ctfp;
+
+ ctf_id_t lbase = CTF_ERR, rbase = CTF_ERR;
+ ctf_id_t lref = CTF_ERR, rref = CTF_ERR;
+
+ int lp_is_void, rp_is_void, lp_is_int, rp_is_int, compat;
+ uint_t lkind, rkind;
+ ctf_encoding_t e;
+ ctf_arinfo_t r;
+
+ assert(lp->dn_flags & DT_NF_COOKED);
+ assert(rp->dn_flags & DT_NF_COOKED);
+
+ if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp))
+ return (0); /* fail if either node is a dynamic variable */
+
+ lp_is_int = dt_node_is_integer(lp);
+ rp_is_int = dt_node_is_integer(rp);
+
+ if (lp_is_int && rp_is_int)
+ return (0); /* fail if both nodes are integers */
+
+ if (lp_is_int && (lp->dn_kind != DT_NODE_INT || lp->dn_value != 0))
+ return (0); /* fail if lp is an integer that isn't 0 constant */
+
+ if (rp_is_int && (rp->dn_kind != DT_NODE_INT || rp->dn_value != 0))
+ return (0); /* fail if rp is an integer that isn't 0 constant */
+
+ if ((lp_is_int == 0 && rp_is_int == 0) && (
+ (lp->dn_flags & DT_NF_USERLAND) ^ (rp->dn_flags & DT_NF_USERLAND)))
+ return (0); /* fail if only one pointer is a userland address */
+
+ /*
+ * Resolve the left-hand and right-hand types to their base type, and
+ * then resolve the referenced type as well (assuming the base type
+ * is CTF_K_POINTER or CTF_K_ARRAY). Otherwise [lr]ref = CTF_ERR.
+ */
+ if (!lp_is_int) {
+ lbase = ctf_type_resolve(lfp, lp->dn_type);
+ lkind = ctf_type_kind(lfp, lbase);
+
+ if (lkind == CTF_K_POINTER) {
+ lref = ctf_type_resolve(lfp,
+ ctf_type_reference(lfp, lbase));
+ } else if (lkind == CTF_K_ARRAY &&
+ ctf_array_info(lfp, lbase, &r) == 0) {
+ lref = ctf_type_resolve(lfp, r.ctr_contents);
+ }
+ }
+
+ if (!rp_is_int) {
+ rbase = ctf_type_resolve(rfp, rp->dn_type);
+ rkind = ctf_type_kind(rfp, rbase);
+
+ if (rkind == CTF_K_POINTER) {
+ rref = ctf_type_resolve(rfp,
+ ctf_type_reference(rfp, rbase));
+ } else if (rkind == CTF_K_ARRAY &&
+ ctf_array_info(rfp, rbase, &r) == 0) {
+ rref = ctf_type_resolve(rfp, r.ctr_contents);
+ }
+ }
+
+ /*
+ * We know that one or the other type may still be a zero-valued
+ * integer constant. To simplify the code below, set the integer
+ * type variables equal to the non-integer types and proceed.
+ */
+ if (lp_is_int) {
+ lbase = rbase;
+ lkind = rkind;
+ lref = rref;
+ lfp = rfp;
+ } else if (rp_is_int) {
+ rbase = lbase;
+ rkind = lkind;
+ rref = lref;
+ rfp = lfp;
+ }
+
+ lp_is_void = ctf_type_encoding(lfp, lref, &e) == 0 && IS_VOID(e);
+ rp_is_void = ctf_type_encoding(rfp, rref, &e) == 0 && IS_VOID(e);
+
+ /*
+ * The types are compatible if both are pointers to the same type, or
+ * if either pointer is a void pointer. If they are compatible, set
+ * tp to point to the more specific pointer type and return it.
+ */
+ compat = (lkind == CTF_K_POINTER || lkind == CTF_K_ARRAY) &&
+ (rkind == CTF_K_POINTER || rkind == CTF_K_ARRAY) &&
+ (lp_is_void || rp_is_void || ctf_type_compat(lfp, lref, rfp, rref));
+
+ if (compat) {
+ if (fpp != NULL)
+ *fpp = rp_is_void ? lfp : rfp;
+ if (tp != NULL)
+ *tp = rp_is_void ? lbase : rbase;
+ }
+
+ return (compat);
+}
+
+/*
+ * The rules for checking argument types against parameter types are described
+ * in the ANSI-C spec (see K&R[A7.3.2] and K&R[A7.17]). We use the same rule
+ * set to determine whether associative array arguments match the prototype.
+ */
+int
+dt_node_is_argcompat(const dt_node_t *lp, const dt_node_t *rp)
+{
+ ctf_file_t *lfp = lp->dn_ctfp;
+ ctf_file_t *rfp = rp->dn_ctfp;
+
+ assert(lp->dn_flags & DT_NF_COOKED);
+ assert(rp->dn_flags & DT_NF_COOKED);
+
+ if (dt_node_is_integer(lp) && dt_node_is_integer(rp))
+ return (1); /* integer types are compatible */
+
+ if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp))
+ return (1); /* string types are compatible */
+
+ if (dt_node_is_stack(lp) && dt_node_is_stack(rp))
+ return (1); /* stack types are compatible */
+
+ if (dt_node_is_symaddr(lp) && dt_node_is_symaddr(rp))
+ return (1); /* symaddr types are compatible */
+
+ if (dt_node_is_usymaddr(lp) && dt_node_is_usymaddr(rp))
+ return (1); /* usymaddr types are compatible */
+
+ switch (ctf_type_kind(lfp, ctf_type_resolve(lfp, lp->dn_type))) {
+ case CTF_K_FUNCTION:
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ return (ctf_type_compat(lfp, lp->dn_type, rfp, rp->dn_type));
+ default:
+ return (dt_node_is_ptrcompat(lp, rp, NULL, NULL));
+ }
+}
+
+/*
+ * We provide dt_node_is_posconst() as a convenience routine for callers who
+ * wish to verify that an argument is a positive non-zero integer constant.
+ */
+int
+dt_node_is_posconst(const dt_node_t *dnp)
+{
+ return (dnp->dn_kind == DT_NODE_INT && dnp->dn_value != 0 && (
+ (dnp->dn_flags & DT_NF_SIGNED) == 0 || (int64_t)dnp->dn_value > 0));
+}
+
+int
+dt_node_is_actfunc(const dt_node_t *dnp)
+{
+ return (dnp->dn_kind == DT_NODE_FUNC &&
+ dnp->dn_ident->di_kind == DT_IDENT_ACTFUNC);
+}
+
+/*
+ * The original rules for integer constant typing are described in K&R[A2.5.1].
+ * However, since we support long long, we instead use the rules from ISO C99
+ * clause 6.4.4.1 since that is where long longs are formally described. The
+ * rules require us to know whether the constant was specified in decimal or
+ * in octal or hex, which we do by looking at our lexer's 'yyintdecimal' flag.
+ * The type of an integer constant is the first of the corresponding list in
+ * which its value can be represented:
+ *
+ * unsuffixed decimal: int, long, long long
+ * unsuffixed oct/hex: int, unsigned int, long, unsigned long,
+ * long long, unsigned long long
+ * suffix [uU]: unsigned int, unsigned long, unsigned long long
+ * suffix [lL] decimal: long, long long
+ * suffix [lL] oct/hex: long, unsigned long, long long, unsigned long long
+ * suffix [uU][Ll]: unsigned long, unsigned long long
+ * suffix ll/LL decimal: long long
+ * suffix ll/LL oct/hex: long long, unsigned long long
+ * suffix [uU][ll/LL]: unsigned long long
+ *
+ * Given that our lexer has already validated the suffixes by regexp matching,
+ * there is an obvious way to concisely encode these rules: construct an array
+ * of the types in the order int, unsigned int, long, unsigned long, long long,
+ * unsigned long long. Compute an integer array starting index based on the
+ * suffix (e.g. none = 0, u = 1, ull = 5), and compute an increment based on
+ * the specifier (dec/oct/hex) and suffix (u). Then iterate from the starting
+ * index to the end, advancing using the increment, and searching until we
+ * find a limit that matches or we run out of choices (overflow). To make it
+ * even faster, we precompute the table of type information in dtrace_open().
+ */
+dt_node_t *
+dt_node_int(uintmax_t value)
+{
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_INT);
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ int n = (yyintdecimal | (yyintsuffix[0] == 'u')) + 1;
+ int i = 0;
+
+ const char *p;
+ char c;
+
+ dnp->dn_op = DT_TOK_INT;
+ dnp->dn_value = value;
+
+ for (p = yyintsuffix; (c = *p) != '\0'; p++) {
+ if (c == 'U' || c == 'u')
+ i += 1;
+ else if (c == 'L' || c == 'l')
+ i += 2;
+ }
+
+ for (; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i += n) {
+ if (value <= dtp->dt_ints[i].did_limit) {
+ dt_node_type_assign(dnp,
+ dtp->dt_ints[i].did_ctfp,
+ dtp->dt_ints[i].did_type);
+
+ /*
+ * If a prefix character is present in macro text, add
+ * in the corresponding operator node (see dt_lex.l).
+ */
+ switch (yyintprefix) {
+ case '+':
+ return (dt_node_op1(DT_TOK_IPOS, dnp));
+ case '-':
+ return (dt_node_op1(DT_TOK_INEG, dnp));
+ default:
+ return (dnp);
+ }
+ }
+ }
+
+ xyerror(D_INT_OFLOW, "integer constant 0x%llx cannot be represented "
+ "in any built-in integral type\n", (u_longlong_t)value);
+ /*NOTREACHED*/
+ return (NULL); /* keep gcc happy */
+}
+
+dt_node_t *
+dt_node_string(char *string)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *dnp;
+
+ if (string == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dnp = dt_node_alloc(DT_NODE_STRING);
+ dnp->dn_op = DT_TOK_STRING;
+ dnp->dn_string = string;
+ dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp));
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_ident(char *name)
+{
+ dt_ident_t *idp;
+ dt_node_t *dnp;
+
+ if (name == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * If the identifier is an inlined integer constant, then create an INT
+ * node that is a clone of the inline parse tree node and return that
+ * immediately, allowing this inline to be used in parsing contexts
+ * that require constant expressions (e.g. scalar array sizes).
+ */
+ if ((idp = dt_idstack_lookup(&yypcb->pcb_globals, name)) != NULL &&
+ (idp->di_flags & DT_IDFLG_INLINE)) {
+ dt_idnode_t *inp = idp->di_iarg;
+
+ if (inp->din_root != NULL &&
+ inp->din_root->dn_kind == DT_NODE_INT) {
+ free(name);
+
+ dnp = dt_node_alloc(DT_NODE_INT);
+ dnp->dn_op = DT_TOK_INT;
+ dnp->dn_value = inp->din_root->dn_value;
+ dt_node_type_propagate(inp->din_root, dnp);
+
+ return (dnp);
+ }
+ }
+
+ dnp = dt_node_alloc(DT_NODE_IDENT);
+ dnp->dn_op = name[0] == '@' ? DT_TOK_AGG : DT_TOK_IDENT;
+ dnp->dn_string = name;
+
+ return (dnp);
+}
+
+/*
+ * Create an empty node of type corresponding to the given declaration.
+ * Explicit references to user types (C or D) are assigned the default
+ * stability; references to other types are _dtrace_typattr (Private).
+ */
+dt_node_t *
+dt_node_type(dt_decl_t *ddp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_typeinfo_t dtt;
+ dt_node_t *dnp;
+ char *name = NULL;
+ int err;
+
+ /*
+ * If 'ddp' is NULL, we get a decl by popping the decl stack. This
+ * form of dt_node_type() is used by parameter rules in dt_grammar.y.
+ */
+ if (ddp == NULL)
+ ddp = dt_decl_pop_param(&name);
+
+ err = dt_decl_type(ddp, &dtt);
+ dt_decl_free(ddp);
+
+ if (err != 0) {
+ free(name);
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ dnp = dt_node_alloc(DT_NODE_TYPE);
+ dnp->dn_op = DT_TOK_IDENT;
+ dnp->dn_string = name;
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+
+ if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp ||
+ dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp)
+ dt_node_attr_assign(dnp, _dtrace_defattr);
+ else
+ dt_node_attr_assign(dnp, _dtrace_typattr);
+
+ return (dnp);
+}
+
+/*
+ * Create a type node corresponding to a varargs (...) parameter by just
+ * assigning it type CTF_ERR. The decl processing code will handle this.
+ */
+dt_node_t *
+dt_node_vatype(void)
+{
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_TYPE);
+
+ dnp->dn_op = DT_TOK_IDENT;
+ dnp->dn_ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
+ dnp->dn_type = CTF_ERR;
+ dnp->dn_attr = _dtrace_defattr;
+
+ return (dnp);
+}
+
+/*
+ * Instantiate a decl using the contents of the current declaration stack. As
+ * we do not currently permit decls to be initialized, this function currently
+ * returns NULL and no parse node is created. When this function is called,
+ * the topmost scope's ds_ident pointer will be set to NULL (indicating no
+ * init_declarator rule was matched) or will point to the identifier to use.
+ */
+dt_node_t *
+dt_node_decl(void)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_dclass_t class = dsp->ds_class;
+ dt_decl_t *ddp = dt_decl_top();
+
+ dt_module_t *dmp;
+ dtrace_typeinfo_t dtt;
+ ctf_id_t type;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ if (dt_decl_type(ddp, &dtt) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+
+ /*
+ * If we have no declaration identifier, then this is either a spurious
+ * declaration of an intrinsic type (e.g. "extern int;") or declaration
+ * or redeclaration of a struct, union, or enum type or tag.
+ */
+ if (dsp->ds_ident == NULL) {
+ if (ddp->dd_kind != CTF_K_STRUCT &&
+ ddp->dd_kind != CTF_K_UNION && ddp->dd_kind != CTF_K_ENUM)
+ xyerror(D_DECL_USELESS, "useless declaration\n");
+
+ dt_dprintf("type %s added as id %ld\n", dt_type_name(
+ ddp->dd_ctfp, ddp->dd_type, n1, sizeof (n1)), ddp->dd_type);
+
+ return (NULL);
+ }
+
+ if (strchr(dsp->ds_ident, '`') != NULL) {
+ xyerror(D_DECL_SCOPE, "D scoping operator may not be used in "
+ "a declaration name (%s)\n", dsp->ds_ident);
+ }
+
+ /*
+ * If we are nested inside of a C include file, add the declaration to
+ * the C definition module; otherwise use the D definition module.
+ */
+ if (yypcb->pcb_idepth != 0)
+ dmp = dtp->dt_cdefs;
+ else
+ dmp = dtp->dt_ddefs;
+
+ /*
+ * If we see a global or static declaration of a function prototype,
+ * treat this as equivalent to a D extern declaration.
+ */
+ if (ctf_type_kind(dtt.dtt_ctfp, dtt.dtt_type) == CTF_K_FUNCTION &&
+ (class == DT_DC_DEFAULT || class == DT_DC_STATIC))
+ class = DT_DC_EXTERN;
+
+ switch (class) {
+ case DT_DC_AUTO:
+ case DT_DC_REGISTER:
+ case DT_DC_STATIC:
+ xyerror(D_DECL_BADCLASS, "specified storage class not "
+ "appropriate in D\n");
+ /*NOTREACHED*/
+
+ case DT_DC_EXTERN: {
+ dtrace_typeinfo_t ott;
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+
+ int exists = dtrace_lookup_by_name(dtp,
+ dmp->dm_name, dsp->ds_ident, &sym, &dts) == 0;
+
+ if (exists && (dtrace_symbol_type(dtp, &sym, &dts, &ott) != 0 ||
+ ctf_type_cmp(dtt.dtt_ctfp, dtt.dtt_type,
+ ott.dtt_ctfp, ott.dtt_type) != 0)) {
+ xyerror(D_DECL_IDRED, "identifier redeclared: %s`%s\n"
+ "\t current: %s\n\tprevious: %s\n",
+ dmp->dm_name, dsp->ds_ident,
+ dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
+ n1, sizeof (n1)),
+ dt_type_name(ott.dtt_ctfp, ott.dtt_type,
+ n2, sizeof (n2)));
+ } else if (!exists && dt_module_extern(dtp, dmp,
+ dsp->ds_ident, &dtt) == NULL) {
+ xyerror(D_UNKNOWN,
+ "failed to extern %s: %s\n", dsp->ds_ident,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ } else {
+ dt_dprintf("extern %s`%s type=<%s>\n",
+ dmp->dm_name, dsp->ds_ident,
+ dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
+ n1, sizeof (n1)));
+ }
+ break;
+ }
+
+ case DT_DC_TYPEDEF:
+ if (dt_idstack_lookup(&yypcb->pcb_globals, dsp->ds_ident)) {
+ xyerror(D_DECL_IDRED, "global variable identifier "
+ "redeclared: %s\n", dsp->ds_ident);
+ }
+
+ if (ctf_lookup_by_name(dmp->dm_ctfp,
+ dsp->ds_ident) != CTF_ERR) {
+ xyerror(D_DECL_IDRED,
+ "typedef redeclared: %s\n", dsp->ds_ident);
+ }
+
+ /*
+ * If the source type for the typedef is not defined in the
+ * target container or its parent, copy the type to the target
+ * container and reset dtt_ctfp and dtt_type to the copy.
+ */
+ if (dtt.dtt_ctfp != dmp->dm_ctfp &&
+ dtt.dtt_ctfp != ctf_parent_file(dmp->dm_ctfp)) {
+
+ dtt.dtt_type = ctf_add_type(dmp->dm_ctfp,
+ dtt.dtt_ctfp, dtt.dtt_type);
+ dtt.dtt_ctfp = dmp->dm_ctfp;
+
+ if (dtt.dtt_type == CTF_ERR ||
+ ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to copy typedef %s "
+ "source type: %s\n", dsp->ds_ident,
+ ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
+ }
+ }
+
+ type = ctf_add_typedef(dmp->dm_ctfp,
+ CTF_ADD_ROOT, dsp->ds_ident, dtt.dtt_type);
+
+ if (type == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to typedef %s: %s\n",
+ dsp->ds_ident, ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
+ }
+
+ dt_dprintf("typedef %s added as id %ld\n", dsp->ds_ident, type);
+ break;
+
+ default: {
+ ctf_encoding_t cte;
+ dt_idhash_t *dhp;
+ dt_ident_t *idp;
+ dt_node_t idn;
+ int assc, idkind;
+ uint_t id, kind;
+ ushort_t idflags;
+
+ switch (class) {
+ case DT_DC_THIS:
+ dhp = yypcb->pcb_locals;
+ idflags = DT_IDFLG_LOCAL;
+ idp = dt_idhash_lookup(dhp, dsp->ds_ident);
+ break;
+ case DT_DC_SELF:
+ dhp = dtp->dt_tls;
+ idflags = DT_IDFLG_TLS;
+ idp = dt_idhash_lookup(dhp, dsp->ds_ident);
+ break;
+ default:
+ dhp = dtp->dt_globals;
+ idflags = 0;
+ idp = dt_idstack_lookup(
+ &yypcb->pcb_globals, dsp->ds_ident);
+ break;
+ }
+
+ if (ddp->dd_kind == CTF_K_ARRAY && ddp->dd_node == NULL) {
+ xyerror(D_DECL_ARRNULL,
+ "array declaration requires array dimension or "
+ "tuple signature: %s\n", dsp->ds_ident);
+ }
+
+ if (idp != NULL && idp->di_gen == 0) {
+ xyerror(D_DECL_IDRED, "built-in identifier "
+ "redeclared: %s\n", idp->di_name);
+ }
+
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_CDEFS,
+ dsp->ds_ident, NULL) == 0 ||
+ dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS,
+ dsp->ds_ident, NULL) == 0) {
+ xyerror(D_DECL_IDRED, "typedef identifier "
+ "redeclared: %s\n", dsp->ds_ident);
+ }
+
+ /*
+ * Cache some attributes of the decl to make the rest of this
+ * code simpler: if the decl is an array which is subscripted
+ * by a type rather than an integer, then it's an associative
+ * array (assc). We then expect to match either DT_IDENT_ARRAY
+ * for associative arrays or DT_IDENT_SCALAR for anything else.
+ */
+ assc = ddp->dd_kind == CTF_K_ARRAY &&
+ ddp->dd_node->dn_kind == DT_NODE_TYPE;
+
+ idkind = assc ? DT_IDENT_ARRAY : DT_IDENT_SCALAR;
+
+ /*
+ * Create a fake dt_node_t on the stack so we can determine the
+ * type of any matching identifier by assigning to this node.
+ * If the pre-existing ident has its di_type set, propagate
+ * the type by hand so as not to trigger a prototype check for
+ * arrays (yet); otherwise we use dt_ident_cook() on the ident
+ * to ensure it is fully initialized before looking at it.
+ */
+ bzero(&idn, sizeof (dt_node_t));
+
+ if (idp != NULL && idp->di_type != CTF_ERR)
+ dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type);
+ else if (idp != NULL)
+ (void) dt_ident_cook(&idn, idp, NULL);
+
+ if (assc) {
+ if (class == DT_DC_THIS) {
+ xyerror(D_DECL_LOCASSC, "associative arrays "
+ "may not be declared as local variables:"
+ " %s\n", dsp->ds_ident);
+ }
+
+ if (dt_decl_type(ddp->dd_next, &dtt) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ if (idp != NULL && (idp->di_kind != idkind ||
+ ctf_type_cmp(dtt.dtt_ctfp, dtt.dtt_type,
+ idn.dn_ctfp, idn.dn_type) != 0)) {
+ xyerror(D_DECL_IDRED, "identifier redeclared: %s\n"
+ "\t current: %s %s\n\tprevious: %s %s\n",
+ dsp->ds_ident, dt_idkind_name(idkind),
+ dt_type_name(dtt.dtt_ctfp,
+ dtt.dtt_type, n1, sizeof (n1)),
+ dt_idkind_name(idp->di_kind),
+ dt_node_type_name(&idn, n2, sizeof (n2)));
+
+ } else if (idp != NULL && assc) {
+ const dt_idsig_t *isp = idp->di_data;
+ dt_node_t *dnp = ddp->dd_node;
+ int argc = 0;
+
+ for (; dnp != NULL; dnp = dnp->dn_list, argc++) {
+ const dt_node_t *pnp = &isp->dis_args[argc];
+
+ if (argc >= isp->dis_argc)
+ continue; /* tuple length mismatch */
+
+ if (ctf_type_cmp(dnp->dn_ctfp, dnp->dn_type,
+ pnp->dn_ctfp, pnp->dn_type) == 0)
+ continue;
+
+ xyerror(D_DECL_IDRED,
+ "identifier redeclared: %s\n"
+ "\t current: %s, key #%d of type %s\n"
+ "\tprevious: %s, key #%d of type %s\n",
+ dsp->ds_ident,
+ dt_idkind_name(idkind), argc + 1,
+ dt_node_type_name(dnp, n1, sizeof (n1)),
+ dt_idkind_name(idp->di_kind), argc + 1,
+ dt_node_type_name(pnp, n2, sizeof (n2)));
+ }
+
+ if (isp->dis_argc != argc) {
+ xyerror(D_DECL_IDRED,
+ "identifier redeclared: %s\n"
+ "\t current: %s of %s, tuple length %d\n"
+ "\tprevious: %s of %s, tuple length %d\n",
+ dsp->ds_ident, dt_idkind_name(idkind),
+ dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
+ n1, sizeof (n1)), argc,
+ dt_idkind_name(idp->di_kind),
+ dt_node_type_name(&idn, n2, sizeof (n2)),
+ isp->dis_argc);
+ }
+
+ } else if (idp == NULL) {
+ type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);
+ kind = ctf_type_kind(dtt.dtt_ctfp, type);
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ if (ctf_type_encoding(dtt.dtt_ctfp, type,
+ &cte) == 0 && IS_VOID(cte)) {
+ xyerror(D_DECL_VOIDOBJ, "cannot have "
+ "void object: %s\n", dsp->ds_ident);
+ }
+ break;
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (ctf_type_size(dtt.dtt_ctfp, type) != 0)
+ break; /* proceed to declaring */
+ /*FALLTHRU*/
+ case CTF_K_FORWARD:
+ xyerror(D_DECL_INCOMPLETE,
+ "incomplete struct/union/enum %s: %s\n",
+ dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
+ n1, sizeof (n1)), dsp->ds_ident);
+ /*NOTREACHED*/
+ }
+
+ if (dt_idhash_nextid(dhp, &id) == -1) {
+ xyerror(D_ID_OFLOW, "cannot create %s: limit "
+ "on number of %s variables exceeded\n",
+ dsp->ds_ident, dt_idhash_name(dhp));
+ }
+
+ dt_dprintf("declare %s %s variable %s, id=%u\n",
+ dt_idhash_name(dhp), dt_idkind_name(idkind),
+ dsp->ds_ident, id);
+
+ idp = dt_idhash_insert(dhp, dsp->ds_ident, idkind,
+ idflags | DT_IDFLG_WRITE | DT_IDFLG_DECL, id,
+ _dtrace_defattr, 0, assc ? &dt_idops_assc :
+ &dt_idops_thaw, NULL, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type);
+
+ /*
+ * If we are declaring an associative array, use our
+ * fake parse node to cook the new assoc identifier.
+ * This will force the ident code to instantiate the
+ * array type signature corresponding to the list of
+ * types pointed to by ddp->dd_node. We also reset
+ * the identifier's attributes based upon the result.
+ */
+ if (assc) {
+ idp->di_attr =
+ dt_ident_cook(&idn, idp, &ddp->dd_node);
+ }
+ }
+ }
+
+ } /* end of switch */
+
+ free(dsp->ds_ident);
+ dsp->ds_ident = NULL;
+
+ return (NULL);
+}
+
+dt_node_t *
+dt_node_func(dt_node_t *dnp, dt_node_t *args)
+{
+ dt_ident_t *idp;
+
+ if (dnp->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_FUNC_IDENT,
+ "function designator is not of function type\n");
+ }
+
+ idp = dt_idstack_lookup(&yypcb->pcb_globals, dnp->dn_string);
+
+ if (idp == NULL) {
+ xyerror(D_FUNC_UNDEF,
+ "undefined function name: %s\n", dnp->dn_string);
+ }
+
+ if (idp->di_kind != DT_IDENT_FUNC &&
+ idp->di_kind != DT_IDENT_AGGFUNC &&
+ idp->di_kind != DT_IDENT_ACTFUNC) {
+ xyerror(D_FUNC_IDKIND, "%s '%s' may not be referenced as a "
+ "function\n", dt_idkind_name(idp->di_kind), idp->di_name);
+ }
+
+ free(dnp->dn_string);
+ dnp->dn_string = NULL;
+
+ dnp->dn_kind = DT_NODE_FUNC;
+ dnp->dn_flags &= ~DT_NF_COOKED;
+ dnp->dn_ident = idp;
+ dnp->dn_args = args;
+ dnp->dn_list = NULL;
+
+ return (dnp);
+}
+
+/*
+ * The offsetof() function is special because it takes a type name as an
+ * argument. It does not actually construct its own node; after looking up the
+ * structure or union offset, we just return an integer node with the offset.
+ */
+dt_node_t *
+dt_node_offsetof(dt_decl_t *ddp, char *s)
+{
+ dtrace_typeinfo_t dtt;
+ dt_node_t dn;
+ char *name;
+ int err;
+
+ ctf_membinfo_t ctm;
+ ctf_id_t type;
+ uint_t kind;
+
+ name = alloca(strlen(s) + 1);
+ (void) strcpy(name, s);
+ free(s);
+
+ err = dt_decl_type(ddp, &dtt);
+ dt_decl_free(ddp);
+
+ if (err != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+
+ type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);
+ kind = ctf_type_kind(dtt.dtt_ctfp, type);
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) {
+ xyerror(D_OFFSETOF_TYPE,
+ "offsetof operand must be a struct or union type\n");
+ }
+
+ if (ctf_member_info(dtt.dtt_ctfp, type, name, &ctm) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "failed to determine offset of %s: %s\n",
+ name, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
+ }
+
+ bzero(&dn, sizeof (dn));
+ dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type);
+
+ if (dn.dn_flags & DT_NF_BITFIELD) {
+ xyerror(D_OFFSETOF_BITFIELD,
+ "cannot take offset of a bit-field: %s\n", name);
+ }
+
+ return (dt_node_int(ctm.ctm_offset / NBBY));
+}
+
+dt_node_t *
+dt_node_op1(int op, dt_node_t *cp)
+{
+ dt_node_t *dnp;
+
+ if (cp->dn_kind == DT_NODE_INT) {
+ switch (op) {
+ case DT_TOK_INEG:
+ /*
+ * If we're negating an unsigned integer, zero out any
+ * extra top bits to truncate the value to the size of
+ * the effective type determined by dt_node_int().
+ */
+ cp->dn_value = -cp->dn_value;
+ if (!(cp->dn_flags & DT_NF_SIGNED)) {
+ cp->dn_value &= ~0ULL >>
+ (64 - dt_node_type_size(cp) * NBBY);
+ }
+ /*FALLTHRU*/
+ case DT_TOK_IPOS:
+ return (cp);
+ case DT_TOK_BNEG:
+ cp->dn_value = ~cp->dn_value;
+ return (cp);
+ case DT_TOK_LNEG:
+ cp->dn_value = !cp->dn_value;
+ return (cp);
+ }
+ }
+
+ /*
+ * If sizeof is applied to a type_name or string constant, we can
+ * transform 'cp' into an integer constant in the node construction
+ * pass so that it can then be used for arithmetic in this pass.
+ */
+ if (op == DT_TOK_SIZEOF &&
+ (cp->dn_kind == DT_NODE_STRING || cp->dn_kind == DT_NODE_TYPE)) {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ size_t size = dt_node_type_size(cp);
+
+ if (size == 0) {
+ xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an "
+ "operand of unknown size\n");
+ }
+
+ dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp,
+ ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+
+ cp->dn_kind = DT_NODE_INT;
+ cp->dn_op = DT_TOK_INT;
+ cp->dn_value = size;
+
+ return (cp);
+ }
+
+ dnp = dt_node_alloc(DT_NODE_OP1);
+ assert(op <= USHRT_MAX);
+ dnp->dn_op = (ushort_t)op;
+ dnp->dn_child = cp;
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *dnp;
+
+ /*
+ * First we check for operations that are illegal -- namely those that
+ * might result in integer division by zero, and abort if one is found.
+ */
+ if (rp->dn_kind == DT_NODE_INT && rp->dn_value == 0 &&
+ (op == DT_TOK_MOD || op == DT_TOK_DIV ||
+ op == DT_TOK_MOD_EQ || op == DT_TOK_DIV_EQ))
+ xyerror(D_DIV_ZERO, "expression contains division by zero\n");
+
+ /*
+ * If both children are immediate values, we can just perform inline
+ * calculation and return a new immediate node with the result.
+ */
+ if (lp->dn_kind == DT_NODE_INT && rp->dn_kind == DT_NODE_INT) {
+ uintmax_t l = lp->dn_value;
+ uintmax_t r = rp->dn_value;
+
+ dnp = dt_node_int(0); /* allocate new integer node for result */
+
+ switch (op) {
+ case DT_TOK_LOR:
+ dnp->dn_value = l || r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_LXOR:
+ dnp->dn_value = (l != 0) ^ (r != 0);
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_LAND:
+ dnp->dn_value = l && r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_BOR:
+ dnp->dn_value = l | r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_XOR:
+ dnp->dn_value = l ^ r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_BAND:
+ dnp->dn_value = l & r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_EQU:
+ dnp->dn_value = l == r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_NEQ:
+ dnp->dn_value = l != r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_LT:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l < (intmax_t)r;
+ else
+ dnp->dn_value = l < r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_LE:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l <= (intmax_t)r;
+ else
+ dnp->dn_value = l <= r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_GT:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l > (intmax_t)r;
+ else
+ dnp->dn_value = l > r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_GE:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l >= (intmax_t)r;
+ else
+ dnp->dn_value = l >= r;
+ dt_node_type_assign(dnp,
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+ case DT_TOK_LSH:
+ dnp->dn_value = l << r;
+ dt_node_type_propagate(lp, dnp);
+ dt_node_attr_assign(rp,
+ dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+ case DT_TOK_RSH:
+ dnp->dn_value = l >> r;
+ dt_node_type_propagate(lp, dnp);
+ dt_node_attr_assign(rp,
+ dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+ case DT_TOK_ADD:
+ dnp->dn_value = l + r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_SUB:
+ dnp->dn_value = l - r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_MUL:
+ dnp->dn_value = l * r;
+ dt_node_promote(lp, rp, dnp);
+ break;
+ case DT_TOK_DIV:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l / (intmax_t)r;
+ else
+ dnp->dn_value = l / r;
+ break;
+ case DT_TOK_MOD:
+ dt_node_promote(lp, rp, dnp);
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ dnp->dn_value = (intmax_t)l % (intmax_t)r;
+ else
+ dnp->dn_value = l % r;
+ break;
+ default:
+ dt_node_free(dnp);
+ dnp = NULL;
+ }
+
+ if (dnp != NULL) {
+ dt_node_free(lp);
+ dt_node_free(rp);
+ return (dnp);
+ }
+ }
+
+ /*
+ * If an integer constant is being cast to another integer type, we can
+ * perform the cast as part of integer constant folding in this pass.
+ * We must take action when the integer is being cast to a smaller type
+ * or if it is changing signed-ness. If so, we first shift rp's bits
+ * bits high (losing excess bits if narrowing) and then shift them down
+ * with either a logical shift (unsigned) or arithmetic shift (signed).
+ */
+ if (op == DT_TOK_LPAR && rp->dn_kind == DT_NODE_INT &&
+ dt_node_is_integer(lp)) {
+ size_t srcsize = dt_node_type_size(rp);
+ size_t dstsize = dt_node_type_size(lp);
+
+ if ((dstsize < srcsize) || ((lp->dn_flags & DT_NF_SIGNED) ^
+ (rp->dn_flags & DT_NF_SIGNED))) {
+ int n = dstsize < srcsize ?
+ (sizeof (uint64_t) * NBBY - dstsize * NBBY) :
+ (sizeof (uint64_t) * NBBY - srcsize * NBBY);
+
+ rp->dn_value <<= n;
+ if (lp->dn_flags & DT_NF_SIGNED)
+ rp->dn_value = (intmax_t)rp->dn_value >> n;
+ else
+ rp->dn_value = rp->dn_value >> n;
+ }
+
+ dt_node_type_propagate(lp, rp);
+ dt_node_attr_assign(rp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ dt_node_free(lp);
+
+ return (rp);
+ }
+
+ /*
+ * If no immediate optimizations are available, create an new OP2 node
+ * and glue the left and right children into place and return.
+ */
+ dnp = dt_node_alloc(DT_NODE_OP2);
+ assert(op <= USHRT_MAX);
+ dnp->dn_op = (ushort_t)op;
+ dnp->dn_left = lp;
+ dnp->dn_right = rp;
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_op3(dt_node_t *expr, dt_node_t *lp, dt_node_t *rp)
+{
+ dt_node_t *dnp;
+
+ if (expr->dn_kind == DT_NODE_INT)
+ return (expr->dn_value != 0 ? lp : rp);
+
+ dnp = dt_node_alloc(DT_NODE_OP3);
+ dnp->dn_op = DT_TOK_QUESTION;
+ dnp->dn_expr = expr;
+ dnp->dn_left = lp;
+ dnp->dn_right = rp;
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_statement(dt_node_t *expr)
+{
+ dt_node_t *dnp;
+
+ if (expr->dn_kind == DT_NODE_AGG)
+ return (expr);
+
+ if (expr->dn_kind == DT_NODE_FUNC &&
+ expr->dn_ident->di_kind == DT_IDENT_ACTFUNC)
+ dnp = dt_node_alloc(DT_NODE_DFUNC);
+ else
+ dnp = dt_node_alloc(DT_NODE_DEXPR);
+
+ dnp->dn_expr = expr;
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_pdesc_by_name(char *spec)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *dnp;
+
+ if (spec == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dnp = dt_node_alloc(DT_NODE_PDESC);
+ dnp->dn_spec = spec;
+ dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t));
+
+ if (dnp->dn_desc == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (dtrace_xstr2desc(dtp, yypcb->pcb_pspec, dnp->dn_spec,
+ yypcb->pcb_sargc, yypcb->pcb_sargv, dnp->dn_desc) != 0) {
+ xyerror(D_PDESC_INVAL, "invalid probe description \"%s\": %s\n",
+ dnp->dn_spec, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ free(dnp->dn_spec);
+ dnp->dn_spec = NULL;
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_pdesc_by_id(uintmax_t id)
+{
+ static const char *const names[] = {
+ "providers", "modules", "functions"
+ };
+
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_PDESC);
+
+ if ((dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (id > UINT_MAX) {
+ xyerror(D_PDESC_INVAL, "identifier %llu exceeds maximum "
+ "probe id\n", (u_longlong_t)id);
+ }
+
+ if (yypcb->pcb_pspec != DTRACE_PROBESPEC_NAME) {
+ xyerror(D_PDESC_INVAL, "probe identifier %llu not permitted "
+ "when specifying %s\n", (u_longlong_t)id,
+ names[yypcb->pcb_pspec]);
+ }
+
+ if (dtrace_id2desc(dtp, (dtrace_id_t)id, dnp->dn_desc) != 0) {
+ xyerror(D_PDESC_INVAL, "invalid probe identifier %llu: %s\n",
+ (u_longlong_t)id, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_clause(dt_node_t *pdescs, dt_node_t *pred, dt_node_t *acts)
+{
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_CLAUSE);
+
+ dnp->dn_pdescs = pdescs;
+ dnp->dn_pred = pred;
+ dnp->dn_acts = acts;
+
+ yybegin(YYS_CLAUSE);
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_inline(dt_node_t *expr)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_scope_t *dsp = &yypcb->pcb_dstack;
+ dt_decl_t *ddp = dt_decl_top();
+
+ char n[DT_TYPE_NAMELEN];
+ dtrace_typeinfo_t dtt;
+
+ dt_ident_t *idp, *rdp;
+ dt_idnode_t *inp;
+ dt_node_t *dnp;
+
+ if (dt_decl_type(ddp, &dtt) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+
+ if (dsp->ds_class != DT_DC_DEFAULT) {
+ xyerror(D_DECL_BADCLASS, "specified storage class not "
+ "appropriate for inline declaration\n");
+ }
+
+ if (dsp->ds_ident == NULL)
+ xyerror(D_DECL_USELESS, "inline declaration requires a name\n");
+
+ if ((idp = dt_idstack_lookup(
+ &yypcb->pcb_globals, dsp->ds_ident)) != NULL) {
+ xyerror(D_DECL_IDRED, "identifier redefined: %s\n\t current: "
+ "inline definition\n\tprevious: %s %s\n",
+ idp->di_name, dt_idkind_name(idp->di_kind),
+ (idp->di_flags & DT_IDFLG_INLINE) ? "inline" : "");
+ }
+
+ /*
+ * If we are declaring an inlined array, verify that we have a tuple
+ * signature, and then recompute 'dtt' as the array's value type.
+ */
+ if (ddp->dd_kind == CTF_K_ARRAY) {
+ if (ddp->dd_node == NULL) {
+ xyerror(D_DECL_ARRNULL, "inline declaration requires "
+ "array tuple signature: %s\n", dsp->ds_ident);
+ }
+
+ if (ddp->dd_node->dn_kind != DT_NODE_TYPE) {
+ xyerror(D_DECL_ARRNULL, "inline declaration cannot be "
+ "of scalar array type: %s\n", dsp->ds_ident);
+ }
+
+ if (dt_decl_type(ddp->dd_next, &dtt) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ /*
+ * If the inline identifier is not defined, then create it with the
+ * orphan flag set. We do not insert the identifier into dt_globals
+ * until we have successfully cooked the right-hand expression, below.
+ */
+ dnp = dt_node_alloc(DT_NODE_INLINE);
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_attr_assign(dnp, _dtrace_defattr);
+
+ if (dt_node_is_void(dnp)) {
+ xyerror(D_DECL_VOIDOBJ,
+ "cannot declare void inline: %s\n", dsp->ds_ident);
+ }
+
+ if (ctf_type_kind(dnp->dn_ctfp, ctf_type_resolve(
+ dnp->dn_ctfp, dnp->dn_type)) == CTF_K_FORWARD) {
+ xyerror(D_DECL_INCOMPLETE,
+ "incomplete struct/union/enum %s: %s\n",
+ dt_node_type_name(dnp, n, sizeof (n)), dsp->ds_ident);
+ }
+
+ if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ bzero(inp, sizeof (dt_idnode_t));
+
+ idp = dnp->dn_ident = dt_ident_create(dsp->ds_ident,
+ ddp->dd_kind == CTF_K_ARRAY ? DT_IDENT_ARRAY : DT_IDENT_SCALAR,
+ DT_IDFLG_INLINE | DT_IDFLG_REF | DT_IDFLG_DECL | DT_IDFLG_ORPHAN, 0,
+ _dtrace_defattr, 0, &dt_idops_inline, inp, dtp->dt_gen);
+
+ if (idp == NULL) {
+ free(inp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ /*
+ * If we're inlining an associative array, create a private identifier
+ * hash containing the named parameters and store it in inp->din_hash.
+ * We then push this hash on to the top of the pcb_globals stack.
+ */
+ if (ddp->dd_kind == CTF_K_ARRAY) {
+ dt_idnode_t *pinp;
+ dt_ident_t *pidp;
+ dt_node_t *pnp;
+ uint_t i = 0;
+
+ for (pnp = ddp->dd_node; pnp != NULL; pnp = pnp->dn_list)
+ i++; /* count up parameters for din_argv[] */
+
+ inp->din_hash = dt_idhash_create("inline args", NULL, 0, 0);
+ inp->din_argv = calloc(i, sizeof (dt_ident_t *));
+
+ if (inp->din_hash == NULL || inp->din_argv == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * Create an identifier for each parameter as a scalar inline,
+ * and store it in din_hash and in position in din_argv[]. The
+ * parameter identifiers also use dt_idops_inline, but we leave
+ * the dt_idnode_t argument 'pinp' zeroed. This will be filled
+ * in by the code generation pass with references to the args.
+ */
+ for (i = 0, pnp = ddp->dd_node;
+ pnp != NULL; pnp = pnp->dn_list, i++) {
+
+ if (pnp->dn_string == NULL)
+ continue; /* ignore anonymous parameters */
+
+ if ((pinp = malloc(sizeof (dt_idnode_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ pidp = dt_idhash_insert(inp->din_hash, pnp->dn_string,
+ DT_IDENT_SCALAR, DT_IDFLG_DECL | DT_IDFLG_INLINE, 0,
+ _dtrace_defattr, 0, &dt_idops_inline,
+ pinp, dtp->dt_gen);
+
+ if (pidp == NULL) {
+ free(pinp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ }
+
+ inp->din_argv[i] = pidp;
+ bzero(pinp, sizeof (dt_idnode_t));
+ dt_ident_type_assign(pidp, pnp->dn_ctfp, pnp->dn_type);
+ }
+
+ dt_idstack_push(&yypcb->pcb_globals, inp->din_hash);
+ }
+
+ /*
+ * Unlike most constructors, we need to explicitly cook the right-hand
+ * side of the inline definition immediately to prevent recursion. If
+ * the right-hand side uses the inline itself, the cook will fail.
+ */
+ expr = dt_node_cook(expr, DT_IDFLG_REF);
+
+ if (ddp->dd_kind == CTF_K_ARRAY)
+ dt_idstack_pop(&yypcb->pcb_globals, inp->din_hash);
+
+ /*
+ * Set the type, attributes, and flags for the inline. If the right-
+ * hand expression has an identifier, propagate its flags. Then cook
+ * the identifier to fully initialize it: if we're declaring an inline
+ * associative array this will construct a type signature from 'ddp'.
+ */
+ if (dt_node_is_dynamic(expr))
+ rdp = dt_ident_resolve(expr->dn_ident);
+ else if (expr->dn_kind == DT_NODE_VAR || expr->dn_kind == DT_NODE_SYM)
+ rdp = expr->dn_ident;
+ else
+ rdp = NULL;
+
+ if (rdp != NULL) {
+ idp->di_flags |= (rdp->di_flags &
+ (DT_IDFLG_WRITE | DT_IDFLG_USER | DT_IDFLG_PRIM));
+ }
+
+ idp->di_attr = dt_attr_min(_dtrace_defattr, expr->dn_attr);
+ dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type);
+ (void) dt_ident_cook(dnp, idp, &ddp->dd_node);
+
+ /*
+ * Store the parse tree nodes for 'expr' inside of idp->di_data ('inp')
+ * so that they will be preserved with this identifier. Then pop the
+ * inline declaration from the declaration stack and restore the lexer.
+ */
+ inp->din_list = yypcb->pcb_list;
+ inp->din_root = expr;
+
+ dt_decl_free(dt_decl_pop());
+ yybegin(YYS_CLAUSE);
+
+ /*
+ * Finally, insert the inline identifier into dt_globals to make it
+ * visible, and then cook 'dnp' to check its type against 'expr'.
+ */
+ dt_idhash_xinsert(dtp->dt_globals, idp);
+ return (dt_node_cook(dnp, DT_IDFLG_REF));
+}
+
+dt_node_t *
+dt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr)
+{
+ dtrace_typeinfo_t dtt;
+ dt_node_t *dnp;
+ int err;
+
+ if (ddp != NULL) {
+ err = dt_decl_type(ddp, &dtt);
+ dt_decl_free(ddp);
+
+ if (err != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ dnp = dt_node_alloc(DT_NODE_MEMBER);
+ dnp->dn_membname = name;
+ dnp->dn_membexpr = expr;
+
+ if (ddp != NULL)
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_typeinfo_t src, dst;
+ dt_node_t sn, dn;
+ dt_xlator_t *dxp;
+ dt_node_t *dnp;
+ int edst, esrc;
+ uint_t kind;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ edst = dt_decl_type(ddp, &dst);
+ dt_decl_free(ddp);
+
+ esrc = dt_decl_type(sdp, &src);
+ dt_decl_free(sdp);
+
+ if (edst != 0 || esrc != 0) {
+ free(name);
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+ }
+
+ bzero(&sn, sizeof (sn));
+ dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type);
+
+ bzero(&dn, sizeof (dn));
+ dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type);
+
+ if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) {
+ xyerror(D_XLATE_REDECL,
+ "translator from %s to %s has already been declared\n",
+ dt_node_type_name(&sn, n1, sizeof (n1)),
+ dt_node_type_name(&dn, n2, sizeof (n2)));
+ }
+
+ kind = ctf_type_kind(dst.dtt_ctfp,
+ ctf_type_resolve(dst.dtt_ctfp, dst.dtt_type));
+
+ if (kind == CTF_K_FORWARD) {
+ xyerror(D_XLATE_SOU, "incomplete struct/union/enum %s\n",
+ dt_type_name(dst.dtt_ctfp, dst.dtt_type, n1, sizeof (n1)));
+ }
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) {
+ xyerror(D_XLATE_SOU,
+ "translator output type must be a struct or union\n");
+ }
+
+ dxp = dt_xlator_create(dtp, &src, &dst, name, members, yypcb->pcb_list);
+ yybegin(YYS_CLAUSE);
+ free(name);
+
+ if (dxp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ dnp = dt_node_alloc(DT_NODE_XLATOR);
+ dnp->dn_xlator = dxp;
+ dnp->dn_members = members;
+
+ return (dt_node_cook(dnp, DT_IDFLG_REF));
+}
+
+dt_node_t *
+dt_node_probe(char *s, int protoc, dt_node_t *nargs, dt_node_t *xargs)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ int nargc, xargc;
+ dt_node_t *dnp;
+
+ size_t len = strlen(s) + 3; /* +3 for :: and \0 */
+ char *name = alloca(len);
+
+ (void) snprintf(name, len, "::%s", s);
+ (void) strhyphenate(name);
+ free(s);
+
+ if (strchr(name, '`') != NULL) {
+ xyerror(D_PROV_BADNAME, "probe name may not "
+ "contain scoping operator: %s\n", name);
+ }
+
+ if (strlen(name) - 2 >= DTRACE_NAMELEN) {
+ xyerror(D_PROV_BADNAME, "probe name may not exceed %d "
+ "characters: %s\n", DTRACE_NAMELEN - 1, name);
+ }
+
+ dnp = dt_node_alloc(DT_NODE_PROBE);
+
+ dnp->dn_ident = dt_ident_create(name, DT_IDENT_PROBE,
+ DT_IDFLG_ORPHAN, DTRACE_IDNONE, _dtrace_defattr, 0,
+ &dt_idops_probe, NULL, dtp->dt_gen);
+
+ nargc = dt_decl_prototype(nargs, nargs,
+ "probe input", DT_DP_VOID | DT_DP_ANON);
+
+ xargc = dt_decl_prototype(xargs, nargs,
+ "probe output", DT_DP_VOID);
+
+ if (nargc > UINT8_MAX) {
+ xyerror(D_PROV_PRARGLEN, "probe %s input prototype exceeds %u "
+ "parameters: %d params used\n", name, UINT8_MAX, nargc);
+ }
+
+ if (xargc > UINT8_MAX) {
+ xyerror(D_PROV_PRARGLEN, "probe %s output prototype exceeds %u "
+ "parameters: %d params used\n", name, UINT8_MAX, xargc);
+ }
+
+ if (dnp->dn_ident == NULL || dt_probe_create(dtp,
+ dnp->dn_ident, protoc, nargs, nargc, xargs, xargc) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_provider(char *name, dt_node_t *probes)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_PROVIDER);
+ dt_node_t *lnp;
+ size_t len;
+
+ dnp->dn_provname = name;
+ dnp->dn_probes = probes;
+
+ if (strchr(name, '`') != NULL) {
+ dnerror(dnp, D_PROV_BADNAME, "provider name may not "
+ "contain scoping operator: %s\n", name);
+ }
+
+ if ((len = strlen(name)) >= DTRACE_PROVNAMELEN) {
+ dnerror(dnp, D_PROV_BADNAME, "provider name may not exceed %d "
+ "characters: %s\n", DTRACE_PROVNAMELEN - 1, name);
+ }
+
+ if (isdigit(name[len - 1])) {
+ dnerror(dnp, D_PROV_BADNAME, "provider name may not "
+ "end with a digit: %s\n", name);
+ }
+
+ /*
+ * Check to see if the provider is already defined or visible through
+ * dtrace(7D). If so, set dn_provred to treat it as a re-declaration.
+ * If not, create a new provider and set its interface-only flag. This
+ * flag may be cleared later by calls made to dt_probe_declare().
+ */
+ if ((dnp->dn_provider = dt_provider_lookup(dtp, name)) != NULL)
+ dnp->dn_provred = B_TRUE;
+ else if ((dnp->dn_provider = dt_provider_create(dtp, name)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ else
+ dnp->dn_provider->pv_flags |= DT_PROVIDER_INTF;
+
+ /*
+ * Store all parse nodes created since we consumed the DT_KEY_PROVIDER
+ * token with the provider and then restore our lexing state to CLAUSE.
+ * Note that if dnp->dn_provred is true, we may end up storing dups of
+ * a provider's interface and implementation: we eat this space because
+ * the implementation will likely need to redeclare probe members, and
+ * therefore may result in those member nodes becoming persistent.
+ */
+ for (lnp = yypcb->pcb_list; lnp->dn_link != NULL; lnp = lnp->dn_link)
+ continue; /* skip to end of allocation list */
+
+ lnp->dn_link = dnp->dn_provider->pv_nodes;
+ dnp->dn_provider->pv_nodes = yypcb->pcb_list;
+
+ yybegin(YYS_CLAUSE);
+ return (dnp);
+}
+
+dt_node_t *
+dt_node_program(dt_node_t *lnp)
+{
+ dt_node_t *dnp = dt_node_alloc(DT_NODE_PROG);
+ dnp->dn_list = lnp;
+ return (dnp);
+}
+
+/*
+ * This function provides the underlying implementation of cooking an
+ * identifier given its node, a hash of dynamic identifiers, an identifier
+ * kind, and a boolean flag indicating whether we are allowed to instantiate
+ * a new identifier if the string is not found. This function is either
+ * called from dt_cook_ident(), below, or directly by the various cooking
+ * routines that are allowed to instantiate identifiers (e.g. op2 TOK_ASGN).
+ */
+static void
+dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ const char *sname = dt_idhash_name(dhp);
+ int uref = 0;
+
+ dtrace_attribute_t attr = _dtrace_defattr;
+ dt_ident_t *idp;
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+
+ const char *scope, *mark;
+ uchar_t dnkind;
+ char *name;
+
+ /*
+ * Look for scoping marks in the identifier. If one is found, set our
+ * scope to either DTRACE_OBJ_KMODS or UMODS or to the first part of
+ * the string that specifies the scope using an explicit module name.
+ * If two marks in a row are found, set 'uref' (user symbol reference).
+ * Otherwise we set scope to DTRACE_OBJ_EXEC, indicating that normal
+ * scope is desired and we should search the specified idhash.
+ */
+ if ((name = strrchr(dnp->dn_string, '`')) != NULL) {
+ if (name > dnp->dn_string && name[-1] == '`') {
+ uref++;
+ name[-1] = '\0';
+ }
+
+ if (name == dnp->dn_string + uref)
+ scope = uref ? DTRACE_OBJ_UMODS : DTRACE_OBJ_KMODS;
+ else
+ scope = dnp->dn_string;
+
+ *name++ = '\0'; /* leave name pointing after scoping mark */
+ dnkind = DT_NODE_VAR;
+
+ } else if (idkind == DT_IDENT_AGG) {
+ scope = DTRACE_OBJ_EXEC;
+ name = dnp->dn_string + 1;
+ dnkind = DT_NODE_AGG;
+ } else {
+ scope = DTRACE_OBJ_EXEC;
+ name = dnp->dn_string;
+ dnkind = DT_NODE_VAR;
+ }
+
+ /*
+ * If create is set to false, and we fail our idhash lookup, preset
+ * the errno code to EDT_NOVAR for our final error message below.
+ * If we end up calling dtrace_lookup_by_name(), it will reset the
+ * errno appropriately and that error will be reported instead.
+ */
+ (void) dt_set_errno(dtp, EDT_NOVAR);
+ mark = uref ? "``" : "`";
+
+ if (scope == DTRACE_OBJ_EXEC && (
+ (dhp != dtp->dt_globals &&
+ (idp = dt_idhash_lookup(dhp, name)) != NULL) ||
+ (dhp == dtp->dt_globals &&
+ (idp = dt_idstack_lookup(&yypcb->pcb_globals, name)) != NULL))) {
+ /*
+ * Check that we are referencing the ident in the manner that
+ * matches its type if this is a global lookup. In the TLS or
+ * local case, we don't know how the ident will be used until
+ * the time operator -> is seen; more parsing is needed.
+ */
+ if (idp->di_kind != idkind && dhp == dtp->dt_globals) {
+ xyerror(D_IDENT_BADREF, "%s '%s' may not be referenced "
+ "as %s\n", dt_idkind_name(idp->di_kind),
+ idp->di_name, dt_idkind_name(idkind));
+ }
+
+ /*
+ * Arrays and aggregations are not cooked individually. They
+ * have dynamic types and must be referenced using operator [].
+ * This is handled explicitly by the code for DT_TOK_LBRAC.
+ */
+ if (idp->di_kind != DT_IDENT_ARRAY &&
+ idp->di_kind != DT_IDENT_AGG)
+ attr = dt_ident_cook(dnp, idp, NULL);
+ else {
+ dt_node_type_assign(dnp,
+ DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ attr = idp->di_attr;
+ }
+
+ free(dnp->dn_string);
+ dnp->dn_string = NULL;
+ dnp->dn_kind = dnkind;
+ dnp->dn_ident = idp;
+ dnp->dn_flags |= DT_NF_LVALUE;
+
+ if (idp->di_flags & DT_IDFLG_WRITE)
+ dnp->dn_flags |= DT_NF_WRITABLE;
+
+ dt_node_attr_assign(dnp, attr);
+
+ } else if (dhp == dtp->dt_globals && scope != DTRACE_OBJ_EXEC &&
+ dtrace_lookup_by_name(dtp, scope, name, &sym, &dts) == 0) {
+
+ dt_module_t *mp = dt_module_lookup_by_name(dtp, dts.dts_object);
+ int umod = (mp->dm_flags & DT_DM_KERNEL) == 0;
+ static const char *const kunames[] = { "kernel", "user" };
+
+ dtrace_typeinfo_t dtt;
+ dtrace_syminfo_t *sip;
+
+ if (uref ^ umod) {
+ xyerror(D_SYM_BADREF, "%s module '%s' symbol '%s' may "
+ "not be referenced as a %s symbol\n", kunames[umod],
+ dts.dts_object, dts.dts_name, kunames[uref]);
+ }
+
+ if (dtrace_symbol_type(dtp, &sym, &dts, &dtt) != 0) {
+ /*
+ * For now, we special-case EDT_DATAMODEL to clarify
+ * that mixed data models are not currently supported.
+ */
+ if (dtp->dt_errno == EDT_DATAMODEL) {
+ xyerror(D_SYM_MODEL, "cannot use %s symbol "
+ "%s%s%s in a %s D program\n",
+ dt_module_modelname(mp),
+ dts.dts_object, mark, dts.dts_name,
+ dt_module_modelname(dtp->dt_ddefs));
+ }
+
+ xyerror(D_SYM_NOTYPES,
+ "no symbolic type information is available for "
+ "%s%s%s: %s\n", dts.dts_object, mark, dts.dts_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+
+ idp = dt_ident_create(name, DT_IDENT_SYMBOL, 0, 0,
+ _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (mp->dm_flags & DT_DM_PRIMARY)
+ idp->di_flags |= DT_IDFLG_PRIM;
+
+ idp->di_next = dtp->dt_externs;
+ dtp->dt_externs = idp;
+
+ if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ bcopy(&dts, sip, sizeof (dtrace_syminfo_t));
+ idp->di_data = sip;
+ idp->di_ctfp = dtt.dtt_ctfp;
+ idp->di_type = dtt.dtt_type;
+
+ free(dnp->dn_string);
+ dnp->dn_string = NULL;
+ dnp->dn_kind = DT_NODE_SYM;
+ dnp->dn_ident = idp;
+ dnp->dn_flags |= DT_NF_LVALUE;
+
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_attr_assign(dnp, _dtrace_symattr);
+
+ if (uref) {
+ idp->di_flags |= DT_IDFLG_USER;
+ dnp->dn_flags |= DT_NF_USERLAND;
+ }
+
+ } else if (scope == DTRACE_OBJ_EXEC && create == B_TRUE) {
+ uint_t flags = DT_IDFLG_WRITE;
+ uint_t id;
+
+ if (dt_idhash_nextid(dhp, &id) == -1) {
+ xyerror(D_ID_OFLOW, "cannot create %s: limit on number "
+ "of %s variables exceeded\n", name, sname);
+ }
+
+ if (dhp == yypcb->pcb_locals)
+ flags |= DT_IDFLG_LOCAL;
+ else if (dhp == dtp->dt_tls)
+ flags |= DT_IDFLG_TLS;
+
+ dt_dprintf("create %s %s variable %s, id=%u\n",
+ sname, dt_idkind_name(idkind), name, id);
+
+ if (idkind == DT_IDENT_ARRAY || idkind == DT_IDENT_AGG) {
+ idp = dt_idhash_insert(dhp, name,
+ idkind, flags, id, _dtrace_defattr, 0,
+ &dt_idops_assc, NULL, dtp->dt_gen);
+ } else {
+ idp = dt_idhash_insert(dhp, name,
+ idkind, flags, id, _dtrace_defattr, 0,
+ &dt_idops_thaw, NULL, dtp->dt_gen);
+ }
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ /*
+ * Arrays and aggregations are not cooked individually. They
+ * have dynamic types and must be referenced using operator [].
+ * This is handled explicitly by the code for DT_TOK_LBRAC.
+ */
+ if (idp->di_kind != DT_IDENT_ARRAY &&
+ idp->di_kind != DT_IDENT_AGG)
+ attr = dt_ident_cook(dnp, idp, NULL);
+ else {
+ dt_node_type_assign(dnp,
+ DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ attr = idp->di_attr;
+ }
+
+ free(dnp->dn_string);
+ dnp->dn_string = NULL;
+ dnp->dn_kind = dnkind;
+ dnp->dn_ident = idp;
+ dnp->dn_flags |= DT_NF_LVALUE | DT_NF_WRITABLE;
+
+ dt_node_attr_assign(dnp, attr);
+
+ } else if (scope != DTRACE_OBJ_EXEC) {
+ xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n",
+ dnp->dn_string, mark, name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ } else {
+ xyerror(D_IDENT_UNDEF, "failed to resolve %s: %s\n",
+ dnp->dn_string, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+}
+
+static dt_node_t *
+dt_cook_ident(dt_node_t *dnp, uint_t idflags)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ if (dnp->dn_op == DT_TOK_AGG)
+ dt_xcook_ident(dnp, dtp->dt_aggs, DT_IDENT_AGG, B_FALSE);
+ else
+ dt_xcook_ident(dnp, dtp->dt_globals, DT_IDENT_SCALAR, B_FALSE);
+
+ return (dt_node_cook(dnp, idflags));
+}
+
+/*
+ * Since operators [ and -> can instantiate new variables before we know
+ * whether the reference is for a read or a write, we need to check read
+ * references to determine if the identifier is currently dt_ident_unref().
+ * If so, we report that this first access was to an undefined variable.
+ */
+static dt_node_t *
+dt_cook_var(dt_node_t *dnp, uint_t idflags)
+{
+ dt_ident_t *idp = dnp->dn_ident;
+
+ if ((idflags & DT_IDFLG_REF) && dt_ident_unref(idp)) {
+ dnerror(dnp, D_VAR_UNDEF,
+ "%s%s has not yet been declared or assigned\n",
+ (idp->di_flags & DT_IDFLG_LOCAL) ? "this->" :
+ (idp->di_flags & DT_IDFLG_TLS) ? "self->" : "",
+ idp->di_name);
+ }
+
+ dt_node_attr_assign(dnp, dt_ident_cook(dnp, idp, &dnp->dn_args));
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_func(dt_node_t *dnp, uint_t idflags)
+{
+ dt_node_attr_assign(dnp,
+ dt_ident_cook(dnp, dnp->dn_ident, &dnp->dn_args));
+
+ return (dnp);
+}
+
+static dt_node_t *
+dt_cook_op1(dt_node_t *dnp, uint_t idflags)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *cp = dnp->dn_child;
+
+ char n[DT_TYPE_NAMELEN];
+ dtrace_typeinfo_t dtt;
+ dt_ident_t *idp;
+
+ ctf_encoding_t e;
+ ctf_arinfo_t r;
+ ctf_id_t type, base;
+ uint_t kind;
+
+ if (dnp->dn_op == DT_TOK_PREINC || dnp->dn_op == DT_TOK_POSTINC ||
+ dnp->dn_op == DT_TOK_PREDEC || dnp->dn_op == DT_TOK_POSTDEC)
+ idflags = DT_IDFLG_REF | DT_IDFLG_MOD;
+ else
+ idflags = DT_IDFLG_REF;
+
+ /*
+ * We allow the unary ++ and -- operators to instantiate new scalar
+ * variables if applied to an identifier; otherwise just cook as usual.
+ */
+ if (cp->dn_kind == DT_NODE_IDENT && (idflags & DT_IDFLG_MOD))
+ dt_xcook_ident(cp, dtp->dt_globals, DT_IDENT_SCALAR, B_TRUE);
+
+ cp = dnp->dn_child = dt_node_cook(cp, 0); /* don't set idflags yet */
+
+ if (cp->dn_kind == DT_NODE_VAR && dt_ident_unref(cp->dn_ident)) {
+ if (dt_type_lookup("int64_t", &dtt) != 0)
+ xyerror(D_TYPE_ERR, "failed to lookup int64_t\n");
+
+ dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type);
+ }
+
+ if (cp->dn_kind == DT_NODE_VAR)
+ cp->dn_ident->di_flags |= idflags;
+
+ switch (dnp->dn_op) {
+ case DT_TOK_DEREF:
+ /*
+ * If the deref operator is applied to a translated pointer,
+ * we can just set our output type to the base translation.
+ */
+ if ((idp = dt_node_resolve(cp, DT_IDENT_XLPTR)) != NULL) {
+ dt_xlator_t *dxp = idp->di_data;
+
+ dnp->dn_ident = &dxp->dx_souid;
+ dt_node_type_assign(dnp,
+ DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ break;
+ }
+
+ type = ctf_type_resolve(cp->dn_ctfp, cp->dn_type);
+ kind = ctf_type_kind(cp->dn_ctfp, type);
+
+ if (kind == CTF_K_ARRAY) {
+ if (ctf_array_info(cp->dn_ctfp, type, &r) != 0) {
+ dtp->dt_ctferr = ctf_errno(cp->dn_ctfp);
+ longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+ } else
+ type = r.ctr_contents;
+ } else if (kind == CTF_K_POINTER) {
+ type = ctf_type_reference(cp->dn_ctfp, type);
+ } else {
+ xyerror(D_DEREF_NONPTR,
+ "cannot dereference non-pointer type\n");
+ }
+
+ dt_node_type_assign(dnp, cp->dn_ctfp, type);
+ base = ctf_type_resolve(cp->dn_ctfp, type);
+ kind = ctf_type_kind(cp->dn_ctfp, base);
+
+ if (kind == CTF_K_INTEGER && ctf_type_encoding(cp->dn_ctfp,
+ base, &e) == 0 && IS_VOID(e)) {
+ xyerror(D_DEREF_VOID,
+ "cannot dereference pointer to void\n");
+ }
+
+ if (kind == CTF_K_FUNCTION) {
+ xyerror(D_DEREF_FUNC,
+ "cannot dereference pointer to function\n");
+ }
+
+ if (kind != CTF_K_ARRAY || dt_node_is_string(dnp))
+ dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.4.3] */
+
+ /*
+ * If we propagated the l-value bit and the child operand was
+ * a writable D variable or a binary operation of the form
+ * a + b where a is writable, then propagate the writable bit.
+ * This is necessary to permit assignments to scalar arrays,
+ * which are converted to expressions of the form *(a + i).
+ */
+ if ((cp->dn_flags & DT_NF_WRITABLE) ||
+ (cp->dn_kind == DT_NODE_OP2 && cp->dn_op == DT_TOK_ADD &&
+ (cp->dn_left->dn_flags & DT_NF_WRITABLE)))
+ dnp->dn_flags |= DT_NF_WRITABLE;
+
+ if ((cp->dn_flags & DT_NF_USERLAND) &&
+ (kind == CTF_K_POINTER || (dnp->dn_flags & DT_NF_REF)))
+ dnp->dn_flags |= DT_NF_USERLAND;
+ break;
+
+ case DT_TOK_IPOS:
+ case DT_TOK_INEG:
+ if (!dt_node_is_arith(cp)) {
+ xyerror(D_OP_ARITH, "operator %s requires an operand "
+ "of arithmetic type\n", opstr(dnp->dn_op));
+ }
+ dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.4-6] */
+ break;
+
+ case DT_TOK_BNEG:
+ if (!dt_node_is_integer(cp)) {
+ xyerror(D_OP_INT, "operator %s requires an operand of "
+ "integral type\n", opstr(dnp->dn_op));
+ }
+ dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.4-6] */
+ break;
+
+ case DT_TOK_LNEG:
+ if (!dt_node_is_scalar(cp)) {
+ xyerror(D_OP_SCALAR, "operator %s requires an operand "
+ "of scalar type\n", opstr(dnp->dn_op));
+ }
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ break;
+
+ case DT_TOK_ADDROF:
+ if (cp->dn_kind == DT_NODE_VAR || cp->dn_kind == DT_NODE_AGG) {
+ xyerror(D_ADDROF_VAR,
+ "cannot take address of dynamic variable\n");
+ }
+
+ if (dt_node_is_dynamic(cp)) {
+ xyerror(D_ADDROF_VAR,
+ "cannot take address of dynamic object\n");
+ }
+
+ if (!(cp->dn_flags & DT_NF_LVALUE)) {
+ xyerror(D_ADDROF_LVAL, /* see K&R[A7.4.2] */
+ "unacceptable operand for unary & operator\n");
+ }
+
+ if (cp->dn_flags & DT_NF_BITFIELD) {
+ xyerror(D_ADDROF_BITFIELD,
+ "cannot take address of bit-field\n");
+ }
+
+ dtt.dtt_object = NULL;
+ dtt.dtt_ctfp = cp->dn_ctfp;
+ dtt.dtt_type = cp->dn_type;
+
+ if (dt_type_pointer(&dtt) == -1) {
+ xyerror(D_TYPE_ERR, "cannot find type for \"&\": %s*\n",
+ dt_node_type_name(cp, n, sizeof (n)));
+ }
+
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+
+ if (cp->dn_flags & DT_NF_USERLAND)
+ dnp->dn_flags |= DT_NF_USERLAND;
+ break;
+
+ case DT_TOK_SIZEOF:
+ if (cp->dn_flags & DT_NF_BITFIELD) {
+ xyerror(D_SIZEOF_BITFIELD,
+ "cannot apply sizeof to a bit-field\n");
+ }
+
+ if (dt_node_sizeof(cp) == 0) {
+ xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an "
+ "operand of unknown size\n");
+ }
+
+ dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp,
+ ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+ break;
+
+ case DT_TOK_STRINGOF:
+ if (!dt_node_is_scalar(cp) && !dt_node_is_pointer(cp) &&
+ !dt_node_is_strcompat(cp)) {
+ xyerror(D_STRINGOF_TYPE,
+ "cannot apply stringof to a value of type %s\n",
+ dt_node_type_name(cp, n, sizeof (n)));
+ }
+ dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp));
+ break;
+
+ case DT_TOK_PREINC:
+ case DT_TOK_POSTINC:
+ case DT_TOK_PREDEC:
+ case DT_TOK_POSTDEC:
+ if (dt_node_is_scalar(cp) == 0) {
+ xyerror(D_OP_SCALAR, "operator %s requires operand of "
+ "scalar type\n", opstr(dnp->dn_op));
+ }
+
+ if (dt_node_is_vfptr(cp)) {
+ xyerror(D_OP_VFPTR, "operator %s requires an operand "
+ "of known size\n", opstr(dnp->dn_op));
+ }
+
+ if (!(cp->dn_flags & DT_NF_LVALUE)) {
+ xyerror(D_OP_LVAL, "operator %s requires modifiable "
+ "lvalue as an operand\n", opstr(dnp->dn_op));
+ }
+
+ if (!(cp->dn_flags & DT_NF_WRITABLE)) {
+ xyerror(D_OP_WRITE, "operator %s can only be applied "
+ "to a writable variable\n", opstr(dnp->dn_op));
+ }
+
+ dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.1] */
+ break;
+
+ default:
+ xyerror(D_UNKNOWN, "invalid unary op %s\n", opstr(dnp->dn_op));
+ }
+
+ dt_node_attr_assign(dnp, cp->dn_attr);
+ return (dnp);
+}
+
+static dt_node_t *
+dt_cook_op2(dt_node_t *dnp, uint_t idflags)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *lp = dnp->dn_left;
+ dt_node_t *rp = dnp->dn_right;
+ int op = dnp->dn_op;
+
+ ctf_membinfo_t m;
+ ctf_file_t *ctfp;
+ ctf_id_t type;
+ int kind, val, uref;
+ dt_ident_t *idp;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ /*
+ * The expression E1[E2] is identical by definition to *((E1)+(E2)) so
+ * we convert "[" to "+" and glue on "*" at the end (see K&R[A7.3.1])
+ * unless the left-hand side is an untyped D scalar, associative array,
+ * or aggregation. In these cases, we proceed to case DT_TOK_LBRAC and
+ * handle associative array and aggregation references there.
+ */
+ if (op == DT_TOK_LBRAC) {
+ if (lp->dn_kind == DT_NODE_IDENT) {
+ dt_idhash_t *dhp;
+ uint_t idkind;
+
+ if (lp->dn_op == DT_TOK_AGG) {
+ dhp = dtp->dt_aggs;
+ idp = dt_idhash_lookup(dhp, lp->dn_string + 1);
+ idkind = DT_IDENT_AGG;
+ } else {
+ dhp = dtp->dt_globals;
+ idp = dt_idstack_lookup(
+ &yypcb->pcb_globals, lp->dn_string);
+ idkind = DT_IDENT_ARRAY;
+ }
+
+ if (idp == NULL || dt_ident_unref(idp))
+ dt_xcook_ident(lp, dhp, idkind, B_TRUE);
+ else
+ dt_xcook_ident(lp, dhp, idp->di_kind, B_FALSE);
+ } else
+ lp = dnp->dn_left = dt_node_cook(lp, 0);
+
+ /*
+ * Switch op to '+' for *(E1 + E2) array mode in these cases:
+ * (a) lp is a DT_IDENT_ARRAY variable that has already been
+ * referenced using [] notation (dn_args != NULL).
+ * (b) lp is a non-ARRAY variable that has already been given
+ * a type by assignment or declaration (!dt_ident_unref())
+ * (c) lp is neither a variable nor an aggregation
+ */
+ if (lp->dn_kind == DT_NODE_VAR) {
+ if (lp->dn_ident->di_kind == DT_IDENT_ARRAY) {
+ if (lp->dn_args != NULL)
+ op = DT_TOK_ADD;
+ } else if (!dt_ident_unref(lp->dn_ident))
+ op = DT_TOK_ADD;
+ } else if (lp->dn_kind != DT_NODE_AGG)
+ op = DT_TOK_ADD;
+ }
+
+ switch (op) {
+ case DT_TOK_BAND:
+ case DT_TOK_XOR:
+ case DT_TOK_BOR:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) {
+ xyerror(D_OP_INT, "operator %s requires operands of "
+ "integral type\n", opstr(op));
+ }
+
+ dt_node_promote(lp, rp, dnp); /* see K&R[A7.11-13] */
+ break;
+
+ case DT_TOK_LSH:
+ case DT_TOK_RSH:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) {
+ xyerror(D_OP_INT, "operator %s requires operands of "
+ "integral type\n", opstr(op));
+ }
+
+ dt_node_type_propagate(lp, dnp); /* see K&R[A7.8] */
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+
+ case DT_TOK_MOD:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) {
+ xyerror(D_OP_INT, "operator %s requires operands of "
+ "integral type\n", opstr(op));
+ }
+
+ dt_node_promote(lp, rp, dnp); /* see K&R[A7.6] */
+ break;
+
+ case DT_TOK_MUL:
+ case DT_TOK_DIV:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (!dt_node_is_arith(lp) || !dt_node_is_arith(rp)) {
+ xyerror(D_OP_ARITH, "operator %s requires operands of "
+ "arithmetic type\n", opstr(op));
+ }
+
+ dt_node_promote(lp, rp, dnp); /* see K&R[A7.6] */
+ break;
+
+ case DT_TOK_LAND:
+ case DT_TOK_LXOR:
+ case DT_TOK_LOR:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (!dt_node_is_scalar(lp) || !dt_node_is_scalar(rp)) {
+ xyerror(D_OP_SCALAR, "operator %s requires operands "
+ "of scalar type\n", opstr(op));
+ }
+
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+
+ case DT_TOK_LT:
+ case DT_TOK_LE:
+ case DT_TOK_GT:
+ case DT_TOK_GE:
+ case DT_TOK_EQU:
+ case DT_TOK_NEQ:
+ /*
+ * The D comparison operators provide the ability to transform
+ * a right-hand identifier into a corresponding enum tag value
+ * if the left-hand side is an enum type. To do this, we cook
+ * the left-hand side, and then see if the right-hand side is
+ * an unscoped identifier defined in the enum. If so, we
+ * convert into an integer constant node with the tag's value.
+ */
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+
+ kind = ctf_type_kind(lp->dn_ctfp,
+ ctf_type_resolve(lp->dn_ctfp, lp->dn_type));
+
+ if (kind == CTF_K_ENUM && rp->dn_kind == DT_NODE_IDENT &&
+ strchr(rp->dn_string, '`') == NULL && ctf_enum_value(
+ lp->dn_ctfp, lp->dn_type, rp->dn_string, &val) == 0) {
+
+ if ((idp = dt_idstack_lookup(&yypcb->pcb_globals,
+ rp->dn_string)) != NULL) {
+ xyerror(D_IDENT_AMBIG,
+ "ambiguous use of operator %s: %s is "
+ "both a %s enum tag and a global %s\n",
+ opstr(op), rp->dn_string,
+ dt_node_type_name(lp, n1, sizeof (n1)),
+ dt_idkind_name(idp->di_kind));
+ }
+
+ free(rp->dn_string);
+ rp->dn_string = NULL;
+ rp->dn_kind = DT_NODE_INT;
+ rp->dn_flags |= DT_NF_COOKED;
+ rp->dn_op = DT_TOK_INT;
+ rp->dn_value = (intmax_t)val;
+
+ dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type);
+ dt_node_attr_assign(rp, _dtrace_symattr);
+ }
+
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ /*
+ * The rules for type checking for the relational operators are
+ * described in the ANSI-C spec (see K&R[A7.9-10]). We perform
+ * the various tests in order from least to most expensive. We
+ * also allow derived strings to be compared as a first-class
+ * type (resulting in a strcmp(3C)-style comparison), and we
+ * slightly relax the A7.9 rules to permit void pointer
+ * comparisons as in A7.10. Our users won't be confused by
+ * this since they understand pointers are just numbers, and
+ * relaxing this constraint simplifies the implementation.
+ */
+ if (ctf_type_compat(lp->dn_ctfp, lp->dn_type,
+ rp->dn_ctfp, rp->dn_type))
+ /*EMPTY*/;
+ else if (dt_node_is_integer(lp) && dt_node_is_integer(rp))
+ /*EMPTY*/;
+ else if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp) &&
+ (dt_node_is_string(lp) || dt_node_is_string(rp)))
+ /*EMPTY*/;
+ else if (dt_node_is_ptrcompat(lp, rp, NULL, NULL) == 0) {
+ xyerror(D_OP_INCOMPAT, "operands have "
+ "incompatible types: \"%s\" %s \"%s\"\n",
+ dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
+ dt_node_type_name(rp, n2, sizeof (n2)));
+ }
+
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+
+ case DT_TOK_ADD:
+ case DT_TOK_SUB: {
+ /*
+ * The rules for type checking for the additive operators are
+ * described in the ANSI-C spec (see K&R[A7.7]). Pointers and
+ * integers may be manipulated according to specific rules. In
+ * these cases D permits strings to be treated as pointers.
+ */
+ int lp_is_ptr, lp_is_int, rp_is_ptr, rp_is_int;
+
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ lp_is_ptr = dt_node_is_string(lp) ||
+ (dt_node_is_pointer(lp) && !dt_node_is_vfptr(lp));
+ lp_is_int = dt_node_is_integer(lp);
+
+ rp_is_ptr = dt_node_is_string(rp) ||
+ (dt_node_is_pointer(rp) && !dt_node_is_vfptr(rp));
+ rp_is_int = dt_node_is_integer(rp);
+
+ if (lp_is_int && rp_is_int) {
+ dt_type_promote(lp, rp, &ctfp, &type);
+ uref = 0;
+ } else if (lp_is_ptr && rp_is_int) {
+ ctfp = lp->dn_ctfp;
+ type = lp->dn_type;
+ uref = lp->dn_flags & DT_NF_USERLAND;
+ } else if (lp_is_int && rp_is_ptr && op == DT_TOK_ADD) {
+ ctfp = rp->dn_ctfp;
+ type = rp->dn_type;
+ uref = rp->dn_flags & DT_NF_USERLAND;
+ } else if (lp_is_ptr && rp_is_ptr && op == DT_TOK_SUB &&
+ dt_node_is_ptrcompat(lp, rp, NULL, NULL)) {
+ ctfp = dtp->dt_ddefs->dm_ctfp;
+ type = ctf_lookup_by_name(ctfp, "ptrdiff_t");
+ uref = 0;
+ } else {
+ xyerror(D_OP_INCOMPAT, "operands have incompatible "
+ "types: \"%s\" %s \"%s\"\n",
+ dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
+ dt_node_type_name(rp, n2, sizeof (n2)));
+ }
+
+ dt_node_type_assign(dnp, ctfp, type);
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+
+ if (uref)
+ dnp->dn_flags |= DT_NF_USERLAND;
+ break;
+ }
+
+ case DT_TOK_OR_EQ:
+ case DT_TOK_XOR_EQ:
+ case DT_TOK_AND_EQ:
+ case DT_TOK_LSH_EQ:
+ case DT_TOK_RSH_EQ:
+ case DT_TOK_MOD_EQ:
+ if (lp->dn_kind == DT_NODE_IDENT) {
+ dt_xcook_ident(lp, dtp->dt_globals,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+
+ lp = dnp->dn_left =
+ dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ rp = dnp->dn_right =
+ dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) {
+ xyerror(D_OP_INT, "operator %s requires operands of "
+ "integral type\n", opstr(op));
+ }
+ goto asgn_common;
+
+ case DT_TOK_MUL_EQ:
+ case DT_TOK_DIV_EQ:
+ if (lp->dn_kind == DT_NODE_IDENT) {
+ dt_xcook_ident(lp, dtp->dt_globals,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+
+ lp = dnp->dn_left =
+ dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ rp = dnp->dn_right =
+ dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ if (!dt_node_is_arith(lp) || !dt_node_is_arith(rp)) {
+ xyerror(D_OP_ARITH, "operator %s requires operands of "
+ "arithmetic type\n", opstr(op));
+ }
+ goto asgn_common;
+
+ case DT_TOK_ASGN:
+ /*
+ * If the left-hand side is an identifier, attempt to resolve
+ * it as either an aggregation or scalar variable. We pass
+ * B_TRUE to dt_xcook_ident to indicate that a new variable can
+ * be created if no matching variable exists in the namespace.
+ */
+ if (lp->dn_kind == DT_NODE_IDENT) {
+ if (lp->dn_op == DT_TOK_AGG) {
+ dt_xcook_ident(lp, dtp->dt_aggs,
+ DT_IDENT_AGG, B_TRUE);
+ } else {
+ dt_xcook_ident(lp, dtp->dt_globals,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+ }
+
+ lp = dnp->dn_left = dt_node_cook(lp, 0); /* don't set mod yet */
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ /*
+ * If the left-hand side is an aggregation, verify that we are
+ * assigning it the result of an aggregating function. Once
+ * we've done so, hide the func node in the aggregation and
+ * return the aggregation itself up to the parse tree parent.
+ * This transformation is legal since the assigned function
+ * cannot change identity across disjoint cooking passes and
+ * the argument list subtree is retained for later cooking.
+ */
+ if (lp->dn_kind == DT_NODE_AGG) {
+ const char *aname = lp->dn_ident->di_name;
+ dt_ident_t *oid = lp->dn_ident->di_iarg;
+
+ if (rp->dn_kind != DT_NODE_FUNC ||
+ rp->dn_ident->di_kind != DT_IDENT_AGGFUNC) {
+ xyerror(D_AGG_FUNC,
+ "@%s must be assigned the result of "
+ "an aggregating function\n", aname);
+ }
+
+ if (oid != NULL && oid != rp->dn_ident) {
+ xyerror(D_AGG_REDEF,
+ "aggregation redefined: @%s\n\t "
+ "current: @%s = %s( )\n\tprevious: @%s = "
+ "%s( ) : line %d\n", aname, aname,
+ rp->dn_ident->di_name, aname, oid->di_name,
+ lp->dn_ident->di_lineno);
+ } else if (oid == NULL)
+ lp->dn_ident->di_iarg = rp->dn_ident;
+
+ /*
+ * Do not allow multiple aggregation assignments in a
+ * single statement, e.g. (@a = count()) = count();
+ * We produce a message as if the result of aggregating
+ * function does not propagate DT_NF_LVALUE.
+ */
+ if (lp->dn_aggfun != NULL) {
+ xyerror(D_OP_LVAL, "operator = requires "
+ "modifiable lvalue as an operand\n");
+ }
+
+ lp->dn_aggfun = rp;
+ lp = dt_node_cook(lp, DT_IDFLG_MOD);
+
+ dnp->dn_left = dnp->dn_right = NULL;
+ dt_node_free(dnp);
+
+ return (lp);
+ }
+
+ /*
+ * If the right-hand side is a dynamic variable that is the
+ * output of a translator, our result is the translated type.
+ */
+ if ((idp = dt_node_resolve(rp, DT_IDENT_XLSOU)) != NULL) {
+ ctfp = idp->di_ctfp;
+ type = idp->di_type;
+ uref = idp->di_flags & DT_IDFLG_USER;
+ } else {
+ ctfp = rp->dn_ctfp;
+ type = rp->dn_type;
+ uref = rp->dn_flags & DT_NF_USERLAND;
+ }
+
+ /*
+ * If the left-hand side of an assignment statement is a virgin
+ * variable created by this compilation pass, reset the type of
+ * this variable to the type of the right-hand side.
+ */
+ if (lp->dn_kind == DT_NODE_VAR &&
+ dt_ident_unref(lp->dn_ident)) {
+ dt_node_type_assign(lp, ctfp, type);
+ dt_ident_type_assign(lp->dn_ident, ctfp, type);
+
+ if (uref) {
+ lp->dn_flags |= DT_NF_USERLAND;
+ lp->dn_ident->di_flags |= DT_IDFLG_USER;
+ }
+ }
+
+ if (lp->dn_kind == DT_NODE_VAR)
+ lp->dn_ident->di_flags |= DT_IDFLG_MOD;
+
+ /*
+ * The rules for type checking for the assignment operators are
+ * described in the ANSI-C spec (see K&R[A7.17]). We share
+ * most of this code with the argument list checking code.
+ */
+ if (!dt_node_is_string(lp)) {
+ kind = ctf_type_kind(lp->dn_ctfp,
+ ctf_type_resolve(lp->dn_ctfp, lp->dn_type));
+
+ if (kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION) {
+ xyerror(D_OP_ARRFUN, "operator %s may not be "
+ "applied to operand of type \"%s\"\n",
+ opstr(op),
+ dt_node_type_name(lp, n1, sizeof (n1)));
+ }
+ }
+
+ if (idp != NULL && idp->di_kind == DT_IDENT_XLSOU &&
+ ctf_type_compat(lp->dn_ctfp, lp->dn_type, ctfp, type))
+ goto asgn_common;
+
+ if (dt_node_is_argcompat(lp, rp))
+ goto asgn_common;
+
+ xyerror(D_OP_INCOMPAT,
+ "operands have incompatible types: \"%s\" %s \"%s\"\n",
+ dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
+ dt_node_type_name(rp, n2, sizeof (n2)));
+ /*NOTREACHED*/
+
+ case DT_TOK_ADD_EQ:
+ case DT_TOK_SUB_EQ:
+ if (lp->dn_kind == DT_NODE_IDENT) {
+ dt_xcook_ident(lp, dtp->dt_globals,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+
+ lp = dnp->dn_left =
+ dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ rp = dnp->dn_right =
+ dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD);
+
+ if (dt_node_is_string(lp) || dt_node_is_string(rp)) {
+ xyerror(D_OP_INCOMPAT, "operands have "
+ "incompatible types: \"%s\" %s \"%s\"\n",
+ dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
+ dt_node_type_name(rp, n2, sizeof (n2)));
+ }
+
+ /*
+ * The rules for type checking for the assignment operators are
+ * described in the ANSI-C spec (see K&R[A7.17]). To these
+ * rules we add that only writable D nodes can be modified.
+ */
+ if (dt_node_is_integer(lp) == 0 ||
+ dt_node_is_integer(rp) == 0) {
+ if (!dt_node_is_pointer(lp) || dt_node_is_vfptr(lp)) {
+ xyerror(D_OP_VFPTR,
+ "operator %s requires left-hand scalar "
+ "operand of known size\n", opstr(op));
+ } else if (dt_node_is_integer(rp) == 0 &&
+ dt_node_is_ptrcompat(lp, rp, NULL, NULL) == 0) {
+ xyerror(D_OP_INCOMPAT, "operands have "
+ "incompatible types: \"%s\" %s \"%s\"\n",
+ dt_node_type_name(lp, n1, sizeof (n1)),
+ opstr(op),
+ dt_node_type_name(rp, n2, sizeof (n2)));
+ }
+ }
+asgn_common:
+ if (!(lp->dn_flags & DT_NF_LVALUE)) {
+ xyerror(D_OP_LVAL, "operator %s requires modifiable "
+ "lvalue as an operand\n", opstr(op));
+ /* see K&R[A7.17] */
+ }
+
+ if (!(lp->dn_flags & DT_NF_WRITABLE)) {
+ xyerror(D_OP_WRITE, "operator %s can only be applied "
+ "to a writable variable\n", opstr(op));
+ }
+
+ dt_node_type_propagate(lp, dnp); /* see K&R[A7.17] */
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+
+ case DT_TOK_PTR:
+ /*
+ * If the left-hand side of operator -> is the name "self",
+ * then we permit a TLS variable to be created or referenced.
+ */
+ if (lp->dn_kind == DT_NODE_IDENT &&
+ strcmp(lp->dn_string, "self") == 0) {
+ if (rp->dn_kind != DT_NODE_VAR) {
+ dt_xcook_ident(rp, dtp->dt_tls,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+
+ if (idflags != 0)
+ rp = dt_node_cook(rp, idflags);
+
+ dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
+ dt_node_free(dnp);
+ return (rp);
+ }
+
+ /*
+ * If the left-hand side of operator -> is the name "this",
+ * then we permit a local variable to be created or referenced.
+ */
+ if (lp->dn_kind == DT_NODE_IDENT &&
+ strcmp(lp->dn_string, "this") == 0) {
+ if (rp->dn_kind != DT_NODE_VAR) {
+ dt_xcook_ident(rp, yypcb->pcb_locals,
+ DT_IDENT_SCALAR, B_TRUE);
+ }
+
+ if (idflags != 0)
+ rp = dt_node_cook(rp, idflags);
+
+ dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
+ dt_node_free(dnp);
+ return (rp);
+ }
+
+ /*FALLTHRU*/
+
+ case DT_TOK_DOT:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+
+ if (rp->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_OP_IDENT, "operator %s must be followed by "
+ "an identifier\n", opstr(op));
+ }
+
+ if ((idp = dt_node_resolve(lp, DT_IDENT_XLSOU)) != NULL ||
+ (idp = dt_node_resolve(lp, DT_IDENT_XLPTR)) != NULL) {
+ /*
+ * If the left-hand side is a translated struct or ptr,
+ * the type of the left is the translation output type.
+ */
+ dt_xlator_t *dxp = idp->di_data;
+
+ if (dt_xlator_member(dxp, rp->dn_string) == NULL) {
+ xyerror(D_XLATE_NOCONV,
+ "translator does not define conversion "
+ "for member: %s\n", rp->dn_string);
+ }
+
+ ctfp = idp->di_ctfp;
+ type = ctf_type_resolve(ctfp, idp->di_type);
+ uref = idp->di_flags & DT_IDFLG_USER;
+ } else {
+ ctfp = lp->dn_ctfp;
+ type = ctf_type_resolve(ctfp, lp->dn_type);
+ uref = lp->dn_flags & DT_NF_USERLAND;
+ }
+
+ kind = ctf_type_kind(ctfp, type);
+
+ if (op == DT_TOK_PTR) {
+ if (kind != CTF_K_POINTER) {
+ xyerror(D_OP_PTR, "operator %s must be "
+ "applied to a pointer\n", opstr(op));
+ }
+ type = ctf_type_reference(ctfp, type);
+ type = ctf_type_resolve(ctfp, type);
+ kind = ctf_type_kind(ctfp, type);
+ }
+
+ /*
+ * If we follow a reference to a forward declaration tag,
+ * search the entire type space for the actual definition.
+ */
+ while (kind == CTF_K_FORWARD) {
+ char *tag = ctf_type_name(ctfp, type, n1, sizeof (n1));
+ dtrace_typeinfo_t dtt;
+
+ if (tag != NULL && dt_type_lookup(tag, &dtt) == 0 &&
+ (dtt.dtt_ctfp != ctfp || dtt.dtt_type != type)) {
+ ctfp = dtt.dtt_ctfp;
+ type = ctf_type_resolve(ctfp, dtt.dtt_type);
+ kind = ctf_type_kind(ctfp, type);
+ } else {
+ xyerror(D_OP_INCOMPLETE,
+ "operator %s cannot be applied to a "
+ "forward declaration: no %s definition "
+ "is available\n", opstr(op), tag);
+ }
+ }
+
+ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) {
+ if (op == DT_TOK_PTR) {
+ xyerror(D_OP_SOU, "operator -> cannot be "
+ "applied to pointer to type \"%s\"; must "
+ "be applied to a struct or union pointer\n",
+ ctf_type_name(ctfp, type, n1, sizeof (n1)));
+ } else {
+ xyerror(D_OP_SOU, "operator %s cannot be "
+ "applied to type \"%s\"; must be applied "
+ "to a struct or union\n", opstr(op),
+ ctf_type_name(ctfp, type, n1, sizeof (n1)));
+ }
+ }
+
+ if (ctf_member_info(ctfp, type, rp->dn_string, &m) == CTF_ERR) {
+ xyerror(D_TYPE_MEMBER,
+ "%s is not a member of %s\n", rp->dn_string,
+ ctf_type_name(ctfp, type, n1, sizeof (n1)));
+ }
+
+ type = ctf_type_resolve(ctfp, m.ctm_type);
+ kind = ctf_type_kind(ctfp, type);
+
+ dt_node_type_assign(dnp, ctfp, m.ctm_type);
+ dt_node_attr_assign(dnp, lp->dn_attr);
+
+ if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY ||
+ dt_node_is_string(dnp)))
+ dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.3.3] */
+
+ if (op == DT_TOK_DOT && (lp->dn_flags & DT_NF_LVALUE) &&
+ (kind != CTF_K_ARRAY || dt_node_is_string(dnp)))
+ dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.3.3] */
+
+ if (lp->dn_flags & DT_NF_WRITABLE)
+ dnp->dn_flags |= DT_NF_WRITABLE;
+
+ if (uref && (kind == CTF_K_POINTER ||
+ (dnp->dn_flags & DT_NF_REF)))
+ dnp->dn_flags |= DT_NF_USERLAND;
+ break;
+
+ case DT_TOK_LBRAC: {
+ /*
+ * If op is DT_TOK_LBRAC, we know from the special-case code at
+ * the top that lp is either a D variable or an aggregation.
+ */
+ dt_node_t *lnp;
+
+ /*
+ * If the left-hand side is an aggregation, just set dn_aggtup
+ * to the right-hand side and return the cooked aggregation.
+ * This transformation is legal since we are just collapsing
+ * nodes to simplify later processing, and the entire aggtup
+ * parse subtree is retained for subsequent cooking passes.
+ */
+ if (lp->dn_kind == DT_NODE_AGG) {
+ if (lp->dn_aggtup != NULL) {
+ xyerror(D_AGG_MDIM, "improper attempt to "
+ "reference @%s as a multi-dimensional "
+ "array\n", lp->dn_ident->di_name);
+ }
+
+ lp->dn_aggtup = rp;
+ lp = dt_node_cook(lp, 0);
+
+ dnp->dn_left = dnp->dn_right = NULL;
+ dt_node_free(dnp);
+
+ return (lp);
+ }
+
+ assert(lp->dn_kind == DT_NODE_VAR);
+ idp = lp->dn_ident;
+
+ /*
+ * If the left-hand side is a non-global scalar that hasn't yet
+ * been referenced or modified, it was just created by self->
+ * or this-> and we can convert it from scalar to assoc array.
+ */
+ if (idp->di_kind == DT_IDENT_SCALAR && dt_ident_unref(idp) &&
+ (idp->di_flags & (DT_IDFLG_LOCAL | DT_IDFLG_TLS)) != 0) {
+
+ if (idp->di_flags & DT_IDFLG_LOCAL) {
+ xyerror(D_ARR_LOCAL,
+ "local variables may not be used as "
+ "associative arrays: %s\n", idp->di_name);
+ }
+
+ dt_dprintf("morph variable %s (id %u) from scalar to "
+ "array\n", idp->di_name, idp->di_id);
+
+ dt_ident_morph(idp, DT_IDENT_ARRAY,
+ &dt_idops_assc, NULL);
+ }
+
+ if (idp->di_kind != DT_IDENT_ARRAY) {
+ xyerror(D_IDENT_BADREF, "%s '%s' may not be referenced "
+ "as %s\n", dt_idkind_name(idp->di_kind),
+ idp->di_name, dt_idkind_name(DT_IDENT_ARRAY));
+ }
+
+ /*
+ * Now that we've confirmed our left-hand side is a DT_NODE_VAR
+ * of idkind DT_IDENT_ARRAY, we need to splice the [ node from
+ * the parse tree and leave a cooked DT_NODE_VAR in its place
+ * where dn_args for the VAR node is the right-hand 'rp' tree,
+ * as shown in the parse tree diagram below:
+ *
+ * / /
+ * [ OP2 "[" ]=dnp [ VAR ]=dnp
+ * / \ => |
+ * / \ +- dn_args -> [ ??? ]=rp
+ * [ VAR ]=lp [ ??? ]=rp
+ *
+ * Since the final dt_node_cook(dnp) can fail using longjmp we
+ * must perform the transformations as a group first by over-
+ * writing 'dnp' to become the VAR node, so that the parse tree
+ * is guaranteed to be in a consistent state if the cook fails.
+ */
+ assert(lp->dn_kind == DT_NODE_VAR);
+ assert(lp->dn_args == NULL);
+
+ lnp = dnp->dn_link;
+ bcopy(lp, dnp, sizeof (dt_node_t));
+ dnp->dn_link = lnp;
+
+ dnp->dn_args = rp;
+ dnp->dn_list = NULL;
+
+ dt_node_free(lp);
+ return (dt_node_cook(dnp, idflags));
+ }
+
+ case DT_TOK_XLATE: {
+ dt_xlator_t *dxp;
+
+ assert(lp->dn_kind == DT_NODE_TYPE);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+ dxp = dt_xlator_lookup(dtp, rp, lp, DT_XLATE_FUZZY);
+
+ if (dxp == NULL) {
+ xyerror(D_XLATE_NONE,
+ "cannot translate from \"%s\" to \"%s\"\n",
+ dt_node_type_name(rp, n1, sizeof (n1)),
+ dt_node_type_name(lp, n2, sizeof (n2)));
+ }
+
+ dnp->dn_ident = dt_xlator_ident(dxp, lp->dn_ctfp, lp->dn_type);
+ dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ dt_node_attr_assign(dnp,
+ dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr));
+ break;
+ }
+
+ case DT_TOK_LPAR: {
+ ctf_id_t ltype, rtype;
+ uint_t lkind, rkind;
+
+ assert(lp->dn_kind == DT_NODE_TYPE);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ ltype = ctf_type_resolve(lp->dn_ctfp, lp->dn_type);
+ lkind = ctf_type_kind(lp->dn_ctfp, ltype);
+
+ rtype = ctf_type_resolve(rp->dn_ctfp, rp->dn_type);
+ rkind = ctf_type_kind(rp->dn_ctfp, rtype);
+
+ /*
+ * The rules for casting are loosely explained in K&R[A7.5]
+ * and K&R[A6]. Basically, we can cast to the same type or
+ * same base type, between any kind of scalar values, from
+ * arrays to pointers, and we can cast anything to void.
+ * To these rules D adds casts from scalars to strings.
+ */
+ if (ctf_type_compat(lp->dn_ctfp, lp->dn_type,
+ rp->dn_ctfp, rp->dn_type))
+ /*EMPTY*/;
+ else if (dt_node_is_scalar(lp) &&
+ (dt_node_is_scalar(rp) || rkind == CTF_K_FUNCTION))
+ /*EMPTY*/;
+ else if (dt_node_is_void(lp))
+ /*EMPTY*/;
+ else if (lkind == CTF_K_POINTER && dt_node_is_pointer(rp))
+ /*EMPTY*/;
+ else if (dt_node_is_string(lp) && (dt_node_is_scalar(rp) ||
+ dt_node_is_pointer(rp) || dt_node_is_strcompat(rp)))
+ /*EMPTY*/;
+ else {
+ xyerror(D_CAST_INVAL,
+ "invalid cast expression: \"%s\" to \"%s\"\n",
+ dt_node_type_name(rp, n1, sizeof (n1)),
+ dt_node_type_name(lp, n2, sizeof (n2)));
+ }
+
+ dt_node_type_propagate(lp, dnp); /* see K&R[A7.5] */
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+ }
+
+ case DT_TOK_COMMA:
+ lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
+
+ if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) {
+ xyerror(D_OP_DYN, "operator %s operands "
+ "cannot be of dynamic type\n", opstr(op));
+ }
+
+ if (dt_node_is_actfunc(lp) || dt_node_is_actfunc(rp)) {
+ xyerror(D_OP_ACT, "operator %s operands "
+ "cannot be actions\n", opstr(op));
+ }
+
+ dt_node_type_propagate(rp, dnp); /* see K&R[A7.18] */
+ dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
+ break;
+
+ default:
+ xyerror(D_UNKNOWN, "invalid binary op %s\n", opstr(op));
+ }
+
+ /*
+ * Complete the conversion of E1[E2] to *((E1)+(E2)) that we started
+ * at the top of our switch() above (see K&R[A7.3.1]). Since E2 is
+ * parsed as an argument_expression_list by dt_grammar.y, we can
+ * end up with a comma-separated list inside of a non-associative
+ * array reference. We check for this and report an appropriate error.
+ */
+ if (dnp->dn_op == DT_TOK_LBRAC && op == DT_TOK_ADD) {
+ dt_node_t *pnp;
+
+ if (rp->dn_list != NULL) {
+ xyerror(D_ARR_BADREF,
+ "cannot access %s as an associative array\n",
+ dt_node_name(lp, n1, sizeof (n1)));
+ }
+
+ dnp->dn_op = DT_TOK_ADD;
+ pnp = dt_node_op1(DT_TOK_DEREF, dnp);
+
+ /*
+ * Cook callbacks are not typically permitted to allocate nodes.
+ * When we do, we must insert them in the middle of an existing
+ * allocation list rather than having them appended to the pcb
+ * list because the sub-expression may be part of a definition.
+ */
+ assert(yypcb->pcb_list == pnp);
+ yypcb->pcb_list = pnp->dn_link;
+
+ pnp->dn_link = dnp->dn_link;
+ dnp->dn_link = pnp;
+
+ return (dt_node_cook(pnp, DT_IDFLG_REF));
+ }
+
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_op3(dt_node_t *dnp, uint_t idflags)
+{
+ dt_node_t *lp, *rp;
+ ctf_file_t *ctfp;
+ ctf_id_t type;
+
+ dnp->dn_expr = dt_node_cook(dnp->dn_expr, DT_IDFLG_REF);
+ lp = dnp->dn_left = dt_node_cook(dnp->dn_left, DT_IDFLG_REF);
+ rp = dnp->dn_right = dt_node_cook(dnp->dn_right, DT_IDFLG_REF);
+
+ if (!dt_node_is_scalar(dnp->dn_expr)) {
+ xyerror(D_OP_SCALAR,
+ "operator ?: expression must be of scalar type\n");
+ }
+
+ if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) {
+ xyerror(D_OP_DYN,
+ "operator ?: operands cannot be of dynamic type\n");
+ }
+
+ /*
+ * The rules for type checking for the ternary operator are complex and
+ * are described in the ANSI-C spec (see K&R[A7.16]). We implement
+ * the various tests in order from least to most expensive.
+ */
+ if (ctf_type_compat(lp->dn_ctfp, lp->dn_type,
+ rp->dn_ctfp, rp->dn_type)) {
+ ctfp = lp->dn_ctfp;
+ type = lp->dn_type;
+ } else if (dt_node_is_integer(lp) && dt_node_is_integer(rp)) {
+ dt_type_promote(lp, rp, &ctfp, &type);
+ } else if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp) &&
+ (dt_node_is_string(lp) || dt_node_is_string(rp))) {
+ ctfp = DT_STR_CTFP(yypcb->pcb_hdl);
+ type = DT_STR_TYPE(yypcb->pcb_hdl);
+ } else if (dt_node_is_ptrcompat(lp, rp, &ctfp, &type) == 0) {
+ xyerror(D_OP_INCOMPAT,
+ "operator ?: operands must have compatible types\n");
+ }
+
+ if (dt_node_is_actfunc(lp) || dt_node_is_actfunc(rp)) {
+ xyerror(D_OP_ACT, "action cannot be "
+ "used in a conditional context\n");
+ }
+
+ dt_node_type_assign(dnp, ctfp, type);
+ dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr,
+ dt_attr_min(lp->dn_attr, rp->dn_attr)));
+
+ return (dnp);
+}
+
+static dt_node_t *
+dt_cook_statement(dt_node_t *dnp, uint_t idflags)
+{
+ dnp->dn_expr = dt_node_cook(dnp->dn_expr, idflags);
+ dt_node_attr_assign(dnp, dnp->dn_expr->dn_attr);
+
+ return (dnp);
+}
+
+/*
+ * If dn_aggfun is set, this node is a collapsed aggregation assignment (see
+ * the special case code for DT_TOK_ASGN in dt_cook_op2() above), in which
+ * case we cook both the tuple and the function call. If dn_aggfun is NULL,
+ * this node is just a reference to the aggregation's type and attributes.
+ */
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_aggregation(dt_node_t *dnp, uint_t idflags)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
+ if (dnp->dn_aggfun != NULL) {
+ dnp->dn_aggfun = dt_node_cook(dnp->dn_aggfun, DT_IDFLG_REF);
+ dt_node_attr_assign(dnp, dt_ident_cook(dnp,
+ dnp->dn_ident, &dnp->dn_aggtup));
+ } else {
+ dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ dt_node_attr_assign(dnp, dnp->dn_ident->di_attr);
+ }
+
+ return (dnp);
+}
+
+/*
+ * Since D permits new variable identifiers to be instantiated in any program
+ * expression, we may need to cook a clause's predicate either before or after
+ * the action list depending on the program code in question. Consider:
+ *
+ * probe-description-list probe-description-list
+ * /x++/ /x == 0/
+ * { {
+ * trace(x); trace(x++);
+ * } }
+ *
+ * In the left-hand example, the predicate uses operator ++ to instantiate 'x'
+ * as a variable of type int64_t. The predicate must be cooked first because
+ * otherwise the statement trace(x) refers to an unknown identifier. In the
+ * right-hand example, the action list uses ++ to instantiate 'x'; the action
+ * list must be cooked first because otherwise the predicate x == 0 refers to
+ * an unknown identifier. In order to simplify programming, we support both.
+ *
+ * When cooking a clause, we cook the action statements before the predicate by
+ * default, since it seems more common to create or modify identifiers in the
+ * action list. If cooking fails due to an unknown identifier, we attempt to
+ * cook the predicate (i.e. do it first) and then go back and cook the actions.
+ * If this, too, fails (or if we get an error other than D_IDENT_UNDEF) we give
+ * up and report failure back to the user. There are five possible paths:
+ *
+ * cook actions = OK, cook predicate = OK -> OK
+ * cook actions = OK, cook predicate = ERR -> ERR
+ * cook actions = ERR, cook predicate = ERR -> ERR
+ * cook actions = ERR, cook predicate = OK, cook actions = OK -> OK
+ * cook actions = ERR, cook predicate = OK, cook actions = ERR -> ERR
+ *
+ * The programmer can still defeat our scheme by creating circular definition
+ * dependencies between predicates and actions, as in this example clause:
+ *
+ * probe-description-list
+ * /x++ && y == 0/
+ * {
+ * trace(x + y++);
+ * }
+ *
+ * but it doesn't seem worth the complexity to handle such rare cases. The
+ * user can simply use the D variable declaration syntax to work around them.
+ */
+static dt_node_t *
+dt_cook_clause(dt_node_t *dnp, uint_t idflags)
+{
+ volatile int err, tries;
+ jmp_buf ojb;
+
+ /*
+ * Before assigning dn_ctxattr, temporarily assign the probe attribute
+ * to 'dnp' itself to force an attribute check and minimum violation.
+ */
+ dt_node_attr_assign(dnp, yypcb->pcb_pinfo.dtp_attr);
+ dnp->dn_ctxattr = yypcb->pcb_pinfo.dtp_attr;
+
+ bcopy(yypcb->pcb_jmpbuf, ojb, sizeof (jmp_buf));
+ tries = 0;
+
+ if (dnp->dn_pred != NULL && (err = setjmp(yypcb->pcb_jmpbuf)) != 0) {
+ bcopy(ojb, yypcb->pcb_jmpbuf, sizeof (jmp_buf));
+ if (tries++ != 0 || err != EDT_COMPILER || (
+ yypcb->pcb_hdl->dt_errtag != dt_errtag(D_IDENT_UNDEF) &&
+ yypcb->pcb_hdl->dt_errtag != dt_errtag(D_VAR_UNDEF)))
+ longjmp(yypcb->pcb_jmpbuf, err);
+ }
+
+ if (tries == 0) {
+ yylabel("action list");
+
+ dt_node_attr_assign(dnp,
+ dt_node_list_cook(&dnp->dn_acts, idflags));
+
+ bcopy(ojb, yypcb->pcb_jmpbuf, sizeof (jmp_buf));
+ yylabel(NULL);
+ }
+
+ if (dnp->dn_pred != NULL) {
+ yylabel("predicate");
+
+ dnp->dn_pred = dt_node_cook(dnp->dn_pred, idflags);
+ dt_node_attr_assign(dnp,
+ dt_attr_min(dnp->dn_attr, dnp->dn_pred->dn_attr));
+
+ if (!dt_node_is_scalar(dnp->dn_pred)) {
+ xyerror(D_PRED_SCALAR,
+ "predicate result must be of scalar type\n");
+ }
+
+ yylabel(NULL);
+ }
+
+ if (tries != 0) {
+ yylabel("action list");
+
+ dt_node_attr_assign(dnp,
+ dt_node_list_cook(&dnp->dn_acts, idflags));
+
+ yylabel(NULL);
+ }
+
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_inline(dt_node_t *dnp, uint_t idflags)
+{
+ dt_idnode_t *inp = dnp->dn_ident->di_iarg;
+ dt_ident_t *rdp;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ assert(dnp->dn_ident->di_flags & DT_IDFLG_INLINE);
+ assert(inp->din_root->dn_flags & DT_NF_COOKED);
+
+ /*
+ * If we are inlining a translation, verify that the inline declaration
+ * type exactly matches the type that is returned by the translation.
+ * Otherwise just use dt_node_is_argcompat() to check the types.
+ */
+ if ((rdp = dt_node_resolve(inp->din_root, DT_IDENT_XLSOU)) != NULL ||
+ (rdp = dt_node_resolve(inp->din_root, DT_IDENT_XLPTR)) != NULL) {
+
+ ctf_file_t *lctfp = dnp->dn_ctfp;
+ ctf_id_t ltype = ctf_type_resolve(lctfp, dnp->dn_type);
+
+ dt_xlator_t *dxp = rdp->di_data;
+ ctf_file_t *rctfp = dxp->dx_dst_ctfp;
+ ctf_id_t rtype = dxp->dx_dst_base;
+
+ if (ctf_type_kind(lctfp, ltype) == CTF_K_POINTER) {
+ ltype = ctf_type_reference(lctfp, ltype);
+ ltype = ctf_type_resolve(lctfp, ltype);
+ }
+
+ if (ctf_type_compat(lctfp, ltype, rctfp, rtype) == 0) {
+ dnerror(dnp, D_OP_INCOMPAT,
+ "inline %s definition uses incompatible types: "
+ "\"%s\" = \"%s\"\n", dnp->dn_ident->di_name,
+ dt_type_name(lctfp, ltype, n1, sizeof (n1)),
+ dt_type_name(rctfp, rtype, n2, sizeof (n2)));
+ }
+
+ } else if (dt_node_is_argcompat(dnp, inp->din_root) == 0) {
+ dnerror(dnp, D_OP_INCOMPAT,
+ "inline %s definition uses incompatible types: "
+ "\"%s\" = \"%s\"\n", dnp->dn_ident->di_name,
+ dt_node_type_name(dnp, n1, sizeof (n1)),
+ dt_node_type_name(inp->din_root, n2, sizeof (n2)));
+ }
+
+ return (dnp);
+}
+
+static dt_node_t *
+dt_cook_member(dt_node_t *dnp, uint_t idflags)
+{
+ dnp->dn_membexpr = dt_node_cook(dnp->dn_membexpr, idflags);
+ dt_node_attr_assign(dnp, dnp->dn_membexpr->dn_attr);
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_xlator(dt_node_t *dnp, uint_t idflags)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_xlator_t *dxp = dnp->dn_xlator;
+ dt_node_t *mnp;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ dtrace_attribute_t attr = _dtrace_maxattr;
+ ctf_membinfo_t ctm;
+
+ /*
+ * Before cooking each translator member, we push a reference to the
+ * hash containing translator-local identifiers on to pcb_globals to
+ * temporarily interpose these identifiers in front of other globals.
+ */
+ dt_idstack_push(&yypcb->pcb_globals, dxp->dx_locals);
+
+ for (mnp = dnp->dn_members; mnp != NULL; mnp = mnp->dn_list) {
+ if (ctf_member_info(dxp->dx_dst_ctfp, dxp->dx_dst_type,
+ mnp->dn_membname, &ctm) == CTF_ERR) {
+ xyerror(D_XLATE_MEMB,
+ "translator member %s is not a member of %s\n",
+ mnp->dn_membname, ctf_type_name(dxp->dx_dst_ctfp,
+ dxp->dx_dst_type, n1, sizeof (n1)));
+ }
+
+ (void) dt_node_cook(mnp, DT_IDFLG_REF);
+ dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type);
+ attr = dt_attr_min(attr, mnp->dn_attr);
+
+ if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) {
+ xyerror(D_XLATE_INCOMPAT,
+ "translator member %s definition uses "
+ "incompatible types: \"%s\" = \"%s\"\n",
+ mnp->dn_membname,
+ dt_node_type_name(mnp, n1, sizeof (n1)),
+ dt_node_type_name(mnp->dn_membexpr,
+ n2, sizeof (n2)));
+ }
+ }
+
+ dt_idstack_pop(&yypcb->pcb_globals, dxp->dx_locals);
+
+ dxp->dx_souid.di_attr = attr;
+ dxp->dx_ptrid.di_attr = attr;
+
+ dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ dt_node_attr_assign(dnp, _dtrace_defattr);
+
+ return (dnp);
+}
+
+static void
+dt_node_provider_cmp_argv(dt_provider_t *pvp, dt_node_t *pnp, const char *kind,
+ uint_t old_argc, dt_node_t *old_argv, uint_t new_argc, dt_node_t *new_argv)
+{
+ dt_probe_t *prp = pnp->dn_ident->di_data;
+ uint_t i;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ if (old_argc != new_argc) {
+ dnerror(pnp, D_PROV_INCOMPAT,
+ "probe %s:%s %s prototype mismatch:\n"
+ "\t current: %u arg%s\n\tprevious: %u arg%s\n",
+ pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, kind,
+ new_argc, new_argc != 1 ? "s" : "",
+ old_argc, old_argc != 1 ? "s" : "");
+ }
+
+ for (i = 0; i < old_argc; i++,
+ old_argv = old_argv->dn_list, new_argv = new_argv->dn_list) {
+ if (ctf_type_cmp(old_argv->dn_ctfp, old_argv->dn_type,
+ new_argv->dn_ctfp, new_argv->dn_type) == 0)
+ continue;
+
+ dnerror(pnp, D_PROV_INCOMPAT,
+ "probe %s:%s %s prototype argument #%u mismatch:\n"
+ "\t current: %s\n\tprevious: %s\n",
+ pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, kind, i + 1,
+ dt_node_type_name(new_argv, n1, sizeof (n1)),
+ dt_node_type_name(old_argv, n2, sizeof (n2)));
+ }
+}
+
+/*
+ * Compare a new probe declaration with an existing probe definition (either
+ * from a previous declaration or cached from the kernel). If the existing
+ * definition and declaration both have an input and output parameter list,
+ * compare both lists. Otherwise compare only the output parameter lists.
+ */
+static void
+dt_node_provider_cmp(dt_provider_t *pvp, dt_node_t *pnp,
+ dt_probe_t *old, dt_probe_t *new)
+{
+ dt_node_provider_cmp_argv(pvp, pnp, "output",
+ old->pr_xargc, old->pr_xargs, new->pr_xargc, new->pr_xargs);
+
+ if (old->pr_nargs != old->pr_xargs && new->pr_nargs != new->pr_xargs) {
+ dt_node_provider_cmp_argv(pvp, pnp, "input",
+ old->pr_nargc, old->pr_nargs, new->pr_nargc, new->pr_nargs);
+ }
+
+ if (old->pr_nargs == old->pr_xargs && new->pr_nargs != new->pr_xargs) {
+ if (pvp->pv_flags & DT_PROVIDER_IMPL) {
+ dnerror(pnp, D_PROV_INCOMPAT,
+ "provider interface mismatch: %s\n"
+ "\t current: probe %s:%s has an output prototype\n"
+ "\tprevious: probe %s:%s has no output prototype\n",
+ pvp->pv_desc.dtvd_name, pvp->pv_desc.dtvd_name,
+ new->pr_ident->di_name, pvp->pv_desc.dtvd_name,
+ old->pr_ident->di_name);
+ }
+
+ if (old->pr_ident->di_gen == yypcb->pcb_hdl->dt_gen)
+ old->pr_ident->di_flags |= DT_IDFLG_ORPHAN;
+
+ dt_idhash_delete(pvp->pv_probes, old->pr_ident);
+ dt_probe_declare(pvp, new);
+ }
+}
+
+static void
+dt_cook_probe(dt_node_t *dnp, dt_provider_t *pvp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_probe_t *prp = dnp->dn_ident->di_data;
+
+ dt_xlator_t *dxp;
+ uint_t i;
+
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ if (prp->pr_nargs == prp->pr_xargs)
+ return;
+
+ for (i = 0; i < prp->pr_xargc; i++) {
+ dt_node_t *xnp = prp->pr_xargv[i];
+ dt_node_t *nnp = prp->pr_nargv[prp->pr_mapping[i]];
+
+ if ((dxp = dt_xlator_lookup(dtp,
+ nnp, xnp, DT_XLATE_FUZZY)) != NULL) {
+ if (dt_provider_xref(dtp, pvp, dxp->dx_id) != 0)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ continue;
+ }
+
+ if (dt_node_is_argcompat(nnp, xnp))
+ continue; /* no translator defined and none required */
+
+ dnerror(dnp, D_PROV_PRXLATOR, "translator for %s:%s output "
+ "argument #%u from %s to %s is not defined\n",
+ pvp->pv_desc.dtvd_name, dnp->dn_ident->di_name, i + 1,
+ dt_node_type_name(nnp, n1, sizeof (n1)),
+ dt_node_type_name(xnp, n2, sizeof (n2)));
+ }
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_provider(dt_node_t *dnp, uint_t idflags)
+{
+ dt_provider_t *pvp = dnp->dn_provider;
+ dt_node_t *pnp;
+
+ /*
+ * If we're declaring a provider for the first time and it is unknown
+ * to dtrace(7D), insert the probe definitions into the provider's hash.
+ * If we're redeclaring a known provider, verify the interface matches.
+ */
+ for (pnp = dnp->dn_probes; pnp != NULL; pnp = pnp->dn_list) {
+ const char *probename = pnp->dn_ident->di_name;
+ dt_probe_t *prp = dt_probe_lookup(pvp, probename);
+
+ assert(pnp->dn_kind == DT_NODE_PROBE);
+
+ if (prp != NULL && dnp->dn_provred) {
+ dt_node_provider_cmp(pvp, pnp,
+ prp, pnp->dn_ident->di_data);
+ } else if (prp == NULL && dnp->dn_provred) {
+ dnerror(pnp, D_PROV_INCOMPAT,
+ "provider interface mismatch: %s\n"
+ "\t current: probe %s:%s defined\n"
+ "\tprevious: probe %s:%s not defined\n",
+ dnp->dn_provname, dnp->dn_provname,
+ probename, dnp->dn_provname, probename);
+ } else if (prp != NULL) {
+ dnerror(pnp, D_PROV_PRDUP, "probe redeclared: %s:%s\n",
+ dnp->dn_provname, probename);
+ } else
+ dt_probe_declare(pvp, pnp->dn_ident->di_data);
+
+ dt_cook_probe(pnp, pvp);
+ }
+
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static dt_node_t *
+dt_cook_none(dt_node_t *dnp, uint_t idflags)
+{
+ return (dnp);
+}
+
+static dt_node_t *(*dt_cook_funcs[])(dt_node_t *, uint_t) = {
+ dt_cook_none, /* DT_NODE_FREE */
+ dt_cook_none, /* DT_NODE_INT */
+ dt_cook_none, /* DT_NODE_STRING */
+ dt_cook_ident, /* DT_NODE_IDENT */
+ dt_cook_var, /* DT_NODE_VAR */
+ dt_cook_none, /* DT_NODE_SYM */
+ dt_cook_none, /* DT_NODE_TYPE */
+ dt_cook_func, /* DT_NODE_FUNC */
+ dt_cook_op1, /* DT_NODE_OP1 */
+ dt_cook_op2, /* DT_NODE_OP2 */
+ dt_cook_op3, /* DT_NODE_OP3 */
+ dt_cook_statement, /* DT_NODE_DEXPR */
+ dt_cook_statement, /* DT_NODE_DFUNC */
+ dt_cook_aggregation, /* DT_NODE_AGG */
+ dt_cook_none, /* DT_NODE_PDESC */
+ dt_cook_clause, /* DT_NODE_CLAUSE */
+ dt_cook_inline, /* DT_NODE_INLINE */
+ dt_cook_member, /* DT_NODE_MEMBER */
+ dt_cook_xlator, /* DT_NODE_XLATOR */
+ dt_cook_none, /* DT_NODE_PROBE */
+ dt_cook_provider, /* DT_NODE_PROVIDER */
+ dt_cook_none /* DT_NODE_PROG */
+};
+
+/*
+ * Recursively cook the parse tree starting at the specified node. The idflags
+ * parameter is used to indicate the type of reference (r/w) and is applied to
+ * the resulting identifier if it is a D variable or D aggregation.
+ */
+dt_node_t *
+dt_node_cook(dt_node_t *dnp, uint_t idflags)
+{
+ int oldlineno = yylineno;
+
+ yylineno = dnp->dn_line;
+
+ dnp = dt_cook_funcs[dnp->dn_kind](dnp, idflags);
+ dnp->dn_flags |= DT_NF_COOKED;
+
+ if (dnp->dn_kind == DT_NODE_VAR || dnp->dn_kind == DT_NODE_AGG)
+ dnp->dn_ident->di_flags |= idflags;
+
+ yylineno = oldlineno;
+ return (dnp);
+}
+
+dtrace_attribute_t
+dt_node_list_cook(dt_node_t **pnp, uint_t idflags)
+{
+ dtrace_attribute_t attr = _dtrace_defattr;
+ dt_node_t *dnp, *nnp;
+
+ for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) {
+ nnp = dnp->dn_list;
+ dnp = *pnp = dt_node_cook(dnp, idflags);
+ attr = dt_attr_min(attr, dnp->dn_attr);
+ dnp->dn_list = nnp;
+ pnp = &dnp->dn_list;
+ }
+
+ return (attr);
+}
+
+void
+dt_node_list_free(dt_node_t **pnp)
+{
+ dt_node_t *dnp, *nnp;
+
+ for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) {
+ nnp = dnp->dn_list;
+ dt_node_free(dnp);
+ }
+
+ if (pnp != NULL)
+ *pnp = NULL;
+}
+
+void
+dt_node_link_free(dt_node_t **pnp)
+{
+ dt_node_t *dnp, *nnp;
+
+ for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) {
+ nnp = dnp->dn_link;
+ dt_node_free(dnp);
+ }
+
+ for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) {
+ nnp = dnp->dn_link;
+ free(dnp);
+ }
+
+ if (pnp != NULL)
+ *pnp = NULL;
+}
+
+dt_node_t *
+dt_node_link(dt_node_t *lp, dt_node_t *rp)
+{
+ dt_node_t *dnp;
+
+ if (lp == NULL)
+ return (rp);
+ else if (rp == NULL)
+ return (lp);
+
+ for (dnp = lp; dnp->dn_list != NULL; dnp = dnp->dn_list)
+ continue;
+
+ dnp->dn_list = rp;
+ return (lp);
+}
+
+/*
+ * Compute the DOF dtrace_diftype_t representation of a node's type. This is
+ * called from a variety of places in the library so it cannot assume yypcb
+ * is valid: any references to handle-specific data must be made through 'dtp'.
+ */
+void
+dt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp)
+{
+ if (dnp->dn_ctfp == DT_STR_CTFP(dtp) &&
+ dnp->dn_type == DT_STR_TYPE(dtp)) {
+ tp->dtdt_kind = DIF_TYPE_STRING;
+ tp->dtdt_ckind = CTF_K_UNKNOWN;
+ } else {
+ tp->dtdt_kind = DIF_TYPE_CTF;
+ tp->dtdt_ckind = ctf_type_kind(dnp->dn_ctfp,
+ ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type));
+ }
+
+ tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0;
+ tp->dtdt_pad = 0;
+ tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type);
+}
+
+void
+dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
+{
+ char n[DT_TYPE_NAMELEN], buf[BUFSIZ], a[8];
+ const dtrace_syminfo_t *dts;
+ const dt_idnode_t *inp;
+ dt_node_t *arg;
+
+ (void) fprintf(fp, "%*s", depth * 2, "");
+ (void) dt_attr_str(dnp->dn_attr, a, sizeof (a));
+
+ if (dnp->dn_ctfp != NULL && dnp->dn_type != CTF_ERR &&
+ ctf_type_name(dnp->dn_ctfp, dnp->dn_type, n, sizeof (n)) != NULL) {
+ (void) snprintf(buf, BUFSIZ, "type=<%s> attr=%s flags=", n, a);
+ } else {
+ (void) snprintf(buf, BUFSIZ, "type=<%ld> attr=%s flags=",
+ dnp->dn_type, a);
+ }
+
+ if (dnp->dn_flags != 0) {
+ n[0] = '\0';
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ (void) strcat(n, ",SIGN");
+ if (dnp->dn_flags & DT_NF_COOKED)
+ (void) strcat(n, ",COOK");
+ if (dnp->dn_flags & DT_NF_REF)
+ (void) strcat(n, ",REF");
+ if (dnp->dn_flags & DT_NF_LVALUE)
+ (void) strcat(n, ",LVAL");
+ if (dnp->dn_flags & DT_NF_WRITABLE)
+ (void) strcat(n, ",WRITE");
+ if (dnp->dn_flags & DT_NF_BITFIELD)
+ (void) strcat(n, ",BITF");
+ if (dnp->dn_flags & DT_NF_USERLAND)
+ (void) strcat(n, ",USER");
+ (void) strcat(buf, n + 1);
+ } else
+ (void) strcat(buf, "0");
+
+ switch (dnp->dn_kind) {
+ case DT_NODE_FREE:
+ (void) fprintf(fp, "FREE <node %p>\n", (void *)dnp);
+ break;
+
+ case DT_NODE_INT:
+ (void) fprintf(fp, "INT 0x%llx (%s)\n",
+ (u_longlong_t)dnp->dn_value, buf);
+ break;
+
+ case DT_NODE_STRING:
+ (void) fprintf(fp, "STRING \"%s\" (%s)\n", dnp->dn_string, buf);
+ break;
+
+ case DT_NODE_IDENT:
+ (void) fprintf(fp, "IDENT %s (%s)\n", dnp->dn_string, buf);
+ break;
+
+ case DT_NODE_VAR:
+ (void) fprintf(fp, "VARIABLE %s%s (%s)\n",
+ (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL) ? "this->" :
+ (dnp->dn_ident->di_flags & DT_IDFLG_TLS) ? "self->" : "",
+ dnp->dn_ident->di_name, buf);
+
+ if (dnp->dn_args != NULL)
+ (void) fprintf(fp, "%*s[\n", depth * 2, "");
+
+ for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) {
+ dt_node_printr(arg, fp, depth + 1);
+ if (arg->dn_list != NULL)
+ (void) fprintf(fp, "%*s,\n", depth * 2, "");
+ }
+
+ if (dnp->dn_args != NULL)
+ (void) fprintf(fp, "%*s]\n", depth * 2, "");
+ break;
+
+ case DT_NODE_SYM:
+ dts = dnp->dn_ident->di_data;
+ (void) fprintf(fp, "SYMBOL %s`%s (%s)\n",
+ dts->dts_object, dts->dts_name, buf);
+ break;
+
+ case DT_NODE_TYPE:
+ if (dnp->dn_string != NULL) {
+ (void) fprintf(fp, "TYPE (%s) %s\n",
+ buf, dnp->dn_string);
+ } else
+ (void) fprintf(fp, "TYPE (%s)\n", buf);
+ break;
+
+ case DT_NODE_FUNC:
+ (void) fprintf(fp, "FUNC %s (%s)\n",
+ dnp->dn_ident->di_name, buf);
+
+ for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) {
+ dt_node_printr(arg, fp, depth + 1);
+ if (arg->dn_list != NULL)
+ (void) fprintf(fp, "%*s,\n", depth * 2, "");
+ }
+ break;
+
+ case DT_NODE_OP1:
+ (void) fprintf(fp, "OP1 %s (%s)\n", opstr(dnp->dn_op), buf);
+ dt_node_printr(dnp->dn_child, fp, depth + 1);
+ break;
+
+ case DT_NODE_OP2:
+ (void) fprintf(fp, "OP2 %s (%s)\n", opstr(dnp->dn_op), buf);
+ dt_node_printr(dnp->dn_left, fp, depth + 1);
+ dt_node_printr(dnp->dn_right, fp, depth + 1);
+ break;
+
+ case DT_NODE_OP3:
+ (void) fprintf(fp, "OP3 (%s)\n", buf);
+ dt_node_printr(dnp->dn_expr, fp, depth + 1);
+ (void) fprintf(fp, "%*s?\n", depth * 2, "");
+ dt_node_printr(dnp->dn_left, fp, depth + 1);
+ (void) fprintf(fp, "%*s:\n", depth * 2, "");
+ dt_node_printr(dnp->dn_right, fp, depth + 1);
+ break;
+
+ case DT_NODE_DEXPR:
+ case DT_NODE_DFUNC:
+ (void) fprintf(fp, "D EXPRESSION attr=%s\n", a);
+ dt_node_printr(dnp->dn_expr, fp, depth + 1);
+ break;
+
+ case DT_NODE_AGG:
+ (void) fprintf(fp, "AGGREGATE @%s attr=%s [\n",
+ dnp->dn_ident->di_name, a);
+
+ for (arg = dnp->dn_aggtup; arg != NULL; arg = arg->dn_list) {
+ dt_node_printr(arg, fp, depth + 1);
+ if (arg->dn_list != NULL)
+ (void) fprintf(fp, "%*s,\n", depth * 2, "");
+ }
+
+ if (dnp->dn_aggfun) {
+ (void) fprintf(fp, "%*s] = ", depth * 2, "");
+ dt_node_printr(dnp->dn_aggfun, fp, depth + 1);
+ } else
+ (void) fprintf(fp, "%*s]\n", depth * 2, "");
+
+ if (dnp->dn_aggfun)
+ (void) fprintf(fp, "%*s)\n", depth * 2, "");
+ break;
+
+ case DT_NODE_PDESC:
+ (void) fprintf(fp, "PDESC %s:%s:%s:%s [%u]\n",
+ dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod,
+ dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name,
+ dnp->dn_desc->dtpd_id);
+ break;
+
+ case DT_NODE_CLAUSE:
+ (void) fprintf(fp, "CLAUSE attr=%s\n", a);
+
+ for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list)
+ dt_node_printr(arg, fp, depth + 1);
+
+ (void) fprintf(fp, "%*sCTXATTR %s\n", depth * 2, "",
+ dt_attr_str(dnp->dn_ctxattr, a, sizeof (a)));
+
+ if (dnp->dn_pred != NULL) {
+ (void) fprintf(fp, "%*sPREDICATE /\n", depth * 2, "");
+ dt_node_printr(dnp->dn_pred, fp, depth + 1);
+ (void) fprintf(fp, "%*s/\n", depth * 2, "");
+ }
+
+ for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
+ dt_node_printr(arg, fp, depth + 1);
+ break;
+
+ case DT_NODE_INLINE:
+ inp = dnp->dn_ident->di_iarg;
+
+ (void) fprintf(fp, "INLINE %s (%s)\n",
+ dnp->dn_ident->di_name, buf);
+ dt_node_printr(inp->din_root, fp, depth + 1);
+ break;
+
+ case DT_NODE_MEMBER:
+ (void) fprintf(fp, "MEMBER %s (%s)\n", dnp->dn_membname, buf);
+ if (dnp->dn_membexpr)
+ dt_node_printr(dnp->dn_membexpr, fp, depth + 1);
+ break;
+
+ case DT_NODE_XLATOR:
+ (void) fprintf(fp, "XLATOR (%s)", buf);
+
+ if (ctf_type_name(dnp->dn_xlator->dx_src_ctfp,
+ dnp->dn_xlator->dx_src_type, n, sizeof (n)) != NULL)
+ (void) fprintf(fp, " from <%s>", n);
+
+ if (ctf_type_name(dnp->dn_xlator->dx_dst_ctfp,
+ dnp->dn_xlator->dx_dst_type, n, sizeof (n)) != NULL)
+ (void) fprintf(fp, " to <%s>", n);
+
+ (void) fprintf(fp, "\n");
+
+ for (arg = dnp->dn_members; arg != NULL; arg = arg->dn_list)
+ dt_node_printr(arg, fp, depth + 1);
+ break;
+
+ case DT_NODE_PROBE:
+ (void) fprintf(fp, "PROBE %s\n", dnp->dn_ident->di_name);
+ break;
+
+ case DT_NODE_PROVIDER:
+ (void) fprintf(fp, "PROVIDER %s (%s)\n",
+ dnp->dn_provname, dnp->dn_provred ? "redecl" : "decl");
+ for (arg = dnp->dn_probes; arg != NULL; arg = arg->dn_list)
+ dt_node_printr(arg, fp, depth + 1);
+ break;
+
+ case DT_NODE_PROG:
+ (void) fprintf(fp, "PROGRAM attr=%s\n", a);
+ for (arg = dnp->dn_list; arg != NULL; arg = arg->dn_list)
+ dt_node_printr(arg, fp, depth + 1);
+ break;
+
+ default:
+ (void) fprintf(fp, "<bad node %p, kind %d>\n",
+ (void *)dnp, dnp->dn_kind);
+ }
+}
+
+int
+dt_node_root(dt_node_t *dnp)
+{
+ yypcb->pcb_root = dnp;
+ return (0);
+}
+
+/*PRINTFLIKE3*/
+void
+dnerror(const dt_node_t *dnp, dt_errtag_t tag, const char *format, ...)
+{
+ int oldlineno = yylineno;
+ va_list ap;
+
+ yylineno = dnp->dn_line;
+
+ va_start(ap, format);
+ xyvwarn(tag, format, ap);
+ va_end(ap);
+
+ yylineno = oldlineno;
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+}
+
+/*PRINTFLIKE3*/
+void
+dnwarn(const dt_node_t *dnp, dt_errtag_t tag, const char *format, ...)
+{
+ int oldlineno = yylineno;
+ va_list ap;
+
+ yylineno = dnp->dn_line;
+
+ va_start(ap, format);
+ xyvwarn(tag, format, ap);
+ va_end(ap);
+
+ yylineno = oldlineno;
+}
+
+/*PRINTFLIKE2*/
+void
+xyerror(dt_errtag_t tag, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xyvwarn(tag, format, ap);
+ va_end(ap);
+
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+}
+
+/*PRINTFLIKE2*/
+void
+xywarn(dt_errtag_t tag, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xyvwarn(tag, format, ap);
+ va_end(ap);
+}
+
+void
+xyvwarn(dt_errtag_t tag, const char *format, va_list ap)
+{
+ if (yypcb == NULL)
+ return; /* compiler is not currently active: act as a no-op */
+
+ dt_set_errmsg(yypcb->pcb_hdl, dt_errtag(tag), yypcb->pcb_region,
+ yypcb->pcb_filetag, yypcb->pcb_fileptr ? yylineno : 0, format, ap);
+}
+
+/*PRINTFLIKE1*/
+void
+yyerror(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ yyvwarn(format, ap);
+ va_end(ap);
+
+ longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
+}
+
+/*PRINTFLIKE1*/
+void
+yywarn(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ yyvwarn(format, ap);
+ va_end(ap);
+}
+
+void
+yyvwarn(const char *format, va_list ap)
+{
+ if (yypcb == NULL)
+ return; /* compiler is not currently active: act as a no-op */
+
+ dt_set_errmsg(yypcb->pcb_hdl, dt_errtag(D_SYNTAX), yypcb->pcb_region,
+ yypcb->pcb_filetag, yypcb->pcb_fileptr ? yylineno : 0, format, ap);
+
+ if (strchr(format, '\n') == NULL) {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ size_t len = strlen(dtp->dt_errmsg);
+ char *p, *s = dtp->dt_errmsg + len;
+ size_t n = sizeof (dtp->dt_errmsg) - len;
+
+ if (yytext[0] == '\0')
+ (void) snprintf(s, n, " near end of input");
+ else if (yytext[0] == '\n')
+ (void) snprintf(s, n, " near end of line");
+ else {
+ if ((p = strchr(yytext, '\n')) != NULL)
+ *p = '\0'; /* crop at newline */
+ (void) snprintf(s, n, " near \"%s\"", yytext);
+ }
+ }
+}
+
+void
+yylabel(const char *label)
+{
+ dt_dprintf("set label to <%s>\n", label ? label : "NULL");
+ yypcb->pcb_region = label;
+}
+
+int
+yywrap(void)
+{
+ return (1); /* indicate that lex should return a zero token for EOF */
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
new file mode 100644
index 0000000..6064efb
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
@@ -0,0 +1,285 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PARSER_H
+#define _DT_PARSER_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/dtrace.h>
+
+#include <libctf.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dt_errtags.h>
+#include <dt_ident.h>
+#include <dt_decl.h>
+#include <dt_xlator.h>
+#include <dt_list.h>
+
+typedef struct dt_node {
+ ctf_file_t *dn_ctfp; /* CTF type container for node's type */
+ ctf_id_t dn_type; /* CTF type reference for node's type */
+ uchar_t dn_kind; /* node kind (DT_NODE_*, defined below) */
+ uchar_t dn_flags; /* node flags (DT_NF_*, defined below) */
+ ushort_t dn_op; /* operator (DT_TOK_*, defined by lex) */
+ int dn_line; /* line number for error messages */
+ int dn_reg; /* register allocated by cg */
+ dtrace_attribute_t dn_attr; /* node stability attributes */
+
+ /*
+ * D compiler nodes, as is the usual style, contain a union of the
+ * different sub-elements required by the various kinds of nodes.
+ * These sub-elements are accessed using the macros defined below.
+ */
+ union {
+ struct {
+ uintmax_t _value; /* integer value */
+ char *_string; /* string value */
+ } _const;
+
+ struct {
+ dt_ident_t *_ident; /* identifier reference */
+ struct dt_node *_links[3]; /* child node pointers */
+ } _nodes;
+
+ struct {
+ struct dt_node *_descs; /* list of descriptions */
+ struct dt_node *_pred; /* predicate expression */
+ struct dt_node *_acts; /* action statement list */
+ dt_idhash_t *_locals; /* local variable hash */
+ dtrace_attribute_t _attr; /* context attributes */
+ } _clause;
+
+ struct {
+ char *_spec; /* specifier string (if any) */
+ dtrace_probedesc_t *_desc; /* final probe description */
+ } _pdesc;
+
+ struct {
+ char *_name; /* string name of member */
+ struct dt_node *_expr; /* expression node pointer */
+ dt_xlator_t *_xlator; /* translator reference */
+ uint_t _id; /* member identifier */
+ } _member;
+
+ struct {
+ dt_xlator_t *_xlator; /* translator reference */
+ struct dt_node *_xmemb; /* individual xlator member */
+ struct dt_node *_membs; /* list of member nodes */
+ } _xlator;
+
+ struct {
+ char *_name; /* string name of provider */
+ struct dt_provider *_pvp; /* provider references */
+ struct dt_node *_probes; /* list of probe nodes */
+ int _redecl; /* provider redeclared */
+ } _provider;
+ } dn_u;
+
+ struct dt_node *dn_list; /* parse tree list link */
+ struct dt_node *dn_link; /* allocation list link */
+} dt_node_t;
+
+#define dn_value dn_u._const._value /* DT_NODE_INT */
+#define dn_string dn_u._const._string /* STRING, IDENT, TYPE */
+#define dn_ident dn_u._nodes._ident /* VAR,SYM,FUN,AGG,INL,PROBE */
+#define dn_args dn_u._nodes._links[0] /* DT_NODE_VAR, FUNC */
+#define dn_child dn_u._nodes._links[0] /* DT_NODE_OP1 */
+#define dn_left dn_u._nodes._links[0] /* DT_NODE_OP2, OP3 */
+#define dn_right dn_u._nodes._links[1] /* DT_NODE_OP2, OP3 */
+#define dn_expr dn_u._nodes._links[2] /* DT_NODE_OP3, DEXPR */
+#define dn_aggfun dn_u._nodes._links[0] /* DT_NODE_AGG */
+#define dn_aggtup dn_u._nodes._links[1] /* DT_NODE_AGG */
+#define dn_pdescs dn_u._clause._descs /* DT_NODE_CLAUSE */
+#define dn_pred dn_u._clause._pred /* DT_NODE_CLAUSE */
+#define dn_acts dn_u._clause._acts /* DT_NODE_CLAUSE */
+#define dn_locals dn_u._clause._locals /* DT_NODE_CLAUSE */
+#define dn_ctxattr dn_u._clause._attr /* DT_NODE_CLAUSE */
+#define dn_spec dn_u._pdesc._spec /* DT_NODE_PDESC */
+#define dn_desc dn_u._pdesc._desc /* DT_NODE_PDESC */
+#define dn_membname dn_u._member._name /* DT_NODE_MEMBER */
+#define dn_membexpr dn_u._member._expr /* DT_NODE_MEMBER */
+#define dn_membxlator dn_u._member._xlator /* DT_NODE_MEMBER */
+#define dn_membid dn_u._member._id /* DT_NODE_MEMBER */
+#define dn_xlator dn_u._xlator._xlator /* DT_NODE_XLATOR */
+#define dn_xmember dn_u._xlator._xmemb /* DT_NODE_XLATOR */
+#define dn_members dn_u._xlator._membs /* DT_NODE_XLATOR */
+#define dn_provname dn_u._provider._name /* DT_NODE_PROVIDER */
+#define dn_provider dn_u._provider._pvp /* DT_NODE_PROVIDER */
+#define dn_provred dn_u._provider._redecl /* DT_NODE_PROVIDER */
+#define dn_probes dn_u._provider._probes /* DT_NODE_PROVIDER */
+
+#define DT_NODE_FREE 0 /* unused node (waiting to be freed) */
+#define DT_NODE_INT 1 /* integer value */
+#define DT_NODE_STRING 2 /* string value */
+#define DT_NODE_IDENT 3 /* identifier */
+#define DT_NODE_VAR 4 /* variable reference */
+#define DT_NODE_SYM 5 /* symbol reference */
+#define DT_NODE_TYPE 6 /* type reference or formal parameter */
+#define DT_NODE_FUNC 7 /* function call */
+#define DT_NODE_OP1 8 /* unary operator */
+#define DT_NODE_OP2 9 /* binary operator */
+#define DT_NODE_OP3 10 /* ternary operator */
+#define DT_NODE_DEXPR 11 /* D expression action */
+#define DT_NODE_DFUNC 12 /* D function action */
+#define DT_NODE_AGG 13 /* aggregation */
+#define DT_NODE_PDESC 14 /* probe description */
+#define DT_NODE_CLAUSE 15 /* clause definition */
+#define DT_NODE_INLINE 16 /* inline definition */
+#define DT_NODE_MEMBER 17 /* member definition */
+#define DT_NODE_XLATOR 18 /* translator definition */
+#define DT_NODE_PROBE 19 /* probe definition */
+#define DT_NODE_PROVIDER 20 /* provider definition */
+#define DT_NODE_PROG 21 /* program translation unit */
+
+#define DT_NF_SIGNED 0x01 /* data is a signed quantity (else unsigned) */
+#define DT_NF_COOKED 0x02 /* data is a known type (else still cooking) */
+#define DT_NF_REF 0x04 /* pass by reference (array, struct, union) */
+#define DT_NF_LVALUE 0x08 /* node is an l-value according to ANSI-C */
+#define DT_NF_WRITABLE 0x10 /* node is writable (can be modified) */
+#define DT_NF_BITFIELD 0x20 /* node is an integer bitfield */
+#define DT_NF_USERLAND 0x40 /* data is a userland address */
+
+#define DT_TYPE_NAMELEN 128 /* reasonable size for ctf_type_name() */
+
+extern int dt_node_is_integer(const dt_node_t *);
+extern int dt_node_is_float(const dt_node_t *);
+extern int dt_node_is_scalar(const dt_node_t *);
+extern int dt_node_is_arith(const dt_node_t *);
+extern int dt_node_is_vfptr(const dt_node_t *);
+extern int dt_node_is_dynamic(const dt_node_t *);
+extern int dt_node_is_stack(const dt_node_t *);
+extern int dt_node_is_symaddr(const dt_node_t *);
+extern int dt_node_is_usymaddr(const dt_node_t *);
+extern int dt_node_is_string(const dt_node_t *);
+extern int dt_node_is_strcompat(const dt_node_t *);
+extern int dt_node_is_pointer(const dt_node_t *);
+extern int dt_node_is_void(const dt_node_t *);
+extern int dt_node_is_ptrcompat(const dt_node_t *, const dt_node_t *,
+ ctf_file_t **, ctf_id_t *);
+extern int dt_node_is_argcompat(const dt_node_t *, const dt_node_t *);
+extern int dt_node_is_posconst(const dt_node_t *);
+extern int dt_node_is_actfunc(const dt_node_t *);
+
+extern dt_node_t *dt_node_int(uintmax_t);
+extern dt_node_t *dt_node_string(char *);
+extern dt_node_t *dt_node_ident(char *);
+extern dt_node_t *dt_node_type(dt_decl_t *);
+extern dt_node_t *dt_node_vatype(void);
+extern dt_node_t *dt_node_decl(void);
+extern dt_node_t *dt_node_func(dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_offsetof(dt_decl_t *, char *);
+extern dt_node_t *dt_node_op1(int, dt_node_t *);
+extern dt_node_t *dt_node_op2(int, dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_op3(dt_node_t *, dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_statement(dt_node_t *);
+extern dt_node_t *dt_node_pdesc_by_name(char *);
+extern dt_node_t *dt_node_pdesc_by_id(uintmax_t);
+extern dt_node_t *dt_node_clause(dt_node_t *, dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_inline(dt_node_t *);
+extern dt_node_t *dt_node_member(dt_decl_t *, char *, dt_node_t *);
+extern dt_node_t *dt_node_xlator(dt_decl_t *, dt_decl_t *, char *, dt_node_t *);
+extern dt_node_t *dt_node_probe(char *, int, dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_provider(char *, dt_node_t *);
+extern dt_node_t *dt_node_program(dt_node_t *);
+
+extern dt_node_t *dt_node_link(dt_node_t *, dt_node_t *);
+extern dt_node_t *dt_node_cook(dt_node_t *, uint_t);
+
+extern dt_node_t *dt_node_xalloc(dtrace_hdl_t *, int);
+extern void dt_node_free(dt_node_t *);
+
+extern dtrace_attribute_t dt_node_list_cook(dt_node_t **, uint_t);
+extern void dt_node_list_free(dt_node_t **);
+extern void dt_node_link_free(dt_node_t **);
+
+extern void dt_node_attr_assign(dt_node_t *, dtrace_attribute_t);
+extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t);
+extern void dt_node_type_propagate(const dt_node_t *, dt_node_t *);
+extern const char *dt_node_type_name(const dt_node_t *, char *, size_t);
+extern size_t dt_node_type_size(const dt_node_t *);
+
+extern dt_ident_t *dt_node_resolve(const dt_node_t *, uint_t);
+extern size_t dt_node_sizeof(const dt_node_t *);
+extern void dt_node_promote(dt_node_t *, dt_node_t *, dt_node_t *);
+
+extern void dt_node_diftype(dtrace_hdl_t *,
+ const dt_node_t *, dtrace_diftype_t *);
+extern void dt_node_printr(dt_node_t *, FILE *, int);
+extern const char *dt_node_name(const dt_node_t *, char *, size_t);
+extern int dt_node_root(dt_node_t *);
+
+struct dtrace_typeinfo; /* see <dtrace.h> */
+struct dt_pcb; /* see <dt_impl.h> */
+
+#define IS_CHAR(e) \
+ (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == \
+ (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY)
+
+#define IS_VOID(e) \
+ ((e).cte_offset == 0 && (e).cte_bits == 0)
+
+extern int dt_type_lookup(const char *, struct dtrace_typeinfo *);
+extern int dt_type_pointer(struct dtrace_typeinfo *);
+extern const char *dt_type_name(ctf_file_t *, ctf_id_t, char *, size_t);
+
+typedef enum {
+ YYS_CLAUSE, /* lex/yacc state for finding program clauses */
+ YYS_DEFINE, /* lex/yacc state for parsing persistent definitions */
+ YYS_EXPR, /* lex/yacc state for parsing D expressions */
+ YYS_DONE, /* lex/yacc state for indicating parse tree is done */
+ YYS_CONTROL /* lex/yacc state for parsing control lines */
+} yystate_t;
+
+extern void dnerror(const dt_node_t *, dt_errtag_t, const char *, ...);
+extern void dnwarn(const dt_node_t *, dt_errtag_t, const char *, ...);
+
+extern void xyerror(dt_errtag_t, const char *, ...);
+extern void xywarn(dt_errtag_t, const char *, ...);
+extern void xyvwarn(dt_errtag_t, const char *, va_list);
+
+extern void yyerror(const char *, ...);
+extern void yywarn(const char *, ...);
+extern void yyvwarn(const char *, va_list);
+
+extern void yylabel(const char *);
+extern void yybegin(yystate_t);
+extern void yyinit(struct dt_pcb *);
+
+extern int yyparse(void);
+extern int yyinput(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PARSER_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.c
new file mode 100644
index 0000000..d80c359
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.c
@@ -0,0 +1,187 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * DTrace Parsing Control Block
+ *
+ * A DTrace Parsing Control Block (PCB) contains all of the state that is used
+ * by a single pass of the D compiler, other than the global variables used by
+ * lex and yacc. The routines in this file are used to set up and tear down
+ * PCBs, which are kept on a stack pointed to by the libdtrace global 'yypcb'.
+ * The main engine of the compiler, dt_compile(), is located in dt_cc.c and is
+ * responsible for calling these routines to begin and end a compilation pass.
+ *
+ * Sun's lex/yacc are not MT-safe or re-entrant, but we permit limited nested
+ * use of dt_compile() once the entire parse tree has been constructed but has
+ * not yet executed the "cooking" pass (see dt_cc.c for more information). The
+ * PCB design also makes it easier to debug (since all global state is kept in
+ * one place) and could permit us to make the D compiler MT-safe or re-entrant
+ * in the future by adding locks to libdtrace or switching to Flex and Bison.
+ */
+
+#include <strings.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <dt_impl.h>
+#include <dt_program.h>
+#include <dt_provider.h>
+#include <dt_pcb.h>
+
+/*
+ * Initialize the specified PCB by zeroing it and filling in a few default
+ * members, and then pushing it on to the top of the PCB stack and setting
+ * yypcb to point to it. Increment the current handle's generation count.
+ */
+void
+dt_pcb_push(dtrace_hdl_t *dtp, dt_pcb_t *pcb)
+{
+ /*
+ * Since lex/yacc are not re-entrant and we don't implement state save,
+ * assert that if another PCB is active, it is from the same handle and
+ * has completed execution of yyparse(). If the first assertion fires,
+ * the caller is calling libdtrace without proper MT locking. If the
+ * second assertion fires, dt_compile() is being called recursively
+ * from an illegal location in libdtrace, or a dt_pcb_pop() is missing.
+ */
+ if (yypcb != NULL) {
+ assert(yypcb->pcb_hdl == dtp);
+ assert(yypcb->pcb_yystate == YYS_DONE);
+ }
+
+ bzero(pcb, sizeof (dt_pcb_t));
+
+ dt_scope_create(&pcb->pcb_dstack);
+ dt_idstack_push(&pcb->pcb_globals, dtp->dt_globals);
+ dt_irlist_create(&pcb->pcb_ir);
+
+ pcb->pcb_hdl = dtp;
+ pcb->pcb_prev = dtp->dt_pcb;
+
+ dtp->dt_pcb = pcb;
+ dtp->dt_gen++;
+
+ yyinit(pcb);
+}
+
+static int
+dt_pcb_pop_ident(dt_idhash_t *dhp, dt_ident_t *idp, void *arg)
+{
+ dtrace_hdl_t *dtp = arg;
+
+ if (idp->di_gen == dtp->dt_gen)
+ dt_idhash_delete(dhp, idp);
+
+ return (0);
+}
+
+/*
+ * Pop the topmost PCB from the PCB stack and destroy any data structures that
+ * are associated with it. If 'err' is non-zero, destroy any intermediate
+ * state that is left behind as part of a compilation that has failed.
+ */
+void
+dt_pcb_pop(dtrace_hdl_t *dtp, int err)
+{
+ dt_pcb_t *pcb = yypcb;
+ uint_t i;
+
+ assert(pcb != NULL);
+ assert(pcb == dtp->dt_pcb);
+
+ while (pcb->pcb_dstack.ds_next != NULL)
+ (void) dt_scope_pop();
+
+ dt_scope_destroy(&pcb->pcb_dstack);
+ dt_irlist_destroy(&pcb->pcb_ir);
+
+ dt_node_link_free(&pcb->pcb_list);
+ dt_node_link_free(&pcb->pcb_hold);
+
+ if (err != 0) {
+ dt_xlator_t *dxp, *nxp;
+ dt_provider_t *pvp, *nvp;
+
+ if (pcb->pcb_prog != NULL)
+ dt_program_destroy(dtp, pcb->pcb_prog);
+ if (pcb->pcb_stmt != NULL)
+ dtrace_stmt_destroy(dtp, pcb->pcb_stmt);
+ if (pcb->pcb_ecbdesc != NULL)
+ dt_ecbdesc_release(dtp, pcb->pcb_ecbdesc);
+
+ for (dxp = dt_list_next(&dtp->dt_xlators); dxp; dxp = nxp) {
+ nxp = dt_list_next(dxp);
+ if (dxp->dx_gen == dtp->dt_gen)
+ dt_xlator_destroy(dtp, dxp);
+ }
+
+ for (pvp = dt_list_next(&dtp->dt_provlist); pvp; pvp = nvp) {
+ nvp = dt_list_next(pvp);
+ if (pvp->pv_gen == dtp->dt_gen)
+ dt_provider_destroy(dtp, pvp);
+ }
+
+ (void) dt_idhash_iter(dtp->dt_aggs, dt_pcb_pop_ident, dtp);
+ dt_idhash_update(dtp->dt_aggs);
+
+ (void) dt_idhash_iter(dtp->dt_globals, dt_pcb_pop_ident, dtp);
+ dt_idhash_update(dtp->dt_globals);
+
+ (void) dt_idhash_iter(dtp->dt_tls, dt_pcb_pop_ident, dtp);
+ dt_idhash_update(dtp->dt_tls);
+
+ (void) ctf_discard(dtp->dt_cdefs->dm_ctfp);
+ (void) ctf_discard(dtp->dt_ddefs->dm_ctfp);
+ }
+
+ if (pcb->pcb_pragmas != NULL)
+ dt_idhash_destroy(pcb->pcb_pragmas);
+ if (pcb->pcb_locals != NULL)
+ dt_idhash_destroy(pcb->pcb_locals);
+ if (pcb->pcb_idents != NULL)
+ dt_idhash_destroy(pcb->pcb_idents);
+ if (pcb->pcb_inttab != NULL)
+ dt_inttab_destroy(pcb->pcb_inttab);
+ if (pcb->pcb_strtab != NULL)
+ dt_strtab_destroy(pcb->pcb_strtab);
+ if (pcb->pcb_regs != NULL)
+ dt_regset_destroy(pcb->pcb_regs);
+
+ for (i = 0; i < pcb->pcb_asxreflen; i++)
+ dt_free(dtp, pcb->pcb_asxrefs[i]);
+
+ dt_free(dtp, pcb->pcb_asxrefs);
+ dt_difo_free(dtp, pcb->pcb_difo);
+
+ free(pcb->pcb_filetag);
+ free(pcb->pcb_sflagv);
+
+ dtp->dt_pcb = pcb->pcb_prev;
+ bzero(pcb, sizeof (dt_pcb_t));
+ yyinit(dtp->dt_pcb);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.h
new file mode 100644
index 0000000..0ba2c6b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pcb.h
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PCB_H
+#define _DT_PCB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dtrace.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dt_parser.h>
+#include <dt_regset.h>
+#include <dt_inttab.h>
+#include <dt_strtab.h>
+#include <dt_decl.h>
+#include <dt_as.h>
+
+typedef struct dt_pcb {
+ dtrace_hdl_t *pcb_hdl; /* pointer to library handle */
+ struct dt_pcb *pcb_prev; /* pointer to previous pcb in stack */
+ FILE *pcb_fileptr; /* pointer to input file (or NULL) */
+ char *pcb_filetag; /* optional file name string (or NULL) */
+ const char *pcb_string; /* pointer to input string (or NULL) */
+ const char *pcb_strptr; /* pointer to input position */
+ size_t pcb_strlen; /* length of pcb_string */
+ int pcb_sargc; /* number of script arguments (if any) */
+ char *const *pcb_sargv; /* script argument strings (if any) */
+ ushort_t *pcb_sflagv; /* script argument flags (DT_IDFLG_* bits) */
+ dt_scope_t pcb_dstack; /* declaration processing stack */
+ dt_node_t *pcb_list; /* list of allocated parse tree nodes */
+ dt_node_t *pcb_hold; /* parse tree nodes on hold until end of defn */
+ dt_node_t *pcb_root; /* root of current parse tree */
+ dt_idstack_t pcb_globals; /* stack of global identifier hash tables */
+ dt_idhash_t *pcb_locals; /* current hash table of local identifiers */
+ dt_idhash_t *pcb_idents; /* current hash table of ambiguous idents */
+ dt_idhash_t *pcb_pragmas; /* current hash table of pending pragmas */
+ dt_inttab_t *pcb_inttab; /* integer table for constant references */
+ dt_strtab_t *pcb_strtab; /* string table for string references */
+ dt_regset_t *pcb_regs; /* register set for code generation */
+ dt_irlist_t pcb_ir; /* list of unrelocated IR instructions */
+ uint_t pcb_asvidx; /* assembler vartab index (see dt_as.c) */
+ ulong_t **pcb_asxrefs; /* assembler imported xlators (see dt_as.c) */
+ uint_t pcb_asxreflen; /* assembler xlator map length (see dt_as.c) */
+ const dtrace_probedesc_t *pcb_pdesc; /* probedesc for current context */
+ struct dt_probe *pcb_probe; /* probe associated with current context */
+ dtrace_probeinfo_t pcb_pinfo; /* info associated with current context */
+ dtrace_attribute_t pcb_amin; /* stability minimum for compilation */
+ dt_node_t *pcb_dret; /* node containing return type for assembler */
+ dtrace_difo_t *pcb_difo; /* intermediate DIF object made by assembler */
+ dtrace_prog_t *pcb_prog; /* intermediate program made by compiler */
+ dtrace_stmtdesc_t *pcb_stmt; /* intermediate stmt made by compiler */
+ dtrace_ecbdesc_t *pcb_ecbdesc; /* intermediate ecbdesc made by cmplr */
+ jmp_buf pcb_jmpbuf; /* setjmp(3C) buffer for error return */
+ const char *pcb_region; /* optional region name for yyerror() suffix */
+ dtrace_probespec_t pcb_pspec; /* probe description evaluation context */
+ uint_t pcb_cflags; /* optional compilation flags (see dtrace.h) */
+ uint_t pcb_idepth; /* preprocessor #include nesting depth */
+ yystate_t pcb_yystate; /* lex/yacc parsing state (see yybegin()) */
+ int pcb_context; /* yyparse() rules context (DT_CTX_* value) */
+ int pcb_token; /* token to be returned by yylex() (if != 0) */
+ int pcb_cstate; /* state to be restored by lexer at state end */
+ int pcb_braces; /* number of open curly braces in lexer */
+ int pcb_brackets; /* number of open square brackets in lexer */
+ int pcb_parens; /* number of open parentheses in lexer */
+} dt_pcb_t;
+
+extern void dt_pcb_push(dtrace_hdl_t *, dt_pcb_t *);
+extern void dt_pcb_pop(dtrace_hdl_t *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PCB_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
new file mode 100644
index 0000000..b145818
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
@@ -0,0 +1,829 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <assert.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <libgen.h>
+#include <stddef.h>
+
+#include <dt_impl.h>
+#include <dt_program.h>
+#include <dt_pid.h>
+#include <dt_string.h>
+#if !defined(sun)
+#include <libproc_compat.h>
+#endif
+
+typedef struct dt_pid_probe {
+ dtrace_hdl_t *dpp_dtp;
+ dt_pcb_t *dpp_pcb;
+ dt_proc_t *dpp_dpr;
+ struct ps_prochandle *dpp_pr;
+ const char *dpp_mod;
+ char *dpp_func;
+ const char *dpp_name;
+ const char *dpp_obj;
+ uintptr_t dpp_pc;
+ size_t dpp_size;
+ Lmid_t dpp_lmid;
+ uint_t dpp_nmatches;
+ uint64_t dpp_stret[4];
+ GElf_Sym dpp_last;
+ uint_t dpp_last_taken;
+} dt_pid_probe_t;
+
+/*
+ * Compose the lmid and object name into the canonical representation. We
+ * omit the lmid for the default link map for convenience.
+ */
+static void
+dt_pid_objname(char *buf, size_t len, Lmid_t lmid, const char *obj)
+{
+#if defined(sun)
+ if (lmid == LM_ID_BASE)
+ (void) strncpy(buf, obj, len);
+ else
+ (void) snprintf(buf, len, "LM%lx`%s", lmid, obj);
+#else
+ (void) strncpy(buf, obj, len);
+#endif
+}
+
+static int
+dt_pid_error(dtrace_hdl_t *dtp, dt_pcb_t *pcb, dt_proc_t *dpr,
+ fasttrap_probe_spec_t *ftp, dt_errtag_t tag, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ if (ftp != NULL)
+ dt_free(dtp, ftp);
+
+ va_start(ap, fmt);
+ if (pcb == NULL) {
+ assert(dpr != NULL);
+ len = vsnprintf(dpr->dpr_errmsg, sizeof (dpr->dpr_errmsg),
+ fmt, ap);
+ assert(len >= 2);
+ if (dpr->dpr_errmsg[len - 2] == '\n')
+ dpr->dpr_errmsg[len - 2] = '\0';
+ } else {
+ dt_set_errmsg(dtp, dt_errtag(tag), pcb->pcb_region,
+ pcb->pcb_filetag, pcb->pcb_fileptr ? yylineno : 0, fmt, ap);
+ }
+ va_end(ap);
+
+ return (1);
+}
+
+static int
+dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func)
+{
+ dtrace_hdl_t *dtp = pp->dpp_dtp;
+ dt_pcb_t *pcb = pp->dpp_pcb;
+ dt_proc_t *dpr = pp->dpp_dpr;
+ fasttrap_probe_spec_t *ftp;
+ uint64_t off;
+ char *end;
+ uint_t nmatches = 0;
+ ulong_t sz;
+ int glob, err;
+ int isdash = strcmp("-", func) == 0;
+ pid_t pid;
+
+#if defined(sun)
+ pid = Pstatus(pp->dpp_pr)->pr_pid;
+#else
+ pid = proc_getpid(pp->dpp_pr);
+#endif
+
+ dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid, pp->dpp_obj,
+ func, pp->dpp_name);
+
+ sz = sizeof (fasttrap_probe_spec_t) + (isdash ? 4 :
+ (symp->st_size - 1) * sizeof (ftp->ftps_offs[0]));
+
+ if ((ftp = dt_alloc(dtp, sz)) == NULL) {
+ dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz);
+ return (1); /* errno is set for us */
+ }
+
+ ftp->ftps_pid = pid;
+ (void) strncpy(ftp->ftps_func, func, sizeof (ftp->ftps_func));
+
+ dt_pid_objname(ftp->ftps_mod, sizeof (ftp->ftps_mod), pp->dpp_lmid,
+ pp->dpp_obj);
+
+ if (!isdash && gmatch("return", pp->dpp_name)) {
+ if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp,
+ pp->dpp_stret) < 0) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp,
+ D_PROC_CREATEFAIL, "failed to create return probe "
+ "for '%s': %s", func,
+ dtrace_errmsg(dtp, dtrace_errno(dtp))));
+ }
+
+ nmatches++;
+ }
+
+ if (!isdash && gmatch("entry", pp->dpp_name)) {
+ if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp,
+ D_PROC_CREATEFAIL, "failed to create entry probe "
+ "for '%s': %s", func,
+ dtrace_errmsg(dtp, dtrace_errno(dtp))));
+ }
+
+ nmatches++;
+ }
+
+ glob = strisglob(pp->dpp_name);
+ if (!glob && nmatches == 0) {
+ off = strtoull(pp->dpp_name, &end, 16);
+ if (*end != '\0') {
+ return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_NAME,
+ "'%s' is an invalid probe name", pp->dpp_name));
+ }
+
+ if (off >= symp->st_size) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_OFF,
+ "offset 0x%llx outside of function '%s'",
+ (u_longlong_t)off, func));
+ }
+
+ err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp,
+ symp, off);
+
+ if (err == DT_PROC_ERR) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp,
+ D_PROC_CREATEFAIL, "failed to create probe at "
+ "'%s+0x%llx': %s", func, (u_longlong_t)off,
+ dtrace_errmsg(dtp, dtrace_errno(dtp))));
+ }
+
+ if (err == DT_PROC_ALIGN) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_ALIGN,
+ "offset 0x%llx is not aligned on an instruction",
+ (u_longlong_t)off));
+ }
+
+ nmatches++;
+
+ } else if (glob && !isdash) {
+ if (dt_pid_create_glob_offset_probes(pp->dpp_pr,
+ pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) {
+ return (dt_pid_error(dtp, pcb, dpr, ftp,
+ D_PROC_CREATEFAIL,
+ "failed to create offset probes in '%s': %s", func,
+ dtrace_errmsg(dtp, dtrace_errno(dtp))));
+ }
+
+ nmatches++;
+ }
+
+ pp->dpp_nmatches += nmatches;
+
+ dt_free(dtp, ftp);
+
+ return (0);
+}
+
+static int
+dt_pid_sym_filt(void *arg, const GElf_Sym *symp, const char *func)
+{
+ dt_pid_probe_t *pp = arg;
+
+ if (symp->st_shndx == SHN_UNDEF)
+ return (0);
+
+ if (symp->st_size == 0) {
+ dt_dprintf("st_size of %s is zero\n", func);
+ return (0);
+ }
+
+ if (pp->dpp_last_taken == 0 ||
+ symp->st_value != pp->dpp_last.st_value ||
+ symp->st_size != pp->dpp_last.st_size) {
+ /*
+ * Due to 4524008, _init and _fini may have a bloated st_size.
+ * While this bug has been fixed for a while, old binaries
+ * may exist that still exhibit this problem. As a result, we
+ * don't match _init and _fini though we allow users to
+ * specify them explicitly.
+ */
+ if (strcmp(func, "_init") == 0 || strcmp(func, "_fini") == 0)
+ return (0);
+
+ if ((pp->dpp_last_taken = gmatch(func, pp->dpp_func)) != 0) {
+ pp->dpp_last = *symp;
+ return (dt_pid_per_sym(pp, symp, func));
+ }
+ }
+
+ return (0);
+}
+
+static int
+dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj)
+{
+ dt_pid_probe_t *pp = arg;
+ dtrace_hdl_t *dtp = pp->dpp_dtp;
+ dt_pcb_t *pcb = pp->dpp_pcb;
+ dt_proc_t *dpr = pp->dpp_dpr;
+ GElf_Sym sym;
+
+ if (obj == NULL)
+ return (0);
+
+#if defined(sun)
+ (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
+#endif
+
+
+ if ((pp->dpp_obj = strrchr(obj, '/')) == NULL)
+ pp->dpp_obj = obj;
+ else
+ pp->dpp_obj++;
+#if defined(sun)
+ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym,
+ NULL) == 0)
+ pp->dpp_stret[0] = sym.st_value;
+ else
+ pp->dpp_stret[0] = 0;
+
+ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret2", &sym,
+ NULL) == 0)
+ pp->dpp_stret[1] = sym.st_value;
+ else
+ pp->dpp_stret[1] = 0;
+
+ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret4", &sym,
+ NULL) == 0)
+ pp->dpp_stret[2] = sym.st_value;
+ else
+ pp->dpp_stret[2] = 0;
+
+ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret8", &sym,
+ NULL) == 0)
+ pp->dpp_stret[3] = sym.st_value;
+ else
+ pp->dpp_stret[3] = 0;
+#else
+ pp->dpp_stret[0] = 0;
+ pp->dpp_stret[1] = 0;
+ pp->dpp_stret[2] = 0;
+ pp->dpp_stret[3] = 0;
+#endif
+
+ dt_dprintf("%s stret %llx %llx %llx %llx\n", obj,
+ (u_longlong_t)pp->dpp_stret[0], (u_longlong_t)pp->dpp_stret[1],
+ (u_longlong_t)pp->dpp_stret[2], (u_longlong_t)pp->dpp_stret[3]);
+
+ /*
+ * If pp->dpp_func contains any globbing meta-characters, we need
+ * to iterate over the symbol table and compare each function name
+ * against the pattern.
+ */
+ if (!strisglob(pp->dpp_func)) {
+ /*
+ * If we fail to lookup the symbol, try interpreting the
+ * function as the special "-" function that indicates that the
+ * probe name should be interpreted as a absolute virtual
+ * address. If that fails and we were matching a specific
+ * function in a specific module, report the error, otherwise
+ * just fail silently in the hopes that some other object will
+ * contain the desired symbol.
+ */
+ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj,
+ pp->dpp_func, &sym, NULL) != 0) {
+ if (strcmp("-", pp->dpp_func) == 0) {
+ sym.st_name = 0;
+ sym.st_info =
+ GELF_ST_INFO(STB_LOCAL, STT_FUNC);
+ sym.st_other = 0;
+ sym.st_value = 0;
+#if defined(sun)
+ sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel ==
+ PR_MODEL_ILP32 ? -1U : -1ULL;
+#else
+ sym.st_size = ~((Elf64_Xword) 0);
+#endif
+
+ } else if (!strisglob(pp->dpp_mod)) {
+ return (dt_pid_error(dtp, pcb, dpr, NULL,
+ D_PROC_FUNC,
+ "failed to lookup '%s' in module '%s'",
+ pp->dpp_func, pp->dpp_mod));
+ } else {
+ return (0);
+ }
+ }
+
+ /*
+ * Only match defined functions of non-zero size.
+ */
+ if (GELF_ST_TYPE(sym.st_info) != STT_FUNC ||
+ sym.st_shndx == SHN_UNDEF || sym.st_size == 0)
+ return (0);
+
+ /*
+ * We don't instrument PLTs -- they're dynamically rewritten,
+ * and, so, inherently dicey to instrument.
+ */
+#ifdef DOODAD
+ if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL)
+ return (0);
+#endif
+
+ (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func,
+ DTRACE_FUNCNAMELEN, &sym);
+
+ return (dt_pid_per_sym(pp, &sym, pp->dpp_func));
+ } else {
+ uint_t nmatches = pp->dpp_nmatches;
+
+ if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB,
+ BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1)
+ return (1);
+
+ if (nmatches == pp->dpp_nmatches) {
+ /*
+ * If we didn't match anything in the PR_SYMTAB, try
+ * the PR_DYNSYM.
+ */
+ if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM,
+ BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1)
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj)
+{
+ char name[DTRACE_MODNAMELEN];
+ dt_pid_probe_t *pp = arg;
+
+ if (gmatch(obj, pp->dpp_mod))
+ return (dt_pid_per_mod(pp, pmp, obj));
+
+#if defined(sun)
+ (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
+#else
+ pp->dpp_lmid = 0;
+#endif
+
+ if ((pp->dpp_obj = strrchr(obj, '/')) == NULL)
+ pp->dpp_obj = obj;
+ else
+ pp->dpp_obj++;
+
+ if (gmatch(pp->dpp_obj, pp->dpp_mod))
+ return (dt_pid_per_mod(pp, pmp, obj));
+
+#if defined(sun)
+ (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid);
+#endif
+
+ dt_pid_objname(name, sizeof (name), pp->dpp_lmid, pp->dpp_obj);
+
+ if (gmatch(name, pp->dpp_mod))
+ return (dt_pid_per_mod(pp, pmp, obj));
+
+ return (0);
+}
+
+static const prmap_t *
+dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P)
+{
+ char m[MAXPATHLEN];
+#if defined(sun)
+ Lmid_t lmid = PR_LMID_EVERY;
+#else
+ Lmid_t lmid = 0;
+#endif
+ const char *obj;
+ const prmap_t *pmp;
+
+#if defined(sun)
+ /*
+ * Pick apart the link map from the library name.
+ */
+ if (strchr(pdp->dtpd_mod, '`') != NULL) {
+ char *end;
+
+ if (strncmp(pdp->dtpd_mod, "LM", 2) != 0 ||
+ !isdigit(pdp->dtpd_mod[2]))
+ return (NULL);
+
+ lmid = strtoul(&pdp->dtpd_mod[2], &end, 16);
+
+ obj = end + 1;
+
+ if (*end != '`' || strchr(obj, '`') != NULL)
+ return (NULL);
+
+ } else {
+ obj = pdp->dtpd_mod;
+ }
+#else
+ obj = pdp->dtpd_mod;
+#endif
+
+ if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL)
+ return (NULL);
+
+#if defined(sun)
+ (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m));
+ if ((obj = strrchr(m, '/')) == NULL)
+ obj = &m[0];
+ else
+ obj++;
+
+ (void) Plmid(P, pmp->pr_vaddr, &lmid);
+#endif
+
+ dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj);
+
+ return (pmp);
+}
+
+
+static int
+dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
+ dt_pcb_t *pcb, dt_proc_t *dpr)
+{
+ dt_pid_probe_t pp;
+ int ret = 0;
+
+ pp.dpp_dtp = dtp;
+ pp.dpp_dpr = dpr;
+ pp.dpp_pr = dpr->dpr_proc;
+ pp.dpp_pcb = pcb;
+
+#ifdef DOODAD
+ /*
+ * We can only trace dynamically-linked executables (since we've
+ * hidden some magic in ld.so.1 as well as libc.so.1).
+ */
+ if (Pname_to_map(pp.dpp_pr, PR_OBJ_LDSO) == NULL) {
+ return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_DYN,
+ "process %s is not a dynamically-linked executable",
+ &pdp->dtpd_provider[3]));
+ }
+#endif
+
+ pp.dpp_mod = pdp->dtpd_mod[0] != '\0' ? pdp->dtpd_mod : "*";
+ pp.dpp_func = pdp->dtpd_func[0] != '\0' ? pdp->dtpd_func : "*";
+ pp.dpp_name = pdp->dtpd_name[0] != '\0' ? pdp->dtpd_name : "*";
+ pp.dpp_last_taken = 0;
+
+ if (strcmp(pp.dpp_func, "-") == 0) {
+ const prmap_t *aout, *pmp;
+
+ if (pdp->dtpd_mod[0] == '\0') {
+ pp.dpp_mod = pdp->dtpd_mod;
+ (void) strcpy(pdp->dtpd_mod, "a.out");
+ } else if (strisglob(pp.dpp_mod) ||
+ (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL ||
+ (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL ||
+ aout->pr_vaddr != pmp->pr_vaddr) {
+ return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB,
+ "only the a.out module is valid with the "
+ "'-' function"));
+ }
+
+ if (strisglob(pp.dpp_name)) {
+ return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_NAME,
+ "only individual addresses may be specified "
+ "with the '-' function"));
+ }
+ }
+
+ /*
+ * If pp.dpp_mod contains any globbing meta-characters, we need
+ * to iterate over each module and compare its name against the
+ * pattern. An empty module name is treated as '*'.
+ */
+ if (strisglob(pp.dpp_mod)) {
+ ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp);
+ } else {
+ const prmap_t *pmp;
+ char *obj;
+
+ /*
+ * If we can't find a matching module, don't sweat it -- either
+ * we'll fail the enabling because the probes don't exist or
+ * we'll wait for that module to come along.
+ */
+ if ((pmp = dt_pid_fix_mod(pdp, pp.dpp_pr)) != NULL) {
+ if ((obj = strchr(pdp->dtpd_mod, '`')) == NULL)
+ obj = pdp->dtpd_mod;
+ else
+ obj++;
+
+ ret = dt_pid_per_mod(&pp, pmp, obj);
+ }
+ }
+
+ return (ret);
+}
+
+static int
+dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
+{
+ struct ps_prochandle *P = data;
+ GElf_Sym sym;
+#if defined(sun)
+ prsyminfo_t sip;
+#endif
+ dof_helper_t dh;
+ GElf_Half e_type;
+ const char *mname;
+ const char *syms[] = { "___SUNW_dof", "__SUNW_dof" };
+ int i, fd = -1;
+
+ /*
+ * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and
+ * __SUNW_dof is for actively-loaded DOF sections. We try to force
+ * in both types of DOF section since the process may not yet have
+ * run the code to instantiate these providers.
+ */
+ for (i = 0; i < 2; i++) {
+ if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym,
+ &sip) != 0) {
+ continue;
+ }
+
+ if ((mname = strrchr(oname, '/')) == NULL)
+ mname = oname;
+ else
+ mname++;
+
+ dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname);
+
+ if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr +
+ offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) {
+ dt_dprintf("read of ELF header failed");
+ continue;
+ }
+
+ dh.dofhp_dof = sym.st_value;
+ dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
+
+ dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
+#if defined(sun)
+ sip.prs_lmid, mname);
+#else
+ 0, mname);
+#endif
+
+#if defined(sun)
+ if (fd == -1 &&
+ (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) {
+ dt_dprintf("pr_open of helper device failed: %s\n",
+ strerror(errno));
+ return (-1); /* errno is set for us */
+ }
+
+ if (pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0)
+ dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod);
+#endif
+ }
+
+#if defined(sun)
+ if (fd != -1)
+ (void) pr_close(P, fd);
+#endif
+
+ return (0);
+}
+
+static int
+dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
+ dt_pcb_t *pcb, dt_proc_t *dpr)
+{
+ struct ps_prochandle *P = dpr->dpr_proc;
+ int ret = 0;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+#if defined(sun)
+ (void) Pupdate_maps(P);
+ if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) {
+ ret = -1;
+ (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT,
+ "failed to instantiate probes for pid %d: %s",
+#if defined(sun)
+ (int)Pstatus(P)->pr_pid, strerror(errno));
+#else
+ (int)proc_getpid(P), strerror(errno));
+#endif
+ }
+#else
+ ret = 0;
+#endif
+
+ /*
+ * Put the module name in its canonical form.
+ */
+ (void) dt_pid_fix_mod(pdp, P);
+
+ return (ret);
+}
+
+static pid_t
+dt_pid_get_pid(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb,
+ dt_proc_t *dpr)
+{
+ pid_t pid;
+ char *c, *last = NULL, *end;
+
+ for (c = &pdp->dtpd_provider[0]; *c != '\0'; c++) {
+ if (!isdigit(*c))
+ last = c;
+ }
+
+ if (last == NULL || (*(++last) == '\0')) {
+ (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPROV,
+ "'%s' is not a valid provider", pdp->dtpd_provider);
+ return (-1);
+ }
+
+ errno = 0;
+ pid = strtol(last, &end, 10);
+
+ if (errno != 0 || end == last || end[0] != '\0' || pid <= 0) {
+ (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_BADPID,
+ "'%s' does not contain a valid pid", pdp->dtpd_provider);
+ return (-1);
+ }
+
+ return (pid);
+}
+
+int
+dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
+{
+ char provname[DTRACE_PROVNAMELEN];
+ struct ps_prochandle *P;
+ dt_proc_t *dpr;
+ pid_t pid;
+ int err = 0;
+
+ assert(pcb != NULL);
+
+ if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1)
+ return (-1);
+
+ if (dtp->dt_ftfd == -1) {
+ if (dtp->dt_fterr == ENOENT) {
+ (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
+ "pid provider is not installed on this system");
+ } else {
+ (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
+ "pid provider is not available: %s",
+ strerror(dtp->dt_fterr));
+ }
+
+ return (-1);
+ }
+
+ (void) snprintf(provname, sizeof (provname), "pid%d", (int)pid);
+
+ if (gmatch(provname, pdp->dtpd_provider) != 0) {
+ if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE,
+ 0)) == NULL) {
+ (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
+ "failed to grab process %d", (int)pid);
+ return (-1);
+ }
+
+ dpr = dt_proc_lookup(dtp, P, 0);
+ assert(dpr != NULL);
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+ if ((err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr)) == 0) {
+ /*
+ * Alert other retained enablings which may match
+ * against the newly created probes.
+ */
+ (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ dt_proc_release(dtp, P);
+ }
+
+ /*
+ * If it's not strictly a pid provider, we might match a USDT provider.
+ */
+ if (strcmp(provname, pdp->dtpd_provider) != 0) {
+ if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) {
+ (void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
+ "failed to grab process %d", (int)pid);
+ return (-1);
+ }
+
+ dpr = dt_proc_lookup(dtp, P, 0);
+ assert(dpr != NULL);
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+ if (!dpr->dpr_usdt) {
+ err = dt_pid_create_usdt_probes(pdp, dtp, pcb, dpr);
+ dpr->dpr_usdt = B_TRUE;
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ dt_proc_release(dtp, P);
+ }
+
+ return (err ? -1 : 0);
+}
+
+int
+dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
+{
+ dtrace_enable_io_t args;
+ dtrace_prog_t *pgp;
+ dt_stmt_t *stp;
+ dtrace_probedesc_t *pdp, pd;
+ pid_t pid;
+ int ret = 0, found = B_FALSE;
+ char provname[DTRACE_PROVNAMELEN];
+
+ (void) snprintf(provname, sizeof (provname), "pid%d",
+ (int)dpr->dpr_pid);
+
+ for (pgp = dt_list_next(&dtp->dt_programs); pgp != NULL;
+ pgp = dt_list_next(pgp)) {
+
+ for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL;
+ stp = dt_list_next(stp)) {
+
+ pdp = &stp->ds_desc->dtsd_ecbdesc->dted_probe;
+ pid = dt_pid_get_pid(pdp, dtp, NULL, dpr);
+ if (pid != dpr->dpr_pid)
+ continue;
+
+ found = B_TRUE;
+
+ pd = *pdp;
+
+ if (gmatch(provname, pdp->dtpd_provider) != 0 &&
+ dt_pid_create_pid_probes(&pd, dtp, NULL, dpr) != 0)
+ ret = 1;
+
+ /*
+ * If it's not strictly a pid provider, we might match
+ * a USDT provider.
+ */
+ if (strcmp(provname, pdp->dtpd_provider) != 0 &&
+ dt_pid_create_usdt_probes(&pd, dtp, NULL, dpr) != 0)
+ ret = 1;
+ }
+ }
+
+ if (found) {
+ /*
+ * Give DTrace a shot to the ribs to get it to check
+ * out the newly created probes.
+ */
+ args.dof = NULL;
+ args.n_matched = 0;
+ (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
new file mode 100644
index 0000000..886e33d
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PID_H
+#define _DT_PID_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libproc.h>
+#include <sys/fasttrap.h>
+#include <dt_impl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DT_PROC_ERR (-1)
+#define DT_PROC_ALIGN (-2)
+
+extern int dt_pid_create_probes(dtrace_probedesc_t *, dtrace_hdl_t *,
+ dt_pcb_t *pcb);
+extern int dt_pid_create_probes_module(dtrace_hdl_t *, dt_proc_t *);
+
+extern int dt_pid_create_entry_probe(struct ps_prochandle *, dtrace_hdl_t *,
+ fasttrap_probe_spec_t *, const GElf_Sym *);
+
+extern int dt_pid_create_return_probe(struct ps_prochandle *, dtrace_hdl_t *,
+ fasttrap_probe_spec_t *, const GElf_Sym *, uint64_t *);
+
+extern int dt_pid_create_offset_probe(struct ps_prochandle *, dtrace_hdl_t *,
+ fasttrap_probe_spec_t *, const GElf_Sym *, ulong_t);
+
+extern int dt_pid_create_glob_offset_probes(struct ps_prochandle *,
+ dtrace_hdl_t *, fasttrap_probe_spec_t *, const GElf_Sym *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PID_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
new file mode 100644
index 0000000..00578f4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
@@ -0,0 +1,531 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <assert.h>
+#include <strings.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dt_parser.h>
+#include <dt_impl.h>
+#include <dt_provider.h>
+#include <dt_module.h>
+
+/*
+ * This callback function is installed in a given identifier hash to search for
+ * and apply deferred pragmas that are pending for a given new identifier name.
+ * Multiple pragmas may be pending for a given name; we processs all of them.
+ */
+/*ARGSUSED*/
+static void
+dt_pragma_apply(dt_idhash_t *dhp, dt_ident_t *idp)
+{
+ dt_idhash_t *php;
+ dt_ident_t *pdp;
+
+ if ((php = yypcb->pcb_pragmas) == NULL)
+ return; /* no pragmas pending for current compilation pass */
+
+ while ((pdp = dt_idhash_lookup(php, idp->di_name)) != NULL) {
+ switch (pdp->di_kind) {
+ case DT_IDENT_PRAGAT:
+ idp->di_attr = pdp->di_attr;
+ break;
+ case DT_IDENT_PRAGBN:
+ idp->di_vers = pdp->di_vers;
+ break;
+ }
+ dt_idhash_delete(php, pdp);
+ }
+}
+
+/*
+ * The #pragma attributes directive can be used to reset stability attributes
+ * on a global identifier or inline definition. If the identifier is already
+ * defined, we can just change di_attr. If not, we insert the pragma into a
+ * hash table of the current pcb's deferred pragmas for later processing.
+ */
+static void
+dt_pragma_attributes(const char *prname, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dtrace_attribute_t attr, *a;
+ dt_provider_t *pvp;
+ const char *name, *part;
+ dt_ident_t *idp;
+
+ if (dnp == NULL || dnp->dn_kind != DT_NODE_IDENT ||
+ dnp->dn_list == NULL || dnp->dn_list->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
+ "<attributes> <ident>\n", prname);
+ }
+
+ if (dtrace_str2attr(dnp->dn_string, &attr) == -1) {
+ xyerror(D_PRAGMA_INVAL, "invalid attributes "
+ "specified by #pragma %s\n", prname);
+ }
+
+ dnp = dnp->dn_list;
+ name = dnp->dn_string;
+
+ if (strcmp(name, "provider") == 0) {
+ dnp = dnp->dn_list;
+ name = dnp->dn_string;
+
+ dnp = dnp->dn_list;
+ part = dnp->dn_string;
+
+ if ((pvp = dt_provider_lookup(dtp, name)) != NULL) {
+ if (strcmp(part, "provider") == 0) {
+ a = &pvp->pv_desc.dtvd_attr.dtpa_provider;
+ } else if (strcmp(part, "module") == 0) {
+ a = &pvp->pv_desc.dtvd_attr.dtpa_mod;
+ } else if (strcmp(part, "function") == 0) {
+ a = &pvp->pv_desc.dtvd_attr.dtpa_func;
+ } else if (strcmp(part, "name") == 0) {
+ a = &pvp->pv_desc.dtvd_attr.dtpa_name;
+ } else if (strcmp(part, "args") == 0) {
+ a = &pvp->pv_desc.dtvd_attr.dtpa_args;
+ } else {
+ xyerror(D_PRAGMA_INVAL, "invalid component "
+ "\"%s\" in attribute #pragma "
+ "for provider %s\n", name, part);
+ }
+
+ *a = attr;
+ return;
+ }
+
+ } else if ((idp = dt_idstack_lookup(
+ &yypcb->pcb_globals, name)) != NULL) {
+
+ if (idp->di_gen != dtp->dt_gen) {
+ xyerror(D_PRAGMA_SCOPE, "#pragma %s cannot modify "
+ "entity defined outside program scope\n", prname);
+ }
+
+ idp->di_attr = attr;
+ return;
+ }
+
+ if (yypcb->pcb_pragmas == NULL && (yypcb->pcb_pragmas =
+ dt_idhash_create("pragma", NULL, 0, 0)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ idp = dt_idhash_insert(yypcb->pcb_pragmas, name, DT_IDENT_PRAGAT, 0, 0,
+ attr, 0, &dt_idops_thaw, (void *)prname, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (dtp->dt_globals->dh_defer == NULL)
+ dtp->dt_globals->dh_defer = &dt_pragma_apply;
+}
+
+/*
+ * The #pragma binding directive can be used to reset the version binding
+ * on a global identifier or inline definition. If the identifier is already
+ * defined, we can just change di_vers. If not, we insert the pragma into a
+ * hash table of the current pcb's deferred pragmas for later processing.
+ */
+static void
+dt_pragma_binding(const char *prname, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_version_t vers;
+ const char *name;
+ dt_ident_t *idp;
+
+ if (dnp == NULL || dnp->dn_kind != DT_NODE_STRING ||
+ dnp->dn_list == NULL || dnp->dn_list->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
+ "\"version\" <ident>\n", prname);
+ }
+
+ if (dt_version_str2num(dnp->dn_string, &vers) == -1) {
+ xyerror(D_PRAGMA_INVAL, "invalid version string "
+ "specified by #pragma %s\n", prname);
+ }
+
+ name = dnp->dn_list->dn_string;
+ idp = dt_idstack_lookup(&yypcb->pcb_globals, name);
+
+ if (idp != NULL) {
+ if (idp->di_gen != dtp->dt_gen) {
+ xyerror(D_PRAGMA_SCOPE, "#pragma %s cannot modify "
+ "entity defined outside program scope\n", prname);
+ }
+ idp->di_vers = vers;
+ return;
+ }
+
+ if (yypcb->pcb_pragmas == NULL && (yypcb->pcb_pragmas =
+ dt_idhash_create("pragma", NULL, 0, 0)) == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ idp = dt_idhash_insert(yypcb->pcb_pragmas, name, DT_IDENT_PRAGBN, 0, 0,
+ _dtrace_defattr, vers, &dt_idops_thaw, (void *)prname, dtp->dt_gen);
+
+ if (idp == NULL)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+
+ if (dtp->dt_globals->dh_defer == NULL)
+ dtp->dt_globals->dh_defer = &dt_pragma_apply;
+}
+
+static void
+dt_pragma_depends_finddep(dtrace_hdl_t *dtp, const char *lname, char *lib,
+ size_t len)
+{
+ dt_dirpath_t *dirp;
+ struct stat sbuf;
+ int found = 0;
+
+ for (dirp = dt_list_next(&dtp->dt_lib_path); dirp != NULL;
+ dirp = dt_list_next(dirp)) {
+ (void) snprintf(lib, len, "%s/%s", dirp->dir_path, lname);
+
+ if (stat(lib, &sbuf) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ xyerror(D_PRAGMA_DEPEND,
+ "failed to find dependency in libpath: %s", lname);
+}
+
+/*
+ * The #pragma depends_on directive can be used to express a dependency on a
+ * module, provider or library which if not present will cause processing to
+ * abort.
+ */
+static void
+dt_pragma_depends(const char *prname, dt_node_t *cnp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ dt_node_t *nnp = cnp ? cnp->dn_list : NULL;
+ int found;
+ dt_lib_depend_t *dld;
+ char lib[MAXPATHLEN];
+
+ if (cnp == NULL || nnp == NULL ||
+ cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
+ "<class> <name>\n", prname);
+ }
+
+ if (strcmp(cnp->dn_string, "provider") == 0)
+ found = dt_provider_lookup(dtp, nnp->dn_string) != NULL;
+ else if (strcmp(cnp->dn_string, "module") == 0) {
+ dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string);
+ found = mp != NULL && dt_module_getctf(dtp, mp) != NULL;
+ } else if (strcmp(cnp->dn_string, "library") == 0) {
+ if (yypcb->pcb_cflags & DTRACE_C_CTL) {
+ assert(dtp->dt_filetag != NULL);
+
+ dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
+ sizeof (lib));
+
+ dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
+ dtp->dt_filetag);
+ assert(dld != NULL);
+
+ if ((dt_lib_depend_add(dtp, &dld->dtld_dependencies,
+ lib)) != 0) {
+ xyerror(D_PRAGMA_DEPEND,
+ "failed to add dependency %s:%s\n", lib,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+ } else {
+ /*
+ * By this point we have already performed a topological
+ * sort of the dependencies; we process this directive
+ * as satisfied as long as the dependency was properly
+ * loaded.
+ */
+ if (dtp->dt_filetag == NULL)
+ xyerror(D_PRAGMA_DEPEND, "main program may "
+ "not explicitly depend on a library");
+
+ dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
+ dtp->dt_filetag);
+ assert(dld != NULL);
+
+ dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
+ sizeof (lib));
+ dld = dt_lib_depend_lookup(&dtp->dt_lib_dep_sorted,
+ lib);
+ assert(dld != NULL);
+
+ if (!dld->dtld_loaded)
+ xyerror(D_PRAGMA_DEPEND, "program requires "
+ "library \"%s\" which failed to load",
+ lib);
+ }
+
+ found = B_TRUE;
+ } else {
+ xyerror(D_PRAGMA_INVAL, "invalid class %s "
+ "specified by #pragma %s\n", cnp->dn_string, prname);
+ }
+
+ if (!found) {
+ xyerror(D_PRAGMA_DEPEND, "program requires %s %s\n",
+ cnp->dn_string, nnp->dn_string);
+ }
+}
+
+/*
+ * The #pragma error directive can be followed by any list of tokens, which we
+ * just concatenate and print as part of our error message.
+ */
+static void
+dt_pragma_error(const char *prname, dt_node_t *dnp)
+{
+ dt_node_t *enp;
+ size_t n = 0;
+ char *s;
+
+ for (enp = dnp; enp != NULL; enp = enp->dn_list) {
+ if (enp->dn_kind == DT_NODE_IDENT ||
+ enp->dn_kind == DT_NODE_STRING)
+ n += strlen(enp->dn_string) + 1;
+ }
+
+ s = alloca(n + 1);
+ s[0] = '\0';
+
+ for (enp = dnp; enp != NULL; enp = enp->dn_list) {
+ if (enp->dn_kind == DT_NODE_IDENT ||
+ enp->dn_kind == DT_NODE_STRING) {
+ (void) strcat(s, enp->dn_string);
+ (void) strcat(s, " ");
+ }
+ }
+
+ xyerror(D_PRAGERR, "#%s: %s\n", prname, s);
+}
+
+/*ARGSUSED*/
+static void
+dt_pragma_ident(const char *prname, dt_node_t *dnp)
+{
+ /* ignore any #ident or #pragma ident lines */
+}
+
+static void
+dt_pragma_option(const char *prname, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+ char *opt, *val;
+
+ if (dnp == NULL || dnp->dn_kind != DT_NODE_IDENT) {
+ xyerror(D_PRAGMA_MALFORM,
+ "malformed #pragma %s <option>=<val>\n", prname);
+ }
+
+ if (dnp->dn_list != NULL) {
+ xyerror(D_PRAGMA_MALFORM,
+ "superfluous arguments specified for #pragma %s\n", prname);
+ }
+
+ opt = alloca(strlen(dnp->dn_string) + 1);
+ (void) strcpy(opt, dnp->dn_string);
+
+ if ((val = strchr(opt, '=')) != NULL)
+ *val++ = '\0';
+
+ if (dtrace_setopt(dtp, opt, val) == -1) {
+ if (val == NULL) {
+ xyerror(D_PRAGMA_OPTSET,
+ "failed to set option '%s': %s\n", opt,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ } else {
+ xyerror(D_PRAGMA_OPTSET,
+ "failed to set option '%s' to '%s': %s\n",
+ opt, val, dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
+ }
+}
+
+/*
+ * The #line directive is used to reset the input line number and to optionally
+ * note the file name for use in error messages. Sun cpp(1) also produces a
+ * third integer token after the filename which is one of the following:
+ *
+ * 0 - line change has nothing to do with an #include file
+ * 1 - line change because we just entered a #include file
+ * 2 - line change because we just exited a #include file
+ *
+ * We use these state tokens to adjust pcb_idepth, which in turn controls
+ * whether type lookups access the global type space or not.
+ */
+static void
+dt_pragma_line(const char *prname, dt_node_t *dnp)
+{
+ dt_node_t *fnp = dnp ? dnp->dn_list : NULL;
+ dt_node_t *inp = fnp ? fnp->dn_list : NULL;
+
+ if ((dnp == NULL || dnp->dn_kind != DT_NODE_INT) ||
+ (fnp != NULL && fnp->dn_kind != DT_NODE_STRING) ||
+ (inp != NULL && inp->dn_kind != DT_NODE_INT)) {
+ xyerror(D_PRAGMA_MALFORM, "malformed #%s "
+ "<line> [ [\"file\"] state ]\n", prname);
+ }
+
+ /*
+ * If a file is specified, free any old pcb_filetag and swap fnp's
+ * dn_string into pcb_filetag as the new filename for error messages.
+ */
+ if (fnp != NULL) {
+ if (yypcb->pcb_filetag != NULL)
+ free(yypcb->pcb_filetag);
+
+ /*
+ * This is not pretty, but is a necessary evil until we either
+ * write "dpp" or get a useful standalone cpp from DevPro. If
+ * the filename begins with /dev/fd, we know it's the master
+ * input file (see dt_preproc() in dt_cc.c), so just clear the
+ * dt_filetag pointer so error messages refer to the main file.
+ */
+ if (strncmp(fnp->dn_string, "/dev/fd/", 8) != 0) {
+ yypcb->pcb_filetag = fnp->dn_string;
+ fnp->dn_string = NULL;
+ } else
+ yypcb->pcb_filetag = NULL;
+ }
+
+ if (inp != NULL) {
+ if (inp->dn_value == 1)
+ yypcb->pcb_idepth++;
+ else if (inp->dn_value == 2 && yypcb->pcb_idepth != 0)
+ yypcb->pcb_idepth--;
+ }
+
+ yylineno = dnp->dn_value;
+}
+
+/*
+ * D compiler pragma types range from control directives to common pragmas to
+ * D custom pragmas, in order of specificity. Similar to gcc, we use #pragma D
+ * as a special prefix for our pragmas so they can be used in mixed headers.
+ */
+#define DT_PRAGMA_DIR 0 /* pragma directive may be used after naked # */
+#define DT_PRAGMA_SUB 1 /* pragma directive may be used after #pragma */
+#define DT_PRAGMA_DCP 2 /* pragma may only be used after #pragma D */
+
+static const struct dt_pragmadesc {
+ const char *dpd_name;
+ void (*dpd_func)(const char *, dt_node_t *);
+ int dpd_kind;
+} dt_pragmas[] = {
+ { "attributes", dt_pragma_attributes, DT_PRAGMA_DCP },
+ { "binding", dt_pragma_binding, DT_PRAGMA_DCP },
+ { "depends_on", dt_pragma_depends, DT_PRAGMA_DCP },
+ { "error", dt_pragma_error, DT_PRAGMA_DIR },
+ { "ident", dt_pragma_ident, DT_PRAGMA_DIR },
+ { "line", dt_pragma_line, DT_PRAGMA_DIR },
+ { "option", dt_pragma_option, DT_PRAGMA_DCP },
+ { NULL, NULL }
+};
+
+/*
+ * Process a control line #directive by looking up the directive name in our
+ * lookup table and invoking the corresponding function with the token list.
+ * According to K&R[A12.9], we silently ignore null directive lines.
+ */
+void
+dt_pragma(dt_node_t *pnp)
+{
+ const struct dt_pragmadesc *dpd;
+ dt_node_t *dnp;
+ int kind = DT_PRAGMA_DIR;
+
+ for (dnp = pnp; dnp != NULL; dnp = dnp->dn_list) {
+ if (dnp->dn_kind == DT_NODE_INT) {
+ dt_pragma_line("line", dnp);
+ break;
+ }
+
+ if (dnp->dn_kind != DT_NODE_IDENT)
+ xyerror(D_PRAGCTL_INVAL, "invalid control directive\n");
+
+ if (kind == DT_PRAGMA_DIR &&
+ strcmp(dnp->dn_string, "pragma") == 0) {
+ kind = DT_PRAGMA_SUB;
+ continue;
+ }
+
+ if (kind == DT_PRAGMA_SUB &&
+ strcmp(dnp->dn_string, "D") == 0) {
+ kind = DT_PRAGMA_DCP;
+ continue;
+ }
+
+ for (dpd = dt_pragmas; dpd->dpd_name != NULL; dpd++) {
+ if (dpd->dpd_kind <= kind &&
+ strcmp(dpd->dpd_name, dnp->dn_string) == 0)
+ break;
+ }
+
+ yylineno--; /* since we've already seen \n */
+
+ if (dpd->dpd_name != NULL) {
+ dpd->dpd_func(dpd->dpd_name, dnp->dn_list);
+ yylineno++;
+ break;
+ }
+
+ switch (kind) {
+ case DT_PRAGMA_DIR:
+ xyerror(D_PRAGCTL_INVAL, "invalid control directive: "
+ "#%s\n", dnp->dn_string);
+ /*NOTREACHED*/
+ case DT_PRAGMA_SUB:
+ break; /* K&R[A12.8] says to ignore unknown pragmas */
+ case DT_PRAGMA_DCP:
+ default:
+ xyerror(D_PRAGMA_INVAL, "invalid D pragma: %s\n",
+ dnp->dn_string);
+ }
+
+ yylineno++;
+ break;
+ }
+
+ dt_node_list_free(&pnp);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
new file mode 100644
index 0000000..261fc8c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
@@ -0,0 +1,648 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+/*
+ * DTrace print() action
+ *
+ * This file contains the post-processing logic for the print() action. The
+ * print action behaves identically to trace() in that it generates a
+ * DTRACEACT_DIFEXPR action, but the action argument field refers to a CTF type
+ * string stored in the DOF string table (similar to printf formats). We
+ * take the result of the trace action and post-process it in the fashion of
+ * MDB's ::print dcmd.
+ *
+ * This implementation differs from MDB's in the following ways:
+ *
+ * - We do not expose any options or flags. The behavior of print() is
+ * equivalent to "::print -tn".
+ *
+ * - MDB will display "holes" in structures (unused padding between
+ * members).
+ *
+ * - When printing arrays of structures, MDB will leave a trailing ','
+ * after the last element.
+ *
+ * - MDB will print time_t types as date and time.
+ *
+ * - MDB will detect when an enum is actually the OR of several flags,
+ * and print it out with the constituent flags separated.
+ *
+ * - For large arrays, MDB will print the first few members and then
+ * print a "..." continuation line.
+ *
+ * - MDB will break and wrap arrays at 80 columns.
+ *
+ * - MDB prints out floats and doubles by hand, as it must run in kmdb
+ * context. We're able to leverage the printf() format strings,
+ * but the result is a slightly different format.
+ */
+
+#include <sys/sysmacros.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <dt_module.h>
+#include <dt_printf.h>
+#include <dt_string.h>
+#include <dt_impl.h>
+
+/* determines whether the given integer CTF encoding is a character */
+#define CTF_IS_CHAR(e) \
+ (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == \
+ (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY)
+/* determines whether the given CTF kind is a struct or union */
+#define CTF_IS_STRUCTLIKE(k) \
+ ((k) == CTF_K_STRUCT || (k) == CTF_K_UNION)
+
+/*
+ * Print structure passed down recursively through printing algorithm.
+ */
+typedef struct dt_printarg {
+ caddr_t pa_addr; /* base address of trace data */
+ ctf_file_t *pa_ctfp; /* CTF container */
+ int pa_depth; /* member depth */
+ int pa_nest; /* nested array depth */
+ FILE *pa_file; /* output file */
+} dt_printarg_t;
+
+static int dt_print_member(const char *, ctf_id_t, ulong_t, int, void *);
+
+/*
+ * Safe version of ctf_type_name() that will fall back to just "<ctfid>" if it
+ * can't resolve the type.
+ */
+static void
+dt_print_type_name(ctf_file_t *ctfp, ctf_id_t id, char *buf, size_t buflen)
+{
+ if (ctf_type_name(ctfp, id, buf, buflen) == NULL)
+ (void) snprintf(buf, buflen, "<%ld>", id);
+}
+
+/*
+ * Print any necessary trailing braces for structures or unions. We don't get
+ * invoked when a struct or union ends, so we infer the need to print braces
+ * based on the depth the last time we printed something and the new depth.
+ */
+static void
+dt_print_trailing_braces(dt_printarg_t *pap, int depth)
+{
+ int d;
+
+ for (d = pap->pa_depth; d > depth; d--) {
+ (void) fprintf(pap->pa_file, "%*s}%s",
+ (d + pap->pa_nest - 1) * 4, "",
+ d == depth + 1 ? "" : "\n");
+ }
+}
+
+/*
+ * Print the appropriate amount of indentation given the current depth and
+ * array nesting.
+ */
+static void
+dt_print_indent(dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "%*s",
+ (pap->pa_depth + pap->pa_nest) * 4, "");
+}
+
+/*
+ * Print a bitfield. It's worth noting that the D compiler support for
+ * bitfields is currently broken; printing "D`user_desc_t" (pulled in by the
+ * various D provider files) will produce incorrect results compared to
+ * "genunix`user_desc_t".
+ */
+static void
+print_bitfield(dt_printarg_t *pap, ulong_t off, ctf_encoding_t *ep)
+{
+ FILE *fp = pap->pa_file;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ uint64_t mask = (1ULL << ep->cte_bits) - 1;
+ uint64_t value = 0;
+ size_t size = (ep->cte_bits + (NBBY - 1)) / NBBY;
+ uint8_t *buf = (uint8_t *)&value;
+ uint8_t shift;
+
+ /*
+ * On big-endian machines, we need to adjust the buf pointer to refer
+ * to the lowest 'size' bytes in 'value', and we need to shift based on
+ * the offset from the end of the data, not the offset of the start.
+ */
+#ifdef _BIG_ENDIAN
+ buf += sizeof (value) - size;
+ off += ep->cte_bits;
+#endif
+ bcopy(addr, buf, size);
+ shift = off % NBBY;
+
+ /*
+ * Offsets are counted from opposite ends on little- and
+ * big-endian machines.
+ */
+#ifdef _BIG_ENDIAN
+ shift = NBBY - shift;
+#endif
+
+ /*
+ * If the bits we want do not begin on a byte boundary, shift the data
+ * right so that the value is in the lowest 'cte_bits' of 'value'.
+ */
+ if (off % NBBY != 0)
+ value >>= shift;
+ value &= mask;
+
+ (void) fprintf(fp, "%#llx", (u_longlong_t)value);
+}
+
+/*
+ * Dump the contents of memory as a fixed-size integer in hex.
+ */
+static void
+dt_print_hex(FILE *fp, caddr_t addr, size_t size)
+{
+ switch (size) {
+ case sizeof (uint8_t):
+ (void) fprintf(fp, "%#x", *(uint8_t *)addr);
+ break;
+ case sizeof (uint16_t):
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%#x", *(uint16_t *)addr);
+ break;
+ case sizeof (uint32_t):
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%#x", *(uint32_t *)addr);
+ break;
+ case sizeof (uint64_t):
+ (void) fprintf(fp, "%#llx",
+ /* LINTED - alignment */
+ (unsigned long long)*(uint64_t *)addr);
+ break;
+ default:
+ (void) fprintf(fp, "<invalid size %u>", (uint_t)size);
+ }
+}
+
+/*
+ * Print an integer type. Before dumping the contents via dt_print_hex(), we
+ * first check the encoding to see if it's part of a bitfield or a character.
+ */
+static void
+dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ ctf_encoding_t e;
+ size_t size;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+
+ if (ctf_type_encoding(ctfp, base, &e) == CTF_ERR) {
+ (void) fprintf(fp, "<unknown encoding>");
+ return;
+ }
+
+ /*
+ * This comes from MDB - it's not clear under what circumstances this
+ * would be found.
+ */
+ if (e.cte_format & CTF_INT_VARARGS) {
+ (void) fprintf(fp, "...");
+ return;
+ }
+
+ /*
+ * We print this as a bitfield if the bit encoding indicates it's not
+ * an even power of two byte size, or is larger than 8 bytes.
+ */
+ size = e.cte_bits / NBBY;
+ if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)) != 0) {
+ print_bitfield(pap, off, &e);
+ return;
+ }
+
+ /*
+ * If this is a character, print it out as such.
+ */
+ if (CTF_IS_CHAR(e)) {
+ char c = *(char *)addr;
+ if (isprint(c))
+ (void) fprintf(fp, "'%c'", c);
+ else if (c == 0)
+ (void) fprintf(fp, "'\\0'");
+ else
+ (void) fprintf(fp, "'\\%03o'", c);
+ return;
+ }
+
+ dt_print_hex(fp, addr, size);
+}
+
+/*
+ * Print a floating point (float, double, long double) value.
+ */
+/* ARGSUSED */
+static void
+dt_print_float(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ ctf_encoding_t e;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+
+ if (ctf_type_encoding(ctfp, base, &e) == 0) {
+ if (e.cte_format == CTF_FP_SINGLE &&
+ e.cte_bits == sizeof (float) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.7e", *((float *)addr));
+ } else if (e.cte_format == CTF_FP_DOUBLE &&
+ e.cte_bits == sizeof (double) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.7e", *((double *)addr));
+ } else if (e.cte_format == CTF_FP_LDOUBLE &&
+ e.cte_bits == sizeof (long double) * NBBY) {
+ /* LINTED - alignment */
+ (void) fprintf(fp, "%+.16LE", *((long double *)addr));
+ } else {
+ (void) fprintf(fp, "<unknown encoding>");
+ }
+ }
+}
+
+/*
+ * A pointer is printed as a fixed-size integer. This is used both for
+ * pointers and functions.
+ */
+static void
+dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ size_t size = ctf_type_size(ctfp, base);
+
+ dt_print_hex(fp, addr, size);
+}
+
+/*
+ * Print out an array. This is somewhat complex, as we must manually visit
+ * each member, and recursively invoke ctf_type_visit() for each member. If
+ * the members are non-structs, then we print them out directly:
+ *
+ * [ 0x14, 0x2e, 0 ]
+ *
+ * If they are structs, then we print out the necessary leading and trailing
+ * braces, to end up with:
+ *
+ * [
+ * type {
+ * ...
+ * },
+ * type {
+ * ...
+ * }
+ * ]
+ *
+ * We also use a heuristic to detect whether the array looks like a character
+ * array. If the encoding indicates it's a character, and we have all
+ * printable characters followed by a null byte, then we display it as a
+ * string:
+ *
+ * [ "string" ]
+ */
+static void
+dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ caddr_t addr = pap->pa_addr + off / NBBY;
+ ctf_arinfo_t car;
+ ssize_t eltsize;
+ ctf_encoding_t e;
+ int i;
+ boolean_t isstring;
+ int kind;
+ ctf_id_t rtype;
+
+ if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
+ (void) fprintf(fp, "0x%p", (void *)addr);
+ return;
+ }
+
+ if ((eltsize = ctf_type_size(ctfp, car.ctr_contents)) < 0 ||
+ (rtype = ctf_type_resolve(ctfp, car.ctr_contents)) == CTF_ERR ||
+ (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR) {
+ (void) fprintf(fp, "<invalid type %lu>", car.ctr_contents);
+ return;
+ }
+
+ /* see if this looks like a string */
+ isstring = B_FALSE;
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(ctfp, rtype, &e) != CTF_ERR && CTF_IS_CHAR(e)) {
+ char c;
+ for (i = 0; i < car.ctr_nelems; i++) {
+ c = *((char *)addr + eltsize * i);
+ if (!isprint(c) || c == '\0')
+ break;
+ }
+
+ if (i != car.ctr_nelems && c == '\0')
+ isstring = B_TRUE;
+ }
+
+ /*
+ * As a slight aesthetic optimization, if we are a top-level type, then
+ * don't bother printing out the brackets. This lets print("foo") look
+ * like:
+ *
+ * string "foo"
+ *
+ * As D will internally represent this as a char[256] array.
+ */
+ if (!isstring || pap->pa_depth != 0)
+ (void) fprintf(fp, "[ ");
+
+ if (isstring)
+ (void) fprintf(fp, "\"");
+
+ for (i = 0; i < car.ctr_nelems; i++) {
+ if (isstring) {
+ char c = *((char *)addr + eltsize * i);
+ if (c == '\0')
+ break;
+ (void) fprintf(fp, "%c", c);
+ } else {
+ /*
+ * Recursively invoke ctf_type_visit() on each member.
+ * We setup a new printarg struct with 'pa_nest' set to
+ * indicate that we are within a nested array.
+ */
+ dt_printarg_t pa = *pap;
+ pa.pa_nest += pap->pa_depth + 1;
+ pa.pa_depth = 0;
+ pa.pa_addr = addr + eltsize * i;
+ (void) ctf_type_visit(ctfp, car.ctr_contents,
+ dt_print_member, &pa);
+
+ dt_print_trailing_braces(&pa, 0);
+ if (i != car.ctr_nelems - 1)
+ (void) fprintf(fp, ", ");
+ else if (CTF_IS_STRUCTLIKE(kind))
+ (void) fprintf(fp, "\n");
+ }
+ }
+
+ if (isstring)
+ (void) fprintf(fp, "\"");
+
+ if (!isstring || pap->pa_depth != 0) {
+ if (CTF_IS_STRUCTLIKE(kind))
+ dt_print_indent(pap);
+ else
+ (void) fprintf(fp, " ");
+ (void) fprintf(fp, "]");
+ }
+}
+
+/*
+ * This isued by both structs and unions to print the leading brace.
+ */
+/* ARGSUSED */
+static void
+dt_print_structlike(ctf_id_t id, ulong_t off, dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "{");
+}
+
+/*
+ * For enums, we try to print the enum name, and fall back to the value if it
+ * can't be determined. We do not do any fancy flag processing like mdb.
+ */
+/* ARGSUSED */
+static void
+dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ const char *ename;
+ int value = 0;
+
+ if ((ename = ctf_enum_name(ctfp, base, value)) != NULL)
+ (void) fprintf(fp, "%s", ename);
+ else
+ (void) fprintf(fp, "%d", value);
+}
+
+/*
+ * Forward declaration. There's not much to do here without the complete
+ * type information, so just print out this fact and drive on.
+ */
+/* ARGSUSED */
+static void
+dt_print_tag(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
+{
+ (void) fprintf(pap->pa_file, "<forward decl>");
+}
+
+typedef void dt_printarg_f(ctf_id_t, ulong_t, dt_printarg_t *);
+
+static dt_printarg_f *const dt_printfuncs[] = {
+ dt_print_int, /* CTF_K_INTEGER */
+ dt_print_float, /* CTF_K_FLOAT */
+ dt_print_ptr, /* CTF_K_POINTER */
+ dt_print_array, /* CTF_K_ARRAY */
+ dt_print_ptr, /* CTF_K_FUNCTION */
+ dt_print_structlike, /* CTF_K_STRUCT */
+ dt_print_structlike, /* CTF_K_UNION */
+ dt_print_enum, /* CTF_K_ENUM */
+ dt_print_tag /* CTF_K_FORWARD */
+};
+
+/*
+ * Print one member of a structure. This callback is invoked from
+ * ctf_type_visit() recursively.
+ */
+static int
+dt_print_member(const char *name, ctf_id_t id, ulong_t off, int depth,
+ void *data)
+{
+ char type[DT_TYPE_NAMELEN];
+ int kind;
+ dt_printarg_t *pap = data;
+ FILE *fp = pap->pa_file;
+ ctf_file_t *ctfp = pap->pa_ctfp;
+ boolean_t arraymember;
+ boolean_t brief;
+ ctf_encoding_t e;
+ ctf_id_t rtype;
+
+ dt_print_trailing_braces(pap, depth);
+ /*
+ * dt_print_trailing_braces() doesn't include the trailing newline; add
+ * it here if necessary.
+ */
+ if (depth < pap->pa_depth)
+ (void) fprintf(fp, "\n");
+ pap->pa_depth = depth;
+
+ if ((rtype = ctf_type_resolve(ctfp, id)) == CTF_ERR ||
+ (kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR ||
+ kind < CTF_K_INTEGER || kind > CTF_K_FORWARD) {
+ dt_print_indent(pap);
+ (void) fprintf(fp, "%s = <invalid type %lu>", name, id);
+ return (0);
+ }
+
+ dt_print_type_name(ctfp, id, type, sizeof (type));
+
+ arraymember = (pap->pa_nest != 0 && depth == 0);
+ brief = (arraymember && !CTF_IS_STRUCTLIKE(kind));
+
+ if (!brief) {
+ /*
+ * If this is a direct array member and a struct (otherwise
+ * brief would be true), then print a trailing newline, as the
+ * array printing code doesn't include it because it might be a
+ * simple type.
+ */
+ if (arraymember)
+ (void) fprintf(fp, "\n");
+ dt_print_indent(pap);
+
+ /* always print the type */
+ (void) fprintf(fp, "%s", type);
+ if (name[0] != '\0') {
+ /*
+ * For aesthetics, we don't include a space between the
+ * type name and member name if the type is a pointer.
+ * This will give us "void *foo =" instead of "void *
+ * foo =". Unions also have the odd behavior that the
+ * type name is returned as "union ", with a trailing
+ * space, so we also avoid printing a space if the type
+ * name already ends with a space.
+ */
+ if (type[strlen(type) - 1] != '*' &&
+ type[strlen(type) -1] != ' ') {
+ (void) fprintf(fp, " ");
+ }
+ (void) fprintf(fp, "%s", name);
+
+ /*
+ * If this looks like a bitfield, or is an integer not
+ * aligned on a byte boundary, print the number of
+ * bits after the name.
+ */
+ if (kind == CTF_K_INTEGER &&
+ ctf_type_encoding(ctfp, id, &e) == 0) {
+ ulong_t bits = e.cte_bits;
+ ulong_t size = bits / NBBY;
+
+ if (bits % NBBY != 0 ||
+ off % NBBY != 0 ||
+ size > 8 ||
+ size != ctf_type_size(ctfp, id)) {
+ (void) fprintf(fp, " :%lu", bits);
+ }
+ }
+
+ (void) fprintf(fp, " =");
+ }
+ (void) fprintf(fp, " ");
+ }
+
+ dt_printfuncs[kind - 1](rtype, off, pap);
+
+ /* direct simple array members are not separated by newlines */
+ if (!brief)
+ (void) fprintf(fp, "\n");
+
+ return (0);
+}
+
+/*
+ * Main print function invoked by dt_consume_cpu().
+ */
+int
+dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
+ caddr_t addr, size_t len)
+{
+ const char *s;
+ char *object;
+ dt_printarg_t pa;
+ ctf_id_t id;
+ dt_module_t *dmp;
+
+ /*
+ * Split the fully-qualified type ID (module`id). This should
+ * always be the format, but if for some reason we don't find the
+ * expected value, return 0 to fall back to the generic trace()
+ * behavior.
+ */
+ for (s = typename; *s != '\0' && *s != '`'; s++)
+ ;
+
+ if (*s != '`')
+ return (0);
+
+ object = alloca(s - typename + 1);
+ bcopy(typename, object, s - typename);
+ object[s - typename] = '\0';
+ id = atoi(s + 1);
+
+ /*
+ * Try to get the CTF kind for this id. If something has gone horribly
+ * wrong and we can't resolve the ID, bail out and let trace() do the
+ * work.
+ */
+ dmp = dt_module_lookup_by_name(dtp, object);
+ if (dmp == NULL || ctf_type_kind(dt_module_getctf(dtp, dmp),
+ id) == CTF_ERR) {
+ return (0);
+ }
+
+ /* setup the print structure and kick off the main print routine */
+ pa.pa_addr = addr;
+ pa.pa_ctfp = dt_module_getctf(dtp, dmp);
+ pa.pa_nest = 0;
+ pa.pa_depth = 0;
+ pa.pa_file = fp;
+ (void) ctf_type_visit(pa.pa_ctfp, id, dt_print_member, &pa);
+
+ dt_print_trailing_braces(&pa, 0);
+
+ return (len);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
new file mode 100644
index 0000000..51f87b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
@@ -0,0 +1,2064 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#if defined(sun)
+#include <sys/sysmacros.h>
+#else
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+#endif
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <dt_printf.h>
+#include <dt_string.h>
+#include <dt_impl.h>
+
+/*ARGSUSED*/
+static int
+pfcheck_addr(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_pointer(dnp) || dt_node_is_integer(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_kaddr(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_pointer(dnp) || dt_node_is_integer(dnp) ||
+ dt_node_is_symaddr(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_uaddr(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = pfv->pfv_dtp;
+ dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
+
+ if (dt_node_is_usymaddr(dnp))
+ return (1);
+
+ if (idp == NULL || idp->di_id == 0)
+ return (0);
+
+ return (dt_node_is_pointer(dnp) || dt_node_is_integer(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_stack(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_stack(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_time(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_integer(dnp) &&
+ dt_node_type_size(dnp) == sizeof (uint64_t));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_str(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ ctf_file_t *ctfp;
+ ctf_encoding_t e;
+ ctf_arinfo_t r;
+ ctf_id_t base;
+ uint_t kind;
+
+ if (dt_node_is_string(dnp))
+ return (1);
+
+ ctfp = dnp->dn_ctfp;
+ base = ctf_type_resolve(ctfp, dnp->dn_type);
+ kind = ctf_type_kind(ctfp, base);
+
+ return (kind == CTF_K_ARRAY && ctf_array_info(ctfp, base, &r) == 0 &&
+ (base = ctf_type_resolve(ctfp, r.ctr_contents)) != CTF_ERR &&
+ ctf_type_encoding(ctfp, base, &e) == 0 && IS_CHAR(e));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_wstr(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_id_t base = ctf_type_resolve(ctfp, dnp->dn_type);
+ uint_t kind = ctf_type_kind(ctfp, base);
+
+ ctf_encoding_t e;
+ ctf_arinfo_t r;
+
+ return (kind == CTF_K_ARRAY && ctf_array_info(ctfp, base, &r) == 0 &&
+ (base = ctf_type_resolve(ctfp, r.ctr_contents)) != CTF_ERR &&
+ ctf_type_kind(ctfp, base) == CTF_K_INTEGER &&
+ ctf_type_encoding(ctfp, base, &e) == 0 && e.cte_bits == 32);
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_csi(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_integer(dnp) &&
+ dt_node_type_size(dnp) <= sizeof (int));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_fp(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_float(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_xint(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (dt_node_is_integer(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_dint(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ if (dnp->dn_flags & DT_NF_SIGNED)
+ pfd->pfd_flags |= DT_PFCONV_SIGNED;
+ else
+ pfd->pfd_fmt[strlen(pfd->pfd_fmt) - 1] = 'u';
+
+ return (dt_node_is_integer(dnp));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_xshort(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_id_t type = ctf_type_resolve(ctfp, dnp->dn_type);
+ char n[DT_TYPE_NAMELEN];
+
+ return (ctf_type_name(ctfp, type, n, sizeof (n)) != NULL && (
+ strcmp(n, "short") == 0 || strcmp(n, "signed short") == 0 ||
+ strcmp(n, "unsigned short") == 0));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_xlong(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_id_t type = ctf_type_resolve(ctfp, dnp->dn_type);
+ char n[DT_TYPE_NAMELEN];
+
+ return (ctf_type_name(ctfp, type, n, sizeof (n)) != NULL && (
+ strcmp(n, "long") == 0 || strcmp(n, "signed long") == 0 ||
+ strcmp(n, "unsigned long") == 0));
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_xlonglong(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ ctf_file_t *ctfp = dnp->dn_ctfp;
+ ctf_id_t type = dnp->dn_type;
+ char n[DT_TYPE_NAMELEN];
+
+ if (ctf_type_name(ctfp, ctf_type_resolve(ctfp, type), n,
+ sizeof (n)) != NULL && (strcmp(n, "long long") == 0 ||
+ strcmp(n, "signed long long") == 0 ||
+ strcmp(n, "unsigned long long") == 0))
+ return (1);
+
+ /*
+ * If the type used for %llx or %llX is not an [unsigned] long long, we
+ * also permit it to be a [u]int64_t or any typedef thereof. We know
+ * that these typedefs are guaranteed to work with %ll[xX] in either
+ * compilation environment even though they alias to "long" in LP64.
+ */
+ while (ctf_type_kind(ctfp, type) == CTF_K_TYPEDEF) {
+ if (ctf_type_name(ctfp, type, n, sizeof (n)) != NULL &&
+ (strcmp(n, "int64_t") == 0 || strcmp(n, "uint64_t") == 0))
+ return (1);
+
+ type = ctf_type_reference(ctfp, type);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+pfcheck_type(dt_pfargv_t *pfv, dt_pfargd_t *pfd, dt_node_t *dnp)
+{
+ return (ctf_type_compat(dnp->dn_ctfp, ctf_type_resolve(dnp->dn_ctfp,
+ dnp->dn_type), pfd->pfd_conv->pfc_dctfp, pfd->pfd_conv->pfc_dtype));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_sint(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t unormal)
+{
+ int64_t normal = (int64_t)unormal;
+ int32_t n = (int32_t)normal;
+
+ switch (size) {
+ case sizeof (int8_t):
+ return (dt_printf(dtp, fp, format,
+ (int32_t)*((int8_t *)addr) / n));
+ case sizeof (int16_t):
+ return (dt_printf(dtp, fp, format,
+ (int32_t)*((int16_t *)addr) / n));
+ case sizeof (int32_t):
+ return (dt_printf(dtp, fp, format,
+ *((int32_t *)addr) / n));
+ case sizeof (int64_t):
+ return (dt_printf(dtp, fp, format,
+ *((int64_t *)addr) / normal));
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+}
+
+/*ARGSUSED*/
+static int
+pfprint_uint(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ uint32_t n = (uint32_t)normal;
+
+ switch (size) {
+ case sizeof (uint8_t):
+ return (dt_printf(dtp, fp, format,
+ (uint32_t)*((uint8_t *)addr) / n));
+ case sizeof (uint16_t):
+ return (dt_printf(dtp, fp, format,
+ (uint32_t)*((uint16_t *)addr) / n));
+ case sizeof (uint32_t):
+ return (dt_printf(dtp, fp, format,
+ *((uint32_t *)addr) / n));
+ case sizeof (uint64_t):
+ return (dt_printf(dtp, fp, format,
+ *((uint64_t *)addr) / normal));
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+}
+
+static int
+pfprint_dint(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ if (pfd->pfd_flags & DT_PFCONV_SIGNED)
+ return (pfprint_sint(dtp, fp, format, pfd, addr, size, normal));
+ else
+ return (pfprint_uint(dtp, fp, format, pfd, addr, size, normal));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_fp(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ double n = (double)normal;
+ long double ldn = (long double)normal;
+
+ switch (size) {
+ case sizeof (float):
+ return (dt_printf(dtp, fp, format,
+ (double)*((float *)addr) / n));
+ case sizeof (double):
+ return (dt_printf(dtp, fp, format,
+ *((double *)addr) / n));
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__mips__)
+ case sizeof (long double):
+ return (dt_printf(dtp, fp, format,
+ *((long double *)addr) / ldn));
+#endif
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+}
+
+/*ARGSUSED*/
+static int
+pfprint_addr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char *s;
+ int n, len = 256;
+ uint64_t val;
+
+ switch (size) {
+ case sizeof (uint32_t):
+ val = *((uint32_t *)addr);
+ break;
+ case sizeof (uint64_t):
+ val = *((uint64_t *)addr);
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+
+ do {
+ n = len;
+ s = alloca(n);
+ } while ((len = dtrace_addr2str(dtp, val, s, n)) > n);
+
+ return (dt_printf(dtp, fp, format, s));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_mod(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_print_mod(dtp, fp, format, (caddr_t)addr));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_print_umod(dtp, fp, format, (caddr_t)addr));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_uaddr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char *s;
+ int n, len = 256;
+ uint64_t val, pid = 0;
+
+ dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
+
+ switch (size) {
+ case sizeof (uint32_t):
+ val = (u_longlong_t)*((uint32_t *)addr);
+ break;
+ case sizeof (uint64_t):
+ val = (u_longlong_t)*((uint64_t *)addr);
+ break;
+ case sizeof (uint64_t) * 2:
+ pid = ((uint64_t *)(uintptr_t)addr)[0];
+ val = ((uint64_t *)(uintptr_t)addr)[1];
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+
+ if (pid == 0 && dtp->dt_vector == NULL && idp != NULL)
+ pid = idp->di_id;
+
+ do {
+ n = len;
+ s = alloca(n);
+ } while ((len = dtrace_uaddr2str(dtp, pid, val, s, n)) > n);
+
+ return (dt_printf(dtp, fp, format, s));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_stack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *vaddr, size_t size, uint64_t normal)
+{
+ int width;
+ dtrace_optval_t saved = dtp->dt_options[DTRACEOPT_STACKINDENT];
+ const dtrace_recdesc_t *rec = pfd->pfd_rec;
+ caddr_t addr = (caddr_t)vaddr;
+ int err = 0;
+
+ /*
+ * We have stashed the value of the STACKINDENT option, and we will
+ * now override it for the purposes of formatting the stack. If the
+ * field has been specified as left-aligned (i.e. (%-#), we set the
+ * indentation to be the width. This is a slightly odd semantic, but
+ * it's useful functionality -- and it's slightly odd to begin with to
+ * be using a single format specifier to be formatting multiple lines
+ * of text...
+ */
+ if (pfd->pfd_dynwidth < 0) {
+ assert(pfd->pfd_flags & DT_PFCONV_DYNWIDTH);
+ width = -pfd->pfd_dynwidth;
+ } else if (pfd->pfd_flags & DT_PFCONV_LEFT) {
+ width = pfd->pfd_dynwidth ? pfd->pfd_dynwidth : pfd->pfd_width;
+ } else {
+ width = 0;
+ }
+
+ dtp->dt_options[DTRACEOPT_STACKINDENT] = width;
+
+ switch (rec->dtrd_action) {
+ case DTRACEACT_USTACK:
+ case DTRACEACT_JSTACK:
+ err = dt_print_ustack(dtp, fp, format, addr, rec->dtrd_arg);
+ break;
+
+ case DTRACEACT_STACK:
+ err = dt_print_stack(dtp, fp, format, addr, rec->dtrd_arg,
+ rec->dtrd_size / rec->dtrd_arg);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ dtp->dt_options[DTRACEOPT_STACKINDENT] = saved;
+
+ return (err);
+}
+
+/*ARGSUSED*/
+static int
+pfprint_time(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char src[32], buf[32], *dst = buf;
+ hrtime_t time = *((uint64_t *)addr);
+ time_t sec = (time_t)(time / NANOSEC);
+ int i;
+
+ /*
+ * ctime(3C) returns a string of the form "Dec 3 17:20:00 1973\n\0".
+ * Below, we turn this into the canonical adb/mdb /[yY] format,
+ * "1973 Dec 3 17:20:00".
+ */
+#if defined(sun)
+ (void) ctime_r(&sec, src, sizeof (src));
+#else
+ (void) ctime_r(&sec, src);
+#endif
+
+ /*
+ * Place the 4-digit year at the head of the string...
+ */
+ for (i = 20; i < 24; i++)
+ *dst++ = src[i];
+
+ /*
+ * ...and follow it with the remainder (month, day, hh:mm:ss).
+ */
+ for (i = 3; i < 19; i++)
+ *dst++ = src[i];
+
+ *dst = '\0';
+ return (dt_printf(dtp, fp, format, buf));
+}
+
+/*
+ * This prints the time in RFC 822 standard form. This is useful for emitting
+ * notions of time that are consumed by standard tools (e.g., as part of an
+ * RSS feed).
+ */
+/*ARGSUSED*/
+static int
+pfprint_time822(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ hrtime_t time = *((uint64_t *)addr);
+ time_t sec = (time_t)(time / NANOSEC);
+ struct tm tm;
+ char buf[64];
+
+ (void) localtime_r(&sec, &tm);
+ (void) strftime(buf, sizeof (buf), "%a, %d %b %G %T %Z", &tm);
+ return (dt_printf(dtp, fp, format, buf));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_port(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ uint16_t port = htons(*((uint16_t *)addr));
+ char buf[256];
+ struct servent *sv, res;
+
+#if defined(sun)
+ if ((sv = getservbyport_r(port, NULL, &res, buf, sizeof (buf))) != NULL)
+#else
+ if (getservbyport_r(port, NULL, &res, buf, sizeof (buf), &sv) > 0)
+#endif
+ return (dt_printf(dtp, fp, format, sv->s_name));
+
+ (void) snprintf(buf, sizeof (buf), "%d", *((uint16_t *)addr));
+ return (dt_printf(dtp, fp, format, buf));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_inetaddr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char *s = alloca(size + 1);
+ struct hostent *host, res;
+ char inetaddr[NS_IN6ADDRSZ];
+ char buf[1024];
+ int e;
+
+ bcopy(addr, s, size);
+ s[size] = '\0';
+
+ if (strchr(s, ':') == NULL && inet_pton(AF_INET, s, inetaddr) != -1) {
+#if defined(sun)
+ if ((host = gethostbyaddr_r(inetaddr, NS_INADDRSZ,
+ AF_INET, &res, buf, sizeof (buf), &e)) != NULL)
+#else
+ if (gethostbyaddr_r(inetaddr, NS_INADDRSZ,
+ AF_INET, &res, buf, sizeof (buf), &host, &e) > 0)
+#endif
+ return (dt_printf(dtp, fp, format, host->h_name));
+ } else if (inet_pton(AF_INET6, s, inetaddr) != -1) {
+ if ((host = getipnodebyaddr(inetaddr, NS_IN6ADDRSZ,
+ AF_INET6, &e)) != NULL)
+ return (dt_printf(dtp, fp, format, host->h_name));
+ }
+
+ return (dt_printf(dtp, fp, format, s));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_cstr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char *s = alloca(size + 1);
+
+ bcopy(addr, s, size);
+ s[size] = '\0';
+ return (dt_printf(dtp, fp, format, s));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_wstr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ wchar_t *ws = alloca(size + sizeof (wchar_t));
+
+ bcopy(addr, ws, size);
+ ws[size / sizeof (wchar_t)] = L'\0';
+ return (dt_printf(dtp, fp, format, ws));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_estr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char *s;
+ int n;
+
+ if ((s = strchr2esc(addr, size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ n = dt_printf(dtp, fp, format, s);
+ free(s);
+ return (n);
+}
+
+static int
+pfprint_echr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ char c;
+
+ switch (size) {
+ case sizeof (int8_t):
+ c = *(int8_t *)addr;
+ break;
+ case sizeof (int16_t):
+ c = *(int16_t *)addr;
+ break;
+ case sizeof (int32_t):
+ c = *(int32_t *)addr;
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+
+ return (pfprint_estr(dtp, fp, format, pfd, &c, 1, normal));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_pct(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_printf(dtp, fp, "%%"));
+}
+
+static const char pfproto_xint[] = "char, short, int, long, or long long";
+static const char pfproto_csi[] = "char, short, or int";
+static const char pfproto_fp[] = "float, double, or long double";
+static const char pfproto_addr[] = "pointer or integer";
+static const char pfproto_uaddr[] =
+ "pointer or integer (with -p/-c) or _usymaddr (without -p/-c)";
+static const char pfproto_cstr[] = "char [] or string (or use stringof)";
+static const char pfproto_wstr[] = "wchar_t []";
+
+/*
+ * Printf format conversion dictionary. This table should match the set of
+ * conversions offered by printf(3C), as well as some additional extensions.
+ * The second parameter is an ASCII string which is either an actual type
+ * name we should look up (if pfcheck_type is specified), or just a descriptive
+ * string of the types expected for use in error messages.
+ */
+static const dt_pfconv_t _dtrace_conversions[] = {
+{ "a", "s", pfproto_addr, pfcheck_kaddr, pfprint_addr },
+{ "A", "s", pfproto_uaddr, pfcheck_uaddr, pfprint_uaddr },
+{ "c", "c", pfproto_csi, pfcheck_csi, pfprint_sint },
+{ "C", "s", pfproto_csi, pfcheck_csi, pfprint_echr },
+{ "d", "d", pfproto_xint, pfcheck_dint, pfprint_dint },
+{ "e", "e", pfproto_fp, pfcheck_fp, pfprint_fp },
+{ "E", "E", pfproto_fp, pfcheck_fp, pfprint_fp },
+{ "f", "f", pfproto_fp, pfcheck_fp, pfprint_fp },
+{ "g", "g", pfproto_fp, pfcheck_fp, pfprint_fp },
+{ "G", "G", pfproto_fp, pfcheck_fp, pfprint_fp },
+{ "hd", "d", "short", pfcheck_type, pfprint_sint },
+{ "hi", "i", "short", pfcheck_type, pfprint_sint },
+{ "ho", "o", "unsigned short", pfcheck_type, pfprint_uint },
+{ "hu", "u", "unsigned short", pfcheck_type, pfprint_uint },
+{ "hx", "x", "short", pfcheck_xshort, pfprint_uint },
+{ "hX", "X", "short", pfcheck_xshort, pfprint_uint },
+{ "i", "i", pfproto_xint, pfcheck_dint, pfprint_dint },
+{ "I", "s", pfproto_cstr, pfcheck_str, pfprint_inetaddr },
+{ "k", "s", "stack", pfcheck_stack, pfprint_stack },
+{ "lc", "lc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wint_t */
+{ "ld", "d", "long", pfcheck_type, pfprint_sint },
+{ "li", "i", "long", pfcheck_type, pfprint_sint },
+{ "lo", "o", "unsigned long", pfcheck_type, pfprint_uint },
+{ "lu", "u", "unsigned long", pfcheck_type, pfprint_uint },
+{ "ls", "ls", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
+{ "lx", "x", "long", pfcheck_xlong, pfprint_uint },
+{ "lX", "X", "long", pfcheck_xlong, pfprint_uint },
+{ "lld", "d", "long long", pfcheck_type, pfprint_sint },
+{ "lli", "i", "long long", pfcheck_type, pfprint_sint },
+{ "llo", "o", "unsigned long long", pfcheck_type, pfprint_uint },
+{ "llu", "u", "unsigned long long", pfcheck_type, pfprint_uint },
+{ "llx", "x", "long long", pfcheck_xlonglong, pfprint_uint },
+{ "llX", "X", "long long", pfcheck_xlonglong, pfprint_uint },
+{ "Le", "e", "long double", pfcheck_type, pfprint_fp },
+{ "LE", "E", "long double", pfcheck_type, pfprint_fp },
+{ "Lf", "f", "long double", pfcheck_type, pfprint_fp },
+{ "Lg", "g", "long double", pfcheck_type, pfprint_fp },
+{ "LG", "G", "long double", pfcheck_type, pfprint_fp },
+{ "o", "o", pfproto_xint, pfcheck_xint, pfprint_uint },
+{ "p", "x", pfproto_addr, pfcheck_addr, pfprint_uint },
+{ "P", "s", "uint16_t", pfcheck_type, pfprint_port },
+{ "s", "s", "char [] or string (or use stringof)", pfcheck_str, pfprint_cstr },
+{ "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr },
+{ "T", "s", "int64_t", pfcheck_time, pfprint_time822 },
+{ "u", "u", pfproto_xint, pfcheck_xint, pfprint_uint },
+{ "wc", "wc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */
+{ "ws", "ws", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
+{ "x", "x", pfproto_xint, pfcheck_xint, pfprint_uint },
+{ "X", "X", pfproto_xint, pfcheck_xint, pfprint_uint },
+{ "Y", "s", "int64_t", pfcheck_time, pfprint_time },
+{ "%", "%", "void", pfcheck_type, pfprint_pct },
+{ NULL, NULL, NULL, NULL, NULL }
+};
+
+int
+dt_pfdict_create(dtrace_hdl_t *dtp)
+{
+ uint_t n = _dtrace_strbuckets;
+ const dt_pfconv_t *pfd;
+ dt_pfdict_t *pdi;
+
+ if ((pdi = malloc(sizeof (dt_pfdict_t))) == NULL ||
+ (pdi->pdi_buckets = malloc(sizeof (dt_pfconv_t *) * n)) == NULL) {
+ free(pdi);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dtp->dt_pfdict = pdi;
+ bzero(pdi->pdi_buckets, sizeof (dt_pfconv_t *) * n);
+ pdi->pdi_nbuckets = n;
+
+ for (pfd = _dtrace_conversions; pfd->pfc_name != NULL; pfd++) {
+ dtrace_typeinfo_t dtt;
+ dt_pfconv_t *pfc;
+ uint_t h;
+
+ if ((pfc = malloc(sizeof (dt_pfconv_t))) == NULL) {
+ dt_pfdict_destroy(dtp);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ bcopy(pfd, pfc, sizeof (dt_pfconv_t));
+ h = dt_strtab_hash(pfc->pfc_name, NULL) % n;
+ pfc->pfc_next = pdi->pdi_buckets[h];
+ pdi->pdi_buckets[h] = pfc;
+
+ dtt.dtt_ctfp = NULL;
+ dtt.dtt_type = CTF_ERR;
+
+ /*
+ * The "D" container or its parent must contain a definition of
+ * any type referenced by a printf conversion. If none can be
+ * found, we fail to initialize the printf dictionary.
+ */
+ if (pfc->pfc_check == &pfcheck_type && dtrace_lookup_by_type(
+ dtp, DTRACE_OBJ_DDEFS, pfc->pfc_tstr, &dtt) != 0) {
+ dt_pfdict_destroy(dtp);
+ return (dt_set_errno(dtp, EDT_NOCONV));
+ }
+
+ pfc->pfc_dctfp = dtt.dtt_ctfp;
+ pfc->pfc_dtype = dtt.dtt_type;
+
+ /*
+ * The "C" container may contain an alternate definition of an
+ * explicit conversion type. If it does, use it; otherwise
+ * just set pfc_ctype to pfc_dtype so it is always valid.
+ */
+ if (pfc->pfc_check == &pfcheck_type && dtrace_lookup_by_type(
+ dtp, DTRACE_OBJ_CDEFS, pfc->pfc_tstr, &dtt) == 0) {
+ pfc->pfc_cctfp = dtt.dtt_ctfp;
+ pfc->pfc_ctype = dtt.dtt_type;
+ } else {
+ pfc->pfc_cctfp = pfc->pfc_dctfp;
+ pfc->pfc_ctype = pfc->pfc_dtype;
+ }
+
+ if (pfc->pfc_check == NULL || pfc->pfc_print == NULL ||
+ pfc->pfc_ofmt == NULL || pfc->pfc_tstr == NULL) {
+ dt_pfdict_destroy(dtp);
+ return (dt_set_errno(dtp, EDT_BADCONV));
+ }
+
+ dt_dprintf("loaded printf conversion %%%s\n", pfc->pfc_name);
+ }
+
+ return (0);
+}
+
+void
+dt_pfdict_destroy(dtrace_hdl_t *dtp)
+{
+ dt_pfdict_t *pdi = dtp->dt_pfdict;
+ dt_pfconv_t *pfc, *nfc;
+ uint_t i;
+
+ if (pdi == NULL)
+ return;
+
+ for (i = 0; i < pdi->pdi_nbuckets; i++) {
+ for (pfc = pdi->pdi_buckets[i]; pfc != NULL; pfc = nfc) {
+ nfc = pfc->pfc_next;
+ free(pfc);
+ }
+ }
+
+ free(pdi->pdi_buckets);
+ free(pdi);
+ dtp->dt_pfdict = NULL;
+}
+
+static const dt_pfconv_t *
+dt_pfdict_lookup(dtrace_hdl_t *dtp, const char *name)
+{
+ dt_pfdict_t *pdi = dtp->dt_pfdict;
+ uint_t h = dt_strtab_hash(name, NULL) % pdi->pdi_nbuckets;
+ const dt_pfconv_t *pfc;
+
+ for (pfc = pdi->pdi_buckets[h]; pfc != NULL; pfc = pfc->pfc_next) {
+ if (strcmp(pfc->pfc_name, name) == 0)
+ break;
+ }
+
+ return (pfc);
+}
+
+static dt_pfargv_t *
+dt_printf_error(dtrace_hdl_t *dtp, int err)
+{
+ if (yypcb != NULL)
+ longjmp(yypcb->pcb_jmpbuf, err);
+
+ (void) dt_set_errno(dtp, err);
+ return (NULL);
+}
+
+dt_pfargv_t *
+dt_printf_create(dtrace_hdl_t *dtp, const char *s)
+{
+ dt_pfargd_t *pfd, *nfd = NULL;
+ dt_pfargv_t *pfv;
+ const char *p, *q;
+ char *format;
+
+ if ((pfv = malloc(sizeof (dt_pfargv_t))) == NULL ||
+ (format = strdup(s)) == NULL) {
+ free(pfv);
+ return (dt_printf_error(dtp, EDT_NOMEM));
+ }
+
+ pfv->pfv_format = format;
+ pfv->pfv_argv = NULL;
+ pfv->pfv_argc = 0;
+ pfv->pfv_flags = 0;
+ pfv->pfv_dtp = dtp;
+
+ for (q = format; (p = strchr(q, '%')) != NULL; q = *p ? p + 1 : p) {
+ uint_t namelen = 0;
+ int digits = 0;
+ int dot = 0;
+
+ char name[8];
+ char c;
+ int n;
+
+ if ((pfd = malloc(sizeof (dt_pfargd_t))) == NULL) {
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_NOMEM));
+ }
+
+ if (pfv->pfv_argv != NULL)
+ nfd->pfd_next = pfd;
+ else
+ pfv->pfv_argv = pfd;
+
+ bzero(pfd, sizeof (dt_pfargd_t));
+ pfv->pfv_argc++;
+ nfd = pfd;
+
+ if (p > q) {
+ pfd->pfd_preflen = (size_t)(p - q);
+ pfd->pfd_prefix = q;
+ }
+
+ fmt_switch:
+ switch (c = *++p) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (dot == 0 && digits == 0 && c == '0') {
+ pfd->pfd_flags |= DT_PFCONV_ZPAD;
+ pfd->pfd_flags &= ~DT_PFCONV_LEFT;
+ goto fmt_switch;
+ }
+
+ for (n = 0; isdigit(c); c = *++p)
+ n = n * 10 + c - '0';
+
+ if (dot)
+ pfd->pfd_prec = n;
+ else
+ pfd->pfd_width = n;
+
+ p--;
+ digits++;
+ goto fmt_switch;
+
+ case '#':
+ pfd->pfd_flags |= DT_PFCONV_ALT;
+ goto fmt_switch;
+
+ case '*':
+ n = dot ? DT_PFCONV_DYNPREC : DT_PFCONV_DYNWIDTH;
+
+ if (pfd->pfd_flags & n) {
+ yywarn("format conversion #%u has more than "
+ "one '*' specified for the output %s\n",
+ pfv->pfv_argc, n ? "precision" : "width");
+
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+ }
+
+ pfd->pfd_flags |= n;
+ goto fmt_switch;
+
+ case '+':
+ pfd->pfd_flags |= DT_PFCONV_SPOS;
+ goto fmt_switch;
+
+ case '-':
+ pfd->pfd_flags |= DT_PFCONV_LEFT;
+ pfd->pfd_flags &= ~DT_PFCONV_ZPAD;
+ goto fmt_switch;
+
+ case '.':
+ if (dot++ != 0) {
+ yywarn("format conversion #%u has more than "
+ "one '.' specified\n", pfv->pfv_argc);
+
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+ }
+ digits = 0;
+ goto fmt_switch;
+
+ case '?':
+ if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
+ pfd->pfd_width = 16;
+ else
+ pfd->pfd_width = 8;
+ goto fmt_switch;
+
+ case '@':
+ pfd->pfd_flags |= DT_PFCONV_AGG;
+ goto fmt_switch;
+
+ case '\'':
+ pfd->pfd_flags |= DT_PFCONV_GROUP;
+ goto fmt_switch;
+
+ case ' ':
+ pfd->pfd_flags |= DT_PFCONV_SPACE;
+ goto fmt_switch;
+
+ case '$':
+ yywarn("format conversion #%u uses unsupported "
+ "positional format (%%n$)\n", pfv->pfv_argc);
+
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+
+ case '%':
+ if (p[-1] == '%')
+ goto default_lbl; /* if %% then use "%" conv */
+
+ yywarn("format conversion #%u cannot be combined "
+ "with other format flags: %%%%\n", pfv->pfv_argc);
+
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+
+ case '\0':
+ yywarn("format conversion #%u name expected before "
+ "end of format string\n", pfv->pfv_argc);
+
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+
+ case 'h':
+ case 'l':
+ case 'L':
+ case 'w':
+ if (namelen < sizeof (name) - 2)
+ name[namelen++] = c;
+ goto fmt_switch;
+
+ default_lbl:
+ default:
+ name[namelen++] = c;
+ name[namelen] = '\0';
+ }
+
+ pfd->pfd_conv = dt_pfdict_lookup(dtp, name);
+
+ if (pfd->pfd_conv == NULL) {
+ yywarn("format conversion #%u is undefined: %%%s\n",
+ pfv->pfv_argc, name);
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_COMPILER));
+ }
+ }
+
+ if (*q != '\0' || *format == '\0') {
+ if ((pfd = malloc(sizeof (dt_pfargd_t))) == NULL) {
+ dt_printf_destroy(pfv);
+ return (dt_printf_error(dtp, EDT_NOMEM));
+ }
+
+ if (pfv->pfv_argv != NULL)
+ nfd->pfd_next = pfd;
+ else
+ pfv->pfv_argv = pfd;
+
+ bzero(pfd, sizeof (dt_pfargd_t));
+ pfv->pfv_argc++;
+
+ pfd->pfd_prefix = q;
+ pfd->pfd_preflen = strlen(q);
+ }
+
+ return (pfv);
+}
+
+void
+dt_printf_destroy(dt_pfargv_t *pfv)
+{
+ dt_pfargd_t *pfd, *nfd;
+
+ for (pfd = pfv->pfv_argv; pfd != NULL; pfd = nfd) {
+ nfd = pfd->pfd_next;
+ free(pfd);
+ }
+
+ free(pfv->pfv_format);
+ free(pfv);
+}
+
+void
+dt_printf_validate(dt_pfargv_t *pfv, uint_t flags,
+ dt_ident_t *idp, int foff, dtrace_actkind_t kind, dt_node_t *dnp)
+{
+ dt_pfargd_t *pfd = pfv->pfv_argv;
+ const char *func = idp->di_name;
+
+ char n[DT_TYPE_NAMELEN];
+ dtrace_typeinfo_t dtt;
+ const char *aggtype;
+ dt_node_t aggnode;
+ int i, j;
+
+ if (pfv->pfv_format[0] == '\0') {
+ xyerror(D_PRINTF_FMT_EMPTY,
+ "%s( ) format string is empty\n", func);
+ }
+
+ pfv->pfv_flags = flags;
+
+ /*
+ * We fake up a parse node representing the type that can be used with
+ * an aggregation result conversion, which -- for all but count() --
+ * is a signed quantity.
+ */
+ if (kind != DTRACEAGG_COUNT)
+ aggtype = "int64_t";
+ else
+ aggtype = "uint64_t";
+
+ if (dt_type_lookup(aggtype, &dtt) != 0)
+ xyerror(D_TYPE_ERR, "failed to lookup agg type %s\n", aggtype);
+
+ bzero(&aggnode, sizeof (aggnode));
+ dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type);
+
+ for (i = 0, j = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) {
+ const dt_pfconv_t *pfc = pfd->pfd_conv;
+ const char *dyns[2];
+ int dync = 0;
+
+ char vname[64];
+ dt_node_t *vnp;
+
+ if (pfc == NULL)
+ continue; /* no checking if argd is just a prefix */
+
+ if (pfc->pfc_print == &pfprint_pct) {
+ (void) strcat(pfd->pfd_fmt, pfc->pfc_ofmt);
+ continue;
+ }
+
+ if (pfd->pfd_flags & DT_PFCONV_DYNPREC)
+ dyns[dync++] = ".*";
+ if (pfd->pfd_flags & DT_PFCONV_DYNWIDTH)
+ dyns[dync++] = "*";
+
+ for (; dync != 0; dync--) {
+ if (dnp == NULL) {
+ xyerror(D_PRINTF_DYN_PROTO,
+ "%s( ) prototype mismatch: conversion "
+ "#%d (%%%s) is missing a corresponding "
+ "\"%s\" argument\n", func, i + 1,
+ pfc->pfc_name, dyns[dync - 1]);
+ }
+
+ if (dt_node_is_integer(dnp) == 0) {
+ xyerror(D_PRINTF_DYN_TYPE,
+ "%s( ) argument #%d is incompatible "
+ "with conversion #%d prototype:\n"
+ "\tconversion: %% %s %s\n"
+ "\t prototype: int\n\t argument: %s\n",
+ func, j + foff + 1, i + 1,
+ dyns[dync - 1], pfc->pfc_name,
+ dt_node_type_name(dnp, n, sizeof (n)));
+ }
+
+ dnp = dnp->dn_list;
+ j++;
+ }
+
+ /*
+ * If this conversion is consuming the aggregation data, set
+ * the value node pointer (vnp) to a fake node based on the
+ * aggregating function result type. Otherwise assign vnp to
+ * the next parse node in the argument list, if there is one.
+ */
+ if (pfd->pfd_flags & DT_PFCONV_AGG) {
+ if (!(flags & DT_PRINTF_AGGREGATION)) {
+ xyerror(D_PRINTF_AGG_CONV,
+ "%%@ conversion requires an aggregation"
+ " and is not for use with %s( )\n", func);
+ }
+ (void) strlcpy(vname, "aggregating action",
+ sizeof (vname));
+ vnp = &aggnode;
+ } else if (dnp == NULL) {
+ xyerror(D_PRINTF_ARG_PROTO,
+ "%s( ) prototype mismatch: conversion #%d (%%"
+ "%s) is missing a corresponding value argument\n",
+ func, i + 1, pfc->pfc_name);
+ } else {
+ (void) snprintf(vname, sizeof (vname),
+ "argument #%d", j + foff + 1);
+ vnp = dnp;
+ dnp = dnp->dn_list;
+ j++;
+ }
+
+ /*
+ * Fill in the proposed final format string by prepending any
+ * size-related prefixes to the pfconv's format string. The
+ * pfc_check() function below may optionally modify the format
+ * as part of validating the type of the input argument.
+ */
+ if (pfc->pfc_print == &pfprint_sint ||
+ pfc->pfc_print == &pfprint_uint ||
+ pfc->pfc_print == &pfprint_dint) {
+ if (dt_node_type_size(vnp) == sizeof (uint64_t))
+ (void) strcpy(pfd->pfd_fmt, "ll");
+ } else if (pfc->pfc_print == &pfprint_fp) {
+ if (dt_node_type_size(vnp) == sizeof (long double))
+ (void) strcpy(pfd->pfd_fmt, "L");
+ }
+
+ (void) strcat(pfd->pfd_fmt, pfc->pfc_ofmt);
+
+ /*
+ * Validate the format conversion against the value node type.
+ * If the conversion is good, create the descriptor format
+ * string by concatenating together any required printf(3C)
+ * size prefixes with the conversion's native format string.
+ */
+ if (pfc->pfc_check(pfv, pfd, vnp) == 0) {
+ xyerror(D_PRINTF_ARG_TYPE,
+ "%s( ) %s is incompatible with "
+ "conversion #%d prototype:\n\tconversion: %%%s\n"
+ "\t prototype: %s\n\t argument: %s\n", func,
+ vname, i + 1, pfc->pfc_name, pfc->pfc_tstr,
+ dt_node_type_name(vnp, n, sizeof (n)));
+ }
+ }
+
+ if ((flags & DT_PRINTF_EXACTLEN) && dnp != NULL) {
+ xyerror(D_PRINTF_ARG_EXTRA,
+ "%s( ) prototype mismatch: only %d arguments "
+ "required by this format string\n", func, j);
+ }
+}
+
+void
+dt_printa_validate(dt_node_t *lhs, dt_node_t *rhs)
+{
+ dt_ident_t *lid, *rid;
+ dt_node_t *lproto, *rproto;
+ int largc, rargc, argn;
+ char n1[DT_TYPE_NAMELEN];
+ char n2[DT_TYPE_NAMELEN];
+
+ assert(lhs->dn_kind == DT_NODE_AGG);
+ assert(rhs->dn_kind == DT_NODE_AGG);
+
+ lid = lhs->dn_ident;
+ rid = rhs->dn_ident;
+
+ lproto = ((dt_idsig_t *)lid->di_data)->dis_args;
+ rproto = ((dt_idsig_t *)rid->di_data)->dis_args;
+
+ /*
+ * First, get an argument count on each side. These must match.
+ */
+ for (largc = 0; lproto != NULL; lproto = lproto->dn_list)
+ largc++;
+
+ for (rargc = 0; rproto != NULL; rproto = rproto->dn_list)
+ rargc++;
+
+ if (largc != rargc) {
+ xyerror(D_PRINTA_AGGKEY, "printa( ): @%s and @%s do not have "
+ "matching key signatures: @%s has %d key%s, @%s has %d "
+ "key%s", lid->di_name, rid->di_name,
+ lid->di_name, largc, largc == 1 ? "" : "s",
+ rid->di_name, rargc, rargc == 1 ? "" : "s");
+ }
+
+ /*
+ * Now iterate over the keys to verify that each type matches.
+ */
+ lproto = ((dt_idsig_t *)lid->di_data)->dis_args;
+ rproto = ((dt_idsig_t *)rid->di_data)->dis_args;
+
+ for (argn = 1; lproto != NULL; argn++, lproto = lproto->dn_list,
+ rproto = rproto->dn_list) {
+ assert(rproto != NULL);
+
+ if (dt_node_is_argcompat(lproto, rproto))
+ continue;
+
+ xyerror(D_PRINTA_AGGPROTO, "printa( ): @%s[ ] key #%d is "
+ "incompatible with @%s:\n%9s key #%d: %s\n"
+ "%9s key #%d: %s\n",
+ rid->di_name, argn, lid->di_name, lid->di_name, argn,
+ dt_node_type_name(lproto, n1, sizeof (n1)), rid->di_name,
+ argn, dt_node_type_name(rproto, n2, sizeof (n2)));
+ }
+}
+
+static int
+dt_printf_getint(dtrace_hdl_t *dtp, const dtrace_recdesc_t *recp,
+ uint_t nrecs, const void *buf, size_t len, int *ip)
+{
+ uintptr_t addr;
+
+ if (nrecs == 0)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ addr = (uintptr_t)buf + recp->dtrd_offset;
+
+ if (addr + sizeof (int) > (uintptr_t)buf + len)
+ return (dt_set_errno(dtp, EDT_DOFFSET));
+
+ if (addr & (recp->dtrd_alignment - 1))
+ return (dt_set_errno(dtp, EDT_DALIGN));
+
+ switch (recp->dtrd_size) {
+ case sizeof (int8_t):
+ *ip = (int)*((int8_t *)addr);
+ break;
+ case sizeof (int16_t):
+ *ip = (int)*((int16_t *)addr);
+ break;
+ case sizeof (int32_t):
+ *ip = (int)*((int32_t *)addr);
+ break;
+ case sizeof (int64_t):
+ *ip = (int)*((int64_t *)addr);
+ break;
+ default:
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+pfprint_average(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ const uint64_t *data = addr;
+
+ if (size != sizeof (uint64_t) * 2)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ return (dt_printf(dtp, fp, format,
+ data[0] ? data[1] / normal / data[0] : 0));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_stddev(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ const uint64_t *data = addr;
+
+ if (size != sizeof (uint64_t) * 4)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ return (dt_printf(dtp, fp, format,
+ dt_stddev((uint64_t *)data, normal)));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_quantize(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_print_quantize(dtp, fp, addr, size, normal));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_lquantize(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_print_lquantize(dtp, fp, addr, size, normal));
+}
+
+/*ARGSUSED*/
+static int
+pfprint_llquantize(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+ const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+ return (dt_print_llquantize(dtp, fp, addr, size, normal));
+}
+
+static int
+dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
+ const dtrace_recdesc_t *recs, uint_t nrecs, const void *buf,
+ size_t len, const dtrace_aggdata_t **aggsdata, int naggvars)
+{
+ dt_pfargd_t *pfd = pfv->pfv_argv;
+ const dtrace_recdesc_t *recp = recs;
+ const dtrace_aggdata_t *aggdata;
+ dtrace_aggdesc_t *agg;
+ caddr_t lim = (caddr_t)buf + len, limit;
+ char format[64] = "%";
+ int i, aggrec, curagg = -1;
+ uint64_t normal;
+
+ /*
+ * If we are formatting an aggregation, set 'aggrec' to the index of
+ * the final record description (the aggregation result) so we can use
+ * this record index with any conversion where DT_PFCONV_AGG is set.
+ * (The actual aggregation used will vary as we increment through the
+ * aggregation variables that we have been passed.) Finally, we
+ * decrement nrecs to prevent this record from being used with any
+ * other conversion.
+ */
+ if (pfv->pfv_flags & DT_PRINTF_AGGREGATION) {
+ assert(aggsdata != NULL);
+ assert(naggvars > 0);
+
+ if (nrecs == 0)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ curagg = naggvars > 1 ? 1 : 0;
+ aggdata = aggsdata[0];
+ aggrec = aggdata->dtada_desc->dtagd_nrecs - 1;
+ nrecs--;
+ }
+
+ for (i = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) {
+ const dt_pfconv_t *pfc = pfd->pfd_conv;
+ int width = pfd->pfd_width;
+ int prec = pfd->pfd_prec;
+ int rval;
+
+ char *f = format + 1; /* skip initial '%' */
+ const dtrace_recdesc_t *rec;
+ dt_pfprint_f *func;
+ caddr_t addr;
+ size_t size;
+ uint32_t flags;
+
+ if (pfd->pfd_preflen != 0) {
+ char *tmp = alloca(pfd->pfd_preflen + 1);
+
+ bcopy(pfd->pfd_prefix, tmp, pfd->pfd_preflen);
+ tmp[pfd->pfd_preflen] = '\0';
+
+ if ((rval = dt_printf(dtp, fp, tmp)) < 0)
+ return (rval);
+
+ if (pfv->pfv_flags & DT_PRINTF_AGGREGATION) {
+ /*
+ * For printa(), we flush the buffer after each
+ * prefix, setting the flags to indicate that
+ * this is part of the printa() format string.
+ */
+ flags = DTRACE_BUFDATA_AGGFORMAT;
+
+ if (pfc == NULL && i == pfv->pfv_argc - 1)
+ flags |= DTRACE_BUFDATA_AGGLAST;
+
+ if (dt_buffered_flush(dtp, NULL, NULL,
+ aggdata, flags) < 0)
+ return (-1);
+ }
+ }
+
+ if (pfc == NULL) {
+ if (pfv->pfv_argc == 1)
+ return (nrecs != 0);
+ continue;
+ }
+
+ /*
+ * If the conversion is %%, just invoke the print callback
+ * with no data record and continue; it consumes no record.
+ */
+ if (pfc->pfc_print == &pfprint_pct) {
+ if (pfc->pfc_print(dtp, fp, NULL, pfd, NULL, 0, 1) >= 0)
+ continue;
+ return (-1); /* errno is set for us */
+ }
+
+ if (pfd->pfd_flags & DT_PFCONV_DYNWIDTH) {
+ if (dt_printf_getint(dtp, recp++, nrecs--, buf,
+ len, &width) == -1)
+ return (-1); /* errno is set for us */
+ pfd->pfd_dynwidth = width;
+ } else {
+ pfd->pfd_dynwidth = 0;
+ }
+
+ if ((pfd->pfd_flags & DT_PFCONV_DYNPREC) && dt_printf_getint(
+ dtp, recp++, nrecs--, buf, len, &prec) == -1)
+ return (-1); /* errno is set for us */
+
+ if (pfd->pfd_flags & DT_PFCONV_AGG) {
+ /*
+ * This should be impossible -- the compiler shouldn't
+ * create a DT_PFCONV_AGG conversion without an
+ * aggregation present. Still, we'd rather fail
+ * gracefully than blow up...
+ */
+ if (aggsdata == NULL)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ aggdata = aggsdata[curagg];
+ agg = aggdata->dtada_desc;
+
+ /*
+ * We increment the current aggregation variable, but
+ * not beyond the number of aggregation variables that
+ * we're printing. This has the (desired) effect that
+ * DT_PFCONV_AGG conversions beyond the number of
+ * aggregation variables (re-)convert the aggregation
+ * value of the last aggregation variable.
+ */
+ if (curagg < naggvars - 1)
+ curagg++;
+
+ rec = &agg->dtagd_rec[aggrec];
+ addr = aggdata->dtada_data + rec->dtrd_offset;
+ limit = addr + aggdata->dtada_size;
+ normal = aggdata->dtada_normal;
+ flags = DTRACE_BUFDATA_AGGVAL;
+ } else {
+ if (nrecs == 0)
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ if (pfv->pfv_flags & DT_PRINTF_AGGREGATION) {
+ /*
+ * When printing aggregation keys, we always
+ * set the aggdata to be the representative
+ * (zeroth) aggregation. The aggdata isn't
+ * actually used here in this case, but it is
+ * passed to the buffer handler and must
+ * therefore still be correct.
+ */
+ aggdata = aggsdata[0];
+ flags = DTRACE_BUFDATA_AGGKEY;
+ }
+
+ rec = recp++;
+ nrecs--;
+ addr = (caddr_t)buf + rec->dtrd_offset;
+ limit = lim;
+ normal = 1;
+ }
+
+ size = rec->dtrd_size;
+
+ if (addr + size > limit) {
+ dt_dprintf("bad size: addr=%p size=0x%x lim=%p\n",
+ (void *)addr, rec->dtrd_size, (void *)lim);
+ return (dt_set_errno(dtp, EDT_DOFFSET));
+ }
+
+ if (rec->dtrd_alignment != 0 &&
+ ((uintptr_t)addr & (rec->dtrd_alignment - 1)) != 0) {
+ dt_dprintf("bad align: addr=%p size=0x%x align=0x%x\n",
+ (void *)addr, rec->dtrd_size, rec->dtrd_alignment);
+ return (dt_set_errno(dtp, EDT_DALIGN));
+ }
+
+ switch (rec->dtrd_action) {
+ case DTRACEAGG_AVG:
+ func = pfprint_average;
+ break;
+ case DTRACEAGG_STDDEV:
+ func = pfprint_stddev;
+ break;
+ case DTRACEAGG_QUANTIZE:
+ func = pfprint_quantize;
+ break;
+ case DTRACEAGG_LQUANTIZE:
+ func = pfprint_lquantize;
+ break;
+ case DTRACEAGG_LLQUANTIZE:
+ func = pfprint_llquantize;
+ break;
+ case DTRACEACT_MOD:
+ func = pfprint_mod;
+ break;
+ case DTRACEACT_UMOD:
+ func = pfprint_umod;
+ break;
+ default:
+ func = pfc->pfc_print;
+ break;
+ }
+
+ if (pfd->pfd_flags & DT_PFCONV_ALT)
+ *f++ = '#';
+ if (pfd->pfd_flags & DT_PFCONV_ZPAD)
+ *f++ = '0';
+ if (width < 0 || (pfd->pfd_flags & DT_PFCONV_LEFT))
+ *f++ = '-';
+ if (pfd->pfd_flags & DT_PFCONV_SPOS)
+ *f++ = '+';
+ if (pfd->pfd_flags & DT_PFCONV_GROUP)
+ *f++ = '\'';
+ if (pfd->pfd_flags & DT_PFCONV_SPACE)
+ *f++ = ' ';
+
+ /*
+ * If we're printing a stack and DT_PFCONV_LEFT is set, we
+ * don't add the width to the format string. See the block
+ * comment in pfprint_stack() for a description of the
+ * behavior in this case.
+ */
+ if (func == pfprint_stack && (pfd->pfd_flags & DT_PFCONV_LEFT))
+ width = 0;
+
+ if (width != 0)
+ f += snprintf(f, sizeof (format), "%d", ABS(width));
+
+ if (prec > 0)
+ f += snprintf(f, sizeof (format), ".%d", prec);
+
+ (void) strcpy(f, pfd->pfd_fmt);
+ pfd->pfd_rec = rec;
+
+ if (func(dtp, fp, format, pfd, addr, size, normal) < 0)
+ return (-1); /* errno is set for us */
+
+ if (pfv->pfv_flags & DT_PRINTF_AGGREGATION) {
+ /*
+ * For printa(), we flush the buffer after each tuple
+ * element, inidicating that this is the last record
+ * as appropriate.
+ */
+ if (i == pfv->pfv_argc - 1)
+ flags |= DTRACE_BUFDATA_AGGLAST;
+
+ if (dt_buffered_flush(dtp, NULL,
+ rec, aggdata, flags) < 0)
+ return (-1);
+ }
+ }
+
+ return ((int)(recp - recs));
+}
+
+int
+dtrace_sprintf(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
+ const dtrace_recdesc_t *recp, uint_t nrecs, const void *buf, size_t len)
+{
+ dtrace_optval_t size;
+ int rval;
+
+ rval = dtrace_getopt(dtp, "strsize", &size);
+ assert(rval == 0);
+ assert(dtp->dt_sprintf_buflen == 0);
+
+ if (dtp->dt_sprintf_buf != NULL)
+ free(dtp->dt_sprintf_buf);
+
+ if ((dtp->dt_sprintf_buf = malloc(size)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ bzero(dtp->dt_sprintf_buf, size);
+ dtp->dt_sprintf_buflen = size;
+ rval = dt_printf_format(dtp, fp, fmtdata, recp, nrecs, buf, len,
+ NULL, 0);
+ dtp->dt_sprintf_buflen = 0;
+
+ if (rval == -1)
+ free(dtp->dt_sprintf_buf);
+
+ return (rval);
+}
+
+/*ARGSUSED*/
+int
+dtrace_system(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
+ const dtrace_probedata_t *data, const dtrace_recdesc_t *recp,
+ uint_t nrecs, const void *buf, size_t len)
+{
+ int rval = dtrace_sprintf(dtp, fp, fmtdata, recp, nrecs, buf, len);
+
+ if (rval == -1)
+ return (rval);
+
+ /*
+ * Before we execute the specified command, flush fp to assure that
+ * any prior dt_printf()'s appear before the output of the command
+ * not after it.
+ */
+ (void) fflush(fp);
+
+ if (system(dtp->dt_sprintf_buf) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ return (rval);
+}
+
+int
+dtrace_freopen(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
+ const dtrace_probedata_t *data, const dtrace_recdesc_t *recp,
+ uint_t nrecs, const void *buf, size_t len)
+{
+ char selfbuf[40], restorebuf[40], *filename;
+ FILE *nfp;
+ int rval, errval;
+ dt_pfargv_t *pfv = fmtdata;
+ dt_pfargd_t *pfd = pfv->pfv_argv;
+
+ rval = dtrace_sprintf(dtp, fp, fmtdata, recp, nrecs, buf, len);
+
+ if (rval == -1 || fp == NULL)
+ return (rval);
+
+#if defined(sun)
+ if (pfd->pfd_preflen != 0 &&
+ strcmp(pfd->pfd_prefix, DT_FREOPEN_RESTORE) == 0) {
+ /*
+ * The only way to have the format string set to the value
+ * DT_FREOPEN_RESTORE is via the empty freopen() string --
+ * denoting that we should restore the old stdout.
+ */
+ assert(strcmp(dtp->dt_sprintf_buf, DT_FREOPEN_RESTORE) == 0);
+
+ if (dtp->dt_stdout_fd == -1) {
+ /*
+ * We could complain here by generating an error,
+ * but it seems like overkill: it seems that calling
+ * freopen() to restore stdout when freopen() has
+ * never before been called should just be a no-op,
+ * so we just return in this case.
+ */
+ return (rval);
+ }
+
+ (void) snprintf(restorebuf, sizeof (restorebuf),
+ "/dev/fd/%d", dtp->dt_stdout_fd);
+ filename = restorebuf;
+ } else {
+ filename = dtp->dt_sprintf_buf;
+ }
+
+ /*
+ * freopen(3C) will always close the specified stream and underlying
+ * file descriptor -- even if the specified file can't be opened.
+ * Even for the semantic cesspool that is standard I/O, this is
+ * surprisingly brain-dead behavior: it means that any failure to
+ * open the specified file destroys the specified stream in the
+ * process -- which is particularly relevant when the specified stream
+ * happens (or rather, happened) to be stdout. This could be resolved
+ * were there an "fdreopen()" equivalent of freopen() that allowed one
+ * to pass a file descriptor instead of the name of a file, but there
+ * is no such thing. However, we can effect this ourselves by first
+ * fopen()'ing the desired file, and then (assuming that that works),
+ * freopen()'ing "/dev/fd/[fileno]", where [fileno] is the underlying
+ * file descriptor for the fopen()'d file. This way, if the fopen()
+ * fails, we can fail the operation without destroying stdout.
+ */
+ if ((nfp = fopen(filename, "aF")) == NULL) {
+ char *msg = strerror(errno);
+ char *faultstr;
+ int len = 80;
+
+ len += strlen(msg) + strlen(filename);
+ faultstr = alloca(len);
+
+ (void) snprintf(faultstr, len, "couldn't freopen() \"%s\": %s",
+ filename, strerror(errno));
+
+ if ((errval = dt_handle_liberr(dtp, data, faultstr)) == 0)
+ return (rval);
+
+ return (errval);
+ }
+
+ (void) snprintf(selfbuf, sizeof (selfbuf), "/dev/fd/%d", fileno(nfp));
+
+ if (dtp->dt_stdout_fd == -1) {
+ /*
+ * If this is the first time that we're calling freopen(),
+ * we're going to stash away the file descriptor for stdout.
+ * We don't expect the dup(2) to fail, so if it does we must
+ * return failure.
+ */
+ if ((dtp->dt_stdout_fd = dup(fileno(fp))) == -1) {
+ (void) fclose(nfp);
+ return (dt_set_errno(dtp, errno));
+ }
+ }
+
+ if (freopen(selfbuf, "aF", fp) == NULL) {
+ (void) fclose(nfp);
+ return (dt_set_errno(dtp, errno));
+ }
+
+ (void) fclose(nfp);
+#else
+ /*
+ * The 'standard output' (which is not necessarily stdout)
+ * treatment on FreeBSD is implemented differently than on
+ * Solaris because FreeBSD's freopen() will attempt to re-use
+ * the current file descriptor, causing the previous file to
+ * be closed and thereby preventing it from be re-activated
+ * later.
+ *
+ * For FreeBSD we use the concept of setting an output file
+ * pointer in the DTrace handle if a dtrace_freopen() has
+ * enabled another output file and we leave the caller's
+ * file pointer untouched. If it was actually stdout, then
+ * stdout remains open. If it was another file, then that
+ * file remains open. While a dtrace_freopen() has activated
+ * another file, we keep a pointer to that which we use in
+ * the output functions by preference and only use the caller's
+ * file pointer if no dtrace_freopen() call has been made.
+ *
+ * The check to see if we're re-activating the caller's
+ * output file is much the same as on Solaris.
+ */
+ if (pfd->pfd_preflen != 0 &&
+ strcmp(pfd->pfd_prefix, DT_FREOPEN_RESTORE) == 0) {
+ /*
+ * The only way to have the format string set to the value
+ * DT_FREOPEN_RESTORE is via the empty freopen() string --
+ * denoting that we should restore the old stdout.
+ */
+ assert(strcmp(dtp->dt_sprintf_buf, DT_FREOPEN_RESTORE) == 0);
+
+ if (dtp->dt_freopen_fp == NULL) {
+ /*
+ * We could complain here by generating an error,
+ * but it seems like overkill: it seems that calling
+ * freopen() to restore stdout when freopen() has
+ * never before been called should just be a no-op,
+ * so we just return in this case.
+ */
+ return (rval);
+ }
+
+ /*
+ * At this point, to re-active the original output file,
+ * on FreeBSD we only code the current file that this
+ * function opened previously.
+ */
+ (void) fclose(dtp->dt_freopen_fp);
+ dtp->dt_freopen_fp = NULL;
+
+ return (rval);
+ }
+
+ if ((nfp = fopen(dtp->dt_sprintf_buf, "a")) == NULL) {
+ char *msg = strerror(errno);
+ char *faultstr;
+ int len = 80;
+
+ len += strlen(msg) + strlen(dtp->dt_sprintf_buf);
+ faultstr = alloca(len);
+
+ (void) snprintf(faultstr, len, "couldn't freopen() \"%s\": %s",
+ dtp->dt_sprintf_buf, strerror(errno));
+
+ if ((errval = dt_handle_liberr(dtp, data, faultstr)) == 0)
+ return (rval);
+
+ return (errval);
+ }
+
+ if (dtp->dt_freopen_fp != NULL)
+ (void) fclose(dtp->dt_freopen_fp);
+
+ /* Remember that the output has been redirected to the new file. */
+ dtp->dt_freopen_fp = nfp;
+#endif
+
+ return (rval);
+}
+
+/*ARGSUSED*/
+int
+dtrace_fprintf(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
+ const dtrace_probedata_t *data, const dtrace_recdesc_t *recp,
+ uint_t nrecs, const void *buf, size_t len)
+{
+ return (dt_printf_format(dtp, fp, fmtdata,
+ recp, nrecs, buf, len, NULL, 0));
+}
+
+void *
+dtrace_printf_create(dtrace_hdl_t *dtp, const char *s)
+{
+ dt_pfargv_t *pfv = dt_printf_create(dtp, s);
+ dt_pfargd_t *pfd;
+ int i;
+
+ if (pfv == NULL)
+ return (NULL); /* errno has been set for us */
+
+ pfd = pfv->pfv_argv;
+
+ for (i = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) {
+ const dt_pfconv_t *pfc = pfd->pfd_conv;
+
+ if (pfc == NULL)
+ continue;
+
+ /*
+ * If the output format is not %s then we assume that we have
+ * been given a correctly-sized format string, so we copy the
+ * true format name including the size modifier. If the output
+ * format is %s, then either the input format is %s as well or
+ * it is one of our custom formats (e.g. pfprint_addr), so we
+ * must set pfd_fmt to be the output format conversion "s".
+ */
+ if (strcmp(pfc->pfc_ofmt, "s") != 0)
+ (void) strcat(pfd->pfd_fmt, pfc->pfc_name);
+ else
+ (void) strcat(pfd->pfd_fmt, pfc->pfc_ofmt);
+ }
+
+ return (pfv);
+}
+
+void *
+dtrace_printa_create(dtrace_hdl_t *dtp, const char *s)
+{
+ dt_pfargv_t *pfv = dtrace_printf_create(dtp, s);
+
+ if (pfv == NULL)
+ return (NULL); /* errno has been set for us */
+
+ pfv->pfv_flags |= DT_PRINTF_AGGREGATION;
+
+ return (pfv);
+}
+
+/*ARGSUSED*/
+size_t
+dtrace_printf_format(dtrace_hdl_t *dtp, void *fmtdata, char *s, size_t len)
+{
+ dt_pfargv_t *pfv = fmtdata;
+ dt_pfargd_t *pfd = pfv->pfv_argv;
+
+ /*
+ * An upper bound on the string length is the length of the original
+ * format string, plus three times the number of conversions (each
+ * conversion could add up an additional "ll" and/or pfd_width digit
+ * in the case of converting %? to %16) plus one for a terminating \0.
+ */
+ size_t formatlen = strlen(pfv->pfv_format) + 3 * pfv->pfv_argc + 1;
+ char *format = alloca(formatlen);
+ char *f = format;
+ int i, j;
+
+ for (i = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) {
+ const dt_pfconv_t *pfc = pfd->pfd_conv;
+ const char *str;
+ int width = pfd->pfd_width;
+ int prec = pfd->pfd_prec;
+
+ if (pfd->pfd_preflen != 0) {
+ for (j = 0; j < pfd->pfd_preflen; j++)
+ *f++ = pfd->pfd_prefix[j];
+ }
+
+ if (pfc == NULL)
+ continue;
+
+ *f++ = '%';
+
+ if (pfd->pfd_flags & DT_PFCONV_ALT)
+ *f++ = '#';
+ if (pfd->pfd_flags & DT_PFCONV_ZPAD)
+ *f++ = '0';
+ if (pfd->pfd_flags & DT_PFCONV_LEFT)
+ *f++ = '-';
+ if (pfd->pfd_flags & DT_PFCONV_SPOS)
+ *f++ = '+';
+ if (pfd->pfd_flags & DT_PFCONV_DYNWIDTH)
+ *f++ = '*';
+ if (pfd->pfd_flags & DT_PFCONV_DYNPREC) {
+ *f++ = '.';
+ *f++ = '*';
+ }
+ if (pfd->pfd_flags & DT_PFCONV_GROUP)
+ *f++ = '\'';
+ if (pfd->pfd_flags & DT_PFCONV_SPACE)
+ *f++ = ' ';
+ if (pfd->pfd_flags & DT_PFCONV_AGG)
+ *f++ = '@';
+
+ if (width != 0)
+ f += snprintf(f, sizeof (format), "%d", width);
+
+ if (prec != 0)
+ f += snprintf(f, sizeof (format), ".%d", prec);
+
+ /*
+ * If the output format is %s, then either %s is the underlying
+ * conversion or the conversion is one of our customized ones,
+ * e.g. pfprint_addr. In these cases, put the original string
+ * name of the conversion (pfc_name) into the pickled format
+ * string rather than the derived conversion (pfd_fmt).
+ */
+ if (strcmp(pfc->pfc_ofmt, "s") == 0)
+ str = pfc->pfc_name;
+ else
+ str = pfd->pfd_fmt;
+
+ for (j = 0; str[j] != '\0'; j++)
+ *f++ = str[j];
+ }
+
+ *f = '\0'; /* insert nul byte; do not count in return value */
+
+ assert(f < format + formatlen);
+ (void) strncpy(s, format, len);
+
+ return ((size_t)(f - format));
+}
+
+static int
+dt_fprinta(const dtrace_aggdata_t *adp, void *arg)
+{
+ const dtrace_aggdesc_t *agg = adp->dtada_desc;
+ const dtrace_recdesc_t *recp = &agg->dtagd_rec[0];
+ uint_t nrecs = agg->dtagd_nrecs;
+ dt_pfwalk_t *pfw = arg;
+ dtrace_hdl_t *dtp = pfw->pfw_argv->pfv_dtp;
+ int id;
+
+ if (dt_printf_getint(dtp, recp++, nrecs--,
+ adp->dtada_data, adp->dtada_size, &id) != 0 || pfw->pfw_aid != id)
+ return (0); /* no aggregation id or id does not match */
+
+ if (dt_printf_format(dtp, pfw->pfw_fp, pfw->pfw_argv,
+ recp, nrecs, adp->dtada_data, adp->dtada_size, &adp, 1) == -1)
+ return (pfw->pfw_err = dtp->dt_errno);
+
+ /*
+ * Cast away the const to set the bit indicating that this aggregation
+ * has been printed.
+ */
+ ((dtrace_aggdesc_t *)agg)->dtagd_flags |= DTRACE_AGD_PRINTED;
+
+ return (0);
+}
+
+static int
+dt_fprintas(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
+{
+ const dtrace_aggdata_t *aggdata = aggsdata[0];
+ const dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ const dtrace_recdesc_t *rec = &agg->dtagd_rec[1];
+ uint_t nrecs = agg->dtagd_nrecs - 1;
+ dt_pfwalk_t *pfw = arg;
+ dtrace_hdl_t *dtp = pfw->pfw_argv->pfv_dtp;
+ int i;
+
+ if (dt_printf_format(dtp, pfw->pfw_fp, pfw->pfw_argv,
+ rec, nrecs, aggdata->dtada_data, aggdata->dtada_size,
+ aggsdata, naggvars) == -1)
+ return (pfw->pfw_err = dtp->dt_errno);
+
+ /*
+ * For each aggregation, indicate that it has been printed, casting
+ * away the const as necessary.
+ */
+ for (i = 1; i < naggvars; i++) {
+ agg = aggsdata[i]->dtada_desc;
+ ((dtrace_aggdesc_t *)agg)->dtagd_flags |= DTRACE_AGD_PRINTED;
+ }
+
+ return (0);
+}
+/*ARGSUSED*/
+int
+dtrace_fprinta(dtrace_hdl_t *dtp, FILE *fp, void *fmtdata,
+ const dtrace_probedata_t *data, const dtrace_recdesc_t *recs,
+ uint_t nrecs, const void *buf, size_t len)
+{
+ dt_pfwalk_t pfw;
+ int i, naggvars = 0;
+ dtrace_aggvarid_t *aggvars;
+
+ aggvars = alloca(nrecs * sizeof (dtrace_aggvarid_t));
+
+ /*
+ * This might be a printa() with multiple aggregation variables. We
+ * need to scan forward through the records until we find a record from
+ * a different statement.
+ */
+ for (i = 0; i < nrecs; i++) {
+ const dtrace_recdesc_t *nrec = &recs[i];
+
+ if (nrec->dtrd_uarg != recs->dtrd_uarg)
+ break;
+
+ if (nrec->dtrd_action != recs->dtrd_action)
+ return (dt_set_errno(dtp, EDT_BADAGG));
+
+ aggvars[naggvars++] =
+ /* LINTED - alignment */
+ *((dtrace_aggvarid_t *)((caddr_t)buf + nrec->dtrd_offset));
+ }
+
+ if (naggvars == 0)
+ return (dt_set_errno(dtp, EDT_BADAGG));
+
+ pfw.pfw_argv = fmtdata;
+ pfw.pfw_fp = fp;
+ pfw.pfw_err = 0;
+
+ if (naggvars == 1) {
+ pfw.pfw_aid = aggvars[0];
+
+ if (dtrace_aggregate_walk_sorted(dtp,
+ dt_fprinta, &pfw) == -1 || pfw.pfw_err != 0)
+ return (-1); /* errno is set for us */
+ } else {
+ if (dtrace_aggregate_walk_joined(dtp, aggvars, naggvars,
+ dt_fprintas, &pfw) == -1 || pfw.pfw_err != 0)
+ return (-1); /* errno is set for us */
+ }
+
+ return (i);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.h
new file mode 100644
index 0000000..b3b5b8b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.h
@@ -0,0 +1,135 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PRINTF_H
+#define _DT_PRINTF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <libctf.h>
+#include <dtrace.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dt_node;
+struct dt_ident;
+
+struct dt_pfconv;
+struct dt_pfargv;
+struct dt_pfargd;
+
+typedef int dt_pfcheck_f(struct dt_pfargv *,
+ struct dt_pfargd *, struct dt_node *);
+typedef int dt_pfprint_f(dtrace_hdl_t *, FILE *, const char *,
+ const struct dt_pfargd *, const void *, size_t, uint64_t);
+
+typedef struct dt_pfconv {
+ const char *pfc_name; /* string name of input conversion */
+ const char *pfc_ofmt; /* string name of output conversion */
+ const char *pfc_tstr; /* string name for conversion type */
+ dt_pfcheck_f *pfc_check; /* function to use for type checking */
+ dt_pfprint_f *pfc_print; /* function to use for formatting */
+ ctf_file_t *pfc_cctfp; /* CTF container for "C" defn of type */
+ ctf_id_t pfc_ctype; /* CTF type ID for "C" defn of type */
+ ctf_file_t *pfc_dctfp; /* CTF container for "D" defn of type */
+ ctf_id_t pfc_dtype; /* CTF type ID for "D" defn of type */
+ struct dt_pfconv *pfc_next; /* next conversion in hash chain */
+} dt_pfconv_t;
+
+typedef struct dt_pfdict {
+ dt_pfconv_t **pdi_buckets; /* hash bucket array */
+ uint_t pdi_nbuckets; /* size of hash bucket array */
+} dt_pfdict_t;
+
+typedef struct dt_pfargd {
+ const char *pfd_prefix; /* prefix string pointer (or NULL) */
+ size_t pfd_preflen; /* length of prefix in bytes */
+ char pfd_fmt[8]; /* output format name to use */
+ uint_t pfd_flags; /* format flags (see below) */
+ int pfd_width; /* field width (or 0) */
+ int pfd_dynwidth; /* dynamic field width (or 0) */
+ int pfd_prec; /* field precision (or 0) */
+ const dt_pfconv_t *pfd_conv; /* conversion specification */
+ const dtrace_recdesc_t *pfd_rec; /* pointer to current record */
+ struct dt_pfargd *pfd_next; /* pointer to next arg descriptor */
+} dt_pfargd_t;
+
+#define DT_PFCONV_ALT 0x0001 /* alternate print format (%#) */
+#define DT_PFCONV_ZPAD 0x0002 /* zero-pad integer field (%0) */
+#define DT_PFCONV_LEFT 0x0004 /* left-align field (%-) */
+#define DT_PFCONV_SPOS 0x0008 /* sign positive values (%+) */
+#define DT_PFCONV_DYNWIDTH 0x0010 /* dynamic width (%*.) */
+#define DT_PFCONV_DYNPREC 0x0020 /* dynamic precision (%.*) */
+#define DT_PFCONV_GROUP 0x0040 /* group thousands (%') */
+#define DT_PFCONV_SPACE 0x0080 /* insert leading space (% ) */
+#define DT_PFCONV_AGG 0x0100 /* use aggregation result (%@) */
+#define DT_PFCONV_SIGNED 0x0200 /* arg is a signed integer */
+
+typedef struct dt_pfargv {
+ dtrace_hdl_t *pfv_dtp; /* libdtrace client handle */
+ char *pfv_format; /* format string pointer */
+ dt_pfargd_t *pfv_argv; /* list of argument descriptors */
+ uint_t pfv_argc; /* number of argument descriptors */
+ uint_t pfv_flags; /* flags used for validation */
+} dt_pfargv_t;
+
+typedef struct dt_pfwalk {
+ const dt_pfargv_t *pfw_argv; /* argument description list */
+ uint_t pfw_aid; /* aggregation variable identifier */
+ FILE *pfw_fp; /* file pointer to use for output */
+ int pfw_err; /* error status code */
+} dt_pfwalk_t;
+
+extern int dt_pfdict_create(dtrace_hdl_t *);
+extern void dt_pfdict_destroy(dtrace_hdl_t *);
+
+extern dt_pfargv_t *dt_printf_create(dtrace_hdl_t *, const char *);
+extern void dt_printf_destroy(dt_pfargv_t *);
+
+#define DT_PRINTF_EXACTLEN 0x1 /* do not permit extra arguments */
+#define DT_PRINTF_AGGREGATION 0x2 /* enable aggregation conversion */
+
+extern void dt_printf_validate(dt_pfargv_t *, uint_t,
+ struct dt_ident *, int, dtrace_actkind_t, struct dt_node *);
+
+extern void dt_printa_validate(struct dt_node *, struct dt_node *);
+
+extern int dt_print_stack(dtrace_hdl_t *, FILE *,
+ const char *, caddr_t, int, int);
+extern int dt_print_ustack(dtrace_hdl_t *, FILE *,
+ const char *, caddr_t, uint64_t);
+extern int dt_print_mod(dtrace_hdl_t *, FILE *, const char *, caddr_t);
+extern int dt_print_umod(dtrace_hdl_t *, FILE *, const char *, caddr_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PRINTF_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
new file mode 100644
index 0000000..d40a0ae
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
@@ -0,0 +1,1209 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * DTrace Process Control
+ *
+ * This file provides a set of routines that permit libdtrace and its clients
+ * to create and grab process handles using libproc, and to share these handles
+ * between library mechanisms that need libproc access, such as ustack(), and
+ * client mechanisms that need libproc access, such as dtrace(1M) -c and -p.
+ * The library provides several mechanisms in the libproc control layer:
+ *
+ * Reference Counting: The library code and client code can independently grab
+ * the same process handles without interfering with one another. Only when
+ * the reference count drops to zero and the handle is not being cached (see
+ * below for more information on caching) will Prelease() be called on it.
+ *
+ * Handle Caching: If a handle is grabbed PGRAB_RDONLY (e.g. by ustack()) and
+ * the reference count drops to zero, the handle is not immediately released.
+ * Instead, libproc handles are maintained on dph_lrulist in order from most-
+ * recently accessed to least-recently accessed. Idle handles are maintained
+ * until a pre-defined LRU cache limit is exceeded, permitting repeated calls
+ * to ustack() to avoid the overhead of releasing and re-grabbing processes.
+ *
+ * Process Control: For processes that are grabbed for control (~PGRAB_RDONLY)
+ * or created by dt_proc_create(), a control thread is created to provide
+ * callbacks on process exit and symbol table caching on dlopen()s.
+ *
+ * MT-Safety: Libproc is not MT-Safe, so dt_proc_lock() and dt_proc_unlock()
+ * are provided to synchronize access to the libproc handle between libdtrace
+ * code and client code and the control thread's use of the ps_prochandle.
+ *
+ * NOTE: MT-Safety is NOT provided for libdtrace itself, or for use of the
+ * dtrace_proc_grab/dtrace_proc_create mechanisms. Like all exported libdtrace
+ * calls, these are assumed to be MT-Unsafe. MT-Safety is ONLY provided for
+ * synchronization between libdtrace control threads and the client thread.
+ *
+ * The ps_prochandles themselves are maintained along with a dt_proc_t struct
+ * in a hash table indexed by PID. This provides basic locking and reference
+ * counting. The dt_proc_t is also maintained in LRU order on dph_lrulist.
+ * The dph_lrucnt and dph_lrulim count the number of cacheable processes and
+ * the current limit on the number of actively cached entries.
+ *
+ * The control thread for a process establishes breakpoints at the rtld_db
+ * locations of interest, updates mappings and symbol tables at these points,
+ * and handles exec and fork (by always following the parent). The control
+ * thread automatically exits when the process dies or control is lost.
+ *
+ * A simple notification mechanism is provided for libdtrace clients using
+ * dtrace_handle_proc() for notification of PS_UNDEAD or PS_LOST events. If
+ * such an event occurs, the dt_proc_t itself is enqueued on a notification
+ * list and the control thread broadcasts to dph_cv. dtrace_sleep() will wake
+ * up using this condition and will then call the client handler as necessary.
+ */
+
+#include <sys/wait.h>
+#if defined(sun)
+#include <sys/lwp.h>
+#endif
+#include <strings.h>
+#include <signal.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <dt_proc.h>
+#include <dt_pid.h>
+#include <dt_impl.h>
+
+#if !defined(sun)
+#include <sys/syscall.h>
+#include <libproc_compat.h>
+#define SYS_forksys SYS_fork
+#endif
+
+#define IS_SYS_EXEC(w) (w == SYS_execve)
+#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
+
+static dt_bkpt_t *
+dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data)
+{
+ struct ps_prochandle *P = dpr->dpr_proc;
+ dt_bkpt_t *dbp;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+ if ((dbp = dt_zalloc(dpr->dpr_hdl, sizeof (dt_bkpt_t))) != NULL) {
+ dbp->dbp_func = func;
+ dbp->dbp_data = data;
+ dbp->dbp_addr = addr;
+
+ if (Psetbkpt(P, dbp->dbp_addr, &dbp->dbp_instr) == 0)
+ dbp->dbp_active = B_TRUE;
+
+ dt_list_append(&dpr->dpr_bps, dbp);
+ }
+
+ return (dbp);
+}
+
+static void
+dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
+{
+ int state = Pstate(dpr->dpr_proc);
+ dt_bkpt_t *dbp, *nbp;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+ for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) {
+ if (delbkpts && dbp->dbp_active &&
+ state != PS_LOST && state != PS_UNDEAD) {
+ (void) Pdelbkpt(dpr->dpr_proc,
+ dbp->dbp_addr, dbp->dbp_instr);
+ }
+ nbp = dt_list_next(dbp);
+ dt_list_delete(&dpr->dpr_bps, dbp);
+ dt_free(dpr->dpr_hdl, dbp);
+ }
+}
+
+static void
+dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
+{
+#if defined(sun)
+ const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
+#else
+ unsigned long pc;
+#endif
+ dt_bkpt_t *dbp;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+#if !defined(sun)
+ proc_regget(dpr->dpr_proc, REG_PC, &pc);
+ proc_bkptregadj(&pc);
+#endif
+
+ for (dbp = dt_list_next(&dpr->dpr_bps);
+ dbp != NULL; dbp = dt_list_next(dbp)) {
+#if defined(sun)
+ if (psp->pr_reg[R_PC] == dbp->dbp_addr)
+ break;
+#else
+ if (pc == dbp->dbp_addr)
+ break;
+#endif
+ }
+
+ if (dbp == NULL) {
+ dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
+#if defined(sun)
+ (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
+#else
+ (int)dpr->dpr_pid, pc);
+#endif
+ return;
+ }
+
+ dt_dprintf("pid %d: hit breakpoint at %lx (%lu)\n",
+ (int)dpr->dpr_pid, (ulong_t)dbp->dbp_addr, ++dbp->dbp_hits);
+
+ dbp->dbp_func(dtp, dpr, dbp->dbp_data);
+ (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr);
+}
+
+static void
+dt_proc_bpenable(dt_proc_t *dpr)
+{
+ dt_bkpt_t *dbp;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+ for (dbp = dt_list_next(&dpr->dpr_bps);
+ dbp != NULL; dbp = dt_list_next(dbp)) {
+ if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc,
+ dbp->dbp_addr, &dbp->dbp_instr) == 0)
+ dbp->dbp_active = B_TRUE;
+ }
+
+ dt_dprintf("breakpoints enabled\n");
+}
+
+static void
+dt_proc_bpdisable(dt_proc_t *dpr)
+{
+ dt_bkpt_t *dbp;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+ for (dbp = dt_list_next(&dpr->dpr_bps);
+ dbp != NULL; dbp = dt_list_next(dbp)) {
+ if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc,
+ dbp->dbp_addr, dbp->dbp_instr) == 0)
+ dbp->dbp_active = B_FALSE;
+ }
+
+ dt_dprintf("breakpoints disabled\n");
+}
+
+static void
+dt_proc_notify(dtrace_hdl_t *dtp, dt_proc_hash_t *dph, dt_proc_t *dpr,
+ const char *msg)
+{
+ dt_proc_notify_t *dprn = dt_alloc(dtp, sizeof (dt_proc_notify_t));
+
+ if (dprn == NULL) {
+ dt_dprintf("failed to allocate notification for %d %s\n",
+ (int)dpr->dpr_pid, msg);
+ } else {
+ dprn->dprn_dpr = dpr;
+ if (msg == NULL)
+ dprn->dprn_errmsg[0] = '\0';
+ else
+ (void) strlcpy(dprn->dprn_errmsg, msg,
+ sizeof (dprn->dprn_errmsg));
+
+ (void) pthread_mutex_lock(&dph->dph_lock);
+
+ dprn->dprn_next = dph->dph_notify;
+ dph->dph_notify = dprn;
+
+ (void) pthread_cond_broadcast(&dph->dph_cv);
+ (void) pthread_mutex_unlock(&dph->dph_lock);
+ }
+}
+
+/*
+ * Check to see if the control thread was requested to stop when the victim
+ * process reached a particular event (why) rather than continuing the victim.
+ * If 'why' is set in the stop mask, we wait on dpr_cv for dt_proc_continue().
+ * If 'why' is not set, this function returns immediately and does nothing.
+ */
+static void
+dt_proc_stop(dt_proc_t *dpr, uint8_t why)
+{
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+ assert(why != DT_PROC_STOP_IDLE);
+
+ if (dpr->dpr_stop & why) {
+ dpr->dpr_stop |= DT_PROC_STOP_IDLE;
+ dpr->dpr_stop &= ~why;
+
+ (void) pthread_cond_broadcast(&dpr->dpr_cv);
+
+ /*
+ * We disable breakpoints while stopped to preserve the
+ * integrity of the program text for both our own disassembly
+ * and that of the kernel.
+ */
+ dt_proc_bpdisable(dpr);
+
+ while (dpr->dpr_stop & DT_PROC_STOP_IDLE)
+ (void) pthread_cond_wait(&dpr->dpr_cv, &dpr->dpr_lock);
+
+ dt_proc_bpenable(dpr);
+ }
+}
+
+/*ARGSUSED*/
+static void
+dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname)
+{
+ dt_dprintf("pid %d: breakpoint at %s()\n", (int)dpr->dpr_pid, fname);
+ dt_proc_stop(dpr, DT_PROC_STOP_MAIN);
+}
+
+static void
+dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname)
+{
+ rd_event_msg_t rdm;
+ rd_err_e err;
+
+ if ((err = rd_event_getmsg(dpr->dpr_rtld, &rdm)) != RD_OK) {
+ dt_dprintf("pid %d: failed to get %s event message: %s\n",
+ (int)dpr->dpr_pid, evname, rd_errstr(err));
+ return;
+ }
+
+ dt_dprintf("pid %d: rtld event %s type=%d state %d\n",
+ (int)dpr->dpr_pid, evname, rdm.type, rdm.u.state);
+
+ switch (rdm.type) {
+ case RD_DLACTIVITY:
+ if (rdm.u.state != RD_CONSISTENT)
+ break;
+
+ Pupdate_syms(dpr->dpr_proc);
+ if (dt_pid_create_probes_module(dtp, dpr) != 0)
+ dt_proc_notify(dtp, dtp->dt_procs, dpr,
+ dpr->dpr_errmsg);
+
+ break;
+ case RD_PREINIT:
+ Pupdate_syms(dpr->dpr_proc);
+ dt_proc_stop(dpr, DT_PROC_STOP_PREINIT);
+ break;
+ case RD_POSTINIT:
+ Pupdate_syms(dpr->dpr_proc);
+ dt_proc_stop(dpr, DT_PROC_STOP_POSTINIT);
+ break;
+ }
+}
+
+static void
+dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname)
+{
+ rd_notify_t rdn;
+ rd_err_e err;
+
+ if ((err = rd_event_addr(dpr->dpr_rtld, event, &rdn)) != RD_OK) {
+ dt_dprintf("pid %d: failed to get event address for %s: %s\n",
+ (int)dpr->dpr_pid, evname, rd_errstr(err));
+ return;
+ }
+
+ if (rdn.type != RD_NOTIFY_BPT) {
+ dt_dprintf("pid %d: event %s has unexpected type %d\n",
+ (int)dpr->dpr_pid, evname, rdn.type);
+ return;
+ }
+
+ (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr,
+#if defined(sun)
+ (dt_bkpt_f *)dt_proc_rdevent, (void *)evname);
+#else
+ /* XXX ugly */
+ (dt_bkpt_f *)dt_proc_rdevent, __DECONST(void *, evname));
+#endif
+}
+
+/*
+ * Common code for enabling events associated with the run-time linker after
+ * attaching to a process or after a victim process completes an exec(2).
+ */
+static void
+dt_proc_attach(dt_proc_t *dpr, int exec)
+{
+#if defined(sun)
+ const pstatus_t *psp = Pstatus(dpr->dpr_proc);
+#endif
+ rd_err_e err;
+ GElf_Sym sym;
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+
+ if (exec) {
+#if defined(sun)
+ if (psp->pr_lwp.pr_errno != 0)
+ return; /* exec failed: nothing needs to be done */
+#endif
+
+ dt_proc_bpdestroy(dpr, B_FALSE);
+#if defined(sun)
+ Preset_maps(dpr->dpr_proc);
+#endif
+ }
+ if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL &&
+ (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) {
+#if defined(sun)
+ dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT");
+#endif
+ dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT");
+#if defined(sun)
+ dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY");
+#endif
+ } else {
+ dt_dprintf("pid %d: failed to enable rtld events: %s\n",
+ (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) :
+ "rtld_db agent initialization failed");
+ }
+
+ Pupdate_maps(dpr->dpr_proc);
+
+ if (Pxlookup_by_name(dpr->dpr_proc, LM_ID_BASE,
+ "a.out", "main", &sym, NULL) == 0) {
+ (void) dt_proc_bpcreate(dpr, (uintptr_t)sym.st_value,
+ (dt_bkpt_f *)dt_proc_bpmain, "a.out`main");
+ } else {
+ dt_dprintf("pid %d: failed to find a.out`main: %s\n",
+ (int)dpr->dpr_pid, strerror(errno));
+ }
+}
+
+/*
+ * Wait for a stopped process to be set running again by some other debugger.
+ * This is typically not required by /proc-based debuggers, since the usual
+ * model is that one debugger controls one victim. But DTrace, as usual, has
+ * its own needs: the stop() action assumes that prun(1) or some other tool
+ * will be applied to resume the victim process. This could be solved by
+ * adding a PCWRUN directive to /proc, but that seems like overkill unless
+ * other debuggers end up needing this functionality, so we implement a cheap
+ * equivalent to PCWRUN using the set of existing kernel mechanisms.
+ *
+ * Our intent is really not just to wait for the victim to run, but rather to
+ * wait for it to run and then stop again for a reason other than the current
+ * PR_REQUESTED stop. Since PCWSTOP/Pstopstatus() can be applied repeatedly
+ * to a stopped process and will return the same result without affecting the
+ * victim, we can just perform these operations repeatedly until Pstate()
+ * changes, the representative LWP ID changes, or the stop timestamp advances.
+ * dt_proc_control() will then rediscover the new state and continue as usual.
+ * When the process is still stopped in the same exact state, we sleep for a
+ * brief interval before waiting again so as not to spin consuming CPU cycles.
+ */
+static void
+dt_proc_waitrun(dt_proc_t *dpr)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#ifdef DOODAD
+ struct ps_prochandle *P = dpr->dpr_proc;
+ const lwpstatus_t *psp = &Pstatus(P)->pr_lwp;
+
+ int krflag = psp->pr_flags & (PR_KLC | PR_RLC);
+ timestruc_t tstamp = psp->pr_tstamp;
+ lwpid_t lwpid = psp->pr_lwpid;
+
+ const long wstop = PCWSTOP;
+ int pfd = Pctlfd(P);
+
+ assert(DT_MUTEX_HELD(&dpr->dpr_lock));
+ assert(psp->pr_flags & PR_STOPPED);
+ assert(Pstate(P) == PS_STOP);
+
+ /*
+ * While we are waiting for the victim to run, clear PR_KLC and PR_RLC
+ * so that if the libdtrace client is killed, the victim stays stopped.
+ * dt_proc_destroy() will also observe this and perform PRELEASE_HANG.
+ */
+ (void) Punsetflags(P, krflag);
+ Psync(P);
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+
+ while (!dpr->dpr_quit) {
+ if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
+ continue; /* check dpr_quit and continue waiting */
+
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+ (void) Pstopstatus(P, PCNULL, 0);
+ psp = &Pstatus(P)->pr_lwp;
+
+ /*
+ * If we've reached a new state, found a new representative, or
+ * the stop timestamp has changed, restore PR_KLC/PR_RLC to its
+ * original setting and then return with dpr_lock held.
+ */
+ if (Pstate(P) != PS_STOP || psp->pr_lwpid != lwpid ||
+ bcmp(&psp->pr_tstamp, &tstamp, sizeof (tstamp)) != 0) {
+ (void) Psetflags(P, krflag);
+ Psync(P);
+ return;
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ (void) poll(NULL, 0, MILLISEC / 2);
+ }
+
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+#endif
+}
+
+typedef struct dt_proc_control_data {
+ dtrace_hdl_t *dpcd_hdl; /* DTrace handle */
+ dt_proc_t *dpcd_proc; /* proccess to control */
+} dt_proc_control_data_t;
+
+/*
+ * Main loop for all victim process control threads. We initialize all the
+ * appropriate /proc control mechanisms, and then enter a loop waiting for
+ * the process to stop on an event or die. We process any events by calling
+ * appropriate subroutines, and exit when the victim dies or we lose control.
+ *
+ * The control thread synchronizes the use of dpr_proc with other libdtrace
+ * threads using dpr_lock. We hold the lock for all of our operations except
+ * waiting while the process is running: this is accomplished by writing a
+ * PCWSTOP directive directly to the underlying /proc/<pid>/ctl file. If the
+ * libdtrace client wishes to exit or abort our wait, SIGCANCEL can be used.
+ */
+static void *
+dt_proc_control(void *arg)
+{
+ dt_proc_control_data_t *datap = arg;
+ dtrace_hdl_t *dtp = datap->dpcd_hdl;
+ dt_proc_t *dpr = datap->dpcd_proc;
+ dt_proc_hash_t *dph = dpr->dpr_hdl->dt_procs;
+ struct ps_prochandle *P = dpr->dpr_proc;
+ int pid = dpr->dpr_pid;
+
+#if defined(sun)
+ int pfd = Pctlfd(P);
+
+ const long wstop = PCWSTOP;
+#endif
+ int notify = B_FALSE;
+
+ /*
+ * We disable the POSIX thread cancellation mechanism so that the
+ * client program using libdtrace can't accidentally cancel our thread.
+ * dt_proc_destroy() uses SIGCANCEL explicitly to simply poke us out
+ * of PCWSTOP with EINTR, at which point we will see dpr_quit and exit.
+ */
+ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ /*
+ * Set up the corresponding process for tracing by libdtrace. We want
+ * to be able to catch breakpoints and efficiently single-step over
+ * them, and we need to enable librtld_db to watch libdl activity.
+ */
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+#if defined(sun)
+ (void) Punsetflags(P, PR_ASYNC); /* require synchronous mode */
+ (void) Psetflags(P, PR_BPTADJ); /* always adjust eip on x86 */
+ (void) Punsetflags(P, PR_FORK); /* do not inherit on fork */
+
+ (void) Pfault(P, FLTBPT, B_TRUE); /* always trace breakpoints */
+ (void) Pfault(P, FLTTRACE, B_TRUE); /* always trace single-step */
+
+ /*
+ * We must trace exit from exec() system calls so that if the exec is
+ * successful, we can reset our breakpoints and re-initialize libproc.
+ */
+ (void) Psysexit(P, SYS_execve, B_TRUE);
+
+ /*
+ * We must trace entry and exit for fork() system calls in order to
+ * disable our breakpoints temporarily during the fork. We do not set
+ * the PR_FORK flag, so if fork succeeds the child begins executing and
+ * does not inherit any other tracing behaviors or a control thread.
+ */
+ (void) Psysentry(P, SYS_vfork, B_TRUE);
+ (void) Psysexit(P, SYS_vfork, B_TRUE);
+ (void) Psysentry(P, SYS_forksys, B_TRUE);
+ (void) Psysexit(P, SYS_forksys, B_TRUE);
+
+ Psync(P); /* enable all /proc changes */
+#endif
+ dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */
+
+ /*
+ * If PR_KLC is set, we created the process; otherwise we grabbed it.
+ * Check for an appropriate stop request and wait for dt_proc_continue.
+ */
+#if defined(sun)
+ if (Pstatus(P)->pr_flags & PR_KLC)
+#else
+ if (proc_getflags(P) & PR_KLC)
+#endif
+ dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
+ else
+ dt_proc_stop(dpr, DT_PROC_STOP_GRAB);
+
+ if (Psetrun(P, 0, 0) == -1) {
+ dt_dprintf("pid %d: failed to set running: %s\n",
+ (int)dpr->dpr_pid, strerror(errno));
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+
+ /*
+ * Wait for the process corresponding to this control thread to stop,
+ * process the event, and then set it running again. We want to sleep
+ * with dpr_lock *unheld* so that other parts of libdtrace can use the
+ * ps_prochandle in the meantime (e.g. ustack()). To do this, we write
+ * a PCWSTOP directive directly to the underlying /proc/<pid>/ctl file.
+ * Once the process stops, we wake up, grab dpr_lock, and then call
+ * Pwait() (which will return immediately) and do our processing.
+ */
+ while (!dpr->dpr_quit) {
+ const lwpstatus_t *psp;
+
+#if defined(sun)
+ if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
+ continue; /* check dpr_quit and continue waiting */
+#else
+ /* Wait for the process to report status. */
+ proc_wstatus(P);
+ if (errno == EINTR)
+ continue; /* check dpr_quit and continue waiting */
+#endif
+
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+#if defined(sun)
+pwait_locked:
+ if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) {
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ continue; /* check dpr_quit and continue waiting */
+ }
+#endif
+
+ switch (Pstate(P)) {
+ case PS_STOP:
+#if defined(sun)
+ psp = &Pstatus(P)->pr_lwp;
+#else
+ psp = proc_getlwpstatus(P);
+#endif
+
+ dt_dprintf("pid %d: proc stopped showing %d/%d\n",
+ pid, psp->pr_why, psp->pr_what);
+
+ /*
+ * If the process stops showing PR_REQUESTED, then the
+ * DTrace stop() action was applied to it or another
+ * debugging utility (e.g. pstop(1)) asked it to stop.
+ * In either case, the user's intention is for the
+ * process to remain stopped until another external
+ * mechanism (e.g. prun(1)) is applied. So instead of
+ * setting the process running ourself, we wait for
+ * someone else to do so. Once that happens, we return
+ * to our normal loop waiting for an event of interest.
+ */
+ if (psp->pr_why == PR_REQUESTED) {
+ dt_proc_waitrun(dpr);
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ continue;
+ }
+
+ /*
+ * If the process stops showing one of the events that
+ * we are tracing, perform the appropriate response.
+ * Note that we ignore PR_SUSPENDED, PR_CHECKPOINT, and
+ * PR_JOBCONTROL by design: if one of these conditions
+ * occurs, we will fall through to Psetrun() but the
+ * process will remain stopped in the kernel by the
+ * corresponding mechanism (e.g. job control stop).
+ */
+ if (psp->pr_why == PR_FAULTED && psp->pr_what == FLTBPT)
+ dt_proc_bpmatch(dtp, dpr);
+ else if (psp->pr_why == PR_SYSENTRY &&
+ IS_SYS_FORK(psp->pr_what))
+ dt_proc_bpdisable(dpr);
+ else if (psp->pr_why == PR_SYSEXIT &&
+ IS_SYS_FORK(psp->pr_what))
+ dt_proc_bpenable(dpr);
+ else if (psp->pr_why == PR_SYSEXIT &&
+ IS_SYS_EXEC(psp->pr_what))
+ dt_proc_attach(dpr, B_TRUE);
+ break;
+
+ case PS_LOST:
+#if defined(sun)
+ if (Preopen(P) == 0)
+ goto pwait_locked;
+#endif
+
+ dt_dprintf("pid %d: proc lost: %s\n",
+ pid, strerror(errno));
+
+ dpr->dpr_quit = B_TRUE;
+ notify = B_TRUE;
+ break;
+
+ case PS_UNDEAD:
+ dt_dprintf("pid %d: proc died\n", pid);
+ dpr->dpr_quit = B_TRUE;
+ notify = B_TRUE;
+ break;
+ }
+
+ if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) {
+ dt_dprintf("pid %d: failed to set running: %s\n",
+ (int)dpr->dpr_pid, strerror(errno));
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ }
+
+ /*
+ * If the control thread detected PS_UNDEAD or PS_LOST, then enqueue
+ * the dt_proc_t structure on the dt_proc_hash_t notification list.
+ */
+ if (notify)
+ dt_proc_notify(dtp, dph, dpr, NULL);
+
+ /*
+ * Destroy and remove any remaining breakpoints, set dpr_done and clear
+ * dpr_tid to indicate the control thread has exited, and notify any
+ * waiting thread in dt_proc_destroy() that we have succesfully exited.
+ */
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+ dt_proc_bpdestroy(dpr, B_TRUE);
+ dpr->dpr_done = B_TRUE;
+ dpr->dpr_tid = 0;
+
+ (void) pthread_cond_broadcast(&dpr->dpr_cv);
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+
+ return (NULL);
+}
+
+/*PRINTFLIKE3*/
+static struct ps_prochandle *
+dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
+ va_end(ap);
+
+ if (dpr->dpr_proc != NULL)
+ Prelease(dpr->dpr_proc, 0);
+
+ dt_free(dtp, dpr);
+ (void) dt_set_errno(dtp, EDT_COMPILER);
+ return (NULL);
+}
+
+dt_proc_t *
+dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)
+{
+ dt_proc_hash_t *dph = dtp->dt_procs;
+#if defined(sun)
+ pid_t pid = Pstatus(P)->pr_pid;
+#else
+ pid_t pid = proc_getpid(P);
+#endif
+ dt_proc_t *dpr, **dpp = &dph->dph_hash[pid & (dph->dph_hashlen - 1)];
+
+ for (dpr = *dpp; dpr != NULL; dpr = dpr->dpr_hash) {
+ if (dpr->dpr_pid == pid)
+ break;
+ else
+ dpp = &dpr->dpr_hash;
+ }
+
+ assert(dpr != NULL);
+ assert(dpr->dpr_proc == P);
+
+ if (remove)
+ *dpp = dpr->dpr_hash; /* remove from pid hash chain */
+
+ return (dpr);
+}
+
+static void
+dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
+ dt_proc_hash_t *dph = dtp->dt_procs;
+ dt_proc_notify_t *npr, **npp;
+ int rflag;
+
+ assert(dpr != NULL);
+
+ /*
+ * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
+ * an external debugger and we were waiting in dt_proc_waitrun().
+ * Leave the process in this condition using PRELEASE_HANG.
+ */
+#if defined(sun)
+ if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) {
+#else
+ if (!(proc_getflags(dpr->dpr_proc) & (PR_KLC | PR_RLC))) {
+#endif
+ dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid);
+ rflag = PRELEASE_HANG;
+#if defined(sun)
+ } else if (Pstatus(dpr->dpr_proc)->pr_flags & PR_KLC) {
+#else
+ } else if (proc_getflags(dpr->dpr_proc) & PR_KLC) {
+#endif
+ dt_dprintf("killing pid %d\n", (int)dpr->dpr_pid);
+ rflag = PRELEASE_KILL; /* apply kill-on-last-close */
+ } else {
+ dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid);
+ rflag = 0; /* apply run-on-last-close */
+ }
+
+ if (dpr->dpr_tid) {
+ /*
+ * Set the dpr_quit flag to tell the daemon thread to exit. We
+ * send it a SIGCANCEL to poke it out of PCWSTOP or any other
+ * long-term /proc system call. Our daemon threads have POSIX
+ * cancellation disabled, so EINTR will be the only effect. We
+ * then wait for dpr_done to indicate the thread has exited.
+ *
+ * We can't use pthread_kill() to send SIGCANCEL because the
+ * interface forbids it and we can't use pthread_cancel()
+ * because with cancellation disabled it won't actually
+ * send SIGCANCEL to the target thread, so we use _lwp_kill()
+ * to do the job. This is all built on evil knowledge of
+ * the details of the cancellation mechanism in libc.
+ */
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+ dpr->dpr_quit = B_TRUE;
+#if defined(sun)
+ (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
+#else
+ pthread_kill(dpr->dpr_tid, SIGTHR);
+#endif
+
+ /*
+ * If the process is currently idling in dt_proc_stop(), re-
+ * enable breakpoints and poke it into running again.
+ */
+ if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
+ dt_proc_bpenable(dpr);
+ dpr->dpr_stop &= ~DT_PROC_STOP_IDLE;
+ (void) pthread_cond_broadcast(&dpr->dpr_cv);
+ }
+
+ while (!dpr->dpr_done)
+ (void) pthread_cond_wait(&dpr->dpr_cv, &dpr->dpr_lock);
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ }
+
+ /*
+ * Before we free the process structure, remove this dt_proc_t from the
+ * lookup hash, and then walk the dt_proc_hash_t's notification list
+ * and remove this dt_proc_t if it is enqueued.
+ */
+ (void) pthread_mutex_lock(&dph->dph_lock);
+ (void) dt_proc_lookup(dtp, P, B_TRUE);
+ npp = &dph->dph_notify;
+
+ while ((npr = *npp) != NULL) {
+ if (npr->dprn_dpr == dpr) {
+ *npp = npr->dprn_next;
+ dt_free(dtp, npr);
+ } else {
+ npp = &npr->dprn_next;
+ }
+ }
+
+ (void) pthread_mutex_unlock(&dph->dph_lock);
+
+ /*
+ * Remove the dt_proc_list from the LRU list, release the underlying
+ * libproc handle, and free our dt_proc_t data structure.
+ */
+ if (dpr->dpr_cacheable) {
+ assert(dph->dph_lrucnt != 0);
+ dph->dph_lrucnt--;
+ }
+
+ dt_list_delete(&dph->dph_lrulist, dpr);
+ Prelease(dpr->dpr_proc, rflag);
+ dt_free(dtp, dpr);
+}
+
+static int
+dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
+{
+ dt_proc_control_data_t data;
+ sigset_t nset, oset;
+ pthread_attr_t a;
+ int err;
+
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+ dpr->dpr_stop |= stop; /* set bit for initial rendezvous */
+
+ (void) pthread_attr_init(&a);
+ (void) pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+
+ (void) sigfillset(&nset);
+ (void) sigdelset(&nset, SIGABRT); /* unblocked for assert() */
+#if defined(sun)
+ (void) sigdelset(&nset, SIGCANCEL); /* see dt_proc_destroy() */
+#else
+ (void) sigdelset(&nset, SIGUSR1); /* see dt_proc_destroy() */
+#endif
+
+ data.dpcd_hdl = dtp;
+ data.dpcd_proc = dpr;
+
+ (void) pthread_sigmask(SIG_SETMASK, &nset, &oset);
+ err = pthread_create(&dpr->dpr_tid, &a, dt_proc_control, &data);
+ (void) pthread_sigmask(SIG_SETMASK, &oset, NULL);
+
+ /*
+ * If the control thread was created, then wait on dpr_cv for either
+ * dpr_done to be set (the victim died or the control thread failed)
+ * or DT_PROC_STOP_IDLE to be set, indicating that the victim is now
+ * stopped by /proc and the control thread is at the rendezvous event.
+ * On success, we return with the process and control thread stopped:
+ * the caller can then apply dt_proc_continue() to resume both.
+ */
+ if (err == 0) {
+ while (!dpr->dpr_done && !(dpr->dpr_stop & DT_PROC_STOP_IDLE))
+ (void) pthread_cond_wait(&dpr->dpr_cv, &dpr->dpr_lock);
+
+ /*
+ * If dpr_done is set, the control thread aborted before it
+ * reached the rendezvous event. This is either due to PS_LOST
+ * or PS_UNDEAD (i.e. the process died). We try to provide a
+ * small amount of useful information to help figure it out.
+ */
+ if (dpr->dpr_done) {
+#if defined(sun)
+ const psinfo_t *prp = Ppsinfo(dpr->dpr_proc);
+ int stat = prp ? prp->pr_wstat : 0;
+ int pid = dpr->dpr_pid;
+#else
+ int stat = proc_getwstat(dpr->dpr_proc);
+ int pid = proc_getpid(dpr->dpr_proc);
+#endif
+ if (proc_state(dpr->dpr_proc) == PS_LOST) {
+ (void) dt_proc_error(dpr->dpr_hdl, dpr,
+ "failed to control pid %d: process exec'd "
+ "set-id or unobservable program\n", pid);
+ } else if (WIFSIGNALED(stat)) {
+ (void) dt_proc_error(dpr->dpr_hdl, dpr,
+ "failed to control pid %d: process died "
+ "from signal %d\n", pid, WTERMSIG(stat));
+ } else {
+ (void) dt_proc_error(dpr->dpr_hdl, dpr,
+ "failed to control pid %d: process exited "
+ "with status %d\n", pid, WEXITSTATUS(stat));
+ }
+
+ err = ESRCH; /* cause grab() or create() to fail */
+ }
+ } else {
+ (void) dt_proc_error(dpr->dpr_hdl, dpr,
+ "failed to create control thread for process-id %d: %s\n",
+ (int)dpr->dpr_pid, strerror(err));
+ }
+
+ if (err == 0)
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+ (void) pthread_attr_destroy(&a);
+
+ return (err);
+}
+
+struct ps_prochandle *
+dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
+ proc_child_func *pcf, void *child_arg)
+{
+ dt_proc_hash_t *dph = dtp->dt_procs;
+ dt_proc_t *dpr;
+ int err;
+
+ if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
+ return (NULL); /* errno is set for us */
+
+ (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
+ (void) pthread_cond_init(&dpr->dpr_cv, NULL);
+
+#if defined(sun)
+ if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) {
+#else
+ if ((err = proc_create(file, argv, pcf, child_arg,
+ &dpr->dpr_proc)) != 0) {
+#endif
+ return (dt_proc_error(dtp, dpr,
+ "failed to execute %s: %s\n", file, Pcreate_error(err)));
+ }
+
+ dpr->dpr_hdl = dtp;
+#if defined(sun)
+ dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid;
+#else
+ dpr->dpr_pid = proc_getpid(dpr->dpr_proc);
+#endif
+
+ (void) Punsetflags(dpr->dpr_proc, PR_RLC);
+ (void) Psetflags(dpr->dpr_proc, PR_KLC);
+
+ if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0)
+ return (NULL); /* dt_proc_error() has been called for us */
+
+ dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)];
+ dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)] = dpr;
+ dt_list_prepend(&dph->dph_lrulist, dpr);
+
+ dt_dprintf("created pid %d\n", (int)dpr->dpr_pid);
+ dpr->dpr_refs++;
+
+ return (dpr->dpr_proc);
+}
+
+struct ps_prochandle *
+dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor)
+{
+ dt_proc_hash_t *dph = dtp->dt_procs;
+ uint_t h = pid & (dph->dph_hashlen - 1);
+ dt_proc_t *dpr, *opr;
+ int err;
+
+ /*
+ * Search the hash table for the pid. If it is already grabbed or
+ * created, move the handle to the front of the lrulist, increment
+ * the reference count, and return the existing ps_prochandle.
+ */
+ for (dpr = dph->dph_hash[h]; dpr != NULL; dpr = dpr->dpr_hash) {
+ if (dpr->dpr_pid == pid && !dpr->dpr_stale) {
+ /*
+ * If the cached handle was opened read-only and
+ * this request is for a writeable handle, mark
+ * the cached handle as stale and open a new handle.
+ * Since it's stale, unmark it as cacheable.
+ */
+ if (dpr->dpr_rdonly && !(flags & PGRAB_RDONLY)) {
+ dt_dprintf("upgrading pid %d\n", (int)pid);
+ dpr->dpr_stale = B_TRUE;
+ dpr->dpr_cacheable = B_FALSE;
+ dph->dph_lrucnt--;
+ break;
+ }
+
+ dt_dprintf("grabbed pid %d (cached)\n", (int)pid);
+ dt_list_delete(&dph->dph_lrulist, dpr);
+ dt_list_prepend(&dph->dph_lrulist, dpr);
+ dpr->dpr_refs++;
+ return (dpr->dpr_proc);
+ }
+ }
+
+ if ((dpr = dt_zalloc(dtp, sizeof (dt_proc_t))) == NULL)
+ return (NULL); /* errno is set for us */
+
+ (void) pthread_mutex_init(&dpr->dpr_lock, NULL);
+ (void) pthread_cond_init(&dpr->dpr_cv, NULL);
+
+#if defined(sun)
+ if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) {
+#else
+ if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) {
+#endif
+ return (dt_proc_error(dtp, dpr,
+ "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err)));
+ }
+
+ dpr->dpr_hdl = dtp;
+ dpr->dpr_pid = pid;
+
+ (void) Punsetflags(dpr->dpr_proc, PR_KLC);
+ (void) Psetflags(dpr->dpr_proc, PR_RLC);
+
+ /*
+ * If we are attempting to grab the process without a monitor
+ * thread, then mark the process cacheable only if it's being
+ * grabbed read-only. If we're currently caching more process
+ * handles than dph_lrulim permits, attempt to find the
+ * least-recently-used handle that is currently unreferenced and
+ * release it from the cache. Otherwise we are grabbing the process
+ * for control: create a control thread for this process and store
+ * its ID in dpr->dpr_tid.
+ */
+ if (nomonitor || (flags & PGRAB_RDONLY)) {
+ if (dph->dph_lrucnt >= dph->dph_lrulim) {
+ for (opr = dt_list_prev(&dph->dph_lrulist);
+ opr != NULL; opr = dt_list_prev(opr)) {
+ if (opr->dpr_cacheable && opr->dpr_refs == 0) {
+ dt_proc_destroy(dtp, opr->dpr_proc);
+ break;
+ }
+ }
+ }
+
+ if (flags & PGRAB_RDONLY) {
+ dpr->dpr_cacheable = B_TRUE;
+ dpr->dpr_rdonly = B_TRUE;
+ dph->dph_lrucnt++;
+ }
+
+ } else if (dt_proc_create_thread(dtp, dpr, DT_PROC_STOP_GRAB) != 0)
+ return (NULL); /* dt_proc_error() has been called for us */
+
+ dpr->dpr_hash = dph->dph_hash[h];
+ dph->dph_hash[h] = dpr;
+ dt_list_prepend(&dph->dph_lrulist, dpr);
+
+ dt_dprintf("grabbed pid %d\n", (int)pid);
+ dpr->dpr_refs++;
+
+ return (dpr->dpr_proc);
+}
+
+void
+dt_proc_release(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
+ dt_proc_hash_t *dph = dtp->dt_procs;
+
+ assert(dpr != NULL);
+ assert(dpr->dpr_refs != 0);
+
+ if (--dpr->dpr_refs == 0 &&
+ (!dpr->dpr_cacheable || dph->dph_lrucnt > dph->dph_lrulim))
+ dt_proc_destroy(dtp, P);
+}
+
+void
+dt_proc_continue(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
+
+ (void) pthread_mutex_lock(&dpr->dpr_lock);
+
+ if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
+ dpr->dpr_stop &= ~DT_PROC_STOP_IDLE;
+ (void) pthread_cond_broadcast(&dpr->dpr_cv);
+ }
+
+ (void) pthread_mutex_unlock(&dpr->dpr_lock);
+}
+
+void
+dt_proc_lock(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
+ int err = pthread_mutex_lock(&dpr->dpr_lock);
+ assert(err == 0); /* check for recursion */
+}
+
+void
+dt_proc_unlock(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
+ int err = pthread_mutex_unlock(&dpr->dpr_lock);
+ assert(err == 0); /* check for unheld lock */
+}
+
+void
+dt_proc_hash_create(dtrace_hdl_t *dtp)
+{
+ if ((dtp->dt_procs = dt_zalloc(dtp, sizeof (dt_proc_hash_t) +
+ sizeof (dt_proc_t *) * _dtrace_pidbuckets - 1)) != NULL) {
+
+ (void) pthread_mutex_init(&dtp->dt_procs->dph_lock, NULL);
+ (void) pthread_cond_init(&dtp->dt_procs->dph_cv, NULL);
+
+ dtp->dt_procs->dph_hashlen = _dtrace_pidbuckets;
+ dtp->dt_procs->dph_lrulim = _dtrace_pidlrulim;
+ }
+}
+
+void
+dt_proc_hash_destroy(dtrace_hdl_t *dtp)
+{
+ dt_proc_hash_t *dph = dtp->dt_procs;
+ dt_proc_t *dpr;
+
+ while ((dpr = dt_list_next(&dph->dph_lrulist)) != NULL)
+ dt_proc_destroy(dtp, dpr->dpr_proc);
+
+ dtp->dt_procs = NULL;
+ dt_free(dtp, dph);
+}
+
+struct ps_prochandle *
+dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
+ proc_child_func *pcf, void *child_arg)
+{
+ dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
+ struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
+
+ if (P != NULL && idp != NULL && idp->di_id == 0) {
+#if defined(sun)
+ idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */
+#else
+ idp->di_id = proc_getpid(P); /* $target = created pid */
+#endif
+ }
+
+ return (P);
+}
+
+struct ps_prochandle *
+dtrace_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags)
+{
+ dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
+ struct ps_prochandle *P = dt_proc_grab(dtp, pid, flags, 0);
+
+ if (P != NULL && idp != NULL && idp->di_id == 0)
+ idp->di_id = pid; /* $target = grabbed pid */
+
+ return (P);
+}
+
+void
+dtrace_proc_release(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_release(dtp, P);
+}
+
+void
+dtrace_proc_continue(dtrace_hdl_t *dtp, struct ps_prochandle *P)
+{
+ dt_proc_continue(dtp, P);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
new file mode 100644
index 0000000..d1fc765
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
@@ -0,0 +1,116 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PROC_H
+#define _DT_PROC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libproc.h>
+#include <dtrace.h>
+#include <pthread.h>
+#include <dt_list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_proc {
+ dt_list_t dpr_list; /* prev/next pointers for lru chain */
+ struct dt_proc *dpr_hash; /* next pointer for pid hash chain */
+ dtrace_hdl_t *dpr_hdl; /* back pointer to libdtrace handle */
+ struct ps_prochandle *dpr_proc; /* proc handle for libproc calls */
+ char dpr_errmsg[BUFSIZ]; /* error message */
+ rd_agent_t *dpr_rtld; /* rtld handle for librtld_db calls */
+ pthread_mutex_t dpr_lock; /* lock for manipulating dpr_hdl */
+ pthread_cond_t dpr_cv; /* cond for dpr_stop/quit/done */
+ pid_t dpr_pid; /* pid of process */
+ uint_t dpr_refs; /* reference count */
+ uint8_t dpr_cacheable; /* cache handle using lru list */
+ uint8_t dpr_stop; /* stop mask: see flag bits below */
+ uint8_t dpr_quit; /* quit flag: ctl thread should quit */
+ uint8_t dpr_done; /* done flag: ctl thread has exited */
+ uint8_t dpr_usdt; /* usdt flag: usdt initialized */
+ uint8_t dpr_stale; /* proc flag: been deprecated */
+ uint8_t dpr_rdonly; /* proc flag: opened read-only */
+ pthread_t dpr_tid; /* control thread (or zero if none) */
+ dt_list_t dpr_bps; /* list of dt_bkpt_t structures */
+} dt_proc_t;
+
+typedef struct dt_proc_notify {
+ dt_proc_t *dprn_dpr; /* process associated with the event */
+ char dprn_errmsg[BUFSIZ]; /* error message */
+ struct dt_proc_notify *dprn_next; /* next pointer */
+} dt_proc_notify_t;
+
+#define DT_PROC_STOP_IDLE 0x01 /* idle on owner's stop request */
+#define DT_PROC_STOP_CREATE 0x02 /* wait on dpr_cv at process exec */
+#define DT_PROC_STOP_GRAB 0x04 /* wait on dpr_cv at process grab */
+#define DT_PROC_STOP_PREINIT 0x08 /* wait on dpr_cv at rtld preinit */
+#define DT_PROC_STOP_POSTINIT 0x10 /* wait on dpr_cv at rtld postinit */
+#define DT_PROC_STOP_MAIN 0x20 /* wait on dpr_cv at a.out`main() */
+
+typedef void dt_bkpt_f(dtrace_hdl_t *, dt_proc_t *, void *);
+
+typedef struct dt_bkpt {
+ dt_list_t dbp_list; /* prev/next pointers for bkpt list */
+ dt_bkpt_f *dbp_func; /* callback function to execute */
+ void *dbp_data; /* callback function private data */
+ uintptr_t dbp_addr; /* virtual address of breakpoint */
+ ulong_t dbp_instr; /* saved instruction from breakpoint */
+ ulong_t dbp_hits; /* count of breakpoint hits for debug */
+ int dbp_active; /* flag indicating breakpoint is on */
+} dt_bkpt_t;
+
+typedef struct dt_proc_hash {
+ pthread_mutex_t dph_lock; /* lock protecting dph_notify list */
+ pthread_cond_t dph_cv; /* cond for waiting for dph_notify */
+ dt_proc_notify_t *dph_notify; /* list of pending proc notifications */
+ dt_list_t dph_lrulist; /* list of dt_proc_t's in lru order */
+ uint_t dph_lrulim; /* limit on number of procs to hold */
+ uint_t dph_lrucnt; /* count of cached process handles */
+ uint_t dph_hashlen; /* size of hash chains array */
+ dt_proc_t *dph_hash[1]; /* hash chains array */
+} dt_proc_hash_t;
+
+extern struct ps_prochandle *dt_proc_create(dtrace_hdl_t *,
+ const char *, char *const *, proc_child_func *, void *);
+
+extern struct ps_prochandle *dt_proc_grab(dtrace_hdl_t *, pid_t, int, int);
+extern void dt_proc_release(dtrace_hdl_t *, struct ps_prochandle *);
+extern void dt_proc_continue(dtrace_hdl_t *, struct ps_prochandle *);
+extern void dt_proc_lock(dtrace_hdl_t *, struct ps_prochandle *);
+extern void dt_proc_unlock(dtrace_hdl_t *, struct ps_prochandle *);
+extern dt_proc_t *dt_proc_lookup(dtrace_hdl_t *, struct ps_prochandle *, int);
+
+extern void dt_proc_hash_create(dtrace_hdl_t *);
+extern void dt_proc_hash_destroy(dtrace_hdl_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PROC_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c
new file mode 100644
index 0000000..a325c42
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c
@@ -0,0 +1,626 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+#include <unistd.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+
+#include <dt_impl.h>
+#include <dt_program.h>
+#include <dt_printf.h>
+#include <dt_provider.h>
+
+dtrace_prog_t *
+dt_program_create(dtrace_hdl_t *dtp)
+{
+ dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t));
+
+ if (pgp != NULL) {
+ dt_list_append(&dtp->dt_programs, pgp);
+ } else {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ /*
+ * By default, programs start with DOF version 1 so that output files
+ * containing DOF are backward compatible. If a program requires new
+ * DOF features, the version is increased as needed.
+ */
+ pgp->dp_dofversion = DOF_VERSION_1;
+
+ return (pgp);
+}
+
+void
+dt_program_destroy(dtrace_hdl_t *dtp, dtrace_prog_t *pgp)
+{
+ dt_stmt_t *stp, *next;
+ uint_t i;
+
+ for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) {
+ next = dt_list_next(stp);
+ dtrace_stmt_destroy(dtp, stp->ds_desc);
+ dt_free(dtp, stp);
+ }
+
+ for (i = 0; i < pgp->dp_xrefslen; i++)
+ dt_free(dtp, pgp->dp_xrefs[i]);
+
+ dt_free(dtp, pgp->dp_xrefs);
+ dt_list_delete(&dtp->dt_programs, pgp);
+ dt_free(dtp, pgp);
+}
+
+/*ARGSUSED*/
+void
+dtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
+ dtrace_proginfo_t *pip)
+{
+ dt_stmt_t *stp;
+ dtrace_actdesc_t *ap;
+ dtrace_ecbdesc_t *last = NULL;
+
+ if (pip == NULL)
+ return;
+
+ bzero(pip, sizeof (dtrace_proginfo_t));
+
+ if (dt_list_next(&pgp->dp_stmts) != NULL) {
+ pip->dpi_descattr = _dtrace_maxattr;
+ pip->dpi_stmtattr = _dtrace_maxattr;
+ } else {
+ pip->dpi_descattr = _dtrace_defattr;
+ pip->dpi_stmtattr = _dtrace_defattr;
+ }
+
+ for (stp = dt_list_next(&pgp->dp_stmts); stp; stp = dt_list_next(stp)) {
+ dtrace_ecbdesc_t *edp = stp->ds_desc->dtsd_ecbdesc;
+
+ if (edp == last)
+ continue;
+ last = edp;
+
+ pip->dpi_descattr =
+ dt_attr_min(stp->ds_desc->dtsd_descattr, pip->dpi_descattr);
+
+ pip->dpi_stmtattr =
+ dt_attr_min(stp->ds_desc->dtsd_stmtattr, pip->dpi_stmtattr);
+
+ /*
+ * If there aren't any actions, account for the fact that
+ * recording the epid will generate a record.
+ */
+ if (edp->dted_action == NULL)
+ pip->dpi_recgens++;
+
+ for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
+ if (ap->dtad_kind == DTRACEACT_SPECULATE) {
+ pip->dpi_speculations++;
+ continue;
+ }
+
+ if (DTRACEACT_ISAGG(ap->dtad_kind)) {
+ pip->dpi_recgens -= ap->dtad_arg;
+ pip->dpi_aggregates++;
+ continue;
+ }
+
+ if (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind))
+ continue;
+
+ if (ap->dtad_kind == DTRACEACT_DIFEXPR &&
+ ap->dtad_difo->dtdo_rtype.dtdt_kind ==
+ DIF_TYPE_CTF &&
+ ap->dtad_difo->dtdo_rtype.dtdt_size == 0)
+ continue;
+
+ pip->dpi_recgens++;
+ }
+ }
+}
+
+int
+dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
+ dtrace_proginfo_t *pip)
+{
+ dtrace_enable_io_t args;
+ void *dof;
+ int n, err;
+
+ dtrace_program_info(dtp, pgp, pip);
+
+ if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL)
+ return (-1);
+
+ args.dof = dof;
+ args.n_matched = 0;
+ n = dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
+ dtrace_dof_destroy(dtp, dof);
+
+ if (n == -1) {
+ switch (errno) {
+ case EINVAL:
+ err = EDT_DIFINVAL;
+ break;
+ case EFAULT:
+ err = EDT_DIFFAULT;
+ break;
+ case E2BIG:
+ err = EDT_DIFSIZE;
+ break;
+ case EBUSY:
+ err = EDT_ENABLING_ERR;
+ break;
+ default:
+ err = errno;
+ }
+
+ return (dt_set_errno(dtp, err));
+ }
+
+ if (pip != NULL)
+ pip->dpi_matches += args.n_matched;
+
+ return (0);
+}
+
+static void
+dt_ecbdesc_hold(dtrace_ecbdesc_t *edp)
+{
+ edp->dted_refcnt++;
+}
+
+void
+dt_ecbdesc_release(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp)
+{
+ if (--edp->dted_refcnt > 0)
+ return;
+
+ dt_difo_free(dtp, edp->dted_pred.dtpdd_difo);
+ assert(edp->dted_action == NULL);
+ dt_free(dtp, edp);
+}
+
+dtrace_ecbdesc_t *
+dt_ecbdesc_create(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
+{
+ dtrace_ecbdesc_t *edp;
+
+ if ((edp = dt_zalloc(dtp, sizeof (dtrace_ecbdesc_t))) == NULL) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ edp->dted_probe = *pdp;
+ dt_ecbdesc_hold(edp);
+ return (edp);
+}
+
+dtrace_stmtdesc_t *
+dtrace_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp)
+{
+ dtrace_stmtdesc_t *sdp;
+
+ if ((sdp = dt_zalloc(dtp, sizeof (dtrace_stmtdesc_t))) == NULL)
+ return (NULL);
+
+ dt_ecbdesc_hold(edp);
+ sdp->dtsd_ecbdesc = edp;
+ sdp->dtsd_descattr = _dtrace_defattr;
+ sdp->dtsd_stmtattr = _dtrace_defattr;
+
+ return (sdp);
+}
+
+dtrace_actdesc_t *
+dtrace_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *new;
+ dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
+
+ if ((new = dt_alloc(dtp, sizeof (dtrace_actdesc_t))) == NULL)
+ return (NULL);
+
+ if (sdp->dtsd_action_last != NULL) {
+ assert(sdp->dtsd_action != NULL);
+ assert(sdp->dtsd_action_last->dtad_next == NULL);
+ sdp->dtsd_action_last->dtad_next = new;
+ } else {
+ dtrace_actdesc_t *ap = edp->dted_action;
+
+ assert(sdp->dtsd_action == NULL);
+ sdp->dtsd_action = new;
+
+ while (ap != NULL && ap->dtad_next != NULL)
+ ap = ap->dtad_next;
+
+ if (ap == NULL)
+ edp->dted_action = new;
+ else
+ ap->dtad_next = new;
+ }
+
+ sdp->dtsd_action_last = new;
+ bzero(new, sizeof (dtrace_actdesc_t));
+ new->dtad_uarg = (uintptr_t)sdp;
+
+ return (new);
+}
+
+int
+dtrace_stmt_add(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp)
+{
+ dt_stmt_t *stp = dt_alloc(dtp, sizeof (dt_stmt_t));
+
+ if (stp == NULL)
+ return (-1); /* errno is set for us */
+
+ dt_list_append(&pgp->dp_stmts, stp);
+ stp->ds_desc = sdp;
+
+ return (0);
+}
+
+int
+dtrace_stmt_iter(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
+ dtrace_stmt_f *func, void *data)
+{
+ dt_stmt_t *stp, *next;
+ int status = 0;
+
+ for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) {
+ next = dt_list_next(stp);
+ if ((status = func(dtp, pgp, stp->ds_desc, data)) != 0)
+ break;
+ }
+
+ return (status);
+}
+
+void
+dtrace_stmt_destroy(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
+
+ /*
+ * We need to remove any actions that we have on this ECB, and
+ * remove our hold on the ECB itself.
+ */
+ if (sdp->dtsd_action != NULL) {
+ dtrace_actdesc_t *last = sdp->dtsd_action_last;
+ dtrace_actdesc_t *ap, *next;
+
+ assert(last != NULL);
+
+ for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
+ if (ap == sdp->dtsd_action)
+ break;
+
+ if (ap->dtad_next == sdp->dtsd_action)
+ break;
+ }
+
+ assert(ap != NULL);
+
+ if (ap == edp->dted_action)
+ edp->dted_action = last->dtad_next;
+ else
+ ap->dtad_next = last->dtad_next;
+
+ /*
+ * We have now removed our action list from its ECB; we can
+ * safely destroy the list.
+ */
+ last->dtad_next = NULL;
+
+ for (ap = sdp->dtsd_action; ap != NULL; ap = next) {
+ assert(ap->dtad_uarg == (uintptr_t)sdp);
+ dt_difo_free(dtp, ap->dtad_difo);
+ next = ap->dtad_next;
+ dt_free(dtp, ap);
+ }
+ }
+
+ if (sdp->dtsd_fmtdata != NULL)
+ dt_printf_destroy(sdp->dtsd_fmtdata);
+ dt_free(dtp, sdp->dtsd_strdata);
+
+ dt_ecbdesc_release(dtp, sdp->dtsd_ecbdesc);
+ dt_free(dtp, sdp);
+}
+
+typedef struct dt_header_info {
+ dtrace_hdl_t *dthi_dtp; /* consumer handle */
+ FILE *dthi_out; /* output file */
+ char *dthi_pmname; /* provider macro name */
+ char *dthi_pfname; /* provider function name */
+ int dthi_empty; /* should we generate empty macros */
+} dt_header_info_t;
+
+static void
+dt_header_fmt_macro(char *buf, const char *str)
+{
+ for (;;) {
+ if (islower(*str)) {
+ *buf++ = *str++ + 'A' - 'a';
+ } else if (*str == '-') {
+ *buf++ = '_';
+ str++;
+ } else if (*str == '.') {
+ *buf++ = '_';
+ str++;
+ } else if ((*buf++ = *str++) == '\0') {
+ break;
+ }
+ }
+}
+
+static void
+dt_header_fmt_func(char *buf, const char *str)
+{
+ for (;;) {
+ if (*str == '-') {
+ *buf++ = '_';
+ *buf++ = '_';
+ str++;
+ } else if ((*buf++ = *str++) == '\0') {
+ break;
+ }
+ }
+}
+
+/*ARGSUSED*/
+static int
+dt_header_decl(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
+{
+ dt_header_info_t *infop = data;
+ dtrace_hdl_t *dtp = infop->dthi_dtp;
+ dt_probe_t *prp = idp->di_data;
+ dt_node_t *dnp;
+ char buf[DT_TYPE_NAMELEN];
+ char *fname;
+ const char *p;
+ int i;
+
+ p = prp->pr_name;
+ for (i = 0; (p = strchr(p, '-')) != NULL; i++)
+ p++;
+
+ fname = alloca(strlen(prp->pr_name) + 1 + i);
+ dt_header_fmt_func(fname, prp->pr_name);
+
+ if (fprintf(infop->dthi_out, "extern void __dtrace_%s___%s(",
+ infop->dthi_pfname, fname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ for (dnp = prp->pr_nargs, i = 0; dnp != NULL; dnp = dnp->dn_list, i++) {
+ if (fprintf(infop->dthi_out, "%s",
+ ctf_type_name(dnp->dn_ctfp, dnp->dn_type,
+ buf, sizeof (buf))) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (i + 1 != prp->pr_nargc &&
+ fprintf(infop->dthi_out, ", ") < 0)
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if (i == 0 && fprintf(infop->dthi_out, "void") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (fprintf(infop->dthi_out, ");\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (fprintf(infop->dthi_out,
+ "#ifndef\t__sparc\n"
+ "extern int __dtraceenabled_%s___%s(void);\n"
+ "#else\n"
+ "extern int __dtraceenabled_%s___%s(long);\n"
+ "#endif\n",
+ infop->dthi_pfname, fname, infop->dthi_pfname, fname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dt_header_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
+{
+ dt_header_info_t *infop = data;
+ dtrace_hdl_t *dtp = infop->dthi_dtp;
+ dt_probe_t *prp = idp->di_data;
+ char *mname, *fname;
+ const char *p;
+ int i;
+
+ p = prp->pr_name;
+ for (i = 0; (p = strchr(p, '-')) != NULL; i++)
+ p++;
+
+ mname = alloca(strlen(prp->pr_name) + 1);
+ dt_header_fmt_macro(mname, prp->pr_name);
+
+ fname = alloca(strlen(prp->pr_name) + 1 + i);
+ dt_header_fmt_func(fname, prp->pr_name);
+
+ if (fprintf(infop->dthi_out, "#define\t%s_%s(",
+ infop->dthi_pmname, mname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ for (i = 0; i < prp->pr_nargc; i++) {
+ if (fprintf(infop->dthi_out, "arg%d", i) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (i + 1 != prp->pr_nargc &&
+ fprintf(infop->dthi_out, ", ") < 0)
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if (!infop->dthi_empty) {
+ if (fprintf(infop->dthi_out, ") \\\n\t") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (fprintf(infop->dthi_out, "__dtrace_%s___%s(",
+ infop->dthi_pfname, fname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ for (i = 0; i < prp->pr_nargc; i++) {
+ if (fprintf(infop->dthi_out, "arg%d", i) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (i + 1 != prp->pr_nargc &&
+ fprintf(infop->dthi_out, ", ") < 0)
+ return (dt_set_errno(dtp, errno));
+ }
+ }
+
+ if (fprintf(infop->dthi_out, ")\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (!infop->dthi_empty) {
+ if (fprintf(infop->dthi_out,
+ "#ifndef\t__sparc\n"
+ "#define\t%s_%s_ENABLED() \\\n"
+ "\t__dtraceenabled_%s___%s()\n"
+ "#else\n"
+ "#define\t%s_%s_ENABLED() \\\n"
+ "\t__dtraceenabled_%s___%s(0)\n"
+ "#endif\n",
+ infop->dthi_pmname, mname,
+ infop->dthi_pfname, fname,
+ infop->dthi_pmname, mname,
+ infop->dthi_pfname, fname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ } else {
+ if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() (0)\n",
+ infop->dthi_pmname, mname) < 0)
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (0);
+}
+
+static int
+dt_header_provider(dtrace_hdl_t *dtp, dt_provider_t *pvp, FILE *out)
+{
+ dt_header_info_t info;
+ const char *p;
+ int i;
+
+ if (pvp->pv_flags & DT_PROVIDER_IMPL)
+ return (0);
+
+ /*
+ * Count the instances of the '-' character since we'll need to double
+ * those up.
+ */
+ p = pvp->pv_desc.dtvd_name;
+ for (i = 0; (p = strchr(p, '-')) != NULL; i++)
+ p++;
+
+ info.dthi_dtp = dtp;
+ info.dthi_out = out;
+ info.dthi_empty = 0;
+
+ info.dthi_pmname = alloca(strlen(pvp->pv_desc.dtvd_name) + 1);
+ dt_header_fmt_macro(info.dthi_pmname, pvp->pv_desc.dtvd_name);
+
+ info.dthi_pfname = alloca(strlen(pvp->pv_desc.dtvd_name) + 1 + i);
+ dt_header_fmt_func(info.dthi_pfname, pvp->pv_desc.dtvd_name);
+
+#ifdef __FreeBSD__
+ if (fprintf(out, "#include <sys/sdt.h>\n\n") < 0)
+ return (dt_set_errno(dtp, errno));
+#endif
+ if (fprintf(out, "#if _DTRACE_VERSION\n\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (dt_idhash_iter(pvp->pv_probes, dt_header_probe, &info) != 0)
+ return (-1); /* dt_errno is set for us */
+ if (fprintf(out, "\n\n") < 0)
+ return (dt_set_errno(dtp, errno));
+ if (dt_idhash_iter(pvp->pv_probes, dt_header_decl, &info) != 0)
+ return (-1); /* dt_errno is set for us */
+
+ if (fprintf(out, "\n#else\n\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ info.dthi_empty = 1;
+
+ if (dt_idhash_iter(pvp->pv_probes, dt_header_probe, &info) != 0)
+ return (-1); /* dt_errno is set for us */
+
+ if (fprintf(out, "\n#endif\n\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ return (0);
+}
+
+int
+dtrace_program_header(dtrace_hdl_t *dtp, FILE *out, const char *fname)
+{
+ dt_provider_t *pvp;
+ char *mfname, *p;
+
+ if (fname != NULL) {
+ if ((p = strrchr(fname, '/')) != NULL)
+ fname = p + 1;
+
+ mfname = alloca(strlen(fname) + 1);
+ dt_header_fmt_macro(mfname, fname);
+ if (fprintf(out, "#ifndef\t_%s\n#define\t_%s\n\n",
+ mfname, mfname) < 0)
+ return (dt_set_errno(dtp, errno));
+ }
+
+ if (fprintf(out, "#include <unistd.h>\n\n") < 0)
+ return (-1);
+
+ if (fprintf(out, "#ifdef\t__cplusplus\nextern \"C\" {\n#endif\n\n") < 0)
+ return (-1);
+
+ for (pvp = dt_list_next(&dtp->dt_provlist);
+ pvp != NULL; pvp = dt_list_next(pvp)) {
+ if (dt_header_provider(dtp, pvp, out) != 0)
+ return (-1); /* dt_errno is set for us */
+ }
+
+ if (fprintf(out, "\n#ifdef\t__cplusplus\n}\n#endif\n") < 0)
+ return (dt_set_errno(dtp, errno));
+
+ if (fname != NULL && fprintf(out, "\n#endif\t/* _%s */\n", mfname) < 0)
+ return (dt_set_errno(dtp, errno));
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.h
new file mode 100644
index 0000000..3fe1c39
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.h
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PROGRAM_H
+#define _DT_PROGRAM_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dtrace.h>
+#include <dt_list.h>
+
+typedef struct dt_stmt {
+ dt_list_t ds_list; /* list forward/back pointers */
+ dtrace_stmtdesc_t *ds_desc; /* pointer to statement description */
+} dt_stmt_t;
+
+struct dtrace_prog {
+ dt_list_t dp_list; /* list forward/back pointers */
+ dt_list_t dp_stmts; /* linked list of dt_stmt_t's */
+ ulong_t **dp_xrefs; /* array of translator reference bitmaps */
+ uint_t dp_xrefslen; /* length of dp_xrefs array */
+ uint8_t dp_dofversion; /* DOF version this program requires */
+};
+
+extern dtrace_prog_t *dt_program_create(dtrace_hdl_t *);
+extern void dt_program_destroy(dtrace_hdl_t *, dtrace_prog_t *);
+
+extern dtrace_ecbdesc_t *dt_ecbdesc_create(dtrace_hdl_t *,
+ const dtrace_probedesc_t *);
+extern void dt_ecbdesc_release(dtrace_hdl_t *, dtrace_ecbdesc_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PROGRAM_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
new file mode 100644
index 0000000..188ce0e
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
@@ -0,0 +1,883 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#if defined(sun)
+#include <sys/sysmacros.h>
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <strings.h>
+#include <stdlib.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+
+#include <dt_provider.h>
+#include <dt_module.h>
+#include <dt_string.h>
+#include <dt_list.h>
+
+static dt_provider_t *
+dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h)
+{
+ dt_list_append(&dtp->dt_provlist, pvp);
+
+ pvp->pv_next = dtp->dt_provs[h];
+ dtp->dt_provs[h] = pvp;
+ dtp->dt_nprovs++;
+
+ return (pvp);
+}
+
+dt_provider_t *
+dt_provider_lookup(dtrace_hdl_t *dtp, const char *name)
+{
+ uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets;
+ dtrace_providerdesc_t desc;
+ dt_provider_t *pvp;
+
+ for (pvp = dtp->dt_provs[h]; pvp != NULL; pvp = pvp->pv_next) {
+ if (strcmp(pvp->pv_desc.dtvd_name, name) == 0)
+ return (pvp);
+ }
+
+ if (strisglob(name) || name[0] == '\0') {
+ (void) dt_set_errno(dtp, EDT_NOPROV);
+ return (NULL);
+ }
+
+ bzero(&desc, sizeof (desc));
+ (void) strlcpy(desc.dtvd_name, name, DTRACE_PROVNAMELEN);
+
+ if (dt_ioctl(dtp, DTRACEIOC_PROVIDER, &desc) == -1) {
+ (void) dt_set_errno(dtp, errno == ESRCH ? EDT_NOPROV : errno);
+ return (NULL);
+ }
+
+ if ((pvp = dt_provider_create(dtp, name)) == NULL)
+ return (NULL); /* dt_errno is set for us */
+
+ bcopy(&desc, &pvp->pv_desc, sizeof (desc));
+ pvp->pv_flags |= DT_PROVIDER_IMPL;
+ return (pvp);
+}
+
+dt_provider_t *
+dt_provider_create(dtrace_hdl_t *dtp, const char *name)
+{
+ dt_provider_t *pvp;
+
+ if ((pvp = dt_zalloc(dtp, sizeof (dt_provider_t))) == NULL)
+ return (NULL);
+
+ (void) strlcpy(pvp->pv_desc.dtvd_name, name, DTRACE_PROVNAMELEN);
+ pvp->pv_probes = dt_idhash_create(pvp->pv_desc.dtvd_name, NULL, 0, 0);
+ pvp->pv_gen = dtp->dt_gen;
+ pvp->pv_hdl = dtp;
+
+ if (pvp->pv_probes == NULL) {
+ dt_free(dtp, pvp);
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ pvp->pv_desc.dtvd_attr.dtpa_provider = _dtrace_prvattr;
+ pvp->pv_desc.dtvd_attr.dtpa_mod = _dtrace_prvattr;
+ pvp->pv_desc.dtvd_attr.dtpa_func = _dtrace_prvattr;
+ pvp->pv_desc.dtvd_attr.dtpa_name = _dtrace_prvattr;
+ pvp->pv_desc.dtvd_attr.dtpa_args = _dtrace_prvattr;
+
+ return (dt_provider_insert(dtp, pvp,
+ dt_strtab_hash(name, NULL) % dtp->dt_provbuckets));
+}
+
+void
+dt_provider_destroy(dtrace_hdl_t *dtp, dt_provider_t *pvp)
+{
+ dt_provider_t **pp;
+ uint_t h;
+
+ assert(pvp->pv_hdl == dtp);
+
+ h = dt_strtab_hash(pvp->pv_desc.dtvd_name, NULL) % dtp->dt_provbuckets;
+ pp = &dtp->dt_provs[h];
+
+ while (*pp != NULL && *pp != pvp)
+ pp = &(*pp)->pv_next;
+
+ assert(*pp != NULL && *pp == pvp);
+ *pp = pvp->pv_next;
+
+ dt_list_delete(&dtp->dt_provlist, pvp);
+ dtp->dt_nprovs--;
+
+ if (pvp->pv_probes != NULL)
+ dt_idhash_destroy(pvp->pv_probes);
+
+ dt_node_link_free(&pvp->pv_nodes);
+ dt_free(dtp, pvp->pv_xrefs);
+ dt_free(dtp, pvp);
+}
+
+int
+dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id)
+{
+ size_t oldsize = BT_SIZEOFMAP(pvp->pv_xrmax);
+ size_t newsize = BT_SIZEOFMAP(dtp->dt_xlatorid);
+
+ assert(id >= 0 && id < dtp->dt_xlatorid);
+
+ if (newsize > oldsize) {
+ ulong_t *xrefs = dt_zalloc(dtp, newsize);
+
+ if (xrefs == NULL)
+ return (-1);
+
+ bcopy(pvp->pv_xrefs, xrefs, oldsize);
+ dt_free(dtp, pvp->pv_xrefs);
+
+ pvp->pv_xrefs = xrefs;
+ pvp->pv_xrmax = dtp->dt_xlatorid;
+ }
+
+ BT_SET(pvp->pv_xrefs, id);
+ return (0);
+}
+
+static uint8_t
+dt_probe_argmap(dt_node_t *xnp, dt_node_t *nnp)
+{
+ uint8_t i;
+
+ for (i = 0; nnp != NULL; i++) {
+ if (nnp->dn_string != NULL &&
+ strcmp(nnp->dn_string, xnp->dn_string) == 0)
+ break;
+ else
+ nnp = nnp->dn_list;
+ }
+
+ return (i);
+}
+
+static dt_node_t *
+dt_probe_alloc_args(dt_provider_t *pvp, int argc)
+{
+ dt_node_t *args = NULL, *pnp = NULL, *dnp;
+ int i;
+
+ for (i = 0; i < argc; i++, pnp = dnp) {
+ if ((dnp = dt_node_xalloc(pvp->pv_hdl, DT_NODE_TYPE)) == NULL)
+ return (NULL);
+
+ dnp->dn_link = pvp->pv_nodes;
+ pvp->pv_nodes = dnp;
+
+ if (args == NULL)
+ args = dnp;
+ else
+ pnp->dn_list = dnp;
+ }
+
+ return (args);
+}
+
+static size_t
+dt_probe_keylen(const dtrace_probedesc_t *pdp)
+{
+ return (strlen(pdp->dtpd_mod) + 1 +
+ strlen(pdp->dtpd_func) + 1 + strlen(pdp->dtpd_name) + 1);
+}
+
+static char *
+dt_probe_key(const dtrace_probedesc_t *pdp, char *s)
+{
+ (void) snprintf(s, INT_MAX, "%s:%s:%s",
+ pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
+ return (s);
+}
+
+/*
+ * If a probe was discovered from the kernel, ask dtrace(7D) for a description
+ * of each of its arguments, including native and translated types.
+ */
+static dt_probe_t *
+dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp)
+{
+ dtrace_hdl_t *dtp = pvp->pv_hdl;
+ char *name = dt_probe_key(pdp, alloca(dt_probe_keylen(pdp)));
+
+ dt_node_t *xargs, *nargs;
+ dt_ident_t *idp;
+ dt_probe_t *prp;
+
+ dtrace_typeinfo_t dtt;
+ int i, nc, xc;
+
+ int adc = _dtrace_argmax;
+ dtrace_argdesc_t *adv = alloca(sizeof (dtrace_argdesc_t) * adc);
+ dtrace_argdesc_t *adp = adv;
+
+ assert(strcmp(pvp->pv_desc.dtvd_name, pdp->dtpd_provider) == 0);
+ assert(pdp->dtpd_id != DTRACE_IDNONE);
+
+ dt_dprintf("discovering probe %s:%s id=%d\n",
+ pvp->pv_desc.dtvd_name, name, pdp->dtpd_id);
+
+ for (nc = -1, i = 0; i < adc; i++, adp++) {
+ bzero(adp, sizeof (dtrace_argdesc_t));
+ adp->dtargd_ndx = i;
+ adp->dtargd_id = pdp->dtpd_id;
+
+ if (dt_ioctl(dtp, DTRACEIOC_PROBEARG, adp) != 0) {
+ (void) dt_set_errno(dtp, errno);
+ return (NULL);
+ }
+
+ if (adp->dtargd_ndx == DTRACE_ARGNONE)
+ break; /* all argument descs have been retrieved */
+
+ nc = MAX(nc, adp->dtargd_mapping);
+ }
+
+ xc = i;
+ nc++;
+
+ /*
+ * Now that we have discovered the number of native and translated
+ * arguments from the argument descriptions, allocate a new probe ident
+ * and corresponding dt_probe_t and hash it into the provider.
+ */
+ xargs = dt_probe_alloc_args(pvp, xc);
+ nargs = dt_probe_alloc_args(pvp, nc);
+
+ if ((xc != 0 && xargs == NULL) || (nc != 0 && nargs == NULL))
+ return (NULL); /* dt_errno is set for us */
+
+ idp = dt_ident_create(name, DT_IDENT_PROBE,
+ DT_IDFLG_ORPHAN, pdp->dtpd_id, _dtrace_defattr, 0,
+ &dt_idops_probe, NULL, dtp->dt_gen);
+
+ if (idp == NULL) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ if ((prp = dt_probe_create(dtp, idp, 2,
+ nargs, nc, xargs, xc)) == NULL) {
+ dt_ident_destroy(idp);
+ return (NULL);
+ }
+
+ dt_probe_declare(pvp, prp);
+
+ /*
+ * Once our new dt_probe_t is fully constructed, iterate over the
+ * cached argument descriptions and assign types to prp->pr_nargv[]
+ * and prp->pr_xargv[] and assign mappings to prp->pr_mapping[].
+ */
+ for (adp = adv, i = 0; i < xc; i++, adp++) {
+ if (dtrace_type_strcompile(dtp,
+ adp->dtargd_native, &dtt) != 0) {
+ dt_dprintf("failed to resolve input type %s "
+ "for %s:%s arg #%d: %s\n", adp->dtargd_native,
+ pvp->pv_desc.dtvd_name, name, i + 1,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+
+ dtt.dtt_object = NULL;
+ dtt.dtt_ctfp = NULL;
+ dtt.dtt_type = CTF_ERR;
+ } else {
+ dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping],
+ dtt.dtt_ctfp, dtt.dtt_type);
+ }
+
+ if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' ||
+ strcmp(adp->dtargd_native, adp->dtargd_xlate) == 0)) {
+ dt_node_type_propagate(prp->pr_nargv[
+ adp->dtargd_mapping], prp->pr_xargv[i]);
+ } else if (dtrace_type_strcompile(dtp,
+ adp->dtargd_xlate, &dtt) != 0) {
+ dt_dprintf("failed to resolve output type %s "
+ "for %s:%s arg #%d: %s\n", adp->dtargd_xlate,
+ pvp->pv_desc.dtvd_name, name, i + 1,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+
+ dtt.dtt_object = NULL;
+ dtt.dtt_ctfp = NULL;
+ dtt.dtt_type = CTF_ERR;
+ } else {
+ dt_node_type_assign(prp->pr_xargv[i],
+ dtt.dtt_ctfp, dtt.dtt_type);
+ }
+
+ prp->pr_mapping[i] = adp->dtargd_mapping;
+ prp->pr_argv[i] = dtt;
+ }
+
+ return (prp);
+}
+
+/*
+ * Lookup a probe declaration based on a known provider and full or partially
+ * specified module, function, and name. If the probe is not known to us yet,
+ * ask dtrace(7D) to match the description and then cache any useful results.
+ */
+dt_probe_t *
+dt_probe_lookup(dt_provider_t *pvp, const char *s)
+{
+ dtrace_hdl_t *dtp = pvp->pv_hdl;
+ dtrace_probedesc_t pd;
+ dt_ident_t *idp;
+ size_t keylen;
+ char *key;
+
+ if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, s, &pd) != 0)
+ return (NULL); /* dt_errno is set for us */
+
+ keylen = dt_probe_keylen(&pd);
+ key = dt_probe_key(&pd, alloca(keylen));
+
+ /*
+ * If the probe is already declared, then return the dt_probe_t from
+ * the existing identifier. This could come from a static declaration
+ * or it could have been cached from an earlier call to this function.
+ */
+ if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL)
+ return (idp->di_data);
+
+ /*
+ * If the probe isn't known, use the probe description computed above
+ * to ask dtrace(7D) to find the first matching probe.
+ */
+ if (dt_ioctl(dtp, DTRACEIOC_PROBEMATCH, &pd) == 0)
+ return (dt_probe_discover(pvp, &pd));
+
+ if (errno == ESRCH || errno == EBADF)
+ (void) dt_set_errno(dtp, EDT_NOPROBE);
+ else
+ (void) dt_set_errno(dtp, errno);
+
+ return (NULL);
+}
+
+dt_probe_t *
+dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp, int protoc,
+ dt_node_t *nargs, uint_t nargc, dt_node_t *xargs, uint_t xargc)
+{
+ dt_module_t *dmp;
+ dt_probe_t *prp;
+ const char *p;
+ uint_t i;
+
+ assert(idp->di_kind == DT_IDENT_PROBE);
+ assert(idp->di_data == NULL);
+
+ /*
+ * If only a single prototype is given, set xargc/s to nargc/s to
+ * simplify subsequent use. Note that we can have one or both of nargs
+ * and xargs be specified but set to NULL, indicating a void prototype.
+ */
+ if (protoc < 2) {
+ assert(xargs == NULL);
+ assert(xargc == 0);
+ xargs = nargs;
+ xargc = nargc;
+ }
+
+ if ((prp = dt_alloc(dtp, sizeof (dt_probe_t))) == NULL)
+ return (NULL);
+
+ prp->pr_pvp = NULL;
+ prp->pr_ident = idp;
+
+ p = strrchr(idp->di_name, ':');
+ assert(p != NULL);
+ prp->pr_name = p + 1;
+
+ prp->pr_nargs = nargs;
+ prp->pr_nargv = dt_alloc(dtp, sizeof (dt_node_t *) * nargc);
+ prp->pr_nargc = nargc;
+ prp->pr_xargs = xargs;
+ prp->pr_xargv = dt_alloc(dtp, sizeof (dt_node_t *) * xargc);
+ prp->pr_xargc = xargc;
+ prp->pr_mapping = dt_alloc(dtp, sizeof (uint8_t) * xargc);
+ prp->pr_inst = NULL;
+ prp->pr_argv = dt_alloc(dtp, sizeof (dtrace_typeinfo_t) * xargc);
+ prp->pr_argc = xargc;
+
+ if ((prp->pr_nargc != 0 && prp->pr_nargv == NULL) ||
+ (prp->pr_xargc != 0 && prp->pr_xargv == NULL) ||
+ (prp->pr_xargc != 0 && prp->pr_mapping == NULL) ||
+ (prp->pr_argc != 0 && prp->pr_argv == NULL)) {
+ dt_probe_destroy(prp);
+ return (NULL);
+ }
+
+ for (i = 0; i < xargc; i++, xargs = xargs->dn_list) {
+ if (xargs->dn_string != NULL)
+ prp->pr_mapping[i] = dt_probe_argmap(xargs, nargs);
+ else
+ prp->pr_mapping[i] = i;
+
+ prp->pr_xargv[i] = xargs;
+
+ if ((dmp = dt_module_lookup_by_ctf(dtp,
+ xargs->dn_ctfp)) != NULL)
+ prp->pr_argv[i].dtt_object = dmp->dm_name;
+ else
+ prp->pr_argv[i].dtt_object = NULL;
+
+ prp->pr_argv[i].dtt_ctfp = xargs->dn_ctfp;
+ prp->pr_argv[i].dtt_type = xargs->dn_type;
+ }
+
+ for (i = 0; i < nargc; i++, nargs = nargs->dn_list)
+ prp->pr_nargv[i] = nargs;
+
+ idp->di_data = prp;
+ return (prp);
+}
+
+void
+dt_probe_declare(dt_provider_t *pvp, dt_probe_t *prp)
+{
+ assert(prp->pr_ident->di_kind == DT_IDENT_PROBE);
+ assert(prp->pr_ident->di_data == prp);
+ assert(prp->pr_pvp == NULL);
+
+ if (prp->pr_xargs != prp->pr_nargs)
+ pvp->pv_flags &= ~DT_PROVIDER_INTF;
+
+ prp->pr_pvp = pvp;
+ dt_idhash_xinsert(pvp->pv_probes, prp->pr_ident);
+}
+
+void
+dt_probe_destroy(dt_probe_t *prp)
+{
+ dt_probe_instance_t *pip, *pip_next;
+ dtrace_hdl_t *dtp;
+
+ if (prp->pr_pvp != NULL)
+ dtp = prp->pr_pvp->pv_hdl;
+ else
+ dtp = yypcb->pcb_hdl;
+
+ dt_node_list_free(&prp->pr_nargs);
+ dt_node_list_free(&prp->pr_xargs);
+
+ dt_free(dtp, prp->pr_nargv);
+ dt_free(dtp, prp->pr_xargv);
+
+ for (pip = prp->pr_inst; pip != NULL; pip = pip_next) {
+ pip_next = pip->pi_next;
+ dt_free(dtp, pip->pi_offs);
+ dt_free(dtp, pip->pi_enoffs);
+ dt_free(dtp, pip);
+ }
+
+ dt_free(dtp, prp->pr_mapping);
+ dt_free(dtp, prp->pr_argv);
+ dt_free(dtp, prp);
+}
+
+int
+dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
+ const char *fname, const char *rname, uint32_t offset, int isenabled)
+{
+ dtrace_hdl_t *dtp = pvp->pv_hdl;
+ dt_probe_instance_t *pip;
+ uint32_t **offs;
+ uint_t *noffs, *maxoffs;
+
+ assert(fname != NULL);
+
+ for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
+ if (strcmp(pip->pi_fname, fname) == 0 &&
+ ((rname == NULL && pip->pi_rname[0] == '\0') ||
+ (rname != NULL && strcmp(pip->pi_rname, rname)) == 0))
+ break;
+ }
+
+ if (pip == NULL) {
+ if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL)
+ return (-1);
+
+ if ((pip->pi_offs = dt_zalloc(dtp,
+ sizeof (uint32_t))) == NULL) {
+ dt_free(dtp, pip);
+ return (-1);
+ }
+
+ if ((pip->pi_enoffs = dt_zalloc(dtp,
+ sizeof (uint32_t))) == NULL) {
+ dt_free(dtp, pip->pi_offs);
+ dt_free(dtp, pip);
+ return (-1);
+ }
+
+ (void) strlcpy(pip->pi_fname, fname, sizeof (pip->pi_fname));
+ if (rname != NULL) {
+ if (strlen(rname) + 1 > sizeof (pip->pi_rname)) {
+ dt_free(dtp, pip->pi_offs);
+ dt_free(dtp, pip);
+ return (dt_set_errno(dtp, EDT_COMPILER));
+ }
+ (void) strcpy(pip->pi_rname, rname);
+ }
+
+ pip->pi_noffs = 0;
+ pip->pi_maxoffs = 1;
+ pip->pi_nenoffs = 0;
+ pip->pi_maxenoffs = 1;
+
+ pip->pi_next = prp->pr_inst;
+
+ prp->pr_inst = pip;
+ }
+
+ if (isenabled) {
+ offs = &pip->pi_enoffs;
+ noffs = &pip->pi_nenoffs;
+ maxoffs = &pip->pi_maxenoffs;
+ } else {
+ offs = &pip->pi_offs;
+ noffs = &pip->pi_noffs;
+ maxoffs = &pip->pi_maxoffs;
+ }
+
+ if (*noffs == *maxoffs) {
+ uint_t new_max = *maxoffs * 2;
+ uint32_t *new_offs = dt_alloc(dtp, sizeof (uint32_t) * new_max);
+
+ if (new_offs == NULL)
+ return (-1);
+
+ bcopy(*offs, new_offs, sizeof (uint32_t) * *maxoffs);
+
+ dt_free(dtp, *offs);
+ *maxoffs = new_max;
+ *offs = new_offs;
+ }
+
+ dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
+ isenabled ? "(is-enabled)" : "",
+ pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset,
+ rname != NULL ? rname : fname);
+
+ assert(*noffs < *maxoffs);
+ (*offs)[(*noffs)++] = offset;
+
+ return (0);
+}
+
+/*
+ * Lookup the dynamic translator type tag for the specified probe argument and
+ * assign the type to the specified node. If the type is not yet defined, add
+ * it to the "D" module's type container as a typedef for an unknown type.
+ */
+dt_node_t *
+dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = prp->pr_pvp->pv_hdl;
+ dtrace_typeinfo_t dtt;
+ size_t len;
+ char *tag;
+
+ len = snprintf(NULL, 0, "__dtrace_%s___%s_arg%u",
+ prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
+
+ tag = alloca(len + 1);
+
+ (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u",
+ prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
+
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) {
+ dtt.dtt_object = DTRACE_OBJ_DDEFS;
+ dtt.dtt_ctfp = DT_DYN_CTFP(dtp);
+ dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp),
+ CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp));
+
+ if (dtt.dtt_type == CTF_ERR ||
+ ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "cannot define type %s: %s\n",
+ tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
+ }
+ }
+
+ bzero(dnp, sizeof (dt_node_t));
+ dnp->dn_kind = DT_NODE_TYPE;
+
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_attr_assign(dnp, _dtrace_defattr);
+
+ return (dnp);
+}
+
+/*ARGSUSED*/
+static int
+dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
+{
+ if (((dtrace_probedesc_t *)arg)->dtpd_id == DTRACE_IDNONE) {
+ bcopy(pdp, arg, sizeof (dtrace_probedesc_t));
+ return (0);
+ }
+
+ return (1);
+}
+
+dt_probe_t *
+dt_probe_info(dtrace_hdl_t *dtp,
+ const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip)
+{
+ int m_is_glob = pdp->dtpd_mod[0] == '\0' || strisglob(pdp->dtpd_mod);
+ int f_is_glob = pdp->dtpd_func[0] == '\0' || strisglob(pdp->dtpd_func);
+ int n_is_glob = pdp->dtpd_name[0] == '\0' || strisglob(pdp->dtpd_name);
+
+ dt_probe_t *prp = NULL;
+ const dtrace_pattr_t *pap;
+ dt_provider_t *pvp;
+ dt_ident_t *idp;
+
+ /*
+ * Attempt to lookup the probe in our existing cache for this provider.
+ * If none is found and an explicit probe ID was specified, discover
+ * that specific probe and cache its description and arguments.
+ */
+ if ((pvp = dt_provider_lookup(dtp, pdp->dtpd_provider)) != NULL) {
+ size_t keylen = dt_probe_keylen(pdp);
+ char *key = dt_probe_key(pdp, alloca(keylen));
+
+ if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL)
+ prp = idp->di_data;
+ else if (pdp->dtpd_id != DTRACE_IDNONE)
+ prp = dt_probe_discover(pvp, pdp);
+ }
+
+ /*
+ * If no probe was found in our cache, convert the caller's partial
+ * probe description into a fully-formed matching probe description by
+ * iterating over up to at most two probes that match 'pdp'. We then
+ * call dt_probe_discover() on the resulting probe identifier.
+ */
+ if (prp == NULL) {
+ dtrace_probedesc_t pd;
+ int m;
+
+ bzero(&pd, sizeof (pd));
+ pd.dtpd_id = DTRACE_IDNONE;
+
+ /*
+ * Call dtrace_probe_iter() to find matching probes. Our
+ * dt_probe_desc() callback will produce the following results:
+ *
+ * m < 0 dtrace_probe_iter() found zero matches (or failed).
+ * m > 0 dtrace_probe_iter() found more than one match.
+ * m = 0 dtrace_probe_iter() found exactly one match.
+ */
+ if ((m = dtrace_probe_iter(dtp, pdp, dt_probe_desc, &pd)) < 0)
+ return (NULL); /* dt_errno is set for us */
+
+ if ((pvp = dt_provider_lookup(dtp, pd.dtpd_provider)) == NULL)
+ return (NULL); /* dt_errno is set for us */
+
+ /*
+ * If more than one probe was matched, then do not report probe
+ * information if either of the following conditions is true:
+ *
+ * (a) The Arguments Data stability of the matched provider is
+ * less than Evolving.
+ *
+ * (b) Any description component that is at least Evolving is
+ * empty or is specified using a globbing expression.
+ *
+ * These conditions imply that providers that provide Evolving
+ * or better Arguments Data stability must guarantee that all
+ * probes with identical field names in a field of Evolving or
+ * better Name stability have identical argument signatures.
+ */
+ if (m > 0) {
+ if (pvp->pv_desc.dtvd_attr.dtpa_args.dtat_data <
+ DTRACE_STABILITY_EVOLVING) {
+ (void) dt_set_errno(dtp, EDT_UNSTABLE);
+ return (NULL);
+ }
+
+
+ if (pvp->pv_desc.dtvd_attr.dtpa_mod.dtat_name >=
+ DTRACE_STABILITY_EVOLVING && m_is_glob) {
+ (void) dt_set_errno(dtp, EDT_UNSTABLE);
+ return (NULL);
+ }
+
+ if (pvp->pv_desc.dtvd_attr.dtpa_func.dtat_name >=
+ DTRACE_STABILITY_EVOLVING && f_is_glob) {
+ (void) dt_set_errno(dtp, EDT_UNSTABLE);
+ return (NULL);
+ }
+
+ if (pvp->pv_desc.dtvd_attr.dtpa_name.dtat_name >=
+ DTRACE_STABILITY_EVOLVING && n_is_glob) {
+ (void) dt_set_errno(dtp, EDT_UNSTABLE);
+ return (NULL);
+ }
+ }
+
+ /*
+ * If we matched a probe exported by dtrace(7D), then discover
+ * the real attributes. Otherwise grab the static declaration.
+ */
+ if (pd.dtpd_id != DTRACE_IDNONE)
+ prp = dt_probe_discover(pvp, &pd);
+ else
+ prp = dt_probe_lookup(pvp, pd.dtpd_name);
+
+ if (prp == NULL)
+ return (NULL); /* dt_errno is set for us */
+ }
+
+ assert(pvp != NULL && prp != NULL);
+
+ /*
+ * Compute the probe description attributes by taking the minimum of
+ * the attributes of the specified fields. If no provider is specified
+ * or a glob pattern is used for the provider, use Unstable attributes.
+ */
+ if (pdp->dtpd_provider[0] == '\0' || strisglob(pdp->dtpd_provider))
+ pap = &_dtrace_prvdesc;
+ else
+ pap = &pvp->pv_desc.dtvd_attr;
+
+ pip->dtp_attr = pap->dtpa_provider;
+
+ if (!m_is_glob)
+ pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_mod);
+ if (!f_is_glob)
+ pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_func);
+ if (!n_is_glob)
+ pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_name);
+
+ pip->dtp_arga = pap->dtpa_args;
+ pip->dtp_argv = prp->pr_argv;
+ pip->dtp_argc = prp->pr_argc;
+
+ return (prp);
+}
+
+int
+dtrace_probe_info(dtrace_hdl_t *dtp,
+ const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip)
+{
+ return (dt_probe_info(dtp, pdp, pip) != NULL ? 0 : -1);
+}
+
+/*ARGSUSED*/
+static int
+dt_probe_iter(dt_idhash_t *ihp, dt_ident_t *idp, dt_probe_iter_t *pit)
+{
+ const dt_probe_t *prp = idp->di_data;
+
+ if (!dt_gmatch(prp->pr_name, pit->pit_pat))
+ return (0); /* continue on and examine next probe in hash */
+
+ (void) strlcpy(pit->pit_desc.dtpd_name, prp->pr_name, DTRACE_NAMELEN);
+ pit->pit_desc.dtpd_id = idp->di_id;
+ pit->pit_matches++;
+
+ return (pit->pit_func(pit->pit_hdl, &pit->pit_desc, pit->pit_arg));
+}
+
+int
+dtrace_probe_iter(dtrace_hdl_t *dtp,
+ const dtrace_probedesc_t *pdp, dtrace_probe_f *func, void *arg)
+{
+ const char *provider = pdp ? pdp->dtpd_provider : NULL;
+ dtrace_id_t id = DTRACE_IDNONE;
+
+ dtrace_probedesc_t pd;
+ dt_probe_iter_t pit;
+ int cmd, rv;
+
+ bzero(&pit, sizeof (pit));
+ pit.pit_hdl = dtp;
+ pit.pit_func = func;
+ pit.pit_arg = arg;
+ pit.pit_pat = pdp ? pdp->dtpd_name : NULL;
+
+ for (pit.pit_pvp = dt_list_next(&dtp->dt_provlist);
+ pit.pit_pvp != NULL; pit.pit_pvp = dt_list_next(pit.pit_pvp)) {
+
+ if (pit.pit_pvp->pv_flags & DT_PROVIDER_IMPL)
+ continue; /* we'll get these later using dt_ioctl() */
+
+ if (!dt_gmatch(pit.pit_pvp->pv_desc.dtvd_name, provider))
+ continue;
+
+ (void) strlcpy(pit.pit_desc.dtpd_provider,
+ pit.pit_pvp->pv_desc.dtvd_name, DTRACE_PROVNAMELEN);
+
+ if ((rv = dt_idhash_iter(pit.pit_pvp->pv_probes,
+ (dt_idhash_f *)dt_probe_iter, &pit)) != 0)
+ return (rv);
+ }
+
+ if (pdp != NULL)
+ cmd = DTRACEIOC_PROBEMATCH;
+ else
+ cmd = DTRACEIOC_PROBES;
+
+ for (;;) {
+ if (pdp != NULL)
+ bcopy(pdp, &pd, sizeof (pd));
+
+ pd.dtpd_id = id;
+
+ if (dt_ioctl(dtp, cmd, &pd) != 0)
+ break;
+ else if ((rv = func(dtp, &pd, arg)) != 0)
+ return (rv);
+
+ pit.pit_matches++;
+ id = pd.dtpd_id + 1;
+ }
+
+ switch (errno) {
+ case ESRCH:
+ case EBADF:
+ return (pit.pit_matches ? 0 : dt_set_errno(dtp, EDT_NOPROBE));
+ case EINVAL:
+ return (dt_set_errno(dtp, EDT_BADPGLOB));
+ default:
+ return (dt_set_errno(dtp, errno));
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h
new file mode 100644
index 0000000..af4ec33
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h
@@ -0,0 +1,118 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PROVIDER_H
+#define _DT_PROVIDER_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dt_impl.h>
+#include <dt_ident.h>
+#include <dt_list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_provider {
+ dt_list_t pv_list; /* list forward/back pointers */
+ struct dt_provider *pv_next; /* pointer to next provider in hash */
+ dtrace_providerdesc_t pv_desc; /* provider name and attributes */
+ dt_idhash_t *pv_probes; /* probe defs (if user-declared) */
+ dt_node_t *pv_nodes; /* parse node allocation list */
+ ulong_t *pv_xrefs; /* translator reference bitmap */
+ ulong_t pv_xrmax; /* number of valid bits in pv_xrefs */
+ ulong_t pv_gen; /* generation # that created me */
+ dtrace_hdl_t *pv_hdl; /* pointer to containing dtrace_hdl */
+ uint_t pv_flags; /* flags (see below) */
+} dt_provider_t;
+
+#define DT_PROVIDER_INTF 0x1 /* provider interface declaration */
+#define DT_PROVIDER_IMPL 0x2 /* provider implementation is loaded */
+
+typedef struct dt_probe_iter {
+ dtrace_probedesc_t pit_desc; /* description storage */
+ dtrace_hdl_t *pit_hdl; /* libdtrace handle */
+ dt_provider_t *pit_pvp; /* current provider */
+ const char *pit_pat; /* caller's name pattern (or NULL) */
+ dtrace_probe_f *pit_func; /* caller's function */
+ void *pit_arg; /* caller's argument */
+ uint_t pit_matches; /* number of matches */
+} dt_probe_iter_t;
+
+typedef struct dt_probe_instance {
+ char pi_fname[DTRACE_FUNCNAMELEN]; /* function name */
+ char pi_rname[DTRACE_FUNCNAMELEN + 20]; /* mangled relocation name */
+ uint32_t *pi_offs; /* offsets into the function */
+ uint32_t *pi_enoffs; /* is-enabled offsets */
+ uint_t pi_noffs; /* number of offsets */
+ uint_t pi_maxoffs; /* size of pi_offs allocation */
+ uint_t pi_nenoffs; /* number of is-enabled offsets */
+ uint_t pi_maxenoffs; /* size of pi_enoffs allocation */
+ struct dt_probe_instance *pi_next; /* next instance in the list */
+} dt_probe_instance_t;
+
+typedef struct dt_probe {
+ dt_provider_t *pr_pvp; /* pointer to containing provider */
+ dt_ident_t *pr_ident; /* pointer to probe identifier */
+ const char *pr_name; /* pointer to name component */
+ dt_node_t *pr_nargs; /* native argument list */
+ dt_node_t **pr_nargv; /* native argument vector */
+ uint_t pr_nargc; /* native argument count */
+ dt_node_t *pr_xargs; /* translated argument list */
+ dt_node_t **pr_xargv; /* translated argument vector */
+ uint_t pr_xargc; /* translated argument count */
+ uint8_t *pr_mapping; /* translated argument mapping */
+ dt_probe_instance_t *pr_inst; /* list of functions and offsets */
+ dtrace_typeinfo_t *pr_argv; /* output argument types */
+ int pr_argc; /* output argument count */
+} dt_probe_t;
+
+extern dt_provider_t *dt_provider_lookup(dtrace_hdl_t *, const char *);
+extern dt_provider_t *dt_provider_create(dtrace_hdl_t *, const char *);
+extern void dt_provider_destroy(dtrace_hdl_t *, dt_provider_t *);
+extern int dt_provider_xref(dtrace_hdl_t *, dt_provider_t *, id_t);
+
+extern dt_probe_t *dt_probe_create(dtrace_hdl_t *, dt_ident_t *, int,
+ dt_node_t *, uint_t, dt_node_t *, uint_t);
+
+extern dt_probe_t *dt_probe_info(dtrace_hdl_t *,
+ const dtrace_probedesc_t *, dtrace_probeinfo_t *);
+
+extern dt_probe_t *dt_probe_lookup(dt_provider_t *, const char *);
+extern void dt_probe_declare(dt_provider_t *, dt_probe_t *);
+extern void dt_probe_destroy(dt_probe_t *);
+
+extern int dt_probe_define(dt_provider_t *, dt_probe_t *,
+ const char *, const char *, uint32_t, int);
+
+extern dt_node_t *dt_probe_tag(dt_probe_t *, uint_t, dt_node_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_PROVIDER_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
new file mode 100644
index 0000000..05cc15c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
@@ -0,0 +1,107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/bitmap.h>
+#include <assert.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include <dt_regset.h>
+
+dt_regset_t *
+dt_regset_create(ulong_t size)
+{
+ ulong_t n = BT_BITOUL(size + 1); /* + 1 for %r0 */
+ dt_regset_t *drp = malloc(sizeof (dt_regset_t));
+
+ if (drp == NULL)
+ return (NULL);
+
+ drp->dr_bitmap = malloc(sizeof (ulong_t) * n);
+ drp->dr_size = size + 1;
+
+ if (drp->dr_bitmap == NULL) {
+ dt_regset_destroy(drp);
+ return (NULL);
+ }
+
+ bzero(drp->dr_bitmap, sizeof (ulong_t) * n);
+ return (drp);
+}
+
+void
+dt_regset_destroy(dt_regset_t *drp)
+{
+ free(drp->dr_bitmap);
+ free(drp);
+}
+
+void
+dt_regset_reset(dt_regset_t *drp)
+{
+ bzero(drp->dr_bitmap, sizeof (ulong_t) * BT_BITOUL(drp->dr_size));
+}
+
+int
+dt_regset_alloc(dt_regset_t *drp)
+{
+ ulong_t nbits = drp->dr_size - 1;
+ ulong_t maxw = nbits >> BT_ULSHIFT;
+ ulong_t wx;
+
+ for (wx = 0; wx <= maxw; wx++) {
+ if (drp->dr_bitmap[wx] != ~0UL)
+ break;
+ }
+
+ if (wx <= maxw) {
+ ulong_t maxb = (wx == maxw) ? nbits & BT_ULMASK : BT_NBIPUL - 1;
+ ulong_t word = drp->dr_bitmap[wx];
+ ulong_t bit, bx;
+ int reg;
+
+ for (bit = 1, bx = 0; bx <= maxb; bx++, bit <<= 1) {
+ if ((word & bit) == 0) {
+ reg = (int)((wx << BT_ULSHIFT) | bx);
+ BT_SET(drp->dr_bitmap, reg);
+ return (reg);
+ }
+ }
+ }
+
+ return (-1); /* no available registers */
+}
+
+void
+dt_regset_free(dt_regset_t *drp, int reg)
+{
+ assert(reg > 0 && reg < drp->dr_size);
+ assert(BT_TEST(drp->dr_bitmap, reg) != 0);
+ BT_CLEAR(drp->dr_bitmap, reg);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
new file mode 100644
index 0000000..25e64d0
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_REGSET_H
+#define _DT_REGSET_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_regset {
+ ulong_t dr_size; /* number of registers in set */
+ ulong_t *dr_bitmap; /* bitmap of active registers */
+} dt_regset_t;
+
+extern dt_regset_t *dt_regset_create(ulong_t);
+extern void dt_regset_destroy(dt_regset_t *);
+extern void dt_regset_reset(dt_regset_t *);
+extern int dt_regset_alloc(dt_regset_t *);
+extern void dt_regset_free(dt_regset_t *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_REGSET_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c
new file mode 100644
index 0000000..782d66c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c
@@ -0,0 +1,309 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <strings.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <dt_string.h>
+
+/*
+ * Transform string s inline, converting each embedded C escape sequence string
+ * to the corresponding character. For example, the substring "\n" is replaced
+ * by an inline '\n' character. The length of the resulting string is returned.
+ */
+size_t
+stresc2chr(char *s)
+{
+ char *p, *q, c;
+ int esc = 0;
+ int x;
+
+ for (p = q = s; (c = *p) != '\0'; p++) {
+ if (esc) {
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ c -= '0';
+ p++;
+
+ if (*p >= '0' && *p <= '7') {
+ c = c * 8 + *p++ - '0';
+
+ if (*p >= '0' && *p <= '7')
+ c = c * 8 + *p - '0';
+ else
+ p--;
+ } else
+ p--;
+
+ *q++ = c;
+ break;
+
+ case 'a':
+ *q++ = '\a';
+ break;
+ case 'b':
+ *q++ = '\b';
+ break;
+ case 'f':
+ *q++ = '\f';
+ break;
+ case 'n':
+ *q++ = '\n';
+ break;
+ case 'r':
+ *q++ = '\r';
+ break;
+ case 't':
+ *q++ = '\t';
+ break;
+ case 'v':
+ *q++ = '\v';
+ break;
+
+ case 'x':
+ for (x = 0; (c = *++p) != '\0'; ) {
+ if (c >= '0' && c <= '9')
+ x = x * 16 + c - '0';
+ else if (c >= 'a' && c <= 'f')
+ x = x * 16 + c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ x = x * 16 + c - 'A' + 10;
+ else
+ break;
+ }
+ *q++ = (char)x;
+ p--;
+ break;
+
+ case '"':
+ case '\\':
+ *q++ = c;
+ break;
+ default:
+ *q++ = '\\';
+ *q++ = c;
+ }
+
+ esc = 0;
+
+ } else {
+ if ((esc = c == '\\') == 0)
+ *q++ = c;
+ }
+ }
+
+ *q = '\0';
+ return ((size_t)(q - s));
+}
+
+/*
+ * Create a copy of string s in which certain unprintable or special characters
+ * have been converted to the string representation of their C escape sequence.
+ * For example, the newline character is expanded to the string "\n".
+ */
+char *
+strchr2esc(const char *s, size_t n)
+{
+ const char *p;
+ char *q, *s2, c;
+ size_t addl = 0;
+
+ for (p = s; p < s + n; p++) {
+ switch (c = *p) {
+ case '\0':
+ case '\a':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ case '"':
+ case '\\':
+ addl++; /* 1 add'l char needed to follow \ */
+ break;
+ case ' ':
+ break;
+ default:
+ if (c < '!' || c > '~')
+ addl += 3; /* 3 add'l chars following \ */
+ }
+ }
+
+ if ((s2 = malloc(n + addl + 1)) == NULL)
+ return (NULL);
+
+ for (p = s, q = s2; p < s + n; p++) {
+ switch (c = *p) {
+ case '\0':
+ *q++ = '\\';
+ *q++ = '0';
+ break;
+ case '\a':
+ *q++ = '\\';
+ *q++ = 'a';
+ break;
+ case '\b':
+ *q++ = '\\';
+ *q++ = 'b';
+ break;
+ case '\f':
+ *q++ = '\\';
+ *q++ = 'f';
+ break;
+ case '\n':
+ *q++ = '\\';
+ *q++ = 'n';
+ break;
+ case '\r':
+ *q++ = '\\';
+ *q++ = 'r';
+ break;
+ case '\t':
+ *q++ = '\\';
+ *q++ = 't';
+ break;
+ case '\v':
+ *q++ = '\\';
+ *q++ = 'v';
+ break;
+ case '"':
+ *q++ = '\\';
+ *q++ = '"';
+ break;
+ case '\\':
+ *q++ = '\\';
+ *q++ = '\\';
+ break;
+ case ' ':
+ *q++ = c;
+ break;
+ default:
+ if (c < '!' || c > '~') {
+ *q++ = '\\';
+ *q++ = ((c >> 6) & 3) + '0';
+ *q++ = ((c >> 3) & 7) + '0';
+ *q++ = (c & 7) + '0';
+ } else
+ *q++ = c;
+ }
+
+ if (c == '\0')
+ break; /* don't continue past \0 even if p < s + n */
+ }
+
+ *q = '\0';
+ return (s2);
+}
+
+/*
+ * Return the basename (name after final /) of the given string. We use
+ * strbasename rather than basename to avoid conflicting with libgen.h's
+ * non-const function prototype.
+ */
+const char *
+strbasename(const char *s)
+{
+ const char *p = strrchr(s, '/');
+
+ if (p == NULL)
+ return (s);
+
+ return (++p);
+}
+
+/*
+ * This function tests a string against the regular expression used for idents
+ * and integers in the D lexer, and should match the superset of RGX_IDENT and
+ * RGX_INT in dt_lex.l. If an invalid character is found, the function returns
+ * a pointer to it. Otherwise NULL is returned for a valid string.
+ */
+const char *
+strbadidnum(const char *s)
+{
+ char *p;
+ int c;
+
+ if (*s == '\0')
+ return (s);
+
+ errno = 0;
+ (void) strtoull(s, &p, 0);
+
+ if (errno == 0 && *p == '\0')
+ return (NULL); /* matches RGX_INT */
+
+ while ((c = *s++) != '\0') {
+ if (isalnum(c) == 0 && c != '_' && c != '`')
+ return (s - 1);
+ }
+
+ return (NULL); /* matches RGX_IDENT */
+}
+
+/*
+ * Determine whether the string contains a glob matching pattern or is just a
+ * simple string. See gmatch(3GEN) and sh(1) for the glob syntax definition.
+ */
+int
+strisglob(const char *s)
+{
+ char c;
+
+ while ((c = *s++) != '\0') {
+ if (c == '[' || c == '?' || c == '*' || c == '\\')
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Hyphenate a string in-place by converting any instances of "__" to "-",
+ * which we use for probe names to improve readability, and return the string.
+ */
+char *
+strhyphenate(char *s)
+{
+ char *p, *q;
+
+ for (p = s, q = p + strlen(p); p < q; p++) {
+ if (p[0] == '_' && p[1] == '_') {
+ p[0] = '-';
+ bcopy(p + 2, p + 1, (size_t)(q - p) - 1);
+ }
+ }
+
+ return (s);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.h
new file mode 100644
index 0000000..6ee626d
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _DT_STRING_H
+#define _DT_STRING_H
+
+
+#include <sys/types.h>
+#include <strings.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern size_t stresc2chr(char *);
+extern char *strchr2esc(const char *, size_t);
+extern const char *strbasename(const char *);
+extern const char *strbadidnum(const char *);
+extern int strisglob(const char *);
+extern char *strhyphenate(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_STRING_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c
new file mode 100644
index 0000000..cf6bc48
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c
@@ -0,0 +1,293 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <dt_strtab.h>
+#include <dt_impl.h>
+
+static int
+dt_strtab_grow(dt_strtab_t *sp)
+{
+ char *ptr, **bufs;
+
+ if ((ptr = malloc(sp->str_bufsz)) == NULL)
+ return (-1);
+
+ bufs = realloc(sp->str_bufs, (sp->str_nbufs + 1) * sizeof (char *));
+
+ if (bufs == NULL) {
+ free(ptr);
+ return (-1);
+ }
+
+ sp->str_nbufs++;
+ sp->str_bufs = bufs;
+ sp->str_ptr = ptr;
+ sp->str_bufs[sp->str_nbufs - 1] = sp->str_ptr;
+
+ return (0);
+}
+
+dt_strtab_t *
+dt_strtab_create(size_t bufsz)
+{
+ dt_strtab_t *sp = malloc(sizeof (dt_strtab_t));
+ uint_t nbuckets = _dtrace_strbuckets;
+
+ assert(bufsz != 0);
+
+ if (sp == NULL)
+ return (NULL);
+
+ bzero(sp, sizeof (dt_strtab_t));
+ sp->str_hash = malloc(nbuckets * sizeof (dt_strhash_t *));
+
+ if (sp->str_hash == NULL)
+ goto err;
+
+ bzero(sp->str_hash, nbuckets * sizeof (dt_strhash_t *));
+ sp->str_hashsz = nbuckets;
+ sp->str_bufs = NULL;
+ sp->str_ptr = NULL;
+ sp->str_nbufs = 0;
+ sp->str_bufsz = bufsz;
+ sp->str_nstrs = 1;
+ sp->str_size = 1;
+
+ if (dt_strtab_grow(sp) == -1)
+ goto err;
+
+ *sp->str_ptr++ = '\0';
+ return (sp);
+
+err:
+ dt_strtab_destroy(sp);
+ return (NULL);
+}
+
+void
+dt_strtab_destroy(dt_strtab_t *sp)
+{
+ dt_strhash_t *hp, *hq;
+ ulong_t i;
+
+ for (i = 0; i < sp->str_hashsz; i++) {
+ for (hp = sp->str_hash[i]; hp != NULL; hp = hq) {
+ hq = hp->str_next;
+ free(hp);
+ }
+ }
+
+ for (i = 0; i < sp->str_nbufs; i++)
+ free(sp->str_bufs[i]);
+
+ if (sp->str_hash != NULL)
+ free(sp->str_hash);
+ if (sp->str_bufs != NULL)
+ free(sp->str_bufs);
+
+ free(sp);
+}
+
+ulong_t
+dt_strtab_hash(const char *key, size_t *len)
+{
+ ulong_t g, h = 0;
+ const char *p;
+ size_t n = 0;
+
+ for (p = key; *p != '\0'; p++, n++) {
+ h = (h << 4) + *p;
+
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ if (len != NULL)
+ *len = n;
+
+ return (h);
+}
+
+static int
+dt_strtab_compare(dt_strtab_t *sp, dt_strhash_t *hp,
+ const char *str, size_t len)
+{
+ ulong_t b = hp->str_buf;
+ const char *buf = hp->str_data;
+ size_t resid, n;
+ int rv;
+
+ while (len != 0) {
+ if (buf == sp->str_bufs[b] + sp->str_bufsz)
+ buf = sp->str_bufs[++b];
+
+ resid = sp->str_bufs[b] + sp->str_bufsz - buf;
+ n = MIN(resid, len);
+
+ if ((rv = strncmp(buf, str, n)) != 0)
+ return (rv);
+
+ buf += n;
+ str += n;
+ len -= n;
+ }
+
+ return (0);
+}
+
+static int
+dt_strtab_copyin(dt_strtab_t *sp, const char *str, size_t len)
+{
+ char *old_p = sp->str_ptr;
+ ulong_t old_n = sp->str_nbufs;
+
+ ulong_t b = sp->str_nbufs - 1;
+ size_t resid, n;
+
+ while (len != 0) {
+ if (sp->str_ptr == sp->str_bufs[b] + sp->str_bufsz) {
+ if (dt_strtab_grow(sp) == -1)
+ goto err;
+ b++;
+ }
+
+ resid = sp->str_bufs[b] + sp->str_bufsz - sp->str_ptr;
+ n = MIN(resid, len);
+ bcopy(str, sp->str_ptr, n);
+
+ sp->str_ptr += n;
+ str += n;
+ len -= n;
+ }
+
+ return (0);
+
+err:
+ while (sp->str_nbufs != old_n)
+ free(sp->str_bufs[--sp->str_nbufs]);
+
+ sp->str_ptr = old_p;
+ return (-1);
+}
+
+ssize_t
+dt_strtab_index(dt_strtab_t *sp, const char *str)
+{
+ dt_strhash_t *hp;
+ size_t len;
+ ulong_t h;
+
+ if (str == NULL || str[0] == '\0')
+ return (0); /* we keep a \0 at offset 0 to simplify things */
+
+ h = dt_strtab_hash(str, &len) % sp->str_hashsz;
+
+ for (hp = sp->str_hash[h]; hp != NULL; hp = hp->str_next) {
+ if (dt_strtab_compare(sp, hp, str, len + 1) == 0)
+ return (hp->str_off);
+ }
+
+ return (-1);
+}
+
+ssize_t
+dt_strtab_insert(dt_strtab_t *sp, const char *str)
+{
+ dt_strhash_t *hp;
+ size_t len;
+ ssize_t off;
+ ulong_t h;
+
+ if ((off = dt_strtab_index(sp, str)) != -1)
+ return (off);
+
+ h = dt_strtab_hash(str, &len) % sp->str_hashsz;
+
+ /*
+ * Create a new hash bucket, initialize it, and insert it at the front
+ * of the hash chain for the appropriate bucket.
+ */
+ if ((hp = malloc(sizeof (dt_strhash_t))) == NULL)
+ return (-1L);
+
+ hp->str_data = sp->str_ptr;
+ hp->str_buf = sp->str_nbufs - 1;
+ hp->str_off = sp->str_size;
+ hp->str_len = len;
+ hp->str_next = sp->str_hash[h];
+
+ /*
+ * Now copy the string data into our buffer list, and then update
+ * the global counts of strings and bytes. Return str's byte offset.
+ */
+ if (dt_strtab_copyin(sp, str, len + 1) == -1)
+ return (-1L);
+
+ sp->str_nstrs++;
+ sp->str_size += len + 1;
+ sp->str_hash[h] = hp;
+
+ return (hp->str_off);
+}
+
+size_t
+dt_strtab_size(const dt_strtab_t *sp)
+{
+ return (sp->str_size);
+}
+
+ssize_t
+dt_strtab_write(const dt_strtab_t *sp, dt_strtab_write_f *func, void *private)
+{
+ ssize_t res, total = 0;
+ ulong_t i;
+ size_t n;
+
+ for (i = 0; i < sp->str_nbufs; i++, total += res) {
+ if (i == sp->str_nbufs - 1)
+ n = sp->str_ptr - sp->str_bufs[i];
+ else
+ n = sp->str_bufsz;
+
+ if ((res = func(sp->str_bufs[i], n, total, private)) <= 0)
+ break;
+ }
+
+ if (total == 0 && sp->str_size != 0)
+ return (-1);
+
+ return (total);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h
new file mode 100644
index 0000000..551dabb
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_STRTAB_H
+#define _DT_STRTAB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dt_strhash {
+ const char *str_data; /* pointer to actual string data */
+ ulong_t str_buf; /* index of string data buffer */
+ size_t str_off; /* offset in bytes of this string */
+ size_t str_len; /* length in bytes of this string */
+ struct dt_strhash *str_next; /* next string in hash chain */
+} dt_strhash_t;
+
+typedef struct dt_strtab {
+ dt_strhash_t **str_hash; /* array of hash buckets */
+ ulong_t str_hashsz; /* size of hash bucket array */
+ char **str_bufs; /* array of buffer pointers */
+ char *str_ptr; /* pointer to current buffer location */
+ ulong_t str_nbufs; /* size of buffer pointer array */
+ size_t str_bufsz; /* size of individual buffer */
+ ulong_t str_nstrs; /* total number of strings in strtab */
+ size_t str_size; /* total size of strings in bytes */
+} dt_strtab_t;
+
+typedef ssize_t dt_strtab_write_f(const char *, size_t, size_t, void *);
+
+extern dt_strtab_t *dt_strtab_create(size_t);
+extern void dt_strtab_destroy(dt_strtab_t *);
+extern ssize_t dt_strtab_index(dt_strtab_t *, const char *);
+extern ssize_t dt_strtab_insert(dt_strtab_t *, const char *);
+extern size_t dt_strtab_size(const dt_strtab_t *);
+extern ssize_t dt_strtab_write(const dt_strtab_t *,
+ dt_strtab_write_f *, void *);
+extern ulong_t dt_strtab_hash(const char *, size_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_STRTAB_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
new file mode 100644
index 0000000..df34eec
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
@@ -0,0 +1,993 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#if defined(sun)
+#include <sys/sysmacros.h>
+#endif
+#include <sys/isa_defs.h>
+
+#include <strings.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#if defined(sun)
+#include <alloca.h>
+#else
+#include <sys/sysctl.h>
+#include <libproc_compat.h>
+#endif
+#include <assert.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <dt_impl.h>
+
+static const struct {
+ size_t dtps_offset;
+ size_t dtps_len;
+} dtrace_probespecs[] = {
+ { offsetof(dtrace_probedesc_t, dtpd_provider), DTRACE_PROVNAMELEN },
+ { offsetof(dtrace_probedesc_t, dtpd_mod), DTRACE_MODNAMELEN },
+ { offsetof(dtrace_probedesc_t, dtpd_func), DTRACE_FUNCNAMELEN },
+ { offsetof(dtrace_probedesc_t, dtpd_name), DTRACE_NAMELEN }
+};
+
+int
+dtrace_xstr2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec,
+ const char *s, int argc, char *const argv[], dtrace_probedesc_t *pdp)
+{
+ size_t off, len, vlen, wlen;
+ const char *p, *q, *v, *w;
+
+ char buf[32]; /* for id_t as %d (see below) */
+
+ if (spec < DTRACE_PROBESPEC_NONE || spec > DTRACE_PROBESPEC_NAME)
+ return (dt_set_errno(dtp, EINVAL));
+
+ bzero(pdp, sizeof (dtrace_probedesc_t));
+ p = s + strlen(s) - 1;
+
+ do {
+ for (len = 0; p >= s && *p != ':'; len++)
+ p--; /* move backward until we find a delimiter */
+
+ q = p + 1;
+ vlen = 0;
+ w = NULL;
+ wlen = 0;
+
+ if ((v = strchr(q, '$')) != NULL && v < q + len) {
+ /*
+ * Set vlen to the length of the variable name and then
+ * reset len to the length of the text prior to '$'. If
+ * the name begins with a digit, interpret it using the
+ * the argv[] array. Otherwise we look in dt_macros.
+ * For the moment, all dt_macros variables are of type
+ * id_t (see dtrace_update() for more details on that).
+ */
+ vlen = (size_t)(q + len - v);
+ len = (size_t)(v - q);
+
+ /*
+ * If the variable string begins with $$, skip past the
+ * leading dollar sign since $ and $$ are equivalent
+ * macro reference operators in a probe description.
+ */
+ if (vlen > 2 && v[1] == '$') {
+ vlen--;
+ v++;
+ }
+
+ if (isdigit(v[1])) {
+ long i;
+
+ errno = 0;
+ i = strtol(v + 1, (char **)&w, 10);
+
+ wlen = vlen - (w - v);
+
+ if (i < 0 || i >= argc || errno != 0)
+ return (dt_set_errno(dtp, EDT_BADSPCV));
+
+ v = argv[i];
+ vlen = strlen(v);
+
+ if (yypcb != NULL && yypcb->pcb_sargv == argv)
+ yypcb->pcb_sflagv[i] |= DT_IDFLG_REF;
+
+ } else if (vlen > 1) {
+ char *vstr = alloca(vlen);
+ dt_ident_t *idp;
+
+ (void) strncpy(vstr, v + 1, vlen - 1);
+ vstr[vlen - 1] = '\0';
+ idp = dt_idhash_lookup(dtp->dt_macros, vstr);
+
+ if (idp == NULL)
+ return (dt_set_errno(dtp, EDT_BADSPCV));
+
+ v = buf;
+ vlen = snprintf(buf, 32, "%d", idp->di_id);
+
+ } else
+ return (dt_set_errno(dtp, EDT_BADSPCV));
+ }
+
+ if (spec == DTRACE_PROBESPEC_NONE)
+ return (dt_set_errno(dtp, EDT_BADSPEC));
+
+ if (len + vlen >= dtrace_probespecs[spec].dtps_len)
+ return (dt_set_errno(dtp, ENAMETOOLONG));
+
+ off = dtrace_probespecs[spec--].dtps_offset;
+ bcopy(q, (char *)pdp + off, len);
+ bcopy(v, (char *)pdp + off + len, vlen);
+ bcopy(w, (char *)pdp + off + len + vlen, wlen);
+ } while (--p >= s);
+
+ pdp->dtpd_id = DTRACE_IDNONE;
+ return (0);
+}
+
+int
+dtrace_str2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec,
+ const char *s, dtrace_probedesc_t *pdp)
+{
+ return (dtrace_xstr2desc(dtp, spec, s, 0, NULL, pdp));
+}
+
+int
+dtrace_id2desc(dtrace_hdl_t *dtp, dtrace_id_t id, dtrace_probedesc_t *pdp)
+{
+ bzero(pdp, sizeof (dtrace_probedesc_t));
+ pdp->dtpd_id = id;
+
+ if (dt_ioctl(dtp, DTRACEIOC_PROBES, pdp) == -1 ||
+ pdp->dtpd_id != id)
+ return (dt_set_errno(dtp, EDT_BADID));
+
+ return (0);
+}
+
+char *
+dtrace_desc2str(const dtrace_probedesc_t *pdp, char *buf, size_t len)
+{
+ if (pdp->dtpd_id == 0) {
+ (void) snprintf(buf, len, "%s:%s:%s:%s", pdp->dtpd_provider,
+ pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
+ } else
+ (void) snprintf(buf, len, "%u", pdp->dtpd_id);
+
+ return (buf);
+}
+
+char *
+dtrace_attr2str(dtrace_attribute_t attr, char *buf, size_t len)
+{
+ const char *name = dtrace_stability_name(attr.dtat_name);
+ const char *data = dtrace_stability_name(attr.dtat_data);
+ const char *class = dtrace_class_name(attr.dtat_class);
+
+ if (name == NULL || data == NULL || class == NULL)
+ return (NULL); /* one or more invalid attributes */
+
+ (void) snprintf(buf, len, "%s/%s/%s", name, data, class);
+ return (buf);
+}
+
+static char *
+dt_getstrattr(char *p, char **qp)
+{
+ char *q;
+
+ if (*p == '\0')
+ return (NULL);
+
+ if ((q = strchr(p, '/')) == NULL)
+ q = p + strlen(p);
+ else
+ *q++ = '\0';
+
+ *qp = q;
+ return (p);
+}
+
+int
+dtrace_str2attr(const char *str, dtrace_attribute_t *attr)
+{
+ dtrace_stability_t s;
+ dtrace_class_t c;
+ char *p, *q;
+
+ if (str == NULL || attr == NULL)
+ return (-1); /* invalid function arguments */
+
+ *attr = _dtrace_maxattr;
+ p = alloca(strlen(str) + 1);
+ (void) strcpy(p, str);
+
+ if ((p = dt_getstrattr(p, &q)) == NULL)
+ return (0);
+
+ for (s = 0; s <= DTRACE_STABILITY_MAX; s++) {
+ if (strcasecmp(p, dtrace_stability_name(s)) == 0) {
+ attr->dtat_name = s;
+ break;
+ }
+ }
+
+ if (s > DTRACE_STABILITY_MAX)
+ return (-1);
+
+ if ((p = dt_getstrattr(q, &q)) == NULL)
+ return (0);
+
+ for (s = 0; s <= DTRACE_STABILITY_MAX; s++) {
+ if (strcasecmp(p, dtrace_stability_name(s)) == 0) {
+ attr->dtat_data = s;
+ break;
+ }
+ }
+
+ if (s > DTRACE_STABILITY_MAX)
+ return (-1);
+
+ if ((p = dt_getstrattr(q, &q)) == NULL)
+ return (0);
+
+ for (c = 0; c <= DTRACE_CLASS_MAX; c++) {
+ if (strcasecmp(p, dtrace_class_name(c)) == 0) {
+ attr->dtat_class = c;
+ break;
+ }
+ }
+
+ if (c > DTRACE_CLASS_MAX || (p = dt_getstrattr(q, &q)) != NULL)
+ return (-1);
+
+ return (0);
+}
+
+const char *
+dtrace_stability_name(dtrace_stability_t s)
+{
+ switch (s) {
+ case DTRACE_STABILITY_INTERNAL: return ("Internal");
+ case DTRACE_STABILITY_PRIVATE: return ("Private");
+ case DTRACE_STABILITY_OBSOLETE: return ("Obsolete");
+ case DTRACE_STABILITY_EXTERNAL: return ("External");
+ case DTRACE_STABILITY_UNSTABLE: return ("Unstable");
+ case DTRACE_STABILITY_EVOLVING: return ("Evolving");
+ case DTRACE_STABILITY_STABLE: return ("Stable");
+ case DTRACE_STABILITY_STANDARD: return ("Standard");
+ default: return (NULL);
+ }
+}
+
+const char *
+dtrace_class_name(dtrace_class_t c)
+{
+ switch (c) {
+ case DTRACE_CLASS_UNKNOWN: return ("Unknown");
+ case DTRACE_CLASS_CPU: return ("CPU");
+ case DTRACE_CLASS_PLATFORM: return ("Platform");
+ case DTRACE_CLASS_GROUP: return ("Group");
+ case DTRACE_CLASS_ISA: return ("ISA");
+ case DTRACE_CLASS_COMMON: return ("Common");
+ default: return (NULL);
+ }
+}
+
+dtrace_attribute_t
+dt_attr_min(dtrace_attribute_t a1, dtrace_attribute_t a2)
+{
+ dtrace_attribute_t am;
+
+ am.dtat_name = MIN(a1.dtat_name, a2.dtat_name);
+ am.dtat_data = MIN(a1.dtat_data, a2.dtat_data);
+ am.dtat_class = MIN(a1.dtat_class, a2.dtat_class);
+
+ return (am);
+}
+
+dtrace_attribute_t
+dt_attr_max(dtrace_attribute_t a1, dtrace_attribute_t a2)
+{
+ dtrace_attribute_t am;
+
+ am.dtat_name = MAX(a1.dtat_name, a2.dtat_name);
+ am.dtat_data = MAX(a1.dtat_data, a2.dtat_data);
+ am.dtat_class = MAX(a1.dtat_class, a2.dtat_class);
+
+ return (am);
+}
+
+/*
+ * Compare two attributes and return an integer value in the following ranges:
+ *
+ * <0 if any of a1's attributes are less than a2's attributes
+ * =0 if all of a1's attributes are equal to a2's attributes
+ * >0 if all of a1's attributes are greater than or equal to a2's attributes
+ *
+ * To implement this function efficiently, we subtract a2's attributes from
+ * a1's to obtain a negative result if an a1 attribute is less than its a2
+ * counterpart. We then OR the intermediate results together, relying on the
+ * twos-complement property that if any result is negative, the bitwise union
+ * will also be negative since the highest bit will be set in the result.
+ */
+int
+dt_attr_cmp(dtrace_attribute_t a1, dtrace_attribute_t a2)
+{
+ return (((int)a1.dtat_name - a2.dtat_name) |
+ ((int)a1.dtat_data - a2.dtat_data) |
+ ((int)a1.dtat_class - a2.dtat_class));
+}
+
+char *
+dt_attr_str(dtrace_attribute_t a, char *buf, size_t len)
+{
+ static const char stability[] = "ipoxuesS";
+ static const char class[] = "uCpgIc";
+
+ if (a.dtat_name < sizeof (stability) &&
+ a.dtat_data < sizeof (stability) && a.dtat_class < sizeof (class)) {
+ (void) snprintf(buf, len, "[%c/%c/%c]", stability[a.dtat_name],
+ stability[a.dtat_data], class[a.dtat_class]);
+ } else {
+ (void) snprintf(buf, len, "[%u/%u/%u]",
+ a.dtat_name, a.dtat_data, a.dtat_class);
+ }
+
+ return (buf);
+}
+
+char *
+dt_version_num2str(dt_version_t v, char *buf, size_t len)
+{
+ uint_t M = DT_VERSION_MAJOR(v);
+ uint_t m = DT_VERSION_MINOR(v);
+ uint_t u = DT_VERSION_MICRO(v);
+
+ if (u == 0)
+ (void) snprintf(buf, len, "%u.%u", M, m);
+ else
+ (void) snprintf(buf, len, "%u.%u.%u", M, m, u);
+
+ return (buf);
+}
+
+int
+dt_version_str2num(const char *s, dt_version_t *vp)
+{
+ int i = 0, n[3] = { 0, 0, 0 };
+ char c;
+
+ while ((c = *s++) != '\0') {
+ if (isdigit(c))
+ n[i] = n[i] * 10 + c - '0';
+ else if (c != '.' || i++ >= sizeof (n) / sizeof (n[0]) - 1)
+ return (-1);
+ }
+
+ if (n[0] > DT_VERSION_MAJMAX ||
+ n[1] > DT_VERSION_MINMAX ||
+ n[2] > DT_VERSION_MICMAX)
+ return (-1);
+
+ if (vp != NULL)
+ *vp = DT_VERSION_NUMBER(n[0], n[1], n[2]);
+
+ return (0);
+}
+
+int
+dt_version_defined(dt_version_t v)
+{
+ int i;
+
+ for (i = 0; _dtrace_versions[i] != 0; i++) {
+ if (_dtrace_versions[i] == v)
+ return (1);
+ }
+
+ return (0);
+}
+
+char *
+dt_cpp_add_arg(dtrace_hdl_t *dtp, const char *str)
+{
+ char *arg;
+
+ if (dtp->dt_cpp_argc == dtp->dt_cpp_args) {
+ int olds = dtp->dt_cpp_args;
+ int news = olds * 2;
+ char **argv = realloc(dtp->dt_cpp_argv, sizeof (char *) * news);
+
+ if (argv == NULL)
+ return (NULL);
+
+ bzero(&argv[olds], sizeof (char *) * olds);
+ dtp->dt_cpp_argv = argv;
+ dtp->dt_cpp_args = news;
+ }
+
+ if ((arg = strdup(str)) == NULL)
+ return (NULL);
+
+ assert(dtp->dt_cpp_argc < dtp->dt_cpp_args);
+ dtp->dt_cpp_argv[dtp->dt_cpp_argc++] = arg;
+ return (arg);
+}
+
+char *
+dt_cpp_pop_arg(dtrace_hdl_t *dtp)
+{
+ char *arg;
+
+ if (dtp->dt_cpp_argc <= 1)
+ return (NULL); /* dt_cpp_argv[0] cannot be popped */
+
+ arg = dtp->dt_cpp_argv[--dtp->dt_cpp_argc];
+ dtp->dt_cpp_argv[dtp->dt_cpp_argc] = NULL;
+
+ return (arg);
+}
+
+/*PRINTFLIKE1*/
+void
+dt_dprintf(const char *format, ...)
+{
+ if (_dtrace_debug) {
+ va_list alist;
+
+ va_start(alist, format);
+ (void) fputs("libdtrace DEBUG: ", stderr);
+ (void) vfprintf(stderr, format, alist);
+ va_end(alist);
+ }
+}
+
+int
+#if defined(sun)
+dt_ioctl(dtrace_hdl_t *dtp, int val, void *arg)
+#else
+dt_ioctl(dtrace_hdl_t *dtp, u_long val, void *arg)
+#endif
+{
+ const dtrace_vector_t *v = dtp->dt_vector;
+
+#if !defined(sun)
+ /* Avoid sign extension. */
+ val &= 0xffffffff;
+#endif
+
+ if (v != NULL)
+ return (v->dtv_ioctl(dtp->dt_varg, val, arg));
+
+ if (dtp->dt_fd >= 0)
+ return (ioctl(dtp->dt_fd, val, arg));
+
+ errno = EBADF;
+ return (-1);
+}
+
+int
+dt_status(dtrace_hdl_t *dtp, processorid_t cpu)
+{
+ const dtrace_vector_t *v = dtp->dt_vector;
+
+ if (v == NULL) {
+#if defined(sun)
+ return (p_online(cpu, P_STATUS));
+#else
+ int maxid = 0;
+ size_t len = sizeof(maxid);
+ if (sysctlbyname("kern.smp.maxid", &maxid, &len, NULL, 0) != 0)
+ return (cpu == 0 ? 1 : -1);
+ else
+ return (cpu <= maxid ? 1 : -1);
+#endif
+ }
+
+ return (v->dtv_status(dtp->dt_varg, cpu));
+}
+
+long
+dt_sysconf(dtrace_hdl_t *dtp, int name)
+{
+ const dtrace_vector_t *v = dtp->dt_vector;
+
+ if (v == NULL)
+ return (sysconf(name));
+
+ return (v->dtv_sysconf(dtp->dt_varg, name));
+}
+
+/*
+ * Wrapper around write(2) to handle partial writes. For maximum safety of
+ * output files and proper error reporting, we continuing writing in the
+ * face of partial writes until write(2) fails or 'buf' is completely written.
+ * We also record any errno in the specified dtrace_hdl_t as well as 'errno'.
+ */
+ssize_t
+dt_write(dtrace_hdl_t *dtp, int fd, const void *buf, size_t n)
+{
+ ssize_t resid = n;
+ ssize_t len;
+
+ while (resid != 0) {
+ if ((len = write(fd, buf, resid)) <= 0)
+ break;
+
+ resid -= len;
+ buf = (char *)buf + len;
+ }
+
+ if (resid == n && n != 0)
+ return (dt_set_errno(dtp, errno));
+
+ return (n - resid);
+}
+
+/*
+ * This function handles all output from libdtrace, as well as the
+ * dtrace_sprintf() case. If we're here due to dtrace_sprintf(), then
+ * dt_sprintf_buflen will be non-zero; in this case, we sprintf into the
+ * specified buffer and return. Otherwise, if output is buffered (denoted by
+ * a NULL fp), we sprintf the desired output into the buffered buffer
+ * (expanding the buffer if required). If we don't satisfy either of these
+ * conditions (that is, if we are to actually generate output), then we call
+ * fprintf with the specified fp. In this case, we need to deal with one of
+ * the more annoying peculiarities of libc's printf routines: any failed
+ * write persistently sets an error flag inside the FILE causing every
+ * subsequent write to fail, but only the caller that initiated the error gets
+ * the errno. Since libdtrace clients often intercept SIGINT, this case is
+ * particularly frustrating since we don't want the EINTR on one attempt to
+ * write to the output file to preclude later attempts to write. This
+ * function therefore does a clearerr() if any error occurred, and saves the
+ * errno for the caller inside the specified dtrace_hdl_t.
+ */
+/*PRINTFLIKE3*/
+int
+dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...)
+{
+ va_list ap;
+ int n;
+
+#if !defined(sun)
+ /*
+ * On FreeBSD, check if output is currently being re-directed
+ * to another file. If so, output to that file instead of the
+ * one the caller has specified.
+ */
+ if (dtp->dt_freopen_fp != NULL)
+ fp = dtp->dt_freopen_fp;
+#endif
+
+ va_start(ap, format);
+
+ if (dtp->dt_sprintf_buflen != 0) {
+ int len;
+ char *buf;
+
+ assert(dtp->dt_sprintf_buf != NULL);
+
+ buf = &dtp->dt_sprintf_buf[len = strlen(dtp->dt_sprintf_buf)];
+ len = dtp->dt_sprintf_buflen - len;
+ assert(len >= 0);
+
+ if ((n = vsnprintf(buf, len, format, ap)) < 0)
+ n = dt_set_errno(dtp, errno);
+
+ va_end(ap);
+
+ return (n);
+ }
+
+ if (fp == NULL) {
+ int needed, rval;
+ size_t avail;
+
+ /*
+ * It's not legal to use buffered ouput if there is not a
+ * handler for buffered output.
+ */
+ if (dtp->dt_bufhdlr == NULL) {
+ va_end(ap);
+ return (dt_set_errno(dtp, EDT_NOBUFFERED));
+ }
+
+ if (dtp->dt_buffered_buf == NULL) {
+ assert(dtp->dt_buffered_size == 0);
+ dtp->dt_buffered_size = 1;
+ dtp->dt_buffered_buf = malloc(dtp->dt_buffered_size);
+
+ if (dtp->dt_buffered_buf == NULL) {
+ va_end(ap);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dtp->dt_buffered_offs = 0;
+ dtp->dt_buffered_buf[0] = '\0';
+ }
+
+ if ((needed = vsnprintf(NULL, 0, format, ap)) < 0) {
+ rval = dt_set_errno(dtp, errno);
+ va_end(ap);
+ return (rval);
+ }
+
+ if (needed == 0) {
+ va_end(ap);
+ return (0);
+ }
+
+ for (;;) {
+ char *newbuf;
+
+ assert(dtp->dt_buffered_offs < dtp->dt_buffered_size);
+ avail = dtp->dt_buffered_size - dtp->dt_buffered_offs;
+
+ if (needed + 1 < avail)
+ break;
+
+ if ((newbuf = realloc(dtp->dt_buffered_buf,
+ dtp->dt_buffered_size << 1)) == NULL) {
+ va_end(ap);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+
+ dtp->dt_buffered_buf = newbuf;
+ dtp->dt_buffered_size <<= 1;
+ }
+
+ if (vsnprintf(&dtp->dt_buffered_buf[dtp->dt_buffered_offs],
+ avail, format, ap) < 0) {
+ rval = dt_set_errno(dtp, errno);
+ va_end(ap);
+ return (rval);
+ }
+
+ dtp->dt_buffered_offs += needed;
+ assert(dtp->dt_buffered_buf[dtp->dt_buffered_offs] == '\0');
+ va_end(ap);
+ return (0);
+ }
+
+ n = vfprintf(fp, format, ap);
+ fflush(fp);
+ va_end(ap);
+
+ if (n < 0) {
+ clearerr(fp);
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (n);
+}
+
+int
+dt_buffered_flush(dtrace_hdl_t *dtp, dtrace_probedata_t *pdata,
+ const dtrace_recdesc_t *rec, const dtrace_aggdata_t *agg, uint32_t flags)
+{
+ dtrace_bufdata_t data;
+
+ if (dtp->dt_buffered_offs == 0)
+ return (0);
+
+ data.dtbda_handle = dtp;
+ data.dtbda_buffered = dtp->dt_buffered_buf;
+ data.dtbda_probe = pdata;
+ data.dtbda_recdesc = rec;
+ data.dtbda_aggdata = agg;
+ data.dtbda_flags = flags;
+
+ if ((*dtp->dt_bufhdlr)(&data, dtp->dt_bufarg) == DTRACE_HANDLE_ABORT)
+ return (dt_set_errno(dtp, EDT_DIRABORT));
+
+ dtp->dt_buffered_offs = 0;
+ dtp->dt_buffered_buf[0] = '\0';
+
+ return (0);
+}
+
+void
+dt_buffered_destroy(dtrace_hdl_t *dtp)
+{
+ free(dtp->dt_buffered_buf);
+ dtp->dt_buffered_buf = NULL;
+ dtp->dt_buffered_offs = 0;
+ dtp->dt_buffered_size = 0;
+}
+
+void *
+dt_zalloc(dtrace_hdl_t *dtp, size_t size)
+{
+ void *data;
+
+ if (size > 16 * 1024 * 1024) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ if ((data = malloc(size)) == NULL)
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ else
+ bzero(data, size);
+
+ return (data);
+}
+
+void *
+dt_alloc(dtrace_hdl_t *dtp, size_t size)
+{
+ void *data;
+
+ if (size > 16 * 1024 * 1024) {
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+ return (NULL);
+ }
+
+ if ((data = malloc(size)) == NULL)
+ (void) dt_set_errno(dtp, EDT_NOMEM);
+
+ return (data);
+}
+
+void
+dt_free(dtrace_hdl_t *dtp, void *data)
+{
+ assert(dtp != NULL); /* ensure sane use of this interface */
+ free(data);
+}
+
+void
+dt_difo_free(dtrace_hdl_t *dtp, dtrace_difo_t *dp)
+{
+ if (dp == NULL)
+ return; /* simplify caller code */
+
+ dt_free(dtp, dp->dtdo_buf);
+ dt_free(dtp, dp->dtdo_inttab);
+ dt_free(dtp, dp->dtdo_strtab);
+ dt_free(dtp, dp->dtdo_vartab);
+ dt_free(dtp, dp->dtdo_kreltab);
+ dt_free(dtp, dp->dtdo_ureltab);
+ dt_free(dtp, dp->dtdo_xlmtab);
+
+ dt_free(dtp, dp);
+}
+
+/*
+ * dt_gmatch() is similar to gmatch(3GEN) and dtrace(7D) globbing, but also
+ * implements the behavior that an empty pattern matches any string.
+ */
+int
+dt_gmatch(const char *s, const char *p)
+{
+ return (p == NULL || *p == '\0' || gmatch(s, p));
+}
+
+char *
+dt_basename(char *str)
+{
+ char *last = strrchr(str, '/');
+
+ if (last == NULL)
+ return (str);
+
+ return (last + 1);
+}
+
+/*
+ * dt_popc() is a fast implementation of population count. The algorithm is
+ * from "Hacker's Delight" by Henry Warren, Jr with a 64-bit equivalent added.
+ */
+ulong_t
+dt_popc(ulong_t x)
+{
+#if defined(_ILP32)
+ x = x - ((x >> 1) & 0x55555555UL);
+ x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL);
+ x = (x + (x >> 4)) & 0x0F0F0F0FUL;
+ x = x + (x >> 8);
+ x = x + (x >> 16);
+ return (x & 0x3F);
+#elif defined(_LP64)
+ x = x - ((x >> 1) & 0x5555555555555555ULL);
+ x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
+ x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ x = x + (x >> 8);
+ x = x + (x >> 16);
+ x = x + (x >> 32);
+ return (x & 0x7F);
+#else
+/* This should be a #warning but for now ignore error. Err: "need td_popc() implementation" */
+#endif
+}
+
+/*
+ * dt_popcb() is a bitmap-based version of population count that returns the
+ * number of one bits in the specified bitmap 'bp' at bit positions below 'n'.
+ */
+ulong_t
+dt_popcb(const ulong_t *bp, ulong_t n)
+{
+ ulong_t maxb = n & BT_ULMASK;
+ ulong_t maxw = n >> BT_ULSHIFT;
+ ulong_t w, popc = 0;
+
+ if (n == 0)
+ return (0);
+
+ for (w = 0; w < maxw; w++)
+ popc += dt_popc(bp[w]);
+
+ return (popc + dt_popc(bp[maxw] & ((1UL << maxb) - 1)));
+}
+
+#if defined(sun)
+struct _rwlock;
+struct _lwp_mutex;
+
+int
+dt_rw_read_held(pthread_rwlock_t *lock)
+{
+ extern int _rw_read_held(struct _rwlock *);
+ return (_rw_read_held((struct _rwlock *)lock));
+}
+
+int
+dt_rw_write_held(pthread_rwlock_t *lock)
+{
+ extern int _rw_write_held(struct _rwlock *);
+ return (_rw_write_held((struct _rwlock *)lock));
+}
+#endif
+
+int
+dt_mutex_held(pthread_mutex_t *lock)
+{
+#if defined(sun)
+ extern int _mutex_held(struct _lwp_mutex *);
+ return (_mutex_held((struct _lwp_mutex *)lock));
+#else
+ return (1);
+#endif
+}
+
+static int
+dt_string2str(char *s, char *str, int nbytes)
+{
+ int len = strlen(s);
+
+ if (nbytes == 0) {
+ /*
+ * Like snprintf(3C), we don't check the value of str if the
+ * number of bytes is 0.
+ */
+ return (len);
+ }
+
+ if (nbytes <= len) {
+ (void) strncpy(str, s, nbytes - 1);
+ /*
+ * Like snprintf(3C) (and unlike strncpy(3C)), we guarantee
+ * that the string is null-terminated.
+ */
+ str[nbytes - 1] = '\0';
+ } else {
+ (void) strcpy(str, s);
+ }
+
+ return (len);
+}
+
+int
+dtrace_addr2str(dtrace_hdl_t *dtp, uint64_t addr, char *str, int nbytes)
+{
+ dtrace_syminfo_t dts;
+ GElf_Sym sym;
+
+ size_t n = 20; /* for 0x%llx\0 */
+ char *s;
+ int err;
+
+ if ((err = dtrace_lookup_by_addr(dtp, addr, &sym, &dts)) == 0)
+ n += strlen(dts.dts_object) + strlen(dts.dts_name) + 2; /* +` */
+
+ s = alloca(n);
+
+ if (err == 0 && addr != sym.st_value) {
+ (void) snprintf(s, n, "%s`%s+0x%llx", dts.dts_object,
+ dts.dts_name, (u_longlong_t)addr - sym.st_value);
+ } else if (err == 0) {
+ (void) snprintf(s, n, "%s`%s",
+ dts.dts_object, dts.dts_name);
+ } else {
+ /*
+ * We'll repeat the lookup, but this time we'll specify a NULL
+ * GElf_Sym -- indicating that we're only interested in the
+ * containing module.
+ */
+ if (dtrace_lookup_by_addr(dtp, addr, NULL, &dts) == 0) {
+ (void) snprintf(s, n, "%s`0x%llx", dts.dts_object,
+ (u_longlong_t)addr);
+ } else {
+ (void) snprintf(s, n, "0x%llx", (u_longlong_t)addr);
+ }
+ }
+
+ return (dt_string2str(s, str, nbytes));
+}
+
+int
+dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid,
+ uint64_t addr, char *str, int nbytes)
+{
+ char name[PATH_MAX], objname[PATH_MAX], c[PATH_MAX * 2];
+ struct ps_prochandle *P = NULL;
+ GElf_Sym sym;
+ char *obj;
+
+ if (pid != 0)
+ P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE, 0);
+
+ if (P == NULL) {
+ (void) snprintf(c, sizeof (c), "0x%jx", (uintmax_t)addr);
+ return (dt_string2str(c, str, nbytes));
+ }
+
+ dt_proc_lock(dtp, P);
+
+ if (Plookup_by_addr(P, addr, name, sizeof (name), &sym) == 0) {
+ (void) Pobjname(P, addr, objname, sizeof (objname));
+
+ obj = dt_basename(objname);
+
+ if (addr > sym.st_value) {
+ (void) snprintf(c, sizeof (c), "%s`%s+0x%llx", obj,
+ name, (u_longlong_t)(addr - sym.st_value));
+ } else {
+ (void) snprintf(c, sizeof (c), "%s`%s", obj, name);
+ }
+ } else if (Pobjname(P, addr, objname, sizeof (objname)) != 0) {
+ (void) snprintf(c, sizeof (c), "%s`0x%jx",
+ dt_basename(objname), (uintmax_t)addr);
+ } else {
+ (void) snprintf(c, sizeof (c), "0x%jx", (uintmax_t)addr);
+ }
+
+ dt_proc_unlock(dtp, P);
+ dt_proc_release(dtp, P);
+
+ return (dt_string2str(c, str, nbytes));
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_work.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_work.c
new file mode 100644
index 0000000..68e64bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_work.c
@@ -0,0 +1,319 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <dt_impl.h>
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+
+static const struct {
+ int dtslt_option;
+ size_t dtslt_offs;
+} _dtrace_sleeptab[] = {
+ { DTRACEOPT_STATUSRATE, offsetof(dtrace_hdl_t, dt_laststatus) },
+ { DTRACEOPT_AGGRATE, offsetof(dtrace_hdl_t, dt_lastagg) },
+ { DTRACEOPT_SWITCHRATE, offsetof(dtrace_hdl_t, dt_lastswitch) },
+ { DTRACEOPT_MAX, 0 }
+};
+
+void
+dtrace_sleep(dtrace_hdl_t *dtp)
+{
+ dt_proc_hash_t *dph = dtp->dt_procs;
+ dtrace_optval_t policy = dtp->dt_options[DTRACEOPT_BUFPOLICY];
+ dt_proc_notify_t *dprn;
+
+ hrtime_t earliest = INT64_MAX;
+ struct timespec tv;
+ hrtime_t now;
+ int i;
+
+ for (i = 0; _dtrace_sleeptab[i].dtslt_option < DTRACEOPT_MAX; i++) {
+ uintptr_t a = (uintptr_t)dtp + _dtrace_sleeptab[i].dtslt_offs;
+ int opt = _dtrace_sleeptab[i].dtslt_option;
+ dtrace_optval_t interval = dtp->dt_options[opt];
+
+ /*
+ * If the buffering policy is set to anything other than
+ * "switch", we ignore the aggrate and switchrate -- they're
+ * meaningless.
+ */
+ if (policy != DTRACEOPT_BUFPOLICY_SWITCH &&
+ _dtrace_sleeptab[i].dtslt_option != DTRACEOPT_STATUSRATE)
+ continue;
+
+ if (*((hrtime_t *)a) + interval < earliest)
+ earliest = *((hrtime_t *)a) + interval;
+ }
+
+ (void) pthread_mutex_lock(&dph->dph_lock);
+
+ now = gethrtime();
+
+ if (earliest < now) {
+ (void) pthread_mutex_unlock(&dph->dph_lock);
+ return; /* sleep duration has already past */
+ }
+
+#if defined(sun)
+ tv.tv_sec = (earliest - now) / NANOSEC;
+ tv.tv_nsec = (earliest - now) % NANOSEC;
+
+ /*
+ * Wait for either 'tv' nanoseconds to pass or to receive notification
+ * that a process is in an interesting state. Regardless of why we
+ * awaken, iterate over any pending notifications and process them.
+ */
+ (void) pthread_cond_reltimedwait_np(&dph->dph_cv, &dph->dph_lock, &tv);
+#else
+ earliest -= now;
+ clock_gettime(CLOCK_REALTIME,&tv);
+ tv.tv_sec += earliest / NANOSEC;
+ tv.tv_nsec += earliest % NANOSEC;
+ while (tv.tv_nsec > NANOSEC) {
+ tv.tv_sec += 1;
+ tv.tv_nsec -= NANOSEC;
+ }
+
+ /*
+ * Wait for either 'tv' nanoseconds to pass or to receive notification
+ * that a process is in an interesting state. Regardless of why we
+ * awaken, iterate over any pending notifications and process them.
+ */
+ (void) pthread_cond_timedwait(&dph->dph_cv, &dph->dph_lock, &tv);
+#endif
+
+ while ((dprn = dph->dph_notify) != NULL) {
+ if (dtp->dt_prochdlr != NULL) {
+ char *err = dprn->dprn_errmsg;
+ if (*err == '\0')
+ err = NULL;
+
+ dtp->dt_prochdlr(dprn->dprn_dpr->dpr_proc, err,
+ dtp->dt_procarg);
+ }
+
+ dph->dph_notify = dprn->dprn_next;
+ dt_free(dtp, dprn);
+ }
+
+ (void) pthread_mutex_unlock(&dph->dph_lock);
+}
+
+int
+dtrace_status(dtrace_hdl_t *dtp)
+{
+ int gen = dtp->dt_statusgen;
+ dtrace_optval_t interval = dtp->dt_options[DTRACEOPT_STATUSRATE];
+ hrtime_t now = gethrtime();
+
+ if (!dtp->dt_active)
+ return (DTRACE_STATUS_NONE);
+
+ if (dtp->dt_stopped)
+ return (DTRACE_STATUS_STOPPED);
+
+ if (dtp->dt_laststatus != 0) {
+ if (now - dtp->dt_laststatus < interval)
+ return (DTRACE_STATUS_NONE);
+
+ dtp->dt_laststatus += interval;
+ } else {
+ dtp->dt_laststatus = now;
+ }
+
+ if (dt_ioctl(dtp, DTRACEIOC_STATUS, &dtp->dt_status[gen]) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ dtp->dt_statusgen ^= 1;
+
+ if (dt_handle_status(dtp, &dtp->dt_status[dtp->dt_statusgen],
+ &dtp->dt_status[gen]) == -1)
+ return (-1);
+
+ if (dtp->dt_status[gen].dtst_exiting) {
+ if (!dtp->dt_stopped)
+ (void) dtrace_stop(dtp);
+
+ return (DTRACE_STATUS_EXITED);
+ }
+
+ if (dtp->dt_status[gen].dtst_filled == 0)
+ return (DTRACE_STATUS_OKAY);
+
+ if (dtp->dt_options[DTRACEOPT_BUFPOLICY] != DTRACEOPT_BUFPOLICY_FILL)
+ return (DTRACE_STATUS_OKAY);
+
+ if (!dtp->dt_stopped) {
+ if (dtrace_stop(dtp) == -1)
+ return (-1);
+ }
+
+ return (DTRACE_STATUS_FILLED);
+}
+
+int
+dtrace_go(dtrace_hdl_t *dtp)
+{
+ dtrace_enable_io_t args;
+ void *dof;
+ int err;
+
+ if (dtp->dt_active)
+ return (dt_set_errno(dtp, EINVAL));
+
+ /*
+ * If a dtrace:::ERROR program and callback are registered, enable the
+ * program before we start tracing. If this fails for a vector open
+ * with ENOTTY, we permit dtrace_go() to succeed so that vector clients
+ * such as mdb's dtrace module can execute the rest of dtrace_go() even
+ * though they do not provide support for the DTRACEIOC_ENABLE ioctl.
+ */
+ if (dtp->dt_errprog != NULL &&
+ dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && (
+ dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL))
+ return (-1); /* dt_errno has been set for us */
+
+ if ((dof = dtrace_getopt_dof(dtp)) == NULL)
+ return (-1); /* dt_errno has been set for us */
+
+ args.dof = dof;
+ args.n_matched = 0;
+ err = dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
+ dtrace_dof_destroy(dtp, dof);
+
+ if (err == -1 && (errno != ENOTTY || dtp->dt_vector == NULL))
+ return (dt_set_errno(dtp, errno));
+
+ if (dt_ioctl(dtp, DTRACEIOC_GO, &dtp->dt_beganon) == -1) {
+ if (errno == EACCES)
+ return (dt_set_errno(dtp, EDT_DESTRUCTIVE));
+
+ if (errno == EALREADY)
+ return (dt_set_errno(dtp, EDT_ISANON));
+
+ if (errno == ENOENT)
+ return (dt_set_errno(dtp, EDT_NOANON));
+
+ if (errno == E2BIG)
+ return (dt_set_errno(dtp, EDT_ENDTOOBIG));
+
+ if (errno == ENOSPC)
+ return (dt_set_errno(dtp, EDT_BUFTOOSMALL));
+
+ return (dt_set_errno(dtp, errno));
+ }
+
+ dtp->dt_active = 1;
+
+ if (dt_options_load(dtp) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ return (dt_aggregate_go(dtp));
+}
+
+int
+dtrace_stop(dtrace_hdl_t *dtp)
+{
+ int gen = dtp->dt_statusgen;
+
+ if (dtp->dt_stopped)
+ return (0);
+
+ if (dt_ioctl(dtp, DTRACEIOC_STOP, &dtp->dt_endedon) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ dtp->dt_stopped = 1;
+
+ /*
+ * Now that we're stopped, we're going to get status one final time.
+ */
+ if (dt_ioctl(dtp, DTRACEIOC_STATUS, &dtp->dt_status[gen]) == -1)
+ return (dt_set_errno(dtp, errno));
+
+ if (dt_handle_status(dtp, &dtp->dt_status[gen ^ 1],
+ &dtp->dt_status[gen]) == -1)
+ return (-1);
+
+ return (0);
+}
+
+
+dtrace_workstatus_t
+dtrace_work(dtrace_hdl_t *dtp, FILE *fp,
+ dtrace_consume_probe_f *pfunc, dtrace_consume_rec_f *rfunc, void *arg)
+{
+ int status = dtrace_status(dtp);
+ dtrace_optval_t policy = dtp->dt_options[DTRACEOPT_BUFPOLICY];
+ dtrace_workstatus_t rval;
+
+ switch (status) {
+ case DTRACE_STATUS_EXITED:
+ case DTRACE_STATUS_FILLED:
+ case DTRACE_STATUS_STOPPED:
+ /*
+ * Tracing is stopped. We now want to force dtrace_consume()
+ * and dtrace_aggregate_snap() to proceed, regardless of
+ * switchrate and aggrate. We do this by clearing the times.
+ */
+ dtp->dt_lastswitch = 0;
+ dtp->dt_lastagg = 0;
+ rval = DTRACE_WORKSTATUS_DONE;
+ break;
+
+ case DTRACE_STATUS_NONE:
+ case DTRACE_STATUS_OKAY:
+ rval = DTRACE_WORKSTATUS_OKAY;
+ break;
+
+ case -1:
+ return (DTRACE_WORKSTATUS_ERROR);
+ }
+
+ if ((status == DTRACE_STATUS_NONE || status == DTRACE_STATUS_OKAY) &&
+ policy != DTRACEOPT_BUFPOLICY_SWITCH) {
+ /*
+ * There either isn't any status or things are fine -- and
+ * this is a "ring" or "fill" buffer. We don't want to consume
+ * any of the trace data or snapshot the aggregations; we just
+ * return.
+ */
+ assert(rval == DTRACE_WORKSTATUS_OKAY);
+ return (rval);
+ }
+
+ if (dtrace_aggregate_snap(dtp) == -1)
+ return (DTRACE_WORKSTATUS_ERROR);
+
+ if (dtrace_consume(dtp, fp, pfunc, rfunc, arg) == -1)
+ return (DTRACE_WORKSTATUS_ERROR);
+
+ return (rval);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
new file mode 100644
index 0000000..7ac0cc4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
@@ -0,0 +1,383 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <strings.h>
+#include <assert.h>
+
+#include <dt_xlator.h>
+#include <dt_parser.h>
+#include <dt_grammar.h>
+#include <dt_module.h>
+#include <dt_impl.h>
+
+/*
+ * Create a member node corresponding to one of the output members of a dynamic
+ * translator. We set the member's dn_membexpr to a DT_NODE_XLATOR node that
+ * has dn_op set to DT_TOK_XLATE and refers back to the translator itself. The
+ * code generator will then use this as the indicator for dynamic translation.
+ */
+/*ARGSUSED*/
+static int
+dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ dt_xlator_t *dxp = arg;
+ dtrace_hdl_t *dtp = dxp->dx_hdl;
+ dt_node_t *enp, *mnp;
+
+ if ((enp = dt_node_xalloc(dtp, DT_NODE_XLATOR)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ enp->dn_link = dxp->dx_nodes;
+ dxp->dx_nodes = enp;
+
+ if ((mnp = dt_node_xalloc(dtp, DT_NODE_MEMBER)) == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ mnp->dn_link = dxp->dx_nodes;
+ dxp->dx_nodes = mnp;
+
+ /*
+ * For the member expression, we use a DT_NODE_XLATOR/TOK_XLATE whose
+ * xlator refers back to the translator and whose dn_xmember refers to
+ * the current member. These refs will be used by dt_cg.c and dt_as.c.
+ */
+ enp->dn_op = DT_TOK_XLATE;
+ enp->dn_xlator = dxp;
+ enp->dn_xmember = mnp;
+ dt_node_type_assign(enp, dxp->dx_dst_ctfp, type);
+
+ /*
+ * For the member itself, we use a DT_NODE_MEMBER as usual with the
+ * appropriate name, output type, and member expression set to 'enp'.
+ */
+ if (dxp->dx_members != NULL) {
+ assert(enp->dn_link->dn_kind == DT_NODE_MEMBER);
+ enp->dn_link->dn_list = mnp;
+ } else
+ dxp->dx_members = mnp;
+
+ mnp->dn_membname = strdup(name);
+ mnp->dn_membexpr = enp;
+ dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type);
+
+ if (mnp->dn_membname == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+
+ return (0);
+}
+
+dt_xlator_t *
+dt_xlator_create(dtrace_hdl_t *dtp,
+ const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst,
+ const char *name, dt_node_t *members, dt_node_t *nodes)
+{
+ dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t));
+ dtrace_typeinfo_t ptr = *dst;
+ dt_xlator_t **map;
+ dt_node_t *dnp;
+ uint_t kind;
+
+ if (dxp == NULL)
+ return (NULL);
+
+ dxp->dx_hdl = dtp;
+ dxp->dx_id = dtp->dt_xlatorid++;
+ dxp->dx_gen = dtp->dt_gen;
+ dxp->dx_arg = -1;
+
+ if ((map = dt_alloc(dtp, sizeof (void *) * (dxp->dx_id + 1))) == NULL) {
+ dt_free(dtp, dxp);
+ return (NULL);
+ }
+
+ dt_list_append(&dtp->dt_xlators, dxp);
+ bcopy(dtp->dt_xlatormap, map, sizeof (void *) * dxp->dx_id);
+ dt_free(dtp, dtp->dt_xlatormap);
+ dtp->dt_xlatormap = map;
+ dtp->dt_xlatormap[dxp->dx_id] = dxp;
+
+ if (dt_type_pointer(&ptr) == -1) {
+ ptr.dtt_ctfp = NULL;
+ ptr.dtt_type = CTF_ERR;
+ }
+
+ dxp->dx_ident = dt_ident_create(name ? name : "T",
+ DT_IDENT_SCALAR, DT_IDFLG_REF | DT_IDFLG_ORPHAN, 0,
+ _dtrace_defattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
+
+ if (dxp->dx_ident == NULL)
+ goto err; /* no memory for identifier */
+
+ dxp->dx_ident->di_ctfp = src->dtt_ctfp;
+ dxp->dx_ident->di_type = src->dtt_type;
+
+ /*
+ * If an input parameter name is given, this is a static translator
+ * definition: create an idhash and identifier for the parameter.
+ */
+ if (name != NULL) {
+ dxp->dx_locals = dt_idhash_create("xlparams", NULL, 0, 0);
+
+ if (dxp->dx_locals == NULL)
+ goto err; /* no memory for identifier hash */
+
+ dt_idhash_xinsert(dxp->dx_locals, dxp->dx_ident);
+ }
+
+ dxp->dx_souid.di_name = "translator";
+ dxp->dx_souid.di_kind = DT_IDENT_XLSOU;
+ dxp->dx_souid.di_flags = DT_IDFLG_REF;
+ dxp->dx_souid.di_id = dxp->dx_id;
+ dxp->dx_souid.di_attr = _dtrace_defattr;
+ dxp->dx_souid.di_ops = &dt_idops_thaw;
+ dxp->dx_souid.di_data = dxp;
+ dxp->dx_souid.di_ctfp = dst->dtt_ctfp;
+ dxp->dx_souid.di_type = dst->dtt_type;
+ dxp->dx_souid.di_gen = dtp->dt_gen;
+
+ dxp->dx_ptrid.di_name = "translator";
+ dxp->dx_ptrid.di_kind = DT_IDENT_XLPTR;
+ dxp->dx_ptrid.di_flags = DT_IDFLG_REF;
+ dxp->dx_ptrid.di_id = dxp->dx_id;
+ dxp->dx_ptrid.di_attr = _dtrace_defattr;
+ dxp->dx_ptrid.di_ops = &dt_idops_thaw;
+ dxp->dx_ptrid.di_data = dxp;
+ dxp->dx_ptrid.di_ctfp = ptr.dtt_ctfp;
+ dxp->dx_ptrid.di_type = ptr.dtt_type;
+ dxp->dx_ptrid.di_gen = dtp->dt_gen;
+
+ /*
+ * If a deferred pragma is pending on the keyword "translator", run all
+ * the deferred pragmas on dx_souid and then copy results to dx_ptrid.
+ * See the code in dt_pragma.c for details on deferred ident pragmas.
+ */
+ if (dtp->dt_globals->dh_defer != NULL && yypcb->pcb_pragmas != NULL &&
+ dt_idhash_lookup(yypcb->pcb_pragmas, "translator") != NULL) {
+ dtp->dt_globals->dh_defer(dtp->dt_globals, &dxp->dx_souid);
+ dxp->dx_ptrid.di_attr = dxp->dx_souid.di_attr;
+ dxp->dx_ptrid.di_vers = dxp->dx_souid.di_vers;
+ }
+
+ dxp->dx_src_ctfp = src->dtt_ctfp;
+ dxp->dx_src_type = src->dtt_type;
+ dxp->dx_src_base = ctf_type_resolve(src->dtt_ctfp, src->dtt_type);
+
+ dxp->dx_dst_ctfp = dst->dtt_ctfp;
+ dxp->dx_dst_type = dst->dtt_type;
+ dxp->dx_dst_base = ctf_type_resolve(dst->dtt_ctfp, dst->dtt_type);
+
+ kind = ctf_type_kind(dst->dtt_ctfp, dxp->dx_dst_base);
+ assert(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
+
+ /*
+ * If no input parameter is given, we're making a dynamic translator:
+ * create member nodes for every member of the output type. Otherwise
+ * retain the member and allocation node lists presented by the parser.
+ */
+ if (name == NULL) {
+ if (ctf_member_iter(dxp->dx_dst_ctfp, dxp->dx_dst_base,
+ dt_xlator_create_member, dxp) != 0)
+ goto err;
+ } else {
+ dxp->dx_members = members;
+ dxp->dx_nodes = nodes;
+ }
+
+ /*
+ * Assign member IDs to each member and allocate space for DIFOs
+ * if and when this translator is eventually compiled.
+ */
+ for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) {
+ dnp->dn_membxlator = dxp;
+ dnp->dn_membid = dxp->dx_nmembers++;
+ }
+
+ dxp->dx_membdif = dt_zalloc(dtp,
+ sizeof (dtrace_difo_t *) * dxp->dx_nmembers);
+
+ if (dxp->dx_membdif == NULL) {
+ dxp->dx_nmembers = 0;
+ goto err;
+ }
+
+ return (dxp);
+
+err:
+ dt_xlator_destroy(dtp, dxp);
+ return (NULL);
+}
+
+void
+dt_xlator_destroy(dtrace_hdl_t *dtp, dt_xlator_t *dxp)
+{
+ uint_t i;
+
+ dt_node_link_free(&dxp->dx_nodes);
+
+ if (dxp->dx_locals != NULL)
+ dt_idhash_destroy(dxp->dx_locals);
+ else if (dxp->dx_ident != NULL)
+ dt_ident_destroy(dxp->dx_ident);
+
+ for (i = 0; i < dxp->dx_nmembers; i++)
+ dt_difo_free(dtp, dxp->dx_membdif[i]);
+
+ dt_free(dtp, dxp->dx_membdif);
+ dt_list_delete(&dtp->dt_xlators, dxp);
+ dt_free(dtp, dxp);
+}
+
+dt_xlator_t *
+dt_xlator_lookup(dtrace_hdl_t *dtp, dt_node_t *src, dt_node_t *dst, int flags)
+{
+ ctf_file_t *src_ctfp = src->dn_ctfp;
+ ctf_id_t src_type = src->dn_type;
+ ctf_id_t src_base = ctf_type_resolve(src_ctfp, src_type);
+
+ ctf_file_t *dst_ctfp = dst->dn_ctfp;
+ ctf_id_t dst_type = dst->dn_type;
+ ctf_id_t dst_base = ctf_type_resolve(dst_ctfp, dst_type);
+ uint_t dst_kind = ctf_type_kind(dst_ctfp, dst_base);
+
+ int ptr = dst_kind == CTF_K_POINTER;
+ dtrace_typeinfo_t src_dtt, dst_dtt;
+ dt_node_t xn = { 0 };
+ dt_xlator_t *dxp = NULL;
+
+ if (src_base == CTF_ERR || dst_base == CTF_ERR)
+ return (NULL); /* fail if these are unresolvable types */
+
+ /*
+ * Translators are always defined using a struct or union type, so if
+ * we are attempting to translate to type "T *", we internally look
+ * for a translation to type "T" by following the pointer reference.
+ */
+ if (ptr) {
+ dst_type = ctf_type_reference(dst_ctfp, dst_type);
+ dst_base = ctf_type_resolve(dst_ctfp, dst_type);
+ dst_kind = ctf_type_kind(dst_ctfp, dst_base);
+ }
+
+ if (dst_kind != CTF_K_UNION && dst_kind != CTF_K_STRUCT)
+ return (NULL); /* fail if the output isn't a struct or union */
+
+ /*
+ * In order to find a matching translator, we iterate over the set of
+ * available translators in three passes. First, we look for a
+ * translation from the exact source type to the resolved destination.
+ * Second, we look for a translation from the resolved source type to
+ * the resolved destination. Third, we look for a translation from a
+ * compatible source type (using the same rules as parameter formals)
+ * to the resolved destination. If all passes fail, return NULL.
+ */
+ for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
+ dxp = dt_list_next(dxp)) {
+ if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_type,
+ src_ctfp, src_type) &&
+ ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
+ dst_ctfp, dst_base))
+ goto out;
+ }
+
+ if (flags & DT_XLATE_EXACT)
+ goto out; /* skip remaining passes if exact match required */
+
+ for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
+ dxp = dt_list_next(dxp)) {
+ if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_base,
+ src_ctfp, src_type) &&
+ ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
+ dst_ctfp, dst_base))
+ goto out;
+ }
+
+ for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
+ dxp = dt_list_next(dxp)) {
+ dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type);
+ if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
+ dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn))
+ goto out;
+ }
+
+out:
+ if (ptr && dxp != NULL && dxp->dx_ptrid.di_type == CTF_ERR)
+ return (NULL); /* no translation available to pointer type */
+
+ if (dxp != NULL || !(flags & DT_XLATE_EXTERN) ||
+ dtp->dt_xlatemode == DT_XL_STATIC)
+ return (dxp); /* we succeeded or not allowed to extern */
+
+ /*
+ * If we get here, then we didn't find an existing translator, but the
+ * caller and xlatemode permit us to create an extern to a dynamic one.
+ */
+ src_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, src_ctfp)->dm_name;
+ src_dtt.dtt_ctfp = src_ctfp;
+ src_dtt.dtt_type = src_type;
+
+ dst_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, dst_ctfp)->dm_name;
+ dst_dtt.dtt_ctfp = dst_ctfp;
+ dst_dtt.dtt_type = dst_type;
+
+ return (dt_xlator_create(dtp, &src_dtt, &dst_dtt, NULL, NULL, NULL));
+}
+
+dt_xlator_t *
+dt_xlator_lookup_id(dtrace_hdl_t *dtp, id_t id)
+{
+ assert(id >= 0 && id < dtp->dt_xlatorid);
+ return (dtp->dt_xlatormap[id]);
+}
+
+dt_ident_t *
+dt_xlator_ident(dt_xlator_t *dxp, ctf_file_t *ctfp, ctf_id_t type)
+{
+ if (ctf_type_kind(ctfp, ctf_type_resolve(ctfp, type)) == CTF_K_POINTER)
+ return (&dxp->dx_ptrid);
+ else
+ return (&dxp->dx_souid);
+}
+
+dt_node_t *
+dt_xlator_member(dt_xlator_t *dxp, const char *name)
+{
+ dt_node_t *dnp;
+
+ for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) {
+ if (strcmp(dnp->dn_membname, name) == 0)
+ return (dnp);
+ }
+
+ return (NULL);
+}
+
+int
+dt_xlator_dynamic(const dt_xlator_t *dxp)
+{
+ return (dxp->dx_locals == NULL);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.h
new file mode 100644
index 0000000..a30f3af
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_XLATOR_H
+#define _DT_XLATOR_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libctf.h>
+#include <dtrace.h>
+#include <dt_ident.h>
+#include <dt_list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dt_node;
+
+typedef struct dt_xlator {
+ dt_list_t dx_list; /* list forward/back pointers */
+ dt_idhash_t *dx_locals; /* hash of local scope identifiers */
+ dt_ident_t *dx_ident; /* identifier ref for input param */
+ dt_ident_t dx_souid; /* fake identifier for sou output */
+ dt_ident_t dx_ptrid; /* fake identifier for ptr output */
+ ctf_file_t *dx_src_ctfp; /* CTF container for input type */
+ ctf_id_t dx_src_type; /* CTF reference for input type */
+ ctf_id_t dx_src_base; /* CTF reference for input base */
+ ctf_file_t *dx_dst_ctfp; /* CTF container for output type */
+ ctf_id_t dx_dst_type; /* CTF reference for output type */
+ ctf_id_t dx_dst_base; /* CTF reference for output base */
+ struct dt_node *dx_members; /* list of member translations */
+ uint_t dx_nmembers; /* length of dx_members list */
+ dtrace_difo_t **dx_membdif; /* DIF for member expressions */
+ struct dt_node *dx_nodes; /* list of parse tree nodes */
+ dtrace_hdl_t *dx_hdl; /* back pointer to containing handle */
+ ulong_t dx_gen; /* generation number that created me */
+ id_t dx_id; /* global translator id */
+ int dx_arg; /* dynamic argument index */
+} dt_xlator_t;
+
+extern dt_xlator_t *dt_xlator_create(dtrace_hdl_t *,
+ const dtrace_typeinfo_t *, const dtrace_typeinfo_t *,
+ const char *, struct dt_node *, struct dt_node *);
+
+extern void dt_xlator_destroy(dtrace_hdl_t *, dt_xlator_t *);
+
+#define DT_XLATE_FUZZY 0x0 /* lookup any matching translator */
+#define DT_XLATE_EXACT 0x1 /* lookup only exact type matches */
+#define DT_XLATE_EXTERN 0x2 /* extern translator if none exists */
+
+extern dt_xlator_t *dt_xlator_lookup(dtrace_hdl_t *,
+ struct dt_node *, struct dt_node *, int);
+
+extern dt_xlator_t *dt_xlator_lookup_id(dtrace_hdl_t *, id_t);
+extern dt_ident_t *dt_xlator_ident(dt_xlator_t *, ctf_file_t *, ctf_id_t);
+extern struct dt_node *dt_xlator_member(dt_xlator_t *, const char *);
+extern int dt_xlator_dynamic(const dt_xlator_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DT_XLATOR_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
new file mode 100644
index 0000000..b2e3108
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
@@ -0,0 +1,599 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _DTRACE_H
+#define _DTRACE_H
+
+#include <sys/dtrace.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <gelf.h>
+#include <libproc.h>
+#if !defined(sun)
+#include <rtld_db.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * DTrace Dynamic Tracing Software: Library Interfaces
+ *
+ * Note: The contents of this file are private to the implementation of the
+ * Solaris system and DTrace subsystem and are subject to change at any time
+ * without notice. Applications and drivers using these interfaces will fail
+ * to run on future releases. These interfaces should not be used for any
+ * purpose except those expressly outlined in dtrace(7D) and libdtrace(3LIB).
+ * Please refer to the "Solaris Dynamic Tracing Guide" for more information.
+ */
+
+#define DTRACE_VERSION 3 /* library ABI interface version */
+
+struct ps_prochandle;
+typedef struct dtrace_hdl dtrace_hdl_t;
+typedef struct dtrace_prog dtrace_prog_t;
+typedef struct dtrace_vector dtrace_vector_t;
+typedef struct dtrace_aggdata dtrace_aggdata_t;
+
+#define DTRACE_O_NODEV 0x01 /* do not open dtrace(7D) device */
+#define DTRACE_O_NOSYS 0x02 /* do not load /system/object modules */
+#define DTRACE_O_LP64 0x04 /* force D compiler to be LP64 */
+#define DTRACE_O_ILP32 0x08 /* force D compiler to be ILP32 */
+#define DTRACE_O_MASK 0x0f /* mask of valid flags to dtrace_open */
+
+extern dtrace_hdl_t *dtrace_open(int, int, int *);
+extern dtrace_hdl_t *dtrace_vopen(int, int, int *,
+ const dtrace_vector_t *, void *);
+
+extern int dtrace_go(dtrace_hdl_t *);
+extern int dtrace_stop(dtrace_hdl_t *);
+extern void dtrace_sleep(dtrace_hdl_t *);
+extern void dtrace_close(dtrace_hdl_t *);
+
+extern int dtrace_errno(dtrace_hdl_t *);
+extern const char *dtrace_errmsg(dtrace_hdl_t *, int);
+extern const char *dtrace_faultstr(dtrace_hdl_t *, int);
+extern const char *dtrace_subrstr(dtrace_hdl_t *, int);
+
+extern int dtrace_setopt(dtrace_hdl_t *, const char *, const char *);
+extern int dtrace_getopt(dtrace_hdl_t *, const char *, dtrace_optval_t *);
+
+extern void dtrace_update(dtrace_hdl_t *);
+extern int dtrace_ctlfd(dtrace_hdl_t *);
+
+/*
+ * DTrace Program Interface
+ *
+ * DTrace programs can be created by compiling ASCII text files containing
+ * D programs or by compiling in-memory C strings that specify a D program.
+ * Once created, callers can examine the list of program statements and
+ * enable the probes and actions described by these statements.
+ */
+
+typedef struct dtrace_proginfo {
+ dtrace_attribute_t dpi_descattr; /* minimum probedesc attributes */
+ dtrace_attribute_t dpi_stmtattr; /* minimum statement attributes */
+ uint_t dpi_aggregates; /* number of aggregates specified in program */
+ uint_t dpi_recgens; /* number of record generating probes in prog */
+ uint_t dpi_matches; /* number of probes matched by program */
+ uint_t dpi_speculations; /* number of speculations specified in prog */
+} dtrace_proginfo_t;
+
+#define DTRACE_C_DIFV 0x0001 /* DIF verbose mode: show each compiled DIFO */
+#define DTRACE_C_EMPTY 0x0002 /* Permit compilation of empty D source files */
+#define DTRACE_C_ZDEFS 0x0004 /* Permit probe defs that match zero probes */
+#define DTRACE_C_EATTR 0x0008 /* Error if program attributes less than min */
+#define DTRACE_C_CPP 0x0010 /* Preprocess input file with cpp(1) utility */
+#define DTRACE_C_KNODEF 0x0020 /* Permit unresolved kernel symbols in DIFO */
+#define DTRACE_C_UNODEF 0x0040 /* Permit unresolved user symbols in DIFO */
+#define DTRACE_C_PSPEC 0x0080 /* Intepret ambiguous specifiers as probes */
+#define DTRACE_C_ETAGS 0x0100 /* Prefix error messages with error tags */
+#define DTRACE_C_ARGREF 0x0200 /* Do not require all macro args to be used */
+#define DTRACE_C_DEFARG 0x0800 /* Use 0/"" as value for unspecified args */
+#define DTRACE_C_NOLIBS 0x1000 /* Do not process D system libraries */
+#define DTRACE_C_CTL 0x2000 /* Only process control directives */
+#define DTRACE_C_MASK 0x3bff /* mask of all valid flags to dtrace_*compile */
+
+extern dtrace_prog_t *dtrace_program_strcompile(dtrace_hdl_t *,
+ const char *, dtrace_probespec_t, uint_t, int, char *const []);
+
+extern dtrace_prog_t *dtrace_program_fcompile(dtrace_hdl_t *,
+ FILE *, uint_t, int, char *const []);
+
+extern int dtrace_program_exec(dtrace_hdl_t *, dtrace_prog_t *,
+ dtrace_proginfo_t *);
+extern void dtrace_program_info(dtrace_hdl_t *, dtrace_prog_t *,
+ dtrace_proginfo_t *);
+
+#define DTRACE_D_STRIP 0x01 /* strip non-loadable sections from program */
+#define DTRACE_D_PROBES 0x02 /* include provider and probe definitions */
+#define DTRACE_D_MASK 0x03 /* mask of valid flags to dtrace_dof_create */
+
+extern int dtrace_program_link(dtrace_hdl_t *, dtrace_prog_t *,
+ uint_t, const char *, int, char *const []);
+
+extern int dtrace_program_header(dtrace_hdl_t *, FILE *, const char *);
+
+extern void *dtrace_dof_create(dtrace_hdl_t *, dtrace_prog_t *, uint_t);
+extern void dtrace_dof_destroy(dtrace_hdl_t *, void *);
+
+extern void *dtrace_getopt_dof(dtrace_hdl_t *);
+extern void *dtrace_geterr_dof(dtrace_hdl_t *);
+
+typedef struct dtrace_stmtdesc {
+ dtrace_ecbdesc_t *dtsd_ecbdesc; /* ECB description */
+ dtrace_actdesc_t *dtsd_action; /* action list */
+ dtrace_actdesc_t *dtsd_action_last; /* last action in action list */
+ void *dtsd_aggdata; /* aggregation data */
+ void *dtsd_fmtdata; /* type-specific output data */
+ void *dtsd_strdata; /* type-specific string data */
+ void (*dtsd_callback)(void); /* callback function for EPID */
+ void *dtsd_data; /* callback data pointer */
+ dtrace_attribute_t dtsd_descattr; /* probedesc attributes */
+ dtrace_attribute_t dtsd_stmtattr; /* statement attributes */
+} dtrace_stmtdesc_t;
+
+typedef int dtrace_stmt_f(dtrace_hdl_t *, dtrace_prog_t *,
+ dtrace_stmtdesc_t *, void *);
+
+extern dtrace_stmtdesc_t *dtrace_stmt_create(dtrace_hdl_t *,
+ dtrace_ecbdesc_t *);
+extern dtrace_actdesc_t *dtrace_stmt_action(dtrace_hdl_t *,
+ dtrace_stmtdesc_t *);
+extern int dtrace_stmt_add(dtrace_hdl_t *, dtrace_prog_t *,
+ dtrace_stmtdesc_t *);
+extern int dtrace_stmt_iter(dtrace_hdl_t *, dtrace_prog_t *,
+ dtrace_stmt_f *, void *);
+extern void dtrace_stmt_destroy(dtrace_hdl_t *, dtrace_stmtdesc_t *);
+
+/*
+ * DTrace Data Consumption Interface
+ */
+typedef enum {
+ DTRACEFLOW_ENTRY,
+ DTRACEFLOW_RETURN,
+ DTRACEFLOW_NONE
+} dtrace_flowkind_t;
+
+#define DTRACE_CONSUME_ERROR -1 /* error while processing */
+#define DTRACE_CONSUME_THIS 0 /* consume this probe/record */
+#define DTRACE_CONSUME_NEXT 1 /* advance to next probe/rec */
+#define DTRACE_CONSUME_ABORT 2 /* abort consumption */
+
+typedef struct dtrace_probedata {
+ dtrace_hdl_t *dtpda_handle; /* handle to DTrace library */
+ dtrace_eprobedesc_t *dtpda_edesc; /* enabled probe description */
+ dtrace_probedesc_t *dtpda_pdesc; /* probe description */
+ processorid_t dtpda_cpu; /* CPU for data */
+ caddr_t dtpda_data; /* pointer to raw data */
+ dtrace_flowkind_t dtpda_flow; /* flow kind */
+ const char *dtpda_prefix; /* recommended flow prefix */
+ int dtpda_indent; /* recommended flow indent */
+} dtrace_probedata_t;
+
+typedef int dtrace_consume_probe_f(const dtrace_probedata_t *, void *);
+typedef int dtrace_consume_rec_f(const dtrace_probedata_t *,
+ const dtrace_recdesc_t *, void *);
+
+extern int dtrace_consume(dtrace_hdl_t *, FILE *,
+ dtrace_consume_probe_f *, dtrace_consume_rec_f *, void *);
+
+#define DTRACE_STATUS_NONE 0 /* no status; not yet time */
+#define DTRACE_STATUS_OKAY 1 /* status okay */
+#define DTRACE_STATUS_EXITED 2 /* exit() was called; tracing stopped */
+#define DTRACE_STATUS_FILLED 3 /* fill buffer filled; tracing stoped */
+#define DTRACE_STATUS_STOPPED 4 /* tracing already stopped */
+
+extern int dtrace_status(dtrace_hdl_t *);
+
+/*
+ * DTrace Formatted Output Interfaces
+ *
+ * To format output associated with a given dtrace_stmtdesc, the caller can
+ * invoke one of the following functions, passing the opaque dtsd_fmtdata and a
+ * list of record descriptions. These functions return either -1 to indicate
+ * an error, or a positive integer indicating the number of records consumed.
+ * For anonymous enablings, the consumer can use the dtrd_format member of
+ * the record description to obtain a format description. The dtfd_string
+ * member of the format description may be passed to dtrace_print{fa}_create()
+ * to create the opaque format data.
+ */
+extern void *dtrace_printf_create(dtrace_hdl_t *, const char *);
+extern void *dtrace_printa_create(dtrace_hdl_t *, const char *);
+extern size_t dtrace_printf_format(dtrace_hdl_t *, void *, char *, size_t);
+
+extern int dtrace_fprintf(dtrace_hdl_t *, FILE *, void *,
+ const dtrace_probedata_t *, const dtrace_recdesc_t *, uint_t,
+ const void *, size_t);
+
+extern int dtrace_fprinta(dtrace_hdl_t *, FILE *, void *,
+ const dtrace_probedata_t *, const dtrace_recdesc_t *, uint_t,
+ const void *, size_t);
+
+extern int dtrace_system(dtrace_hdl_t *, FILE *, void *,
+ const dtrace_probedata_t *, const dtrace_recdesc_t *, uint_t,
+ const void *, size_t);
+
+extern int dtrace_freopen(dtrace_hdl_t *, FILE *, void *,
+ const dtrace_probedata_t *, const dtrace_recdesc_t *, uint_t,
+ const void *, size_t);
+
+/*
+ * Type-specific output printing
+ *
+ * The print() action will associate a string data record that is actually the
+ * fully-qualified type name of the data traced by the DIFEXPR action. This is
+ * stored in the same 'format' record from the kernel, but we know by virtue of
+ * the fact that the action is still DIFEXPR that it is actually a reference to
+ * plain string data.
+ */
+extern int dtrace_print(dtrace_hdl_t *, FILE *, const char *,
+ caddr_t, size_t);
+
+/*
+ * DTrace Work Interface
+ */
+typedef enum {
+ DTRACE_WORKSTATUS_ERROR = -1,
+ DTRACE_WORKSTATUS_OKAY,
+ DTRACE_WORKSTATUS_DONE
+} dtrace_workstatus_t;
+
+extern dtrace_workstatus_t dtrace_work(dtrace_hdl_t *, FILE *,
+ dtrace_consume_probe_f *, dtrace_consume_rec_f *, void *);
+
+/*
+ * DTrace Handler Interface
+ */
+#define DTRACE_HANDLE_ABORT -1 /* abort current operation */
+#define DTRACE_HANDLE_OK 0 /* handled okay; continue */
+
+typedef struct dtrace_errdata {
+ dtrace_hdl_t *dteda_handle; /* handle to DTrace library */
+ dtrace_eprobedesc_t *dteda_edesc; /* enabled probe inducing err */
+ dtrace_probedesc_t *dteda_pdesc; /* probe inducing error */
+ processorid_t dteda_cpu; /* CPU of error */
+ int dteda_action; /* action inducing error */
+ int dteda_offset; /* offset in DIFO of error */
+ int dteda_fault; /* specific fault */
+ uint64_t dteda_addr; /* address of fault, if any */
+ const char *dteda_msg; /* preconstructed message */
+} dtrace_errdata_t;
+
+typedef int dtrace_handle_err_f(const dtrace_errdata_t *, void *);
+extern int dtrace_handle_err(dtrace_hdl_t *, dtrace_handle_err_f *, void *);
+
+typedef enum {
+ DTRACEDROP_PRINCIPAL, /* drop to principal buffer */
+ DTRACEDROP_AGGREGATION, /* drop to aggregation buffer */
+ DTRACEDROP_DYNAMIC, /* dynamic drop */
+ DTRACEDROP_DYNRINSE, /* dyn drop due to rinsing */
+ DTRACEDROP_DYNDIRTY, /* dyn drop due to dirty */
+ DTRACEDROP_SPEC, /* speculative drop */
+ DTRACEDROP_SPECBUSY, /* spec drop due to busy */
+ DTRACEDROP_SPECUNAVAIL, /* spec drop due to unavail */
+ DTRACEDROP_STKSTROVERFLOW, /* stack string tab overflow */
+ DTRACEDROP_DBLERROR /* error in ERROR probe */
+} dtrace_dropkind_t;
+
+typedef struct dtrace_dropdata {
+ dtrace_hdl_t *dtdda_handle; /* handle to DTrace library */
+ processorid_t dtdda_cpu; /* CPU, if any */
+ dtrace_dropkind_t dtdda_kind; /* kind of drop */
+ uint64_t dtdda_drops; /* number of drops */
+ uint64_t dtdda_total; /* total drops */
+ const char *dtdda_msg; /* preconstructed message */
+} dtrace_dropdata_t;
+
+typedef int dtrace_handle_drop_f(const dtrace_dropdata_t *, void *);
+extern int dtrace_handle_drop(dtrace_hdl_t *, dtrace_handle_drop_f *, void *);
+
+typedef void dtrace_handle_proc_f(struct ps_prochandle *, const char *, void *);
+extern int dtrace_handle_proc(dtrace_hdl_t *, dtrace_handle_proc_f *, void *);
+
+#define DTRACE_BUFDATA_AGGKEY 0x0001 /* aggregation key */
+#define DTRACE_BUFDATA_AGGVAL 0x0002 /* aggregation value */
+#define DTRACE_BUFDATA_AGGFORMAT 0x0004 /* aggregation format data */
+#define DTRACE_BUFDATA_AGGLAST 0x0008 /* last for this key/val */
+
+typedef struct dtrace_bufdata {
+ dtrace_hdl_t *dtbda_handle; /* handle to DTrace library */
+ const char *dtbda_buffered; /* buffered output */
+ dtrace_probedata_t *dtbda_probe; /* probe data */
+ const dtrace_recdesc_t *dtbda_recdesc; /* record description */
+ const dtrace_aggdata_t *dtbda_aggdata; /* aggregation data, if agg. */
+ uint32_t dtbda_flags; /* flags; see above */
+} dtrace_bufdata_t;
+
+typedef int dtrace_handle_buffered_f(const dtrace_bufdata_t *, void *);
+extern int dtrace_handle_buffered(dtrace_hdl_t *,
+ dtrace_handle_buffered_f *, void *);
+
+typedef struct dtrace_setoptdata {
+ dtrace_hdl_t *dtsda_handle; /* handle to DTrace library */
+ const dtrace_probedata_t *dtsda_probe; /* probe data */
+ const char *dtsda_option; /* option that was set */
+ dtrace_optval_t dtsda_oldval; /* old value */
+ dtrace_optval_t dtsda_newval; /* new value */
+} dtrace_setoptdata_t;
+
+typedef int dtrace_handle_setopt_f(const dtrace_setoptdata_t *, void *);
+extern int dtrace_handle_setopt(dtrace_hdl_t *,
+ dtrace_handle_setopt_f *, void *);
+
+/*
+ * DTrace Aggregate Interface
+ */
+
+#define DTRACE_A_PERCPU 0x0001
+#define DTRACE_A_KEEPDELTA 0x0002
+#define DTRACE_A_ANONYMOUS 0x0004
+
+#define DTRACE_AGGWALK_ERROR -1 /* error while processing */
+#define DTRACE_AGGWALK_NEXT 0 /* proceed to next element */
+#define DTRACE_AGGWALK_ABORT 1 /* abort aggregation walk */
+#define DTRACE_AGGWALK_CLEAR 2 /* clear this element */
+#define DTRACE_AGGWALK_NORMALIZE 3 /* normalize this element */
+#define DTRACE_AGGWALK_DENORMALIZE 4 /* denormalize this element */
+#define DTRACE_AGGWALK_REMOVE 5 /* remove this element */
+
+struct dtrace_aggdata {
+ dtrace_hdl_t *dtada_handle; /* handle to DTrace library */
+ dtrace_aggdesc_t *dtada_desc; /* aggregation description */
+ dtrace_eprobedesc_t *dtada_edesc; /* enabled probe description */
+ dtrace_probedesc_t *dtada_pdesc; /* probe description */
+ caddr_t dtada_data; /* pointer to raw data */
+ uint64_t dtada_normal; /* the normal -- 1 for denorm */
+ size_t dtada_size; /* total size of the data */
+ caddr_t dtada_delta; /* delta data, if available */
+ caddr_t *dtada_percpu; /* per CPU data, if avail */
+ caddr_t *dtada_percpu_delta; /* per CPU delta, if avail */
+};
+
+typedef int dtrace_aggregate_f(const dtrace_aggdata_t *, void *);
+typedef int dtrace_aggregate_walk_f(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+typedef int dtrace_aggregate_walk_joined_f(const dtrace_aggdata_t **,
+ const int, void *);
+
+extern void dtrace_aggregate_clear(dtrace_hdl_t *);
+extern int dtrace_aggregate_snap(dtrace_hdl_t *);
+extern int dtrace_aggregate_print(dtrace_hdl_t *, FILE *,
+ dtrace_aggregate_walk_f *);
+
+extern int dtrace_aggregate_walk(dtrace_hdl_t *, dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_joined(dtrace_hdl_t *,
+ dtrace_aggvarid_t *, int, dtrace_aggregate_walk_joined_f *, void *);
+
+extern int dtrace_aggregate_walk_sorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_keysorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_valsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_keyvarsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_valvarsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_keyrevsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_valrevsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_keyvarrevsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+extern int dtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *,
+ dtrace_aggregate_f *, void *);
+
+#define DTRACE_AGD_PRINTED 0x1 /* aggregation printed in program */
+
+/*
+ * DTrace Process Control Interface
+ *
+ * Library clients who wish to have libdtrace create or grab processes for
+ * monitoring of their symbol table changes may use these interfaces to
+ * request that libdtrace obtain control of the process using libproc.
+ */
+
+extern struct ps_prochandle *dtrace_proc_create(dtrace_hdl_t *,
+ const char *, char *const *, proc_child_func *, void *);
+
+extern struct ps_prochandle *dtrace_proc_grab(dtrace_hdl_t *, pid_t, int);
+extern void dtrace_proc_release(dtrace_hdl_t *, struct ps_prochandle *);
+extern void dtrace_proc_continue(dtrace_hdl_t *, struct ps_prochandle *);
+
+/*
+ * DTrace Object, Symbol, and Type Interfaces
+ *
+ * Library clients can use libdtrace to perform symbol and C type information
+ * lookups by symbol name, symbol address, or C type name, or to lookup meta-
+ * information cached for each of the program objects in use by DTrace. The
+ * resulting struct contain pointers to arbitrary-length strings, including
+ * object, symbol, and type names, that are persistent until the next call to
+ * dtrace_update(). Once dtrace_update() is called, any cached values must
+ * be flushed and not used subsequently by the client program.
+ */
+
+#define DTRACE_OBJ_EXEC ((const char *)0L) /* primary executable file */
+#define DTRACE_OBJ_RTLD ((const char *)1L) /* run-time link-editor */
+#define DTRACE_OBJ_CDEFS ((const char *)2L) /* C include definitions */
+#define DTRACE_OBJ_DDEFS ((const char *)3L) /* D program definitions */
+#define DTRACE_OBJ_EVERY ((const char *)-1L) /* all known objects */
+#define DTRACE_OBJ_KMODS ((const char *)-2L) /* all kernel objects */
+#define DTRACE_OBJ_UMODS ((const char *)-3L) /* all user objects */
+
+typedef struct dtrace_objinfo {
+ const char *dto_name; /* object file scope name */
+ const char *dto_file; /* object file path (if any) */
+ int dto_id; /* object file id (if any) */
+ uint_t dto_flags; /* object flags (see below) */
+ GElf_Addr dto_text_va; /* address of text section */
+ GElf_Xword dto_text_size; /* size of text section */
+ GElf_Addr dto_data_va; /* address of data section */
+ GElf_Xword dto_data_size; /* size of data section */
+ GElf_Addr dto_bss_va; /* address of BSS */
+ GElf_Xword dto_bss_size; /* size of BSS */
+} dtrace_objinfo_t;
+
+#define DTRACE_OBJ_F_KERNEL 0x1 /* object is a kernel module */
+#define DTRACE_OBJ_F_PRIMARY 0x2 /* object is a primary module */
+
+typedef int dtrace_obj_f(dtrace_hdl_t *, const dtrace_objinfo_t *, void *);
+
+extern int dtrace_object_iter(dtrace_hdl_t *, dtrace_obj_f *, void *);
+extern int dtrace_object_info(dtrace_hdl_t *, const char *, dtrace_objinfo_t *);
+
+typedef struct dtrace_syminfo {
+ const char *dts_object; /* object name */
+ const char *dts_name; /* symbol name */
+ ulong_t dts_id; /* symbol id */
+} dtrace_syminfo_t;
+
+extern int dtrace_lookup_by_name(dtrace_hdl_t *, const char *, const char *,
+ GElf_Sym *, dtrace_syminfo_t *);
+
+extern int dtrace_lookup_by_addr(dtrace_hdl_t *, GElf_Addr addr,
+ GElf_Sym *, dtrace_syminfo_t *);
+
+typedef struct dtrace_typeinfo {
+ const char *dtt_object; /* object containing type */
+ ctf_file_t *dtt_ctfp; /* CTF container handle */
+ ctf_id_t dtt_type; /* CTF type identifier */
+} dtrace_typeinfo_t;
+
+extern int dtrace_lookup_by_type(dtrace_hdl_t *, const char *, const char *,
+ dtrace_typeinfo_t *);
+
+extern int dtrace_symbol_type(dtrace_hdl_t *, const GElf_Sym *,
+ const dtrace_syminfo_t *, dtrace_typeinfo_t *);
+
+extern int dtrace_type_strcompile(dtrace_hdl_t *,
+ const char *, dtrace_typeinfo_t *);
+
+extern int dtrace_type_fcompile(dtrace_hdl_t *,
+ FILE *, dtrace_typeinfo_t *);
+
+/*
+ * DTrace Probe Interface
+ *
+ * Library clients can use these functions to iterate over the set of available
+ * probe definitions and inquire as to their attributes. The probe iteration
+ * interfaces report probes that are declared as well as those from dtrace(7D).
+ */
+typedef struct dtrace_probeinfo {
+ dtrace_attribute_t dtp_attr; /* name attributes */
+ dtrace_attribute_t dtp_arga; /* arg attributes */
+ const dtrace_typeinfo_t *dtp_argv; /* arg types */
+ int dtp_argc; /* arg count */
+} dtrace_probeinfo_t;
+
+typedef int dtrace_probe_f(dtrace_hdl_t *, const dtrace_probedesc_t *, void *);
+
+extern int dtrace_probe_iter(dtrace_hdl_t *,
+ const dtrace_probedesc_t *pdp, dtrace_probe_f *, void *);
+
+extern int dtrace_probe_info(dtrace_hdl_t *,
+ const dtrace_probedesc_t *, dtrace_probeinfo_t *);
+
+/*
+ * DTrace Vector Interface
+ *
+ * The DTrace library normally speaks directly to dtrace(7D). However,
+ * this communication may be vectored elsewhere. Consumers who wish to
+ * perform a vectored open must fill in the vector, and use the dtrace_vopen()
+ * entry point to obtain a library handle.
+ */
+struct dtrace_vector {
+#if defined(sun)
+ int (*dtv_ioctl)(void *, int, void *);
+#else
+ int (*dtv_ioctl)(void *, u_long, void *);
+#endif
+ int (*dtv_lookup_by_addr)(void *, GElf_Addr, GElf_Sym *,
+ dtrace_syminfo_t *);
+ int (*dtv_status)(void *, processorid_t);
+ long (*dtv_sysconf)(void *, int);
+};
+
+/*
+ * DTrace Utility Functions
+ *
+ * Library clients can use these functions to convert addresses strings, to
+ * convert between string and integer probe descriptions and the
+ * dtrace_probedesc_t representation, and to perform similar conversions on
+ * stability attributes.
+ */
+extern int dtrace_addr2str(dtrace_hdl_t *, uint64_t, char *, int);
+extern int dtrace_uaddr2str(dtrace_hdl_t *, pid_t, uint64_t, char *, int);
+
+extern int dtrace_xstr2desc(dtrace_hdl_t *, dtrace_probespec_t,
+ const char *, int, char *const [], dtrace_probedesc_t *);
+
+extern int dtrace_str2desc(dtrace_hdl_t *, dtrace_probespec_t,
+ const char *, dtrace_probedesc_t *);
+
+extern int dtrace_id2desc(dtrace_hdl_t *, dtrace_id_t, dtrace_probedesc_t *);
+
+#define DTRACE_DESC2STR_MAX 1024 /* min buf size for dtrace_desc2str() */
+
+extern char *dtrace_desc2str(const dtrace_probedesc_t *, char *, size_t);
+
+#define DTRACE_ATTR2STR_MAX 64 /* min buf size for dtrace_attr2str() */
+
+extern char *dtrace_attr2str(dtrace_attribute_t, char *, size_t);
+extern int dtrace_str2attr(const char *, dtrace_attribute_t *);
+
+extern const char *dtrace_stability_name(dtrace_stability_t);
+extern const char *dtrace_class_name(dtrace_class_t);
+
+extern int dtrace_provider_modules(dtrace_hdl_t *, const char **, int);
+
+extern const char *const _dtrace_version;
+extern int _dtrace_debug;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if !defined(sun)
+#define _SC_CPUID_MAX _SC_NPROCESSORS_CONF
+#define _SC_NPROCESSORS_MAX _SC_NPROCESSORS_CONF
+#endif
+
+#endif /* _DTRACE_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh
new file mode 100755
index 0000000..50b7f1c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+echo "\
+/*\n\
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
+ * Use is subject to license terms.\n\
+ */\n\
+\n\
+#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
+
+pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$'
+replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
+
+sed -n "s/$pattern/$replace/p" | tr '@' '\n'
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh
new file mode 100644
index 0000000..d5651ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+BSDECHO=-e
+
+echo ${BSDECHO} "\
+/*\n\
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
+ * Use is subject to license terms.\n\
+ */\n\
+\n\
+#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
+\n\
+#include <dt_errtags.h>
+\n\
+static const char *const _dt_errtags[] = {"
+
+pattern='^ \(D_[A-Z0-9_]*\),*'
+replace=' "\1",'
+
+sed -n "s/$pattern/$replace/p" || exit 1
+
+echo ${BSDECHO} "\
+};\n\
+\n\
+static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);\n\
+\n\
+const char *
+dt_errtag(dt_errtag_t tag)
+{
+ return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]);
+}"
+
+exit 0
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
new file mode 100644
index 0000000..2fdc2fa
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+BSDECHO=-e
+
+echo ${BSDECHO} "\
+/*\n\
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.\n\
+ * Use is subject to license terms.\n\
+ */\n\
+\n\
+#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\
+\n\
+#include <dtrace.h>\n\
+\n\
+/*ARGSUSED*/
+const char *\n\
+dtrace_subrstr(dtrace_hdl_t *dtp, int subr)\n\
+{\n\
+ switch (subr) {"
+
+nawk '
+/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
+ printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
+}'
+
+echo ${BSDECHO} "\
+ default: return (\"unknown\");\n\
+ }\n\
+}"
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh
new file mode 100755
index 0000000..1bffa64
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+echo "\
+/*\n\
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\
+ * Use is subject to license terms.\n\
+ */\n\
+\n\
+#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n"
+
+pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$'
+replace='inline int \1 = \2;@#pragma D binding "1.0" \1'
+
+sed -n "s/$pattern/$replace/p;/SIGRTMAX/q" | tr '@' '\n'
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c
new file mode 100644
index 0000000..f11ae48
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c
@@ -0,0 +1,532 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <dt_impl.h>
+#include <dt_pid.h>
+
+#include <dis_tables.h>
+
+#if !defined(sun)
+#define PR_MODEL_ILP32 1
+#define PR_MODEL_LP64 2
+#include <libproc_compat.h>
+#endif
+
+#define DT_POPL_EBP 0x5d
+#define DT_RET 0xc3
+#define DT_RET16 0xc2
+#define DT_LEAVE 0xc9
+#define DT_JMP32 0xe9
+#define DT_JMP8 0xeb
+#define DT_REP 0xf3
+
+#define DT_MOVL_EBP_ESP 0xe58b
+
+#define DT_ISJ32(op16) (((op16) & 0xfff0) == 0x0f80)
+#define DT_ISJ8(op8) (((op8) & 0xf0) == 0x70)
+
+#define DT_MODRM_REG(modrm) (((modrm) >> 3) & 0x7)
+
+static int dt_instr_size(uchar_t *, dtrace_hdl_t *, pid_t, uintptr_t, char);
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+ ftp->ftps_type = DTFTP_ENTRY;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 1;
+ ftp->ftps_offs[0] = 0;
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (1);
+}
+
+static int
+dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ uint8_t *text, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+ ulong_t i;
+ int size;
+#if defined(sun)
+ pid_t pid = Pstatus(P)->pr_pid;
+ char dmodel = Pstatus(P)->pr_dmodel;
+#else
+ pid_t pid = proc_getpid(P);
+#if __i386__
+ char dmodel = PR_MODEL_ILP32;
+#elif __amd64__
+ char dmodel = PR_MODEL_LP64;
+#endif
+#endif
+
+ /*
+ * Take a pass through the function looking for a register-dependant
+ * jmp instruction. This could be a jump table so we have to be
+ * ultra conservative.
+ */
+ for (i = 0; i < ftp->ftps_size; i += size) {
+ size = dt_instr_size(&text[i], dtp, pid, symp->st_value + i,
+ dmodel);
+
+ /*
+ * Assume the worst if we hit an illegal instruction.
+ */
+ if (size <= 0) {
+ dt_dprintf("error at %#lx (assuming jump table)\n", i);
+ return (1);
+ }
+
+#ifdef notyet
+ /*
+ * Register-dependant jmp instructions start with a 0xff byte
+ * and have the modrm.reg field set to 4. They can have an
+ * optional REX prefix on the 64-bit ISA.
+ */
+ if ((text[i] == 0xff && DT_MODRM_REG(text[i + 1]) == 4) ||
+ (dmodel == PR_MODEL_LP64 && (text[i] & 0xf0) == 0x40 &&
+ text[i + 1] == 0xff && DT_MODRM_REG(text[i + 2]) == 4)) {
+ dt_dprintf("found a suspected jump table at %s:%lx\n",
+ ftp->ftps_func, i);
+ return (1);
+ }
+#endif
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+ uint8_t *text;
+ ulong_t i, end;
+ int size;
+#if defined(sun)
+ pid_t pid = Pstatus(P)->pr_pid;
+ char dmodel = Pstatus(P)->pr_dmodel;
+#else
+ pid_t pid = proc_getpid(P);
+#if __i386__
+ char dmodel = PR_MODEL_ILP32;
+#elif __amd64__
+ char dmodel = PR_MODEL_LP64;
+#endif
+#endif
+
+ /*
+ * We allocate a few extra bytes at the end so we don't have to check
+ * for overrunning the buffer.
+ */
+ if ((text = calloc(1, symp->st_size + 4)) == NULL) {
+ dt_dprintf("mr sparkle: malloc() failed\n");
+ return (DT_PROC_ERR);
+ }
+
+ if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {
+ dt_dprintf("mr sparkle: Pread() failed\n");
+ free(text);
+ return (DT_PROC_ERR);
+ }
+
+ ftp->ftps_type = DTFTP_RETURN;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 0;
+
+ /*
+ * If there's a jump table in the function we're only willing to
+ * instrument these specific (and equivalent) instruction sequences:
+ * leave
+ * [rep] ret
+ * and
+ * movl %ebp,%esp
+ * popl %ebp
+ * [rep] ret
+ *
+ * We do this to avoid accidentally interpreting jump table
+ * offsets as actual instructions.
+ */
+ if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) {
+ for (i = 0, end = ftp->ftps_size; i < end; i += size) {
+ size = dt_instr_size(&text[i], dtp, pid,
+ symp->st_value + i, dmodel);
+
+ /* bail if we hit an invalid opcode */
+ if (size <= 0)
+ break;
+
+ if (text[i] == DT_LEAVE && text[i + 1] == DT_RET) {
+ dt_dprintf("leave/ret at %lx\n", i + 1);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i + 1;
+ size = 2;
+ } else if (text[i] == DT_LEAVE &&
+ text[i + 1] == DT_REP && text[i + 2] == DT_RET) {
+ dt_dprintf("leave/rep ret at %lx\n", i + 1);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i + 1;
+ size = 3;
+ } else if (*(uint16_t *)&text[i] == DT_MOVL_EBP_ESP &&
+ text[i + 2] == DT_POPL_EBP &&
+ text[i + 3] == DT_RET) {
+ dt_dprintf("movl/popl/ret at %lx\n", i + 3);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i + 3;
+ size = 4;
+ } else if (*(uint16_t *)&text[i] == DT_MOVL_EBP_ESP &&
+ text[i + 2] == DT_POPL_EBP &&
+ text[i + 3] == DT_REP &&
+ text[i + 4] == DT_RET) {
+ dt_dprintf("movl/popl/rep ret at %lx\n", i + 3);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i + 3;
+ size = 5;
+ }
+ }
+ } else {
+ for (i = 0, end = ftp->ftps_size; i < end; i += size) {
+ size = dt_instr_size(&text[i], dtp, pid,
+ symp->st_value + i, dmodel);
+
+ /* bail if we hit an invalid opcode */
+ if (size <= 0)
+ break;
+
+ /* ordinary ret */
+ if (size == 1 && text[i] == DT_RET)
+ goto is_ret;
+
+ /* two-byte ret */
+ if (size == 2 && text[i] == DT_REP &&
+ text[i + 1] == DT_RET)
+ goto is_ret;
+
+ /* ret <imm16> */
+ if (size == 3 && text[i] == DT_RET16)
+ goto is_ret;
+
+ /* two-byte ret <imm16> */
+ if (size == 4 && text[i] == DT_REP &&
+ text[i + 1] == DT_RET16)
+ goto is_ret;
+
+ /* 32-bit displacement jmp outside of the function */
+ if (size == 5 && text[i] == DT_JMP32 && symp->st_size <=
+ (uintptr_t)(i + size + *(int32_t *)&text[i + 1]))
+ goto is_ret;
+
+ /* 8-bit displacement jmp outside of the function */
+ if (size == 2 && text[i] == DT_JMP8 && symp->st_size <=
+ (uintptr_t)(i + size + *(int8_t *)&text[i + 1]))
+ goto is_ret;
+
+ /* 32-bit disp. conditional jmp outside of the func. */
+ if (size == 6 && DT_ISJ32(*(uint16_t *)&text[i]) &&
+ symp->st_size <=
+ (uintptr_t)(i + size + *(int32_t *)&text[i + 2]))
+ goto is_ret;
+
+ /* 8-bit disp. conditional jmp outside of the func. */
+ if (size == 2 && DT_ISJ8(text[i]) && symp->st_size <=
+ (uintptr_t)(i + size + *(int8_t *)&text[i + 1]))
+ goto is_ret;
+
+ continue;
+is_ret:
+ dt_dprintf("return at offset %lx\n", i);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i;
+ }
+ }
+
+ free(text);
+ if (ftp->ftps_noffs > 0) {
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+ }
+
+ return (ftp->ftps_noffs);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+ ftp->ftps_type = DTFTP_OFFSETS;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 1;
+
+ if (strcmp("-", ftp->ftps_func) == 0) {
+ ftp->ftps_offs[0] = off;
+ } else {
+ uint8_t *text;
+ ulong_t i;
+ int size;
+#if defined(sun)
+ pid_t pid = Pstatus(P)->pr_pid;
+ char dmodel = Pstatus(P)->pr_dmodel;
+#else
+ pid_t pid = proc_getpid(P);
+#if __i386__
+ char dmodel = PR_MODEL_ILP32;
+#elif __amd64__
+ char dmodel = PR_MODEL_LP64;
+#endif
+#endif
+
+ if ((text = malloc(symp->st_size)) == NULL) {
+ dt_dprintf("mr sparkle: malloc() failed\n");
+ return (DT_PROC_ERR);
+ }
+
+ if (Pread(P, text, symp->st_size, symp->st_value) !=
+ symp->st_size) {
+ dt_dprintf("mr sparkle: Pread() failed\n");
+ free(text);
+ return (DT_PROC_ERR);
+ }
+
+ /*
+ * We can't instrument offsets in functions with jump tables
+ * as we might interpret a jump table offset as an
+ * instruction.
+ */
+ if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) {
+ free(text);
+ return (0);
+ }
+
+ for (i = 0; i < symp->st_size; i += size) {
+ if (i == off) {
+ ftp->ftps_offs[0] = i;
+ break;
+ }
+
+ /*
+ * If we've passed the desired offset without a
+ * match, then the given offset must not lie on a
+ * instruction boundary.
+ */
+ if (i > off) {
+ free(text);
+ return (DT_PROC_ALIGN);
+ }
+
+ size = dt_instr_size(&text[i], dtp, pid,
+ symp->st_value + i, dmodel);
+
+ /*
+ * If we hit an invalid instruction, bail as if we
+ * couldn't find the offset.
+ */
+ if (size <= 0) {
+ free(text);
+ return (DT_PROC_ALIGN);
+ }
+ }
+
+ free(text);
+ }
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (ftp->ftps_noffs);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+ uint8_t *text;
+ int size;
+ ulong_t i, end = symp->st_size;
+#if defined(sun)
+ pid_t pid = Pstatus(P)->pr_pid;
+ char dmodel = Pstatus(P)->pr_dmodel;
+#else
+ pid_t pid = proc_getpid(P);
+#if __i386__
+ char dmodel = PR_MODEL_ILP32;
+#elif __amd64__
+ char dmodel = PR_MODEL_LP64;
+#endif
+#endif
+
+ ftp->ftps_type = DTFTP_OFFSETS;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 0;
+
+ if ((text = malloc(symp->st_size)) == NULL) {
+ dt_dprintf("mr sparkle: malloc() failed\n");
+ return (DT_PROC_ERR);
+ }
+
+ if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {
+ dt_dprintf("mr sparkle: Pread() failed\n");
+ free(text);
+ return (DT_PROC_ERR);
+ }
+
+ /*
+ * We can't instrument offsets in functions with jump tables as
+ * we might interpret a jump table offset as an instruction.
+ */
+ if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) {
+ free(text);
+ return (0);
+ }
+
+ if (strcmp("*", pattern) == 0) {
+ for (i = 0; i < end; i += size) {
+ ftp->ftps_offs[ftp->ftps_noffs++] = i;
+
+ size = dt_instr_size(&text[i], dtp, pid,
+ symp->st_value + i, dmodel);
+
+ /* bail if we hit an invalid opcode */
+ if (size <= 0)
+ break;
+ }
+ } else {
+ char name[sizeof (i) * 2 + 1];
+
+ for (i = 0; i < end; i += size) {
+ (void) snprintf(name, sizeof (name), "%lx", i);
+ if (gmatch(name, pattern))
+ ftp->ftps_offs[ftp->ftps_noffs++] = i;
+
+ size = dt_instr_size(&text[i], dtp, pid,
+ symp->st_value + i, dmodel);
+
+ /* bail if we hit an invalid opcode */
+ if (size <= 0)
+ break;
+ }
+ }
+
+ free(text);
+ if (ftp->ftps_noffs > 0) {
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+ }
+
+ return (ftp->ftps_noffs);
+}
+
+typedef struct dtrace_dis {
+ uchar_t *instr;
+ dtrace_hdl_t *dtp;
+ pid_t pid;
+ uintptr_t addr;
+} dtrace_dis_t;
+
+static int
+dt_getbyte(void *data)
+{
+ dtrace_dis_t *dis = data;
+ int ret = *dis->instr;
+
+ if (ret == FASTTRAP_INSTR) {
+ fasttrap_instr_query_t instr;
+
+ instr.ftiq_pid = dis->pid;
+ instr.ftiq_pc = dis->addr;
+
+ /*
+ * If we hit a byte that looks like the fasttrap provider's
+ * trap instruction (which doubles as the breakpoint
+ * instruction for debuggers) we need to query the kernel
+ * for the real value. This may just be part of an immediate
+ * value so there's no need to return an error if the
+ * kernel doesn't know about this address.
+ */
+ if (ioctl(dis->dtp->dt_ftfd, FASTTRAPIOC_GETINSTR, &instr) == 0)
+ ret = instr.ftiq_instr;
+ }
+
+ dis->addr++;
+ dis->instr++;
+
+ return (ret);
+}
+
+static int
+dt_instr_size(uchar_t *instr, dtrace_hdl_t *dtp, pid_t pid, uintptr_t addr,
+ char dmodel)
+{
+ dtrace_dis_t data;
+ dis86_t x86dis;
+ uint_t cpu_mode;
+
+ data.instr = instr;
+ data.dtp = dtp;
+ data.pid = pid;
+ data.addr = addr;
+
+ x86dis.d86_data = &data;
+ x86dis.d86_get_byte = dt_getbyte;
+ x86dis.d86_check_func = NULL;
+
+ cpu_mode = (dmodel == PR_MODEL_ILP32) ? SIZE32 : SIZE64;
+
+ if (dtrace_disx86(&x86dis, cpu_mode) != 0)
+ return (-1);
+
+ /*
+ * If the instruction was a single-byte breakpoint, there may be
+ * another debugger attached to this process. The original instruction
+ * can't be recovered so this must fail.
+ */
+ if (x86dis.d86_len == 1 && instr[0] == FASTTRAP_INSTR)
+ return (-1);
+
+ return (x86dis.d86_len);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in
new file mode 100644
index 0000000..3328f33
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+inline int R_GS = @GS@;
+#pragma D binding "1.0" R_GS
+inline int R_FS = @FS@;
+#pragma D binding "1.0" R_FS
+inline int R_ES = @ES@;
+#pragma D binding "1.0" R_ES
+inline int R_DS = @DS@;
+#pragma D binding "1.0" R_DS
+
+inline int R_EDI = @EDI@;
+#pragma D binding "1.0" R_EDI
+inline int R_ESI = @ESI@;
+#pragma D binding "1.0" R_ESI
+inline int R_EBP = @EBP@;
+#pragma D binding "1.0" R_EBP
+inline int R_ESP = @ESP@;
+#pragma D binding "1.0" R_ESP
+inline int R_EBX = @EBX@;
+#pragma D binding "1.0" R_EBX
+inline int R_EDX = @EDX@;
+#pragma D binding "1.0" R_EDX
+inline int R_ECX = @ECX@;
+#pragma D binding "1.0" R_ECX
+inline int R_EAX = @EAX@;
+#pragma D binding "1.0" R_EAX
+
+inline int R_TRAPNO = @TRAPNO@;
+#pragma D binding "1.0" R_TRAPNO
+inline int R_ERR = @ERR@;
+#pragma D binding "1.0" R_ERR
+inline int R_EIP = @EIP@;
+#pragma D binding "1.0" R_EIP
+inline int R_CS = @CS@;
+#pragma D binding "1.0" R_CS
+inline int R_EFL = @EFL@;
+#pragma D binding "1.0" R_EFL
+inline int R_UESP = @UESP@;
+#pragma D binding "1.0" R_UESP
+inline int R_SS = @SS@;
+#pragma D binding "1.0" R_SS
+
+inline int R_PC = R_EIP;
+#pragma D binding "1.0" R_PC
+inline int R_SP = R_UESP;
+#pragma D binding "1.0" R_SP
+inline int R_PS = R_EFL;
+#pragma D binding "1.0" R_PS
+inline int R_R0 = R_EAX;
+#pragma D binding "1.0" R_R0
+inline int R_R1 = R_EBX;
+#pragma D binding "1.0" R_R1
+
+inline int R_RSP = @REG_RSP@;
+#pragma D binding "1.0" R_RSP
+inline int R_RFL = @REG_RFL@;
+#pragma D binding "1.0" R_RFL
+inline int R_RIP = @REG_RIP@;
+#pragma D binding "1.0" R_RIP
+inline int R_RAX = @REG_RAX@;
+#pragma D binding "1.0" R_RAX
+inline int R_RCX = @REG_RCX@;
+#pragma D binding "1.0" R_RCX
+inline int R_RDX = @REG_RDX@;
+#pragma D binding "1.0" R_RDX
+inline int R_RBX = @REG_RBX@;
+#pragma D binding "1.0" R_RBX
+inline int R_RBP = @REG_RBP@;
+#pragma D binding "1.0" R_RBP
+inline int R_RSI = @REG_RSI@;
+#pragma D binding "1.0" R_RSI
+inline int R_RDI = @REG_RDI@;
+#pragma D binding "1.0" R_RDI
+inline int R_R8 = @REG_R8@;
+#pragma D binding "1.0" R_R8
+inline int R_R9 = @REG_R9@;
+#pragma D binding "1.0" R_R9
+inline int R_R10 = @REG_R10@;
+#pragma D binding "1.0" R_R10
+inline int R_R11 = @REG_R11@;
+#pragma D binding "1.0" R_R11
+inline int R_R12 = @REG_R12@;
+#pragma D binding "1.0" R_R12
+inline int R_R13 = @REG_R13@;
+#pragma D binding "1.0" R_R13
+inline int R_R14 = @REG_R14@;
+#pragma D binding "1.0" R_R14
+inline int R_R15 = @REG_R15@;
+#pragma D binding "1.0" R_R15
+
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in
new file mode 100644
index 0000000..2b2080f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file is a sed script which is first preprocessed by cpp or cc -E to
+ * define a set of sed directives which replace #define tokens with their
+ * values. After preprocessing, whitespace is eliminated, and any @ symbols
+ * are translated into single space. The resulting sed script is then run
+ * over regs.d.in to replace the #define tokens listed below to create the
+ * finished regs.d. Refer to the rules in libdtrace/i386/Makefile for more
+ * information.
+ */
+
+#include <sys/regset.h>
+
+#define SED_REPLACE(x) s/#x/x/g
+#define SED_REPLACE64(x) s/#x/SS @+@1@+@ x/g
+
+SED_REPLACE(GS)
+SED_REPLACE(FS)
+SED_REPLACE(ES)
+SED_REPLACE(DS)
+SED_REPLACE(EDI)
+SED_REPLACE(ESI)
+SED_REPLACE(EBP)
+SED_REPLACE(ESP)
+SED_REPLACE(EBX)
+SED_REPLACE(EDX)
+SED_REPLACE(ECX)
+SED_REPLACE(EAX)
+SED_REPLACE(TRAPNO)
+SED_REPLACE(ERR)
+SED_REPLACE(EIP)
+SED_REPLACE(CS)
+SED_REPLACE(EFL)
+SED_REPLACE(UESP)
+SED_REPLACE(SS)
+
+SED_REPLACE64(REG_RSP)
+SED_REPLACE64(REG_RFL)
+SED_REPLACE64(REG_RIP)
+SED_REPLACE64(REG_RAX)
+SED_REPLACE64(REG_RCX)
+SED_REPLACE64(REG_RDX)
+SED_REPLACE64(REG_RBX)
+SED_REPLACE64(REG_RBP)
+SED_REPLACE64(REG_RSI)
+SED_REPLACE64(REG_RDI)
+SED_REPLACE64(REG_R8)
+SED_REPLACE64(REG_R9)
+SED_REPLACE64(REG_R10)
+SED_REPLACE64(REG_R11)
+SED_REPLACE64(REG_R12)
+SED_REPLACE64(REG_R13)
+SED_REPLACE64(REG_R14)
+SED_REPLACE64(REG_R15)
+
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c
new file mode 100644
index 0000000..1aeb95f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <dt_impl.h>
+#include <dt_pid.h>
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c
new file mode 100644
index 0000000..1aeb95f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c
@@ -0,0 +1,75 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <dt_impl.h>
+#include <dt_pid.h>
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+
+ dt_dprintf("%s: unimplemented\n", __func__);
+ return (DT_PROC_ERR);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c
new file mode 100644
index 0000000..ed05275
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c
@@ -0,0 +1,338 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <dt_impl.h>
+#include <dt_pid.h>
+
+#define OP(x) ((x) >> 30)
+#define OP2(x) (((x) >> 22) & 0x07)
+#define COND(x) (((x) >> 25) & 0x0f)
+#define A(x) (((x) >> 29) & 0x01)
+
+#define OP_BRANCH 0
+
+#define OP2_BPcc 0x1
+#define OP2_Bicc 0x2
+#define OP2_BPr 0x3
+#define OP2_FBPfcc 0x5
+#define OP2_FBfcc 0x6
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+ ftp->ftps_type = DTFTP_ENTRY;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 1;
+ ftp->ftps_offs[0] = 0;
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (1);
+}
+
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+
+ uint32_t *text;
+ int i;
+ int srdepth = 0;
+
+ if ((text = malloc(symp->st_size + 4)) == NULL) {
+ dt_dprintf("mr sparkle: malloc() failed\n");
+ return (DT_PROC_ERR);
+ }
+
+ if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {
+ dt_dprintf("mr sparkle: Pread() failed\n");
+ free(text);
+ return (DT_PROC_ERR);
+ }
+
+ /*
+ * Leave a dummy instruction in the last slot to simplify edge
+ * conditions.
+ */
+ text[symp->st_size / 4] = 0;
+
+ ftp->ftps_type = DTFTP_RETURN;
+ ftp->ftps_pc = symp->st_value;
+ ftp->ftps_size = symp->st_size;
+ ftp->ftps_noffs = 0;
+
+ for (i = 0; i < symp->st_size / 4; i++) {
+ /*
+ * If we encounter an existing tracepoint, query the
+ * kernel to find out the instruction that was
+ * replaced at this spot.
+ */
+ while (text[i] == FASTTRAP_INSTR) {
+ fasttrap_instr_query_t instr;
+
+ instr.ftiq_pid = Pstatus(P)->pr_pid;
+ instr.ftiq_pc = symp->st_value + i * 4;
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_GETINSTR,
+ &instr) != 0) {
+
+ if (errno == ESRCH || errno == ENOENT) {
+ if (Pread(P, &text[i], 4,
+ instr.ftiq_pc) != 4) {
+ dt_dprintf("mr sparkle: "
+ "Pread() failed\n");
+ free(text);
+ return (DT_PROC_ERR);
+ }
+ continue;
+ }
+
+ free(text);
+ dt_dprintf("mr sparkle: getinstr query "
+ "failed: %s\n", strerror(errno));
+ return (DT_PROC_ERR);
+ }
+
+ text[i] = instr.ftiq_instr;
+ break;
+ }
+
+ /* save */
+ if ((text[i] & 0xc1f80000) == 0x81e00000) {
+ srdepth++;
+ continue;
+ }
+
+ /* restore */
+ if ((text[i] & 0xc1f80000) == 0x81e80000) {
+ srdepth--;
+ continue;
+ }
+
+ if (srdepth > 0) {
+ /* ret */
+ if (text[i] == 0x81c7e008)
+ goto is_ret;
+
+ /* return */
+ if (text[i] == 0x81cfe008)
+ goto is_ret;
+
+ /* call or jmpl w/ restore in the slot */
+ if (((text[i] & 0xc0000000) == 0x40000000 ||
+ (text[i] & 0xc1f80000) == 0x81c00000) &&
+ (text[i + 1] & 0xc1f80000) == 0x81e80000)
+ goto is_ret;
+
+ /* call to one of the stret routines */
+ if ((text[i] & 0xc0000000) == 0x40000000) {
+ int32_t disp = text[i] << 2;
+ uint64_t dest = ftp->ftps_pc + i * 4 + disp;
+
+ dt_dprintf("dest = %llx\n", (u_longlong_t)dest);
+
+ if (dest == stret[0] || dest == stret[1] ||
+ dest == stret[2] || dest == stret[3])
+ goto is_ret;
+ }
+ } else {
+ /* external call */
+ if ((text[i] & 0xc0000000) == 0x40000000) {
+ int32_t dst = text[i] << 2;
+
+ dst += i * 4;
+
+ if ((uintptr_t)dst >= (uintptr_t)symp->st_size)
+ goto is_ret;
+ }
+
+ /* jmpl into %g0 -- this includes the retl pseudo op */
+ if ((text[i] & 0xfff80000) == 0x81c00000)
+ goto is_ret;
+
+ /* external branch -- possible return site */
+ if (OP(text[i]) == OP_BRANCH) {
+ int32_t dst;
+ int baa;
+
+ switch (OP2(text[i])) {
+ case OP2_BPcc:
+ dst = text[i] & 0x7ffff;
+ dst <<= 13;
+ dst >>= 11;
+
+ baa = COND(text[i]) == 8 && A(text[i]);
+ break;
+ case OP2_Bicc:
+ dst = text[i] & 0x3fffff;
+ dst <<= 10;
+ dst >>= 8;
+
+ baa = COND(text[i]) == 8 && A(text[i]);
+ break;
+ case OP2_BPr:
+ dst = (((text[i]) >> 6) & 0xc000) |
+ ((text[i]) & 0x3fff);
+ dst <<= 16;
+ dst >>= 14;
+
+ baa = 0;
+ break;
+ case OP2_FBPfcc:
+ dst = text[i] & 0x7ffff;
+ dst <<= 13;
+ dst >>= 11;
+
+ baa = COND(text[i]) == 8 && A(text[i]);
+ break;
+ case OP2_FBfcc:
+ dst = text[i] & 0x3fffff;
+ dst <<= 10;
+ dst >>= 8;
+
+ baa = COND(text[i]) == 8 && A(text[i]);
+ break;
+ default:
+ continue;
+ }
+
+ dst += i * 4;
+
+ /*
+ * Interpret branches outside of the function's
+ * bounds as potential return sites. If the
+ * branch is a ba,a don't skip the instruction
+ * in the delay slot.
+ */
+ if ((uintptr_t)dst >=
+ (uintptr_t)symp->st_size) {
+ if (baa)
+ goto is_ret_baa;
+ else
+ goto is_ret;
+ }
+ }
+ }
+
+ continue;
+is_ret:
+ i++;
+is_ret_baa:
+ dt_dprintf("return at offset %x\n", i * 4);
+ ftp->ftps_offs[ftp->ftps_noffs++] = i * 4;
+ }
+
+ free(text);
+ if (ftp->ftps_noffs > 0) {
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+ }
+
+
+ return (ftp->ftps_noffs);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+ if (off & 0x3)
+ return (DT_PROC_ALIGN);
+
+ ftp->ftps_type = DTFTP_OFFSETS;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 1;
+ ftp->ftps_offs[0] = off;
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (1);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+ fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+ ulong_t i;
+
+ ftp->ftps_type = DTFTP_OFFSETS;
+ ftp->ftps_pc = (uintptr_t)symp->st_value;
+ ftp->ftps_size = (size_t)symp->st_size;
+ ftp->ftps_noffs = 0;
+
+ /*
+ * If we're matching against everything, just iterate through each
+ * instruction in the function, otherwise look for matching offset
+ * names by constructing the string and comparing it against the
+ * pattern.
+ */
+ if (strcmp("*", pattern) == 0) {
+ for (i = 0; i < symp->st_size; i += 4) {
+ ftp->ftps_offs[ftp->ftps_noffs++] = i;
+ }
+ } else {
+ char name[sizeof (i) * 2 + 1];
+
+ for (i = 0; i < symp->st_size; i += 4) {
+ (void) sprintf(name, "%lx", i);
+ if (gmatch(name, pattern))
+ ftp->ftps_offs[ftp->ftps_noffs++] = i;
+ }
+ }
+
+ if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+ dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+ strerror(errno));
+ return (dt_set_errno(dtp, errno));
+ }
+
+ return (ftp->ftps_noffs);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d b/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d
new file mode 100644
index 0000000..7c4bc0f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+inline int R_G0 = 0;
+#pragma D binding "1.0" R_G0
+inline int R_G1 = 1;
+#pragma D binding "1.0" R_G1
+inline int R_G2 = 2;
+#pragma D binding "1.0" R_G2
+inline int R_G3 = 3;
+#pragma D binding "1.0" R_G3
+inline int R_G4 = 4;
+#pragma D binding "1.0" R_G4
+inline int R_G5 = 5;
+#pragma D binding "1.0" R_G5
+inline int R_G6 = 6;
+#pragma D binding "1.0" R_G6
+inline int R_G7 = 7;
+#pragma D binding "1.0" R_G7
+
+inline int R_O0 = 8;
+#pragma D binding "1.0" R_O0
+inline int R_O1 = 9;
+#pragma D binding "1.0" R_O1
+inline int R_O2 = 10;
+#pragma D binding "1.0" R_O2
+inline int R_O3 = 11;
+#pragma D binding "1.0" R_O3
+inline int R_O4 = 12;
+#pragma D binding "1.0" R_O4
+inline int R_O5 = 13;
+#pragma D binding "1.0" R_O5
+inline int R_O6 = 14;
+#pragma D binding "1.0" R_O6
+inline int R_O7 = 15;
+#pragma D binding "1.0" R_O7
+
+inline int R_L0 = 16;
+#pragma D binding "1.0" R_L0
+inline int R_L1 = 17;
+#pragma D binding "1.0" R_L1
+inline int R_L2 = 18;
+#pragma D binding "1.0" R_L2
+inline int R_L3 = 19;
+#pragma D binding "1.0" R_L3
+inline int R_L4 = 20;
+#pragma D binding "1.0" R_L4
+inline int R_L5 = 21;
+#pragma D binding "1.0" R_L5
+inline int R_L6 = 22;
+#pragma D binding "1.0" R_L6
+inline int R_L7 = 23;
+#pragma D binding "1.0" R_L7
+
+inline int R_I0 = 24;
+#pragma D binding "1.0" R_I0
+inline int R_I1 = 25;
+#pragma D binding "1.0" R_I1
+inline int R_I2 = 26;
+#pragma D binding "1.0" R_I2
+inline int R_I3 = 27;
+#pragma D binding "1.0" R_I3
+inline int R_I4 = 28;
+#pragma D binding "1.0" R_I4
+inline int R_I5 = 29;
+#pragma D binding "1.0" R_I5
+inline int R_I6 = 30;
+#pragma D binding "1.0" R_I6
+inline int R_I7 = 31;
+#pragma D binding "1.0" R_I7
+
+inline int R_CCR = 32;
+#pragma D binding "1.0" R_CCR
+inline int R_PC = 33;
+#pragma D binding "1.0" R_PC
+inline int R_nPC = 34;
+#pragma D binding "1.0" R_nPC
+inline int R_NPC = R_nPC;
+#pragma D binding "1.0" R_NPC
+inline int R_Y = 35;
+#pragma D binding "1.0" R_Y
+inline int R_ASI = 36;
+#pragma D binding "1.0" R_ASI
+inline int R_FPRS = 37;
+#pragma D binding "1.0" R_FPRS
+inline int R_PS = R_CCR;
+#pragma D binding "1.0" R_PS
+inline int R_SP = R_O6;
+#pragma D binding "1.0" R_SP
+inline int R_FP = R_I6;
+#pragma D binding "1.0" R_FP
+inline int R_R0 = R_O0;
+#pragma D binding "1.0" R_R0
+inline int R_R1 = R_O1;
+#pragma D binding "1.0" R_R1
diff --git a/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c b/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c
new file mode 100644
index 0000000..fe4a382
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#if defined(sun)
+#pragma weak gmatch = _gmatch
+
+#include "gen_synonyms.h"
+#endif
+#include <sys/types.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <limits.h>
+#if defined(sun)
+#include <widec.h>
+#include "_range.h"
+#else
+/* DOODAD */ static int multibyte = 0;
+#define WCHAR_CSMASK 0x30000000
+#define valid_range(c1, c2) \
+ (((c1) & WCHAR_CSMASK) == ((c2) & WCHAR_CSMASK) && \
+ ((c1) > 0xff || !iscntrl((int)c1)) && ((c2) > 0xff || \
+ !iscntrl((int)c2)))
+#endif
+
+#define Popwchar(p, c) \
+ n = mbtowc(&cl, p, MB_LEN_MAX); \
+ c = cl; \
+ if (n <= 0) \
+ return (0); \
+ p += n
+
+int
+gmatch(const char *s, const char *p)
+{
+ const char *olds;
+ wchar_t scc, c;
+ int n;
+ wchar_t cl;
+
+ olds = s;
+ n = mbtowc(&cl, s, MB_LEN_MAX);
+ if (n <= 0) {
+ s++;
+ scc = n;
+ } else {
+ scc = cl;
+ s += n;
+ }
+ n = mbtowc(&cl, p, MB_LEN_MAX);
+ if (n < 0)
+ return (0);
+ if (n == 0)
+ return (scc == 0);
+ p += n;
+ c = cl;
+
+ switch (c) {
+ case '[':
+ if (scc <= 0)
+ return (0);
+ {
+ int ok;
+ wchar_t lc = 0;
+ int notflag = 0;
+
+ ok = 0;
+ if (*p == '!') {
+ notflag = 1;
+ p++;
+ }
+ Popwchar(p, c);
+ do
+ {
+ if (c == '-' && lc && *p != ']') {
+ Popwchar(p, c);
+ if (c == '\\') {
+ Popwchar(p, c);
+ }
+ if (notflag) {
+ if (!multibyte ||
+ valid_range(lc, c)) {
+ if (scc < lc || scc > c)
+ ok++;
+ else
+ return (0);
+ }
+ } else {
+ if (!multibyte ||
+ valid_range(lc, c))
+ if (lc <= scc &&
+ scc <= c)
+ ok++;
+ }
+ } else if (c == '\\') {
+ /* skip to quoted character */
+ Popwchar(p, c);
+ }
+ lc = c;
+ if (notflag) {
+ if (scc != lc)
+ ok++;
+ else
+ return (0);
+ }
+ else
+ {
+ if (scc == lc)
+ ok++;
+ }
+ Popwchar(p, c);
+ } while (c != ']');
+ return (ok ? gmatch(s, p) : 0);
+ }
+
+ case '\\':
+ /* skip to quoted character and see if it matches */
+ Popwchar(p, c);
+
+ default:
+ if (c != scc)
+ return (0);
+ /*FALLTHRU*/
+
+ case '?':
+ return (scc > 0 ? gmatch(s, p) : 0);
+
+ case '*':
+ while (*p == '*')
+ p++;
+
+ if (*p == 0)
+ return (1);
+ s = olds;
+ while (*s) {
+ if (gmatch(s, p))
+ return (1);
+ n = mbtowc(&cl, s, MB_LEN_MAX);
+ if (n < 0)
+ /* skip past illegal byte sequence */
+ s++;
+ else
+ s += n;
+ }
+ return (0);
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c
new file mode 100644
index 0000000..3302ac7
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c
@@ -0,0 +1,1273 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <solaris.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <strings.h>
+#include <libintl.h>
+#include <stdarg.h>
+#include "libnvpair.h"
+
+/*
+ * libnvpair - A tools library for manipulating <name, value> pairs.
+ *
+ * This library provides routines packing an unpacking nv pairs
+ * for transporting data across process boundaries, transporting
+ * between kernel and userland, and possibly saving onto disk files.
+ */
+
+/*
+ * Print control structure.
+ */
+
+#define DEFINEOP(opname, vtype) \
+ struct { \
+ int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
+ const char *, vtype); \
+ void *arg; \
+ } opname
+
+#define DEFINEARROP(opname, vtype) \
+ struct { \
+ int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \
+ const char *, vtype, uint_t); \
+ void *arg; \
+ } opname
+
+struct nvlist_printops {
+ DEFINEOP(print_boolean, int);
+ DEFINEOP(print_boolean_value, boolean_t);
+ DEFINEOP(print_byte, uchar_t);
+ DEFINEOP(print_int8, int8_t);
+ DEFINEOP(print_uint8, uint8_t);
+ DEFINEOP(print_int16, int16_t);
+ DEFINEOP(print_uint16, uint16_t);
+ DEFINEOP(print_int32, int32_t);
+ DEFINEOP(print_uint32, uint32_t);
+ DEFINEOP(print_int64, int64_t);
+ DEFINEOP(print_uint64, uint64_t);
+ DEFINEOP(print_double, double);
+ DEFINEOP(print_string, char *);
+ DEFINEOP(print_hrtime, hrtime_t);
+ DEFINEOP(print_nvlist, nvlist_t *);
+ DEFINEARROP(print_boolean_array, boolean_t *);
+ DEFINEARROP(print_byte_array, uchar_t *);
+ DEFINEARROP(print_int8_array, int8_t *);
+ DEFINEARROP(print_uint8_array, uint8_t *);
+ DEFINEARROP(print_int16_array, int16_t *);
+ DEFINEARROP(print_uint16_array, uint16_t *);
+ DEFINEARROP(print_int32_array, int32_t *);
+ DEFINEARROP(print_uint32_array, uint32_t *);
+ DEFINEARROP(print_int64_array, int64_t *);
+ DEFINEARROP(print_uint64_array, uint64_t *);
+ DEFINEARROP(print_string_array, char **);
+ DEFINEARROP(print_nvlist_array, nvlist_t **);
+};
+
+struct nvlist_prtctl {
+ FILE *nvprt_fp; /* output destination */
+ enum nvlist_indent_mode nvprt_indent_mode; /* see above */
+ int nvprt_indent; /* absolute indent, or tab depth */
+ int nvprt_indentinc; /* indent or tab increment */
+ const char *nvprt_nmfmt; /* member name format, max one %s */
+ const char *nvprt_eomfmt; /* after member format, e.g. "\n" */
+ const char *nvprt_btwnarrfmt; /* between array members */
+ int nvprt_btwnarrfmt_nl; /* nvprt_eoamfmt includes newline? */
+ struct nvlist_printops *nvprt_dfltops;
+ struct nvlist_printops *nvprt_custops;
+};
+
+#define DFLTPRTOP(pctl, type) \
+ ((pctl)->nvprt_dfltops->print_##type.op)
+
+#define DFLTPRTOPARG(pctl, type) \
+ ((pctl)->nvprt_dfltops->print_##type.arg)
+
+#define CUSTPRTOP(pctl, type) \
+ ((pctl)->nvprt_custops->print_##type.op)
+
+#define CUSTPRTOPARG(pctl, type) \
+ ((pctl)->nvprt_custops->print_##type.arg)
+
+#define RENDER(pctl, type, nvl, name, val) \
+ { \
+ int done = 0; \
+ if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
+ done = CUSTPRTOP(pctl, type)(pctl, \
+ CUSTPRTOPARG(pctl, type), nvl, name, val); \
+ } \
+ if (!done) { \
+ (void) DFLTPRTOP(pctl, type)(pctl, \
+ DFLTPRTOPARG(pctl, type), nvl, name, val); \
+ } \
+ (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
+ }
+
+#define ARENDER(pctl, type, nvl, name, arrp, count) \
+ { \
+ int done = 0; \
+ if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \
+ done = CUSTPRTOP(pctl, type)(pctl, \
+ CUSTPRTOPARG(pctl, type), nvl, name, arrp, count); \
+ } \
+ if (!done) { \
+ (void) DFLTPRTOP(pctl, type)(pctl, \
+ DFLTPRTOPARG(pctl, type), nvl, name, arrp, count); \
+ } \
+ (void) fprintf(pctl->nvprt_fp, pctl->nvprt_eomfmt); \
+ }
+
+static void nvlist_print_with_indent(nvlist_t *, nvlist_prtctl_t);
+
+/*
+ * ======================================================================
+ * | |
+ * | Indentation |
+ * | |
+ * ======================================================================
+ */
+
+static void
+indent(nvlist_prtctl_t pctl, int onemore)
+{
+ int depth;
+
+ switch (pctl->nvprt_indent_mode) {
+ case NVLIST_INDENT_ABS:
+ (void) fprintf(pctl->nvprt_fp, "%*s",
+ pctl->nvprt_indent + onemore * pctl->nvprt_indentinc, "");
+ break;
+
+ case NVLIST_INDENT_TABBED:
+ depth = pctl->nvprt_indent + onemore;
+ while (depth-- > 0)
+ (void) fprintf(pctl->nvprt_fp, "\t");
+ }
+}
+
+/*
+ * ======================================================================
+ * | |
+ * | Default nvlist member rendering functions. |
+ * | |
+ * ======================================================================
+ */
+
+/*
+ * Generate functions to print single-valued nvlist members.
+ *
+ * type_and_variant - suffix to form function name
+ * vtype - C type for the member value
+ * ptype - C type to cast value to for printing
+ * vfmt - format string for pair value, e.g "%d" or "0x%llx"
+ */
+
+#define NVLIST_PRTFUNC(type_and_variant, vtype, ptype, vfmt) \
+static int \
+nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
+ nvlist_t *nvl, const char *name, vtype value) \
+{ \
+ FILE *fp = pctl->nvprt_fp; \
+ NOTE(ARGUNUSED(private)) \
+ NOTE(ARGUNUSED(nvl)) \
+ indent(pctl, 1); \
+ (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
+ (void) fprintf(fp, vfmt, (ptype)value); \
+ return (1); \
+}
+
+NVLIST_PRTFUNC(boolean, int, int, "%d")
+NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d")
+NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x")
+NVLIST_PRTFUNC(int8, int8_t, int, "%d")
+NVLIST_PRTFUNC(uint8, uint8_t, uint8_t, "0x%x")
+NVLIST_PRTFUNC(int16, int16_t, int16_t, "%d")
+NVLIST_PRTFUNC(uint16, uint16_t, uint16_t, "0x%x")
+NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d")
+NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
+NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
+NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
+NVLIST_PRTFUNC(double, double, double, "0x%llf")
+NVLIST_PRTFUNC(string, char *, char *, "%s")
+NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
+
+/*
+ * Generate functions to print array-valued nvlist members.
+ */
+
+#define NVLIST_ARRPRTFUNC(type_and_variant, vtype, ptype, vfmt) \
+static int \
+nvaprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \
+ nvlist_t *nvl, const char *name, vtype *valuep, uint_t count) \
+{ \
+ FILE *fp = pctl->nvprt_fp; \
+ uint_t i; \
+ NOTE(ARGUNUSED(private)) \
+ NOTE(ARGUNUSED(nvl)) \
+ for (i = 0; i < count; i++) { \
+ if (i == 0 || pctl->nvprt_btwnarrfmt_nl) { \
+ indent(pctl, 1); \
+ (void) fprintf(fp, pctl->nvprt_nmfmt, name); \
+ if (pctl->nvprt_btwnarrfmt_nl) \
+ (void) fprintf(fp, "[%d]: ", i); \
+ } \
+ if (i != 0) \
+ (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
+ (void) fprintf(fp, vfmt, (ptype)valuep[i]); \
+ } \
+ return (1); \
+}
+
+NVLIST_ARRPRTFUNC(boolean_array, boolean_t, boolean_t, "%d")
+NVLIST_ARRPRTFUNC(byte_array, uchar_t, uchar_t, "0x%2.2x")
+NVLIST_ARRPRTFUNC(int8_array, int8_t, int8_t, "%d")
+NVLIST_ARRPRTFUNC(uint8_array, uint8_t, uint8_t, "0x%x")
+NVLIST_ARRPRTFUNC(int16_array, int16_t, int16_t, "%d")
+NVLIST_ARRPRTFUNC(uint16_array, uint16_t, uint16_t, "0x%x")
+NVLIST_ARRPRTFUNC(int32_array, int32_t, int32_t, "%d")
+NVLIST_ARRPRTFUNC(uint32_array, uint32_t, uint32_t, "0x%x")
+NVLIST_ARRPRTFUNC(int64_array, int64_t, longlong_t, "%lld")
+NVLIST_ARRPRTFUNC(uint64_array, uint64_t, u_longlong_t, "0x%llx")
+NVLIST_ARRPRTFUNC(string_array, char *, char *, "%s")
+
+/*ARGSUSED*/
+static int
+nvprint_nvlist(nvlist_prtctl_t pctl, void *private,
+ nvlist_t *nvl, const char *name, nvlist_t *value)
+{
+ FILE *fp = pctl->nvprt_fp;
+
+ indent(pctl, 1);
+ (void) fprintf(fp, "%s = (embedded nvlist)\n", name);
+
+ pctl->nvprt_indent += pctl->nvprt_indentinc;
+ nvlist_print_with_indent(value, pctl);
+ pctl->nvprt_indent -= pctl->nvprt_indentinc;
+
+ indent(pctl, 1);
+ (void) fprintf(fp, "(end %s)\n", name);
+
+ return (1);
+}
+
+/*ARGSUSED*/
+static int
+nvaprint_nvlist_array(nvlist_prtctl_t pctl, void *private,
+ nvlist_t *nvl, const char *name, nvlist_t **valuep, uint_t count)
+{
+ FILE *fp = pctl->nvprt_fp;
+ uint_t i;
+
+ indent(pctl, 1);
+ (void) fprintf(fp, "%s = (array of embedded nvlists)\n", name);
+
+ for (i = 0; i < count; i++) {
+ indent(pctl, 1);
+ (void) fprintf(fp, "(start %s[%d])\n", name, i);
+
+ pctl->nvprt_indent += pctl->nvprt_indentinc;
+ nvlist_print_with_indent(valuep[i], pctl);
+ pctl->nvprt_indent -= pctl->nvprt_indentinc;
+
+ indent(pctl, 1);
+ (void) fprintf(fp, "(end %s[%d])\n", name, i);
+ }
+
+ return (1);
+}
+
+/*
+ * ======================================================================
+ * | |
+ * | Interfaces that allow control over formatting. |
+ * | |
+ * ======================================================================
+ */
+
+void
+nvlist_prtctl_setdest(nvlist_prtctl_t pctl, FILE *fp)
+{
+ pctl->nvprt_fp = fp;
+}
+
+FILE *
+nvlist_prtctl_getdest(nvlist_prtctl_t pctl)
+{
+ return (pctl->nvprt_fp);
+}
+
+
+void
+nvlist_prtctl_setindent(nvlist_prtctl_t pctl, enum nvlist_indent_mode mode,
+ int start, int inc)
+{
+ if (mode < NVLIST_INDENT_ABS || mode > NVLIST_INDENT_TABBED)
+ mode = NVLIST_INDENT_TABBED;
+
+ if (start < 0)
+ start = 0;
+
+ if (inc < 0)
+ inc = 1;
+
+ pctl->nvprt_indent_mode = mode;
+ pctl->nvprt_indent = start;
+ pctl->nvprt_indentinc = inc;
+}
+
+void
+nvlist_prtctl_doindent(nvlist_prtctl_t pctl, int onemore)
+{
+ indent(pctl, onemore);
+}
+
+
+void
+nvlist_prtctl_setfmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which,
+ const char *fmt)
+{
+ switch (which) {
+ case NVLIST_FMT_MEMBER_NAME:
+ if (fmt == NULL)
+ fmt = "%s = ";
+ pctl->nvprt_nmfmt = fmt;
+ break;
+
+ case NVLIST_FMT_MEMBER_POSTAMBLE:
+ if (fmt == NULL)
+ fmt = "\n";
+ pctl->nvprt_eomfmt = fmt;
+ break;
+
+ case NVLIST_FMT_BTWN_ARRAY:
+ if (fmt == NULL) {
+ pctl->nvprt_btwnarrfmt = " ";
+ pctl->nvprt_btwnarrfmt_nl = 0;
+ } else {
+ pctl->nvprt_btwnarrfmt = fmt;
+ pctl->nvprt_btwnarrfmt_nl = (strstr(fmt, "\n") != NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void
+nvlist_prtctl_dofmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, ...)
+{
+ FILE *fp = pctl->nvprt_fp;
+ va_list ap;
+ char *name;
+
+ va_start(ap, which);
+
+ switch (which) {
+ case NVLIST_FMT_MEMBER_NAME:
+ name = va_arg(ap, char *);
+ (void) fprintf(fp, pctl->nvprt_nmfmt, name);
+ break;
+
+ case NVLIST_FMT_MEMBER_POSTAMBLE:
+ (void) fprintf(fp, pctl->nvprt_eomfmt);
+ break;
+
+ case NVLIST_FMT_BTWN_ARRAY:
+ (void) fprintf(fp, pctl->nvprt_btwnarrfmt); \
+ break;
+
+ default:
+ break;
+ }
+
+ va_end(ap);
+}
+
+/*
+ * ======================================================================
+ * | |
+ * | Interfaces to allow appointment of replacement rendering functions.|
+ * | |
+ * ======================================================================
+ */
+
+#define NVLIST_PRINTCTL_REPLACE(type, vtype) \
+void \
+nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
+ int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype), \
+ void *private) \
+{ \
+ CUSTPRTOP(pctl, type) = func; \
+ CUSTPRTOPARG(pctl, type) = private; \
+}
+
+NVLIST_PRINTCTL_REPLACE(boolean, int)
+NVLIST_PRINTCTL_REPLACE(boolean_value, boolean_t)
+NVLIST_PRINTCTL_REPLACE(byte, uchar_t)
+NVLIST_PRINTCTL_REPLACE(int8, int8_t)
+NVLIST_PRINTCTL_REPLACE(uint8, uint8_t)
+NVLIST_PRINTCTL_REPLACE(int16, int16_t)
+NVLIST_PRINTCTL_REPLACE(uint16, uint16_t)
+NVLIST_PRINTCTL_REPLACE(int32, int32_t)
+NVLIST_PRINTCTL_REPLACE(uint32, uint32_t)
+NVLIST_PRINTCTL_REPLACE(int64, int64_t)
+NVLIST_PRINTCTL_REPLACE(uint64, uint64_t)
+NVLIST_PRINTCTL_REPLACE(double, double)
+NVLIST_PRINTCTL_REPLACE(string, char *)
+NVLIST_PRINTCTL_REPLACE(hrtime, hrtime_t)
+NVLIST_PRINTCTL_REPLACE(nvlist, nvlist_t *)
+
+#define NVLIST_PRINTCTL_AREPLACE(type, vtype) \
+void \
+nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \
+ int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, \
+ uint_t), void *private) \
+{ \
+ CUSTPRTOP(pctl, type) = func; \
+ CUSTPRTOPARG(pctl, type) = private; \
+}
+
+NVLIST_PRINTCTL_AREPLACE(boolean_array, boolean_t *)
+NVLIST_PRINTCTL_AREPLACE(byte_array, uchar_t *)
+NVLIST_PRINTCTL_AREPLACE(int8_array, int8_t *)
+NVLIST_PRINTCTL_AREPLACE(uint8_array, uint8_t *)
+NVLIST_PRINTCTL_AREPLACE(int16_array, int16_t *)
+NVLIST_PRINTCTL_AREPLACE(uint16_array, uint16_t *)
+NVLIST_PRINTCTL_AREPLACE(int32_array, int32_t *)
+NVLIST_PRINTCTL_AREPLACE(uint32_array, uint32_t *)
+NVLIST_PRINTCTL_AREPLACE(int64_array, int64_t *)
+NVLIST_PRINTCTL_AREPLACE(uint64_array, uint64_t *)
+NVLIST_PRINTCTL_AREPLACE(string_array, char **)
+NVLIST_PRINTCTL_AREPLACE(nvlist_array, nvlist_t **)
+
+/*
+ * ======================================================================
+ * | |
+ * | Interfaces to manage nvlist_prtctl_t cookies. |
+ * | |
+ * ======================================================================
+ */
+
+
+static const struct nvlist_printops defprtops = {
+ { nvprint_boolean, NULL },
+ { nvprint_boolean_value, NULL },
+ { nvprint_byte, NULL },
+ { nvprint_int8, NULL },
+ { nvprint_uint8, NULL },
+ { nvprint_int16, NULL },
+ { nvprint_uint16, NULL },
+ { nvprint_int32, NULL },
+ { nvprint_uint32, NULL },
+ { nvprint_int64, NULL },
+ { nvprint_uint64, NULL },
+ { nvprint_double, NULL },
+ { nvprint_string, NULL },
+ { nvprint_hrtime, NULL },
+ { nvprint_nvlist, NULL },
+ { nvaprint_boolean_array, NULL },
+ { nvaprint_byte_array, NULL },
+ { nvaprint_int8_array, NULL },
+ { nvaprint_uint8_array, NULL },
+ { nvaprint_int16_array, NULL },
+ { nvaprint_uint16_array, NULL },
+ { nvaprint_int32_array, NULL },
+ { nvaprint_uint32_array, NULL },
+ { nvaprint_int64_array, NULL },
+ { nvaprint_uint64_array, NULL },
+ { nvaprint_string_array, NULL },
+ { nvaprint_nvlist_array, NULL },
+};
+
+static void
+prtctl_defaults(FILE *fp, struct nvlist_prtctl *pctl,
+ struct nvlist_printops *ops)
+{
+ pctl->nvprt_fp = fp;
+ pctl->nvprt_indent_mode = NVLIST_INDENT_TABBED;
+ pctl->nvprt_indent = 0;
+ pctl->nvprt_indentinc = 1;
+ pctl->nvprt_nmfmt = "%s = ";
+ pctl->nvprt_eomfmt = "\n";
+ pctl->nvprt_btwnarrfmt = " ";
+ pctl->nvprt_btwnarrfmt_nl = 0;
+
+ pctl->nvprt_dfltops = (struct nvlist_printops *)&defprtops;
+ pctl->nvprt_custops = ops;
+}
+
+nvlist_prtctl_t
+nvlist_prtctl_alloc(void)
+{
+ struct nvlist_prtctl *pctl;
+ struct nvlist_printops *ops;
+
+ if ((pctl = malloc(sizeof (*pctl))) == NULL)
+ return (NULL);
+
+ if ((ops = calloc(1, sizeof (*ops))) == NULL) {
+ free(pctl);
+ return (NULL);
+ }
+
+ prtctl_defaults(stdout, pctl, ops);
+
+ return (pctl);
+}
+
+void
+nvlist_prtctl_free(nvlist_prtctl_t pctl)
+{
+ if (pctl != NULL) {
+ free(pctl->nvprt_custops);
+ free(pctl);
+ }
+}
+
+/*
+ * ======================================================================
+ * | |
+ * | Top-level print request interfaces. |
+ * | |
+ * ======================================================================
+ */
+
+/*
+ * nvlist_print - Prints elements in an event buffer
+ */
+static void
+nvlist_print_with_indent(nvlist_t *nvl, nvlist_prtctl_t pctl)
+{
+ FILE *fp = pctl->nvprt_fp;
+ char *name;
+ uint_t nelem;
+ nvpair_t *nvp;
+
+ if (nvl == NULL)
+ return;
+
+ indent(pctl, 0);
+ (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));
+
+ nvp = nvlist_next_nvpair(nvl, NULL);
+
+ while (nvp) {
+ data_type_t type = nvpair_type(nvp);
+
+ name = nvpair_name(nvp);
+ nelem = 0;
+
+ switch (type) {
+ case DATA_TYPE_BOOLEAN: {
+ RENDER(pctl, boolean, nvl, name, 1);
+ break;
+ }
+ case DATA_TYPE_BOOLEAN_VALUE: {
+ boolean_t val;
+ (void) nvpair_value_boolean_value(nvp, &val);
+ RENDER(pctl, boolean_value, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_BYTE: {
+ uchar_t val;
+ (void) nvpair_value_byte(nvp, &val);
+ RENDER(pctl, byte, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_INT8: {
+ int8_t val;
+ (void) nvpair_value_int8(nvp, &val);
+ RENDER(pctl, int8, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_UINT8: {
+ uint8_t val;
+ (void) nvpair_value_uint8(nvp, &val);
+ RENDER(pctl, uint8, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_INT16: {
+ int16_t val;
+ (void) nvpair_value_int16(nvp, &val);
+ RENDER(pctl, int16, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_UINT16: {
+ uint16_t val;
+ (void) nvpair_value_uint16(nvp, &val);
+ RENDER(pctl, uint16, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_INT32: {
+ int32_t val;
+ (void) nvpair_value_int32(nvp, &val);
+ RENDER(pctl, int32, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_UINT32: {
+ uint32_t val;
+ (void) nvpair_value_uint32(nvp, &val);
+ RENDER(pctl, uint32, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_INT64: {
+ int64_t val;
+ (void) nvpair_value_int64(nvp, &val);
+ RENDER(pctl, int64, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_UINT64: {
+ uint64_t val;
+ (void) nvpair_value_uint64(nvp, &val);
+ RENDER(pctl, uint64, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_DOUBLE: {
+ double val;
+ (void) nvpair_value_double(nvp, &val);
+ RENDER(pctl, double, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_STRING: {
+ char *val;
+ (void) nvpair_value_string(nvp, &val);
+ RENDER(pctl, string, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_BOOLEAN_ARRAY: {
+ boolean_t *val;
+ (void) nvpair_value_boolean_array(nvp, &val, &nelem);
+ ARENDER(pctl, boolean_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_BYTE_ARRAY: {
+ uchar_t *val;
+ (void) nvpair_value_byte_array(nvp, &val, &nelem);
+ ARENDER(pctl, byte_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_INT8_ARRAY: {
+ int8_t *val;
+ (void) nvpair_value_int8_array(nvp, &val, &nelem);
+ ARENDER(pctl, int8_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_UINT8_ARRAY: {
+ uint8_t *val;
+ (void) nvpair_value_uint8_array(nvp, &val, &nelem);
+ ARENDER(pctl, uint8_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_INT16_ARRAY: {
+ int16_t *val;
+ (void) nvpair_value_int16_array(nvp, &val, &nelem);
+ ARENDER(pctl, int16_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_UINT16_ARRAY: {
+ uint16_t *val;
+ (void) nvpair_value_uint16_array(nvp, &val, &nelem);
+ ARENDER(pctl, uint16_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_INT32_ARRAY: {
+ int32_t *val;
+ (void) nvpair_value_int32_array(nvp, &val, &nelem);
+ ARENDER(pctl, int32_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_UINT32_ARRAY: {
+ uint32_t *val;
+ (void) nvpair_value_uint32_array(nvp, &val, &nelem);
+ ARENDER(pctl, uint32_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_INT64_ARRAY: {
+ int64_t *val;
+ (void) nvpair_value_int64_array(nvp, &val, &nelem);
+ ARENDER(pctl, int64_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_UINT64_ARRAY: {
+ uint64_t *val;
+ (void) nvpair_value_uint64_array(nvp, &val, &nelem);
+ ARENDER(pctl, uint64_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_STRING_ARRAY: {
+ char **val;
+ (void) nvpair_value_string_array(nvp, &val, &nelem);
+ ARENDER(pctl, string_array, nvl, name, val, nelem);
+ break;
+ }
+ case DATA_TYPE_HRTIME: {
+ hrtime_t val;
+ (void) nvpair_value_hrtime(nvp, &val);
+ RENDER(pctl, hrtime, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_NVLIST: {
+ nvlist_t *val;
+ (void) nvpair_value_nvlist(nvp, &val);
+ RENDER(pctl, nvlist, nvl, name, val);
+ break;
+ }
+ case DATA_TYPE_NVLIST_ARRAY: {
+ nvlist_t **val;
+ (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
+ ARENDER(pctl, nvlist_array, nvl, name, val, nelem);
+ break;
+ }
+ default:
+ (void) fprintf(fp, " unknown data type (%d)", type);
+ break;
+ }
+ nvp = nvlist_next_nvpair(nvl, nvp);
+ }
+}
+
+void
+nvlist_print(FILE *fp, nvlist_t *nvl)
+{
+ struct nvlist_prtctl pc;
+
+ prtctl_defaults(fp, &pc, NULL);
+ nvlist_print_with_indent(nvl, &pc);
+}
+
+void
+nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl)
+{
+ nvlist_print_with_indent(nvl, pctl);
+}
+
+#define NVP(elem, type, vtype, ptype, format) { \
+ vtype value; \
+\
+ (void) nvpair_value_##type(elem, &value); \
+ (void) printf("%*s%s: " format "\n", indent, "", \
+ nvpair_name(elem), (ptype)value); \
+}
+
+#define NVPA(elem, type, vtype, ptype, format) { \
+ uint_t i, count; \
+ vtype *value; \
+\
+ (void) nvpair_value_##type(elem, &value, &count); \
+ for (i = 0; i < count; i++) { \
+ (void) printf("%*s%s[%d]: " format "\n", indent, "", \
+ nvpair_name(elem), i, (ptype)value[i]); \
+ } \
+}
+
+/*
+ * Similar to nvlist_print() but handles arrays slightly differently.
+ */
+void
+dump_nvlist(nvlist_t *list, int indent)
+{
+ nvpair_t *elem = NULL;
+ boolean_t bool_value;
+ nvlist_t *nvlist_value;
+ nvlist_t **nvlist_array_value;
+ uint_t i, count;
+
+ if (list == NULL) {
+ return;
+ }
+
+ while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
+ switch (nvpair_type(elem)) {
+ case DATA_TYPE_BOOLEAN:
+ (void) printf("%*s%s\n", indent, "", nvpair_name(elem));
+ break;
+
+ case DATA_TYPE_BOOLEAN_VALUE:
+ (void) nvpair_value_boolean_value(elem, &bool_value);
+ (void) printf("%*s%s: %s\n", indent, "",
+ nvpair_name(elem), bool_value ? "true" : "false");
+ break;
+
+ case DATA_TYPE_BYTE:
+ NVP(elem, byte, uchar_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT8:
+ NVP(elem, int8, int8_t, int, "%d");
+ break;
+
+ case DATA_TYPE_UINT8:
+ NVP(elem, uint8, uint8_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT16:
+ NVP(elem, int16, int16_t, int, "%d");
+ break;
+
+ case DATA_TYPE_UINT16:
+ NVP(elem, uint16, uint16_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT32:
+ NVP(elem, int32, int32_t, long, "%ld");
+ break;
+
+ case DATA_TYPE_UINT32:
+ NVP(elem, uint32, uint32_t, ulong_t, "%lu");
+ break;
+
+ case DATA_TYPE_INT64:
+ NVP(elem, int64, int64_t, longlong_t, "%lld");
+ break;
+
+ case DATA_TYPE_UINT64:
+ NVP(elem, uint64, uint64_t, u_longlong_t, "%llu");
+ break;
+
+ case DATA_TYPE_STRING:
+ NVP(elem, string, char *, char *, "'%s'");
+ break;
+
+ case DATA_TYPE_BYTE_ARRAY:
+ NVPA(elem, byte_array, uchar_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT8_ARRAY:
+ NVPA(elem, int8_array, int8_t, int, "%d");
+ break;
+
+ case DATA_TYPE_UINT8_ARRAY:
+ NVPA(elem, uint8_array, uint8_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT16_ARRAY:
+ NVPA(elem, int16_array, int16_t, int, "%d");
+ break;
+
+ case DATA_TYPE_UINT16_ARRAY:
+ NVPA(elem, uint16_array, uint16_t, int, "%u");
+ break;
+
+ case DATA_TYPE_INT32_ARRAY:
+ NVPA(elem, int32_array, int32_t, long, "%ld");
+ break;
+
+ case DATA_TYPE_UINT32_ARRAY:
+ NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu");
+ break;
+
+ case DATA_TYPE_INT64_ARRAY:
+ NVPA(elem, int64_array, int64_t, longlong_t, "%lld");
+ break;
+
+ case DATA_TYPE_UINT64_ARRAY:
+ NVPA(elem, uint64_array, uint64_t, u_longlong_t,
+ "%llu");
+ break;
+
+ case DATA_TYPE_STRING_ARRAY:
+ NVPA(elem, string_array, char *, char *, "'%s'");
+ break;
+
+ case DATA_TYPE_NVLIST:
+ (void) nvpair_value_nvlist(elem, &nvlist_value);
+ (void) printf("%*s%s:\n", indent, "",
+ nvpair_name(elem));
+ dump_nvlist(nvlist_value, indent + 4);
+ break;
+
+ case DATA_TYPE_NVLIST_ARRAY:
+ (void) nvpair_value_nvlist_array(elem,
+ &nvlist_array_value, &count);
+ for (i = 0; i < count; i++) {
+ (void) printf("%*s%s[%u]:\n", indent, "",
+ nvpair_name(elem), i);
+ dump_nvlist(nvlist_array_value[i], indent + 4);
+ }
+ break;
+
+ default:
+ (void) printf(dgettext(TEXT_DOMAIN, "bad config type "
+ "%d for %s\n"), nvpair_type(elem),
+ nvpair_name(elem));
+ }
+ }
+}
+
+/*
+ * ======================================================================
+ * | |
+ * | Misc private interface. |
+ * | |
+ * ======================================================================
+ */
+
+/*
+ * Determine if string 'value' matches 'nvp' value. The 'value' string is
+ * converted, depending on the type of 'nvp', prior to match. For numeric
+ * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
+ * is an array type, 'ai' is the index into the array against which we are
+ * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
+ * in a regex_t compilation of value in 'value_regex' to trigger regular
+ * expression string match instead of simple strcmp().
+ *
+ * Return 1 on match, 0 on no-match, and -1 on error. If the error is
+ * related to value syntax error and 'ep' is non-NULL, *ep will point into
+ * the 'value' string at the location where the error exists.
+ *
+ * NOTE: It may be possible to move the non-regex_t version of this into
+ * common code used by library/kernel/boot.
+ */
+int
+nvpair_value_match_regex(nvpair_t *nvp, int ai,
+ char *value, regex_t *value_regex, char **ep)
+{
+ char *evalue;
+ uint_t a_len;
+ int sr;
+
+ if (ep)
+ *ep = NULL;
+
+ if ((nvp == NULL) || (value == NULL))
+ return (-1); /* error fail match - invalid args */
+
+ /* make sure array and index combination make sense */
+ if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
+ (!nvpair_type_is_array(nvp) && (ai >= 0)))
+ return (-1); /* error fail match - bad index */
+
+ /* non-string values should be single 'chunk' */
+ if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
+ (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
+ value += strspn(value, " \t");
+ evalue = value + strcspn(value, " \t");
+ if (*evalue) {
+ if (ep)
+ *ep = evalue;
+ return (-1); /* error fail match - syntax */
+ }
+ }
+
+ sr = EOF;
+ switch (nvpair_type(nvp)) {
+ case DATA_TYPE_STRING: {
+ char *val;
+
+ /* check string value for match */
+ if (nvpair_value_string(nvp, &val) == 0) {
+ if (value_regex) {
+ if (regexec(value_regex, val,
+ (size_t)0, NULL, 0) == 0)
+ return (1); /* match */
+ } else {
+ if (strcmp(value, val) == 0)
+ return (1); /* match */
+ }
+ }
+ break;
+ }
+ case DATA_TYPE_STRING_ARRAY: {
+ char **val_array;
+
+ /* check indexed string value of array for match */
+ if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len)) {
+ if (value_regex) {
+ if (regexec(value_regex, val_array[ai],
+ (size_t)0, NULL, 0) == 0)
+ return (1);
+ } else {
+ if (strcmp(value, val_array[ai]) == 0)
+ return (1);
+ }
+ }
+ break;
+ }
+ case DATA_TYPE_BYTE: {
+ uchar_t val, val_arg;
+
+ /* scanf uchar_t from value and check for match */
+ sr = sscanf(value, "%c", &val_arg);
+ if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_BYTE_ARRAY: {
+ uchar_t *val_array, val_arg;
+
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%c", &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT8: {
+ int8_t val, val_arg;
+
+ /* scanf int8_t from value and check for match */
+ sr = sscanf(value, "%"SCNi8, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int8(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT8_ARRAY: {
+ int8_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi8, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT8: {
+ uint8_t val, val_arg;
+
+ /* scanf uint8_t from value and check for match */
+ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint8(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT8_ARRAY: {
+ uint8_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT16: {
+ int16_t val, val_arg;
+
+ /* scanf int16_t from value and check for match */
+ sr = sscanf(value, "%"SCNi16, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int16(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT16_ARRAY: {
+ int16_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi16, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT16: {
+ uint16_t val, val_arg;
+
+ /* scanf uint16_t from value and check for match */
+ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint16(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT16_ARRAY: {
+ uint16_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT32: {
+ int32_t val, val_arg;
+
+ /* scanf int32_t from value and check for match */
+ sr = sscanf(value, "%"SCNi32, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int32(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT32_ARRAY: {
+ int32_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi32, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT32: {
+ uint32_t val, val_arg;
+
+ /* scanf uint32_t from value and check for match */
+ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint32(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT32_ARRAY: {
+ uint32_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT64: {
+ int64_t val, val_arg;
+
+ /* scanf int64_t from value and check for match */
+ sr = sscanf(value, "%"SCNi64, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int64(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_INT64_ARRAY: {
+ int64_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi64, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT64: {
+ uint64_t val_arg, val;
+
+ /* scanf uint64_t from value and check for match */
+ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint64(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_UINT64_ARRAY: {
+ uint64_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_BOOLEAN_VALUE: {
+ boolean_t val, val_arg;
+
+ /* scanf boolean_t from value and check for match */
+ sr = sscanf(value, "%"SCNi32, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_boolean_value(nvp, &val) == 0) &&
+ (val == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_BOOLEAN_ARRAY: {
+ boolean_t *val_array, val_arg;
+
+ /* check indexed value of array for match */
+ sr = sscanf(value, "%"SCNi32, &val_arg);
+ if ((sr == 1) &&
+ (nvpair_value_boolean_array(nvp,
+ &val_array, &a_len) == 0) &&
+ (ai < a_len) &&
+ (val_array[ai] == val_arg))
+ return (1);
+ break;
+ }
+ case DATA_TYPE_HRTIME:
+ case DATA_TYPE_NVLIST:
+ case DATA_TYPE_NVLIST_ARRAY:
+ case DATA_TYPE_BOOLEAN:
+ case DATA_TYPE_DOUBLE:
+ case DATA_TYPE_UNKNOWN:
+ default:
+ /*
+ * unknown/unsupported data type
+ */
+ return (-1); /* error fail match */
+ }
+
+ /*
+ * check to see if sscanf failed conversion, return approximate
+ * pointer to problem
+ */
+ if (sr != 1) {
+ if (ep)
+ *ep = value;
+ return (-1); /* error fail match - syntax */
+ }
+
+ return (0); /* fail match */
+}
+
+int
+nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
+{
+ return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
+}
diff --git a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.h b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.h
new file mode 100644
index 0000000..4c2615d
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.h
@@ -0,0 +1,194 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _LIBNVPAIR_H
+#define _LIBNVPAIR_H
+
+#include <sys/nvpair.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <regex.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * All interfaces described in this file are private to Solaris, and
+ * are subject to change at any time and without notice. The public
+ * nvlist/nvpair interfaces, as documented in manpage sections 3NVPAIR,
+ * are all imported from <sys/nvpair.h> included above.
+ */
+
+extern int nvpair_value_match(nvpair_t *, int, char *, char **);
+extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *,
+ char **);
+
+extern void nvlist_print(FILE *, nvlist_t *);
+extern void dump_nvlist(nvlist_t *, int);
+
+/*
+ * Private nvlist printing interface that allows the caller some control
+ * over output rendering (as opposed to nvlist_print and dump_nvlist).
+ *
+ * Obtain an opaque nvlist_prtctl_t cookie using nvlist_prtctl_alloc
+ * (NULL on failure); on return the cookie is set up for default formatting
+ * and rendering. Quote the cookie in subsequent customisation functions and
+ * then pass the cookie to nvlist_prt to render the nvlist. Finally,
+ * use nvlist_prtctl_free to release the cookie.
+ *
+ * For all nvlist_lookup_xxx and nvlist_lookup_xxx_array functions
+ * we have a corresponding brace of functions that appoint replacement
+ * rendering functions:
+ *
+ * extern void nvlist_prtctl_xxx(nvlist_prtctl_t,
+ * void (*)(nvlist_prtctl_t ctl, void *private, const char *name,
+ * xxxtype value))
+ *
+ * and
+ *
+ * extern void nvlist_prtctl_xxx_array(nvlist_prtctl_t,
+ * void (*)(nvlist_prtctl_t ctl, void *private, const char *name,
+ * xxxtype value, uint_t count))
+ *
+ * where xxxtype is the C datatype corresponding to xxx, eg int8_t for "int8"
+ * and char * for "string". The function that is appointed to render the
+ * specified datatype receives as arguments the cookie, the nvlist
+ * member name, the value of that member (or a pointer for array function),
+ * and (for array rendering functions) a count of the number of elements.
+ */
+
+typedef struct nvlist_prtctl *nvlist_prtctl_t; /* opaque */
+
+enum nvlist_indent_mode {
+ NVLIST_INDENT_ABS, /* Absolute indentation */
+ NVLIST_INDENT_TABBED /* Indent with tabstops */
+};
+
+extern nvlist_prtctl_t nvlist_prtctl_alloc(void);
+extern void nvlist_prtctl_free(nvlist_prtctl_t);
+extern void nvlist_prt(nvlist_t *, nvlist_prtctl_t);
+
+/* Output stream */
+extern void nvlist_prtctl_setdest(nvlist_prtctl_t, FILE *);
+extern FILE *nvlist_prtctl_getdest(nvlist_prtctl_t);
+
+/* Indentation mode, start indent, indent increment; default tabbed/0/1 */
+extern void nvlist_prtctl_setindent(nvlist_prtctl_t, enum nvlist_indent_mode,
+ int, int);
+extern void nvlist_prtctl_doindent(nvlist_prtctl_t, int);
+
+enum nvlist_prtctl_fmt {
+ NVLIST_FMT_MEMBER_NAME, /* name fmt; default "%s = " */
+ NVLIST_FMT_MEMBER_POSTAMBLE, /* after nvlist member; default "\n" */
+ NVLIST_FMT_BTWN_ARRAY /* between array members; default " " */
+};
+
+extern void nvlist_prtctl_setfmt(nvlist_prtctl_t, enum nvlist_prtctl_fmt,
+ const char *);
+extern void nvlist_prtctl_dofmt(nvlist_prtctl_t, enum nvlist_prtctl_fmt, ...);
+
+/*
+ * Function prototypes for interfaces that appoint a new rendering function
+ * for single-valued nvlist members.
+ *
+ * A replacement function receives arguments as follows:
+ *
+ * nvlist_prtctl_t Print control structure; do not change preferences
+ * for this object from a print callback function.
+ *
+ * void * The function-private cookie argument registered
+ * when the replacement function was appointed.
+ *
+ * nvlist_t * The full nvlist that is being processed. The
+ * rendering function is called to render a single
+ * member (name and value passed as below) but it may
+ * want to reference or incorporate other aspects of
+ * the full nvlist.
+ *
+ * const char * Member name to render
+ *
+ * valtype Value of the member to render
+ *
+ * The function must return non-zero if it has rendered output for this
+ * member, or 0 if it wants to default to standard rendering for this
+ * one member.
+ */
+
+#define NVLIST_PRINTCTL_SVDECL(funcname, valtype) \
+ extern void funcname(nvlist_prtctl_t, \
+ int (*)(nvlist_prtctl_t, void *, nvlist_t *, const char *, valtype), \
+ void *)
+
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_boolean, int);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_boolean_value, boolean_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_byte, uchar_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int8, int8_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint8, uint8_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int16, int16_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint16, uint16_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int32, int32_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint32, uint32_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_int64, int64_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_uint64, uint64_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_double, double);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_string, char *);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_hrtime, hrtime_t);
+NVLIST_PRINTCTL_SVDECL(nvlist_prtctlop_nvlist, nvlist_t *);
+
+#undef NVLIST_PRINTCTL_SVDECL /* was just for "clarity" above */
+
+/*
+ * Function prototypes for interfaces that appoint a new rendering function
+ * for array-valued nvlist members.
+ *
+ * One additional argument is taken: uint_t for the number of array elements
+ *
+ * Return values as above.
+ */
+#define NVLIST_PRINTCTL_AVDECL(funcname, vtype) \
+ extern void funcname(nvlist_prtctl_t, \
+ int (*)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, uint_t), \
+ void *)
+
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_boolean_array, boolean_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_byte_array, uchar_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int8_array, int8_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint8_array, uint8_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int16_array, int16_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint16_array, uint16_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int32_array, int32_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint32_array, uint32_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_int64_array, int64_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_uint64_array, uint64_t *);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_string_array, char **);
+NVLIST_PRINTCTL_AVDECL(nvlist_prtctlop_nvlist_array, nvlist_t **);
+
+#undef NVLIST_PRINTCTL_AVDECL /* was just for "clarity" above */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBNVPAIR_H */
diff --git a/cddl/contrib/opensolaris/lib/libnvpair/nvpair_alloc_system.c b/cddl/contrib/opensolaris/lib/libnvpair/nvpair_alloc_system.c
new file mode 100644
index 0000000..1aefc10
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libnvpair/nvpair_alloc_system.c
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/nvpair.h>
+#include <stdlib.h>
+
+/*ARGSUSED*/
+static void *
+nv_alloc_sys(nv_alloc_t *nva, size_t size)
+{
+ return (malloc(size));
+}
+
+/*ARGSUSED*/
+static void
+nv_free_sys(nv_alloc_t *nva, void *buf, size_t size)
+{
+ free(buf);
+}
+
+const nv_alloc_ops_t system_ops_def = {
+ NULL, /* nv_ao_init() */
+ NULL, /* nv_ao_fini() */
+ nv_alloc_sys, /* nv_ao_alloc() */
+ nv_free_sys, /* nv_ao_free() */
+ NULL /* nv_ao_reset() */
+};
+
+nv_alloc_t nv_alloc_nosleep_def = {
+ &system_ops_def,
+ NULL
+};
+
+nv_alloc_t *nv_alloc_nosleep = &nv_alloc_nosleep_def;
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/libuutil.h b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil.h
new file mode 100644
index 0000000..7a5f8a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil.h
@@ -0,0 +1,391 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _LIBUUTIL_H
+#define _LIBUUTIL_H
+
+#include <solaris.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Standard flags codes.
+ */
+#define UU_DEFAULT 0
+
+/*
+ * Standard error codes.
+ */
+#define UU_ERROR_NONE 0 /* no error */
+#define UU_ERROR_INVALID_ARGUMENT 1 /* invalid argument */
+#define UU_ERROR_UNKNOWN_FLAG 2 /* passed flag invalid */
+#define UU_ERROR_NO_MEMORY 3 /* out of memory */
+#define UU_ERROR_CALLBACK_FAILED 4 /* callback-initiated error */
+#define UU_ERROR_NOT_SUPPORTED 5 /* operation not supported */
+#define UU_ERROR_EMPTY 6 /* no value provided */
+#define UU_ERROR_UNDERFLOW 7 /* value is too small */
+#define UU_ERROR_OVERFLOW 8 /* value is too value */
+#define UU_ERROR_INVALID_CHAR 9 /* value contains unexpected char */
+#define UU_ERROR_INVALID_DIGIT 10 /* value contains digit not in base */
+
+#define UU_ERROR_SYSTEM 99 /* underlying system error */
+#define UU_ERROR_UNKNOWN 100 /* error status not known */
+
+/*
+ * Standard program exit codes.
+ */
+#define UU_EXIT_OK (*(uu_exit_ok()))
+#define UU_EXIT_FATAL (*(uu_exit_fatal()))
+#define UU_EXIT_USAGE (*(uu_exit_usage()))
+
+/*
+ * Exit status profiles.
+ */
+#define UU_PROFILE_DEFAULT 0
+#define UU_PROFILE_LAUNCHER 1
+
+/*
+ * Error reporting functions.
+ */
+uint32_t uu_error(void);
+const char *uu_strerror(uint32_t);
+
+/*
+ * Program notification functions.
+ */
+extern void uu_alt_exit(int);
+extern const char *uu_setpname(char *);
+extern const char *uu_getpname(void);
+/*PRINTFLIKE1*/
+extern void uu_warn(const char *, ...);
+extern void uu_vwarn(const char *, va_list);
+/*PRINTFLIKE1*/
+extern void uu_die(const char *, ...) __NORETURN;
+extern void uu_vdie(const char *, va_list) __NORETURN;
+/*PRINTFLIKE2*/
+extern void uu_xdie(int, const char *, ...) __NORETURN;
+extern void uu_vxdie(int, const char *, va_list) __NORETURN;
+
+/*
+ * Exit status functions (not to be used directly)
+ */
+extern int *uu_exit_ok(void);
+extern int *uu_exit_fatal(void);
+extern int *uu_exit_usage(void);
+
+/*
+ * string->number conversions
+ */
+extern int uu_strtoint(const char *, void *, size_t, int, int64_t, int64_t);
+extern int uu_strtouint(const char *, void *, size_t, int, uint64_t, uint64_t);
+
+/*
+ * Debug print facility functions.
+ */
+typedef struct uu_dprintf uu_dprintf_t;
+
+typedef enum {
+ UU_DPRINTF_SILENT,
+ UU_DPRINTF_FATAL,
+ UU_DPRINTF_WARNING,
+ UU_DPRINTF_NOTICE,
+ UU_DPRINTF_INFO,
+ UU_DPRINTF_DEBUG
+} uu_dprintf_severity_t;
+
+extern uu_dprintf_t *uu_dprintf_create(const char *, uu_dprintf_severity_t,
+ uint_t);
+/*PRINTFLIKE3*/
+extern void uu_dprintf(uu_dprintf_t *, uu_dprintf_severity_t,
+ const char *, ...);
+extern void uu_dprintf_destroy(uu_dprintf_t *);
+extern const char *uu_dprintf_getname(uu_dprintf_t *);
+
+/*
+ * Identifier test flags and function.
+ */
+#define UU_NAME_DOMAIN 0x1 /* allow SUNW, or com.sun, prefix */
+#define UU_NAME_PATH 0x2 /* allow '/'-delimited paths */
+
+int uu_check_name(const char *, uint_t);
+
+/*
+ * File creation functions.
+ */
+extern int uu_open_tmp(const char *dir, uint_t uflags);
+
+/*
+ * Convenience functions.
+ */
+#define UU_NELEM(a) (sizeof (a) / sizeof ((a)[0]))
+
+/*PRINTFLIKE1*/
+extern char *uu_msprintf(const char *format, ...);
+extern void *uu_zalloc(size_t);
+extern char *uu_strdup(const char *);
+extern void uu_free(void *);
+
+extern boolean_t uu_strcaseeq(const char *a, const char *b);
+extern boolean_t uu_streq(const char *a, const char *b);
+extern char *uu_strndup(const char *s, size_t n);
+extern boolean_t uu_strbw(const char *a, const char *b);
+extern void *uu_memdup(const void *buf, size_t sz);
+extern void uu_dump(FILE *out, const char *prefix, const void *buf, size_t len);
+
+/*
+ * Comparison function type definition.
+ * Developers should be careful in their use of the _private argument. If you
+ * break interface guarantees, you get undefined behavior.
+ */
+typedef int uu_compare_fn_t(const void *__left, const void *__right,
+ void *__private);
+
+/*
+ * Walk variant flags.
+ * A data structure need not provide support for all variants and
+ * combinations. Refer to the appropriate documentation.
+ */
+#define UU_WALK_ROBUST 0x00000001 /* walk can survive removes */
+#define UU_WALK_REVERSE 0x00000002 /* reverse walk order */
+
+#define UU_WALK_PREORDER 0x00000010 /* walk tree in pre-order */
+#define UU_WALK_POSTORDER 0x00000020 /* walk tree in post-order */
+
+/*
+ * Walk callback function return codes.
+ */
+#define UU_WALK_ERROR -1
+#define UU_WALK_NEXT 0
+#define UU_WALK_DONE 1
+
+/*
+ * Walk callback function type definition.
+ */
+typedef int uu_walk_fn_t(void *_elem, void *_private);
+
+/*
+ * lists: opaque structures
+ */
+typedef struct uu_list_pool uu_list_pool_t;
+typedef struct uu_list uu_list_t;
+
+typedef struct uu_list_node {
+ uintptr_t uln_opaque[2];
+} uu_list_node_t;
+
+typedef struct uu_list_walk uu_list_walk_t;
+
+typedef uintptr_t uu_list_index_t;
+
+/*
+ * lists: interface
+ *
+ * basic usage:
+ * typedef struct foo {
+ * ...
+ * uu_list_node_t foo_node;
+ * ...
+ * } foo_t;
+ *
+ * static int
+ * foo_compare(void *l_arg, void *r_arg, void *private)
+ * {
+ * foo_t *l = l_arg;
+ * foo_t *r = r_arg;
+ *
+ * if (... l greater than r ...)
+ * return (1);
+ * if (... l less than r ...)
+ * return (-1);
+ * return (0);
+ * }
+ *
+ * ...
+ * // at initialization time
+ * foo_pool = uu_list_pool_create("foo_pool",
+ * sizeof (foo_t), offsetof(foo_t, foo_node), foo_compare,
+ * debugging? 0 : UU_AVL_POOL_DEBUG);
+ * ...
+ */
+uu_list_pool_t *uu_list_pool_create(const char *, size_t, size_t,
+ uu_compare_fn_t *, uint32_t);
+#define UU_LIST_POOL_DEBUG 0x00000001
+
+void uu_list_pool_destroy(uu_list_pool_t *);
+
+/*
+ * usage:
+ *
+ * foo_t *a;
+ * a = malloc(sizeof(*a));
+ * uu_list_node_init(a, &a->foo_list, pool);
+ * ...
+ * uu_list_node_fini(a, &a->foo_list, pool);
+ * free(a);
+ */
+void uu_list_node_init(void *, uu_list_node_t *, uu_list_pool_t *);
+void uu_list_node_fini(void *, uu_list_node_t *, uu_list_pool_t *);
+
+uu_list_t *uu_list_create(uu_list_pool_t *, void *_parent, uint32_t);
+#define UU_LIST_DEBUG 0x00000001
+#define UU_LIST_SORTED 0x00000002 /* list is sorted */
+
+void uu_list_destroy(uu_list_t *); /* list must be empty */
+
+size_t uu_list_numnodes(uu_list_t *);
+
+void *uu_list_first(uu_list_t *);
+void *uu_list_last(uu_list_t *);
+
+void *uu_list_next(uu_list_t *, void *);
+void *uu_list_prev(uu_list_t *, void *);
+
+int uu_list_walk(uu_list_t *, uu_walk_fn_t *, void *, uint32_t);
+
+uu_list_walk_t *uu_list_walk_start(uu_list_t *, uint32_t);
+void *uu_list_walk_next(uu_list_walk_t *);
+void uu_list_walk_end(uu_list_walk_t *);
+
+void *uu_list_find(uu_list_t *, void *, void *, uu_list_index_t *);
+void uu_list_insert(uu_list_t *, void *, uu_list_index_t);
+
+void *uu_list_nearest_next(uu_list_t *, uu_list_index_t);
+void *uu_list_nearest_prev(uu_list_t *, uu_list_index_t);
+
+void *uu_list_teardown(uu_list_t *, void **);
+
+void uu_list_remove(uu_list_t *, void *);
+
+/*
+ * lists: interfaces for non-sorted lists only
+ */
+int uu_list_insert_before(uu_list_t *, void *_target, void *_elem);
+int uu_list_insert_after(uu_list_t *, void *_target, void *_elem);
+
+/*
+ * avl trees: opaque structures
+ */
+typedef struct uu_avl_pool uu_avl_pool_t;
+typedef struct uu_avl uu_avl_t;
+
+typedef struct uu_avl_node {
+#ifdef _LP64
+ uintptr_t uan_opaque[3];
+#else
+ uintptr_t uan_opaque[4];
+#endif
+} uu_avl_node_t;
+
+typedef struct uu_avl_walk uu_avl_walk_t;
+
+typedef uintptr_t uu_avl_index_t;
+
+/*
+ * avl trees: interface
+ *
+ * basic usage:
+ * typedef struct foo {
+ * ...
+ * uu_avl_node_t foo_node;
+ * ...
+ * } foo_t;
+ *
+ * static int
+ * foo_compare(void *l_arg, void *r_arg, void *private)
+ * {
+ * foo_t *l = l_arg;
+ * foo_t *r = r_arg;
+ *
+ * if (... l greater than r ...)
+ * return (1);
+ * if (... l less than r ...)
+ * return (-1);
+ * return (0);
+ * }
+ *
+ * ...
+ * // at initialization time
+ * foo_pool = uu_avl_pool_create("foo_pool",
+ * sizeof (foo_t), offsetof(foo_t, foo_node), foo_compare,
+ * debugging? 0 : UU_AVL_POOL_DEBUG);
+ * ...
+ */
+uu_avl_pool_t *uu_avl_pool_create(const char *, size_t, size_t,
+ uu_compare_fn_t *, uint32_t);
+#define UU_AVL_POOL_DEBUG 0x00000001
+
+void uu_avl_pool_destroy(uu_avl_pool_t *);
+
+/*
+ * usage:
+ *
+ * foo_t *a;
+ * a = malloc(sizeof(*a));
+ * uu_avl_node_init(a, &a->foo_avl, pool);
+ * ...
+ * uu_avl_node_fini(a, &a->foo_avl, pool);
+ * free(a);
+ */
+void uu_avl_node_init(void *, uu_avl_node_t *, uu_avl_pool_t *);
+void uu_avl_node_fini(void *, uu_avl_node_t *, uu_avl_pool_t *);
+
+uu_avl_t *uu_avl_create(uu_avl_pool_t *, void *_parent, uint32_t);
+#define UU_AVL_DEBUG 0x00000001
+
+void uu_avl_destroy(uu_avl_t *); /* list must be empty */
+
+size_t uu_avl_numnodes(uu_avl_t *);
+
+void *uu_avl_first(uu_avl_t *);
+void *uu_avl_last(uu_avl_t *);
+
+void *uu_avl_next(uu_avl_t *, void *);
+void *uu_avl_prev(uu_avl_t *, void *);
+
+int uu_avl_walk(uu_avl_t *, uu_walk_fn_t *, void *, uint32_t);
+
+uu_avl_walk_t *uu_avl_walk_start(uu_avl_t *, uint32_t);
+void *uu_avl_walk_next(uu_avl_walk_t *);
+void uu_avl_walk_end(uu_avl_walk_t *);
+
+void *uu_avl_find(uu_avl_t *, void *, void *, uu_avl_index_t *);
+void uu_avl_insert(uu_avl_t *, void *, uu_avl_index_t);
+
+void *uu_avl_nearest_next(uu_avl_t *, uu_avl_index_t);
+void *uu_avl_nearest_prev(uu_avl_t *, uu_avl_index_t);
+
+void *uu_avl_teardown(uu_avl_t *, void **);
+
+void uu_avl_remove(uu_avl_t *, void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBUUTIL_H */
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_common.h b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_common.h
new file mode 100644
index 0000000..9ebaaed
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_common.h
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBUUTIL_COMMON_H
+#define _LIBUUTIL_COMMON_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libuutil.h>
+#include <libuutil_impl.h>
+
+#endif /* _LIBUUTIL_COMMON_H */
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_impl.h b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_impl.h
new file mode 100644
index 0000000..9466e59
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/libuutil_impl.h
@@ -0,0 +1,181 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBUUTIL_IMPL_H
+#define _LIBUUTIL_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libuutil.h>
+#include <pthread.h>
+
+#include <sys/avl_impl.h>
+#include <sys/byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void uu_set_error(uint_t);
+#pragma rarely_called(uu_set_error)
+
+/*PRINTFLIKE1*/
+void uu_panic(const char *format, ...);
+#pragma rarely_called(uu_panic)
+
+struct uu_dprintf {
+ char *uud_name;
+ uu_dprintf_severity_t uud_severity;
+ uint_t uud_flags;
+};
+
+/*
+ * For debugging purposes, libuutil keeps around linked lists of all uu_lists
+ * and uu_avls, along with pointers to their parents. These can cause false
+ * negatives when looking for memory leaks, so we encode the pointers by
+ * storing them with swapped endianness; this is not perfect, but it's about
+ * the best we can do without wasting a lot of space.
+ */
+#ifdef _LP64
+#define UU_PTR_ENCODE(ptr) BSWAP_64((uintptr_t)(void *)(ptr))
+#else
+#define UU_PTR_ENCODE(ptr) BSWAP_32((uintptr_t)(void *)(ptr))
+#endif
+
+#define UU_PTR_DECODE(ptr) ((void *)UU_PTR_ENCODE(ptr))
+
+/*
+ * uu_list structures
+ */
+typedef struct uu_list_node_impl {
+ struct uu_list_node_impl *uln_next;
+ struct uu_list_node_impl *uln_prev;
+} uu_list_node_impl_t;
+
+struct uu_list_walk {
+ uu_list_walk_t *ulw_next;
+ uu_list_walk_t *ulw_prev;
+
+ uu_list_t *ulw_list;
+ int8_t ulw_dir;
+ uint8_t ulw_robust;
+ uu_list_node_impl_t *ulw_next_result;
+};
+
+struct uu_list {
+ uintptr_t ul_next_enc;
+ uintptr_t ul_prev_enc;
+
+ uu_list_pool_t *ul_pool;
+ uintptr_t ul_parent_enc; /* encoded parent pointer */
+ size_t ul_offset;
+ size_t ul_numnodes;
+ uint8_t ul_debug;
+ uint8_t ul_sorted;
+ uint8_t ul_index; /* mark for uu_list_index_ts */
+
+ uu_list_node_impl_t ul_null_node;
+ uu_list_walk_t ul_null_walk; /* for robust walkers */
+};
+
+#define UU_LIST_PTR(ptr) ((uu_list_t *)UU_PTR_DECODE(ptr))
+
+#define UU_LIST_POOL_MAXNAME 64
+
+struct uu_list_pool {
+ uu_list_pool_t *ulp_next;
+ uu_list_pool_t *ulp_prev;
+
+ char ulp_name[UU_LIST_POOL_MAXNAME];
+ size_t ulp_nodeoffset;
+ size_t ulp_objsize;
+ uu_compare_fn_t *ulp_cmp;
+ uint8_t ulp_debug;
+ uint8_t ulp_last_index;
+ pthread_mutex_t ulp_lock; /* protects null_list */
+ uu_list_t ulp_null_list;
+};
+
+/*
+ * uu_avl structures
+ */
+typedef struct avl_node uu_avl_node_impl_t;
+
+struct uu_avl_walk {
+ uu_avl_walk_t *uaw_next;
+ uu_avl_walk_t *uaw_prev;
+
+ uu_avl_t *uaw_avl;
+ void *uaw_next_result;
+ int8_t uaw_dir;
+ uint8_t uaw_robust;
+};
+
+struct uu_avl {
+ uintptr_t ua_next_enc;
+ uintptr_t ua_prev_enc;
+
+ uu_avl_pool_t *ua_pool;
+ uintptr_t ua_parent_enc;
+ uint8_t ua_debug;
+ uint8_t ua_index; /* mark for uu_avl_index_ts */
+
+ struct avl_tree ua_tree;
+ uu_avl_walk_t ua_null_walk;
+};
+
+#define UU_AVL_PTR(x) ((uu_avl_t *)UU_PTR_DECODE(x))
+
+#define UU_AVL_POOL_MAXNAME 64
+
+struct uu_avl_pool {
+ uu_avl_pool_t *uap_next;
+ uu_avl_pool_t *uap_prev;
+
+ char uap_name[UU_AVL_POOL_MAXNAME];
+ size_t uap_nodeoffset;
+ size_t uap_objsize;
+ uu_compare_fn_t *uap_cmp;
+ uint8_t uap_debug;
+ uint8_t uap_last_index;
+ pthread_mutex_t uap_lock; /* protects null_avl */
+ uu_avl_t uap_null_avl;
+};
+
+/*
+ * atfork() handlers
+ */
+void uu_avl_lockup(void);
+void uu_avl_release(void);
+
+void uu_list_lockup(void);
+void uu_list_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBUUTIL_IMPL_H */
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_alloc.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_alloc.c
new file mode 100644
index 0000000..2bef759
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_alloc.c
@@ -0,0 +1,135 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include "libuutil_common.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void *
+uu_zalloc(size_t n)
+{
+ void *p = malloc(n);
+
+ if (p == NULL) {
+ uu_set_error(UU_ERROR_SYSTEM);
+ return (NULL);
+ }
+
+ (void) memset(p, 0, n);
+
+ return (p);
+}
+
+void
+uu_free(void *p)
+{
+ free(p);
+}
+
+char *
+uu_strdup(const char *str)
+{
+ char *buf = NULL;
+
+ if (str != NULL) {
+ size_t sz;
+
+ sz = strlen(str) + 1;
+ buf = uu_zalloc(sz);
+ if (buf != NULL)
+ (void) memcpy(buf, str, sz);
+ }
+ return (buf);
+}
+
+/*
+ * Duplicate up to n bytes of a string. Kind of sort of like
+ * strdup(strlcpy(s, n)).
+ */
+char *
+uu_strndup(const char *s, size_t n)
+{
+ size_t len;
+ char *p;
+
+ len = strnlen(s, n);
+ p = uu_zalloc(len + 1);
+ if (p == NULL)
+ return (NULL);
+
+ if (len > 0)
+ (void) memcpy(p, s, len);
+ p[len] = '\0';
+
+ return (p);
+}
+
+/*
+ * Duplicate a block of memory. Combines malloc with memcpy, much as
+ * strdup combines malloc, strlen, and strcpy.
+ */
+void *
+uu_memdup(const void *buf, size_t sz)
+{
+ void *p;
+
+ p = uu_zalloc(sz);
+ if (p == NULL)
+ return (NULL);
+ (void) memcpy(p, buf, sz);
+ return (p);
+}
+
+char *
+uu_msprintf(const char *format, ...)
+{
+ va_list args;
+ char attic[1];
+ uint_t M, m;
+ char *b;
+
+ va_start(args, format);
+ M = vsnprintf(attic, 1, format, args);
+ va_end(args);
+
+ for (;;) {
+ m = M;
+ if ((b = uu_zalloc(m + 1)) == NULL)
+ return (NULL);
+
+ va_start(args, format);
+ M = vsnprintf(b, m + 1, format, args);
+ va_end(args);
+
+ if (M == m)
+ break; /* sizes match */
+
+ uu_free(b);
+ }
+
+ return (b);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c
new file mode 100644
index 0000000..308e920
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_avl.c
@@ -0,0 +1,569 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/avl.h>
+
+static uu_avl_pool_t uu_null_apool = { &uu_null_apool, &uu_null_apool };
+static pthread_mutex_t uu_apool_list_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * The index mark change on every insert and delete, to catch stale
+ * references.
+ *
+ * We leave the low bit alone, since the avl code uses it.
+ */
+#define INDEX_MAX (sizeof (uintptr_t) - 2)
+#define INDEX_NEXT(m) (((m) == INDEX_MAX)? 2 : ((m) + 2) & INDEX_MAX)
+
+#define INDEX_DECODE(i) ((i) & ~INDEX_MAX)
+#define INDEX_ENCODE(p, n) (((n) & ~INDEX_MAX) | (p)->ua_index)
+#define INDEX_VALID(p, i) (((i) & INDEX_MAX) == (p)->ua_index)
+#define INDEX_CHECK(i) (((i) & INDEX_MAX) != 0)
+
+/*
+ * When an element is inactive (not in a tree), we keep a marked pointer to
+ * its containing pool in its first word, and a NULL pointer in its second.
+ *
+ * On insert, we use these to verify that it comes from the correct pool.
+ */
+#define NODE_ARRAY(p, n) ((uintptr_t *)((uintptr_t)(n) + \
+ (pp)->uap_nodeoffset))
+
+#define POOL_TO_MARKER(pp) (((uintptr_t)(pp) | 1))
+
+#define DEAD_MARKER 0xc4
+
+uu_avl_pool_t *
+uu_avl_pool_create(const char *name, size_t objsize, size_t nodeoffset,
+ uu_compare_fn_t *compare_func, uint32_t flags)
+{
+ uu_avl_pool_t *pp, *next, *prev;
+
+ if (name == NULL ||
+ uu_check_name(name, UU_NAME_DOMAIN) == -1 ||
+ nodeoffset + sizeof (uu_avl_node_t) > objsize ||
+ compare_func == NULL) {
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (NULL);
+ }
+
+ if (flags & ~UU_AVL_POOL_DEBUG) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ pp = uu_zalloc(sizeof (uu_avl_pool_t));
+ if (pp == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ (void) strlcpy(pp->uap_name, name, sizeof (pp->uap_name));
+ pp->uap_nodeoffset = nodeoffset;
+ pp->uap_objsize = objsize;
+ pp->uap_cmp = compare_func;
+ if (flags & UU_AVL_POOL_DEBUG)
+ pp->uap_debug = 1;
+ pp->uap_last_index = 0;
+
+ (void) pthread_mutex_init(&pp->uap_lock, NULL);
+
+ pp->uap_null_avl.ua_next_enc = UU_PTR_ENCODE(&pp->uap_null_avl);
+ pp->uap_null_avl.ua_prev_enc = UU_PTR_ENCODE(&pp->uap_null_avl);
+
+ (void) pthread_mutex_lock(&uu_apool_list_lock);
+ pp->uap_next = next = &uu_null_apool;
+ pp->uap_prev = prev = next->uap_prev;
+ next->uap_prev = pp;
+ prev->uap_next = pp;
+ (void) pthread_mutex_unlock(&uu_apool_list_lock);
+
+ return (pp);
+}
+
+void
+uu_avl_pool_destroy(uu_avl_pool_t *pp)
+{
+ if (pp->uap_debug) {
+ if (pp->uap_null_avl.ua_next_enc !=
+ UU_PTR_ENCODE(&pp->uap_null_avl) ||
+ pp->uap_null_avl.ua_prev_enc !=
+ UU_PTR_ENCODE(&pp->uap_null_avl)) {
+ uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has "
+ "outstanding avls, or is corrupt.\n",
+ (int)sizeof (pp->uap_name), pp->uap_name,
+ (void *)pp);
+ }
+ }
+ (void) pthread_mutex_lock(&uu_apool_list_lock);
+ pp->uap_next->uap_prev = pp->uap_prev;
+ pp->uap_prev->uap_next = pp->uap_next;
+ (void) pthread_mutex_unlock(&uu_apool_list_lock);
+ pp->uap_prev = NULL;
+ pp->uap_next = NULL;
+ uu_free(pp);
+}
+
+void
+uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
+{
+ uintptr_t *na = (uintptr_t *)np;
+
+ if (pp->uap_debug) {
+ uintptr_t offset = (uintptr_t)np - (uintptr_t)base;
+ if (offset + sizeof (*np) > pp->uap_objsize) {
+ uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
+ "offset %ld doesn't fit in object (size %ld)\n",
+ base, (void *)np, (void *)pp, pp->uap_name,
+ (long)offset, (long)pp->uap_objsize);
+ }
+ if (offset != pp->uap_nodeoffset) {
+ uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
+ "offset %ld doesn't match pool's offset (%ld)\n",
+ base, (void *)np, (void *)pp, pp->uap_name,
+ (long)offset, (long)pp->uap_objsize);
+ }
+ }
+
+ na[0] = POOL_TO_MARKER(pp);
+ na[1] = 0;
+}
+
+void
+uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
+{
+ uintptr_t *na = (uintptr_t *)np;
+
+ if (pp->uap_debug) {
+ if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) {
+ uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
+ "node already finied\n",
+ base, (void *)np, (void *)pp, pp->uap_name);
+ }
+ if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) {
+ uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
+ "node corrupt, in tree, or in different pool\n",
+ base, (void *)np, (void *)pp, pp->uap_name);
+ }
+ }
+
+ na[0] = DEAD_MARKER;
+ na[1] = DEAD_MARKER;
+ na[2] = DEAD_MARKER;
+}
+
+struct uu_avl_node_compare_info {
+ uu_compare_fn_t *ac_compare;
+ void *ac_private;
+ void *ac_right;
+ void *ac_found;
+};
+
+static int
+uu_avl_node_compare(const void *l, const void *r)
+{
+ struct uu_avl_node_compare_info *info =
+ (struct uu_avl_node_compare_info *)l;
+
+ int res = info->ac_compare(r, info->ac_right, info->ac_private);
+
+ if (res == 0) {
+ if (info->ac_found == NULL)
+ info->ac_found = (void *)r;
+ return (-1);
+ }
+ if (res < 0)
+ return (1);
+ return (-1);
+}
+
+uu_avl_t *
+uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags)
+{
+ uu_avl_t *ap, *next, *prev;
+
+ if (flags & ~UU_AVL_DEBUG) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ ap = uu_zalloc(sizeof (*ap));
+ if (ap == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ ap->ua_pool = pp;
+ ap->ua_parent_enc = UU_PTR_ENCODE(parent);
+ ap->ua_debug = pp->uap_debug || (flags & UU_AVL_DEBUG);
+ ap->ua_index = (pp->uap_last_index = INDEX_NEXT(pp->uap_last_index));
+
+ avl_create(&ap->ua_tree, &uu_avl_node_compare, pp->uap_objsize,
+ pp->uap_nodeoffset);
+
+ ap->ua_null_walk.uaw_next = &ap->ua_null_walk;
+ ap->ua_null_walk.uaw_prev = &ap->ua_null_walk;
+
+ (void) pthread_mutex_lock(&pp->uap_lock);
+ next = &pp->uap_null_avl;
+ prev = UU_PTR_DECODE(next->ua_prev_enc);
+ ap->ua_next_enc = UU_PTR_ENCODE(next);
+ ap->ua_prev_enc = UU_PTR_ENCODE(prev);
+ next->ua_prev_enc = UU_PTR_ENCODE(ap);
+ prev->ua_next_enc = UU_PTR_ENCODE(ap);
+ (void) pthread_mutex_unlock(&pp->uap_lock);
+
+ return (ap);
+}
+
+void
+uu_avl_destroy(uu_avl_t *ap)
+{
+ uu_avl_pool_t *pp = ap->ua_pool;
+
+ if (ap->ua_debug) {
+ if (avl_numnodes(&ap->ua_tree) != 0) {
+ uu_panic("uu_avl_destroy(%p): tree not empty\n",
+ (void *)ap);
+ }
+ if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk ||
+ ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) {
+ uu_panic("uu_avl_destroy(%p): outstanding walkers\n",
+ (void *)ap);
+ }
+ }
+ (void) pthread_mutex_lock(&pp->uap_lock);
+ UU_AVL_PTR(ap->ua_next_enc)->ua_prev_enc = ap->ua_prev_enc;
+ UU_AVL_PTR(ap->ua_prev_enc)->ua_next_enc = ap->ua_next_enc;
+ (void) pthread_mutex_unlock(&pp->uap_lock);
+ ap->ua_prev_enc = UU_PTR_ENCODE(NULL);
+ ap->ua_next_enc = UU_PTR_ENCODE(NULL);
+
+ ap->ua_pool = NULL;
+ avl_destroy(&ap->ua_tree);
+
+ uu_free(ap);
+}
+
+size_t
+uu_avl_numnodes(uu_avl_t *ap)
+{
+ return (avl_numnodes(&ap->ua_tree));
+}
+
+void *
+uu_avl_first(uu_avl_t *ap)
+{
+ return (avl_first(&ap->ua_tree));
+}
+
+void *
+uu_avl_last(uu_avl_t *ap)
+{
+ return (avl_last(&ap->ua_tree));
+}
+
+void *
+uu_avl_next(uu_avl_t *ap, void *node)
+{
+ return (AVL_NEXT(&ap->ua_tree, node));
+}
+
+void *
+uu_avl_prev(uu_avl_t *ap, void *node)
+{
+ return (AVL_PREV(&ap->ua_tree, node));
+}
+
+static void
+_avl_walk_init(uu_avl_walk_t *wp, uu_avl_t *ap, uint32_t flags)
+{
+ uu_avl_walk_t *next, *prev;
+
+ int robust = (flags & UU_WALK_ROBUST);
+ int direction = (flags & UU_WALK_REVERSE)? -1 : 1;
+
+ (void) memset(wp, 0, sizeof (*wp));
+ wp->uaw_avl = ap;
+ wp->uaw_robust = robust;
+ wp->uaw_dir = direction;
+
+ if (direction > 0)
+ wp->uaw_next_result = avl_first(&ap->ua_tree);
+ else
+ wp->uaw_next_result = avl_last(&ap->ua_tree);
+
+ if (ap->ua_debug || robust) {
+ wp->uaw_next = next = &ap->ua_null_walk;
+ wp->uaw_prev = prev = next->uaw_prev;
+ next->uaw_prev = wp;
+ prev->uaw_next = wp;
+ }
+}
+
+static void *
+_avl_walk_advance(uu_avl_walk_t *wp, uu_avl_t *ap)
+{
+ void *np = wp->uaw_next_result;
+
+ avl_tree_t *t = &ap->ua_tree;
+
+ if (np == NULL)
+ return (NULL);
+
+ wp->uaw_next_result = (wp->uaw_dir > 0)? AVL_NEXT(t, np) :
+ AVL_PREV(t, np);
+
+ return (np);
+}
+
+static void
+_avl_walk_fini(uu_avl_walk_t *wp)
+{
+ if (wp->uaw_next != NULL) {
+ wp->uaw_next->uaw_prev = wp->uaw_prev;
+ wp->uaw_prev->uaw_next = wp->uaw_next;
+ wp->uaw_next = NULL;
+ wp->uaw_prev = NULL;
+ }
+ wp->uaw_avl = NULL;
+ wp->uaw_next_result = NULL;
+}
+
+uu_avl_walk_t *
+uu_avl_walk_start(uu_avl_t *ap, uint32_t flags)
+{
+ uu_avl_walk_t *wp;
+
+ if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ wp = uu_zalloc(sizeof (*wp));
+ if (wp == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ _avl_walk_init(wp, ap, flags);
+ return (wp);
+}
+
+void *
+uu_avl_walk_next(uu_avl_walk_t *wp)
+{
+ return (_avl_walk_advance(wp, wp->uaw_avl));
+}
+
+void
+uu_avl_walk_end(uu_avl_walk_t *wp)
+{
+ _avl_walk_fini(wp);
+ uu_free(wp);
+}
+
+int
+uu_avl_walk(uu_avl_t *ap, uu_walk_fn_t *func, void *private, uint32_t flags)
+{
+ void *e;
+ uu_avl_walk_t my_walk;
+
+ int status = UU_WALK_NEXT;
+
+ if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (-1);
+ }
+
+ _avl_walk_init(&my_walk, ap, flags);
+ while (status == UU_WALK_NEXT &&
+ (e = _avl_walk_advance(&my_walk, ap)) != NULL)
+ status = (*func)(e, private);
+ _avl_walk_fini(&my_walk);
+
+ if (status >= 0)
+ return (0);
+ uu_set_error(UU_ERROR_CALLBACK_FAILED);
+ return (-1);
+}
+
+void
+uu_avl_remove(uu_avl_t *ap, void *elem)
+{
+ uu_avl_walk_t *wp;
+ uu_avl_pool_t *pp = ap->ua_pool;
+ uintptr_t *na = NODE_ARRAY(pp, elem);
+
+ if (ap->ua_debug) {
+ /*
+ * invalidate outstanding uu_avl_index_ts.
+ */
+ ap->ua_index = INDEX_NEXT(ap->ua_index);
+ }
+
+ /*
+ * Robust walkers most be advanced, if we are removing the node
+ * they are currently using. In debug mode, non-robust walkers
+ * are also on the walker list.
+ */
+ for (wp = ap->ua_null_walk.uaw_next; wp != &ap->ua_null_walk;
+ wp = wp->uaw_next) {
+ if (wp->uaw_robust) {
+ if (elem == wp->uaw_next_result)
+ (void) _avl_walk_advance(wp, ap);
+ } else if (wp->uaw_next_result != NULL) {
+ uu_panic("uu_avl_remove(%p, %p): active non-robust "
+ "walker\n", (void *)ap, elem);
+ }
+ }
+
+ avl_remove(&ap->ua_tree, elem);
+
+ na[0] = POOL_TO_MARKER(pp);
+ na[1] = 0;
+}
+
+void *
+uu_avl_teardown(uu_avl_t *ap, void **cookie)
+{
+ void *elem = avl_destroy_nodes(&ap->ua_tree, cookie);
+
+ if (elem != NULL) {
+ uu_avl_pool_t *pp = ap->ua_pool;
+ uintptr_t *na = NODE_ARRAY(pp, elem);
+
+ na[0] = POOL_TO_MARKER(pp);
+ na[1] = 0;
+ }
+ return (elem);
+}
+
+void *
+uu_avl_find(uu_avl_t *ap, void *elem, void *private, uu_avl_index_t *out)
+{
+ struct uu_avl_node_compare_info info;
+ void *result;
+
+ info.ac_compare = ap->ua_pool->uap_cmp;
+ info.ac_private = private;
+ info.ac_right = elem;
+ info.ac_found = NULL;
+
+ result = avl_find(&ap->ua_tree, &info, out);
+ if (out != NULL)
+ *out = INDEX_ENCODE(ap, *out);
+
+ if (ap->ua_debug && result != NULL)
+ uu_panic("uu_avl_find: internal error: avl_find succeeded\n");
+
+ return (info.ac_found);
+}
+
+void
+uu_avl_insert(uu_avl_t *ap, void *elem, uu_avl_index_t idx)
+{
+ if (ap->ua_debug) {
+ uu_avl_pool_t *pp = ap->ua_pool;
+ uintptr_t *na = NODE_ARRAY(pp, elem);
+
+ if (na[1] != 0)
+ uu_panic("uu_avl_insert(%p, %p, %p): node already "
+ "in tree, or corrupt\n",
+ (void *)ap, elem, (void *)idx);
+ if (na[0] == 0)
+ uu_panic("uu_avl_insert(%p, %p, %p): node not "
+ "initialized\n",
+ (void *)ap, elem, (void *)idx);
+ if (na[0] != POOL_TO_MARKER(pp))
+ uu_panic("uu_avl_insert(%p, %p, %p): node from "
+ "other pool, or corrupt\n",
+ (void *)ap, elem, (void *)idx);
+
+ if (!INDEX_VALID(ap, idx))
+ uu_panic("uu_avl_insert(%p, %p, %p): %s\n",
+ (void *)ap, elem, (void *)idx,
+ INDEX_CHECK(idx)? "outdated index" :
+ "invalid index");
+
+ /*
+ * invalidate outstanding uu_avl_index_ts.
+ */
+ ap->ua_index = INDEX_NEXT(ap->ua_index);
+ }
+ avl_insert(&ap->ua_tree, elem, INDEX_DECODE(idx));
+}
+
+void *
+uu_avl_nearest_next(uu_avl_t *ap, uu_avl_index_t idx)
+{
+ if (ap->ua_debug && !INDEX_VALID(ap, idx))
+ uu_panic("uu_avl_nearest_next(%p, %p): %s\n",
+ (void *)ap, (void *)idx, INDEX_CHECK(idx)?
+ "outdated index" : "invalid index");
+ return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_AFTER));
+}
+
+void *
+uu_avl_nearest_prev(uu_avl_t *ap, uu_avl_index_t idx)
+{
+ if (ap->ua_debug && !INDEX_VALID(ap, idx))
+ uu_panic("uu_avl_nearest_prev(%p, %p): %s\n",
+ (void *)ap, (void *)idx, INDEX_CHECK(idx)?
+ "outdated index" : "invalid index");
+ return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_BEFORE));
+}
+
+/*
+ * called from uu_lockup() and uu_release(), as part of our fork1()-safety.
+ */
+void
+uu_avl_lockup(void)
+{
+ uu_avl_pool_t *pp;
+
+ (void) pthread_mutex_lock(&uu_apool_list_lock);
+ for (pp = uu_null_apool.uap_next; pp != &uu_null_apool;
+ pp = pp->uap_next)
+ (void) pthread_mutex_lock(&pp->uap_lock);
+}
+
+void
+uu_avl_release(void)
+{
+ uu_avl_pool_t *pp;
+
+ for (pp = uu_null_apool.uap_next; pp != &uu_null_apool;
+ pp = pp->uap_next)
+ (void) pthread_mutex_unlock(&pp->uap_lock);
+ (void) pthread_mutex_unlock(&uu_apool_list_lock);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_dprintf.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_dprintf.c
new file mode 100644
index 0000000..528c3e7
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_dprintf.c
@@ -0,0 +1,128 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <errno.h>
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define FACILITY_FMT "%s (%s): "
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+static const char *
+strseverity(uu_dprintf_severity_t severity)
+{
+ switch (severity) {
+ case UU_DPRINTF_SILENT:
+ return (dgettext(TEXT_DOMAIN, "silent"));
+ case UU_DPRINTF_FATAL:
+ return (dgettext(TEXT_DOMAIN, "FATAL"));
+ case UU_DPRINTF_WARNING:
+ return (dgettext(TEXT_DOMAIN, "WARNING"));
+ case UU_DPRINTF_NOTICE:
+ return (dgettext(TEXT_DOMAIN, "note"));
+ case UU_DPRINTF_INFO:
+ return (dgettext(TEXT_DOMAIN, "info"));
+ case UU_DPRINTF_DEBUG:
+ return (dgettext(TEXT_DOMAIN, "debug"));
+ default:
+ return (dgettext(TEXT_DOMAIN, "unspecified"));
+ }
+}
+
+uu_dprintf_t *
+uu_dprintf_create(const char *name, uu_dprintf_severity_t severity,
+ uint_t flags)
+{
+ uu_dprintf_t *D;
+
+ if (uu_check_name(name, UU_NAME_DOMAIN) == -1) {
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (NULL);
+ }
+
+ if ((D = uu_zalloc(sizeof (uu_dprintf_t))) == NULL)
+ return (NULL);
+
+ if (name != NULL) {
+ D->uud_name = strdup(name);
+ if (D->uud_name == NULL) {
+ uu_free(D);
+ return (NULL);
+ }
+ } else {
+ D->uud_name = NULL;
+ }
+
+ D->uud_severity = severity;
+ D->uud_flags = flags;
+
+ return (D);
+}
+
+/*PRINTFLIKE3*/
+void
+uu_dprintf(uu_dprintf_t *D, uu_dprintf_severity_t severity,
+ const char *format, ...)
+{
+ va_list alist;
+
+ /* XXX Assert that severity is not UU_DPRINTF_SILENT. */
+
+ if (severity > D->uud_severity)
+ return;
+
+ (void) fprintf(stderr, FACILITY_FMT, D->uud_name,
+ strseverity(severity));
+
+ va_start(alist, format);
+ (void) vfprintf(stderr, format, alist);
+ va_end(alist);
+}
+
+void
+uu_dprintf_destroy(uu_dprintf_t *D)
+{
+ if (D->uud_name)
+ free(D->uud_name);
+
+ uu_free(D);
+}
+
+const char *
+uu_dprintf_getname(uu_dprintf_t *D)
+{
+ return (D->uud_name);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_ident.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_ident.c
new file mode 100644
index 0000000..9a64384
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_ident.c
@@ -0,0 +1,122 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <string.h>
+
+/*
+ * We require names of the form:
+ * [provider,]identifier[/[provider,]identifier]...
+ *
+ * Where provider is either a stock symbol (SUNW) or a java-style reversed
+ * domain name (com.sun).
+ *
+ * Both providers and identifiers must start with a letter, and may
+ * only contain alphanumerics, dashes, and underlines. Providers
+ * may also contain periods.
+ *
+ * Note that we do _not_ use the macros in <ctype.h>, since they are affected
+ * by the current locale settings.
+ */
+
+#define IS_ALPHA(c) \
+ (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
+
+#define IS_DIGIT(c) \
+ ((c) >= '0' && (c) <= '9')
+
+static int
+is_valid_ident(const char *s, const char *e, int allowdot)
+{
+ char c;
+
+ if (s >= e)
+ return (0); /* name is empty */
+
+ c = *s++;
+ if (!IS_ALPHA(c))
+ return (0); /* does not start with letter */
+
+ while (s < e && (c = *s++) != 0) {
+ if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' ||
+ (allowdot && c == '.'))
+ continue;
+ return (0); /* invalid character */
+ }
+ return (1);
+}
+
+static int
+is_valid_component(const char *b, const char *e, uint_t flags)
+{
+ char *sp;
+
+ if (flags & UU_NAME_DOMAIN) {
+ sp = strchr(b, ',');
+ if (sp != NULL && sp < e) {
+ if (!is_valid_ident(b, sp, 1))
+ return (0);
+ b = sp + 1;
+ }
+ }
+
+ return (is_valid_ident(b, e, 0));
+}
+
+int
+uu_check_name(const char *name, uint_t flags)
+{
+ const char *end = name + strlen(name);
+ const char *p;
+
+ if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (-1);
+ }
+
+ if (!(flags & UU_NAME_PATH)) {
+ if (!is_valid_component(name, end, flags))
+ goto bad;
+ return (0);
+ }
+
+ while ((p = strchr(name, '/')) != NULL) {
+ if (!is_valid_component(name, p - 1, flags))
+ goto bad;
+ name = p + 1;
+ }
+ if (!is_valid_component(name, end, flags))
+ goto bad;
+
+ return (0);
+
+bad:
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (-1);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_list.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_list.c
new file mode 100644
index 0000000..35c7ba8
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_list.c
@@ -0,0 +1,718 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#define ELEM_TO_NODE(lp, e) \
+ ((uu_list_node_impl_t *)((uintptr_t)(e) + (lp)->ul_offset))
+
+#define NODE_TO_ELEM(lp, n) \
+ ((void *)((uintptr_t)(n) - (lp)->ul_offset))
+
+/*
+ * uu_list_index_ts define a location for insertion. They are simply a
+ * pointer to the object after the insertion point. We store a mark
+ * in the low-bits of the index, to help prevent mistakes.
+ *
+ * When debugging, the index mark changes on every insert and delete, to
+ * catch stale references.
+ */
+#define INDEX_MAX (sizeof (uintptr_t) - 1)
+#define INDEX_NEXT(m) (((m) == INDEX_MAX)? 1 : ((m) + 1) & INDEX_MAX)
+
+#define INDEX_TO_NODE(i) ((uu_list_node_impl_t *)((i) & ~INDEX_MAX))
+#define NODE_TO_INDEX(p, n) (((uintptr_t)(n) & ~INDEX_MAX) | (p)->ul_index)
+#define INDEX_VALID(p, i) (((i) & INDEX_MAX) == (p)->ul_index)
+#define INDEX_CHECK(i) (((i) & INDEX_MAX) != 0)
+
+#define POOL_TO_MARKER(pp) ((void *)((uintptr_t)(pp) | 1))
+
+static uu_list_pool_t uu_null_lpool = { &uu_null_lpool, &uu_null_lpool };
+static pthread_mutex_t uu_lpool_list_lock = PTHREAD_MUTEX_INITIALIZER;
+
+uu_list_pool_t *
+uu_list_pool_create(const char *name, size_t objsize,
+ size_t nodeoffset, uu_compare_fn_t *compare_func, uint32_t flags)
+{
+ uu_list_pool_t *pp, *next, *prev;
+
+ if (name == NULL ||
+ uu_check_name(name, UU_NAME_DOMAIN) == -1 ||
+ nodeoffset + sizeof (uu_list_node_t) > objsize) {
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (NULL);
+ }
+
+ if (flags & ~UU_LIST_POOL_DEBUG) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ pp = uu_zalloc(sizeof (uu_list_pool_t));
+ if (pp == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ (void) strlcpy(pp->ulp_name, name, sizeof (pp->ulp_name));
+ pp->ulp_nodeoffset = nodeoffset;
+ pp->ulp_objsize = objsize;
+ pp->ulp_cmp = compare_func;
+ if (flags & UU_LIST_POOL_DEBUG)
+ pp->ulp_debug = 1;
+ pp->ulp_last_index = 0;
+
+ (void) pthread_mutex_init(&pp->ulp_lock, NULL);
+
+ pp->ulp_null_list.ul_next_enc = UU_PTR_ENCODE(&pp->ulp_null_list);
+ pp->ulp_null_list.ul_prev_enc = UU_PTR_ENCODE(&pp->ulp_null_list);
+
+ (void) pthread_mutex_lock(&uu_lpool_list_lock);
+ pp->ulp_next = next = &uu_null_lpool;
+ pp->ulp_prev = prev = next->ulp_prev;
+ next->ulp_prev = pp;
+ prev->ulp_next = pp;
+ (void) pthread_mutex_unlock(&uu_lpool_list_lock);
+
+ return (pp);
+}
+
+void
+uu_list_pool_destroy(uu_list_pool_t *pp)
+{
+ if (pp->ulp_debug) {
+ if (pp->ulp_null_list.ul_next_enc !=
+ UU_PTR_ENCODE(&pp->ulp_null_list) ||
+ pp->ulp_null_list.ul_prev_enc !=
+ UU_PTR_ENCODE(&pp->ulp_null_list)) {
+ uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has "
+ "outstanding lists, or is corrupt.\n",
+ (int)sizeof (pp->ulp_name), pp->ulp_name,
+ (void *)pp);
+ }
+ }
+ (void) pthread_mutex_lock(&uu_lpool_list_lock);
+ pp->ulp_next->ulp_prev = pp->ulp_prev;
+ pp->ulp_prev->ulp_next = pp->ulp_next;
+ (void) pthread_mutex_unlock(&uu_lpool_list_lock);
+ pp->ulp_prev = NULL;
+ pp->ulp_next = NULL;
+ uu_free(pp);
+}
+
+void
+uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
+{
+ uu_list_node_impl_t *np = (uu_list_node_impl_t *)np_arg;
+
+ if (pp->ulp_debug) {
+ uintptr_t offset = (uintptr_t)np - (uintptr_t)base;
+ if (offset + sizeof (*np) > pp->ulp_objsize) {
+ uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
+ "offset %ld doesn't fit in object (size %ld)\n",
+ base, (void *)np, (void *)pp, pp->ulp_name,
+ (long)offset, (long)pp->ulp_objsize);
+ }
+ if (offset != pp->ulp_nodeoffset) {
+ uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
+ "offset %ld doesn't match pool's offset (%ld)\n",
+ base, (void *)np, (void *)pp, pp->ulp_name,
+ (long)offset, (long)pp->ulp_objsize);
+ }
+ }
+ np->uln_next = POOL_TO_MARKER(pp);
+ np->uln_prev = NULL;
+}
+
+void
+uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
+{
+ uu_list_node_impl_t *np = (uu_list_node_impl_t *)np_arg;
+
+ if (pp->ulp_debug) {
+ if (np->uln_next == NULL &&
+ np->uln_prev == NULL) {
+ uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
+ "node already finied\n",
+ base, (void *)np_arg, (void *)pp, pp->ulp_name);
+ }
+ if (np->uln_next != POOL_TO_MARKER(pp) ||
+ np->uln_prev != NULL) {
+ uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
+ "node corrupt or on list\n",
+ base, (void *)np_arg, (void *)pp, pp->ulp_name);
+ }
+ }
+ np->uln_next = NULL;
+ np->uln_prev = NULL;
+}
+
+uu_list_t *
+uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
+{
+ uu_list_t *lp, *next, *prev;
+
+ if (flags & ~(UU_LIST_DEBUG | UU_LIST_SORTED)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ if ((flags & UU_LIST_SORTED) && pp->ulp_cmp == NULL) {
+ if (pp->ulp_debug)
+ uu_panic("uu_list_create(%p, ...): requested "
+ "UU_LIST_SORTED, but pool has no comparison func\n",
+ (void *)pp);
+ uu_set_error(UU_ERROR_NOT_SUPPORTED);
+ return (NULL);
+ }
+
+ lp = uu_zalloc(sizeof (*lp));
+ if (lp == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ lp->ul_pool = pp;
+ lp->ul_parent_enc = UU_PTR_ENCODE(parent);
+ lp->ul_offset = pp->ulp_nodeoffset;
+ lp->ul_debug = pp->ulp_debug || (flags & UU_LIST_DEBUG);
+ lp->ul_sorted = (flags & UU_LIST_SORTED);
+ lp->ul_numnodes = 0;
+ lp->ul_index = (pp->ulp_last_index = INDEX_NEXT(pp->ulp_last_index));
+
+ lp->ul_null_node.uln_next = &lp->ul_null_node;
+ lp->ul_null_node.uln_prev = &lp->ul_null_node;
+
+ lp->ul_null_walk.ulw_next = &lp->ul_null_walk;
+ lp->ul_null_walk.ulw_prev = &lp->ul_null_walk;
+
+ (void) pthread_mutex_lock(&pp->ulp_lock);
+ next = &pp->ulp_null_list;
+ prev = UU_PTR_DECODE(next->ul_prev_enc);
+ lp->ul_next_enc = UU_PTR_ENCODE(next);
+ lp->ul_prev_enc = UU_PTR_ENCODE(prev);
+ next->ul_prev_enc = UU_PTR_ENCODE(lp);
+ prev->ul_next_enc = UU_PTR_ENCODE(lp);
+ (void) pthread_mutex_unlock(&pp->ulp_lock);
+
+ return (lp);
+}
+
+void
+uu_list_destroy(uu_list_t *lp)
+{
+ uu_list_pool_t *pp = lp->ul_pool;
+
+ if (lp->ul_debug) {
+ if (lp->ul_null_node.uln_next != &lp->ul_null_node ||
+ lp->ul_null_node.uln_prev != &lp->ul_null_node) {
+ uu_panic("uu_list_destroy(%p): list not empty\n",
+ (void *)lp);
+ }
+ if (lp->ul_numnodes != 0) {
+ uu_panic("uu_list_destroy(%p): numnodes is nonzero, "
+ "but list is empty\n", (void *)lp);
+ }
+ if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk ||
+ lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) {
+ uu_panic("uu_list_destroy(%p): outstanding walkers\n",
+ (void *)lp);
+ }
+ }
+
+ (void) pthread_mutex_lock(&pp->ulp_lock);
+ UU_LIST_PTR(lp->ul_next_enc)->ul_prev_enc = lp->ul_prev_enc;
+ UU_LIST_PTR(lp->ul_prev_enc)->ul_next_enc = lp->ul_next_enc;
+ (void) pthread_mutex_unlock(&pp->ulp_lock);
+ lp->ul_prev_enc = UU_PTR_ENCODE(NULL);
+ lp->ul_next_enc = UU_PTR_ENCODE(NULL);
+ lp->ul_pool = NULL;
+ uu_free(lp);
+}
+
+static void
+list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev,
+ uu_list_node_impl_t *next)
+{
+ if (lp->ul_debug) {
+ if (next->uln_prev != prev || prev->uln_next != next)
+ uu_panic("insert(%p): internal error: %p and %p not "
+ "neighbors\n", (void *)lp, (void *)next,
+ (void *)prev);
+
+ if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) ||
+ np->uln_prev != NULL) {
+ uu_panic("insert(%p): elem %p node %p corrupt, "
+ "not initialized, or already in a list.\n",
+ (void *)lp, NODE_TO_ELEM(lp, np), (void *)np);
+ }
+ /*
+ * invalidate outstanding uu_list_index_ts.
+ */
+ lp->ul_index = INDEX_NEXT(lp->ul_index);
+ }
+ np->uln_next = next;
+ np->uln_prev = prev;
+ next->uln_prev = np;
+ prev->uln_next = np;
+
+ lp->ul_numnodes++;
+}
+
+void
+uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx)
+{
+ uu_list_node_impl_t *np;
+
+ np = INDEX_TO_NODE(idx);
+ if (np == NULL)
+ np = &lp->ul_null_node;
+
+ if (lp->ul_debug) {
+ if (!INDEX_VALID(lp, idx))
+ uu_panic("uu_list_insert(%p, %p, %p): %s\n",
+ (void *)lp, elem, (void *)idx,
+ INDEX_CHECK(idx)? "outdated index" :
+ "invalid index");
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_insert(%p, %p, %p): out-of-date "
+ "index\n", (void *)lp, elem, (void *)idx);
+ }
+
+ list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
+}
+
+void *
+uu_list_find(uu_list_t *lp, void *elem, void *private, uu_list_index_t *out)
+{
+ int sorted = lp->ul_sorted;
+ uu_compare_fn_t *func = lp->ul_pool->ulp_cmp;
+ uu_list_node_impl_t *np;
+
+ if (func == NULL) {
+ if (out != NULL)
+ *out = 0;
+ uu_set_error(UU_ERROR_NOT_SUPPORTED);
+ return (NULL);
+ }
+ for (np = lp->ul_null_node.uln_next; np != &lp->ul_null_node;
+ np = np->uln_next) {
+ void *ep = NODE_TO_ELEM(lp, np);
+ int cmp = func(ep, elem, private);
+ if (cmp == 0) {
+ if (out != NULL)
+ *out = NODE_TO_INDEX(lp, np);
+ return (ep);
+ }
+ if (sorted && cmp > 0) {
+ if (out != NULL)
+ *out = NODE_TO_INDEX(lp, np);
+ return (NULL);
+ }
+ }
+ if (out != NULL)
+ *out = NODE_TO_INDEX(lp, 0);
+ return (NULL);
+}
+
+void *
+uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx)
+{
+ uu_list_node_impl_t *np = INDEX_TO_NODE(idx);
+
+ if (np == NULL)
+ np = &lp->ul_null_node;
+
+ if (lp->ul_debug) {
+ if (!INDEX_VALID(lp, idx))
+ uu_panic("uu_list_nearest_next(%p, %p): %s\n",
+ (void *)lp, (void *)idx,
+ INDEX_CHECK(idx)? "outdated index" :
+ "invalid index");
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_nearest_next(%p, %p): out-of-date "
+ "index\n", (void *)lp, (void *)idx);
+ }
+
+ if (np == &lp->ul_null_node)
+ return (NULL);
+ else
+ return (NODE_TO_ELEM(lp, np));
+}
+
+void *
+uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx)
+{
+ uu_list_node_impl_t *np = INDEX_TO_NODE(idx);
+
+ if (np == NULL)
+ np = &lp->ul_null_node;
+
+ if (lp->ul_debug) {
+ if (!INDEX_VALID(lp, idx))
+ uu_panic("uu_list_nearest_prev(%p, %p): %s\n",
+ (void *)lp, (void *)idx, INDEX_CHECK(idx)?
+ "outdated index" : "invalid index");
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_nearest_prev(%p, %p): out-of-date "
+ "index\n", (void *)lp, (void *)idx);
+ }
+
+ if ((np = np->uln_prev) == &lp->ul_null_node)
+ return (NULL);
+ else
+ return (NODE_TO_ELEM(lp, np));
+}
+
+static void
+list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags)
+{
+ uu_list_walk_t *next, *prev;
+
+ int robust = (flags & UU_WALK_ROBUST);
+ int direction = (flags & UU_WALK_REVERSE)? -1 : 1;
+
+ (void) memset(wp, 0, sizeof (*wp));
+ wp->ulw_list = lp;
+ wp->ulw_robust = robust;
+ wp->ulw_dir = direction;
+ if (direction > 0)
+ wp->ulw_next_result = lp->ul_null_node.uln_next;
+ else
+ wp->ulw_next_result = lp->ul_null_node.uln_prev;
+
+ if (lp->ul_debug || robust) {
+ /*
+ * Add this walker to the list's list of walkers so
+ * uu_list_remove() can advance us if somebody tries to
+ * remove ulw_next_result.
+ */
+ wp->ulw_next = next = &lp->ul_null_walk;
+ wp->ulw_prev = prev = next->ulw_prev;
+ next->ulw_prev = wp;
+ prev->ulw_next = wp;
+ }
+}
+
+static uu_list_node_impl_t *
+list_walk_advance(uu_list_walk_t *wp, uu_list_t *lp)
+{
+ uu_list_node_impl_t *np = wp->ulw_next_result;
+ uu_list_node_impl_t *next;
+
+ if (np == &lp->ul_null_node)
+ return (NULL);
+
+ next = (wp->ulw_dir > 0)? np->uln_next : np->uln_prev;
+
+ wp->ulw_next_result = next;
+ return (np);
+}
+
+static void
+list_walk_fini(uu_list_walk_t *wp)
+{
+ /* GLXXX debugging? */
+ if (wp->ulw_next != NULL) {
+ wp->ulw_next->ulw_prev = wp->ulw_prev;
+ wp->ulw_prev->ulw_next = wp->ulw_next;
+ wp->ulw_next = NULL;
+ wp->ulw_prev = NULL;
+ }
+ wp->ulw_list = NULL;
+ wp->ulw_next_result = NULL;
+}
+
+uu_list_walk_t *
+uu_list_walk_start(uu_list_t *lp, uint32_t flags)
+{
+ uu_list_walk_t *wp;
+
+ if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (NULL);
+ }
+
+ wp = uu_zalloc(sizeof (*wp));
+ if (wp == NULL) {
+ uu_set_error(UU_ERROR_NO_MEMORY);
+ return (NULL);
+ }
+
+ list_walk_init(wp, lp, flags);
+ return (wp);
+}
+
+void *
+uu_list_walk_next(uu_list_walk_t *wp)
+{
+ uu_list_t *lp = wp->ulw_list;
+ uu_list_node_impl_t *np = list_walk_advance(wp, lp);
+
+ if (np == NULL)
+ return (NULL);
+
+ return (NODE_TO_ELEM(lp, np));
+}
+
+void
+uu_list_walk_end(uu_list_walk_t *wp)
+{
+ list_walk_fini(wp);
+ uu_free(wp);
+}
+
+int
+uu_list_walk(uu_list_t *lp, uu_walk_fn_t *func, void *private, uint32_t flags)
+{
+ uu_list_node_impl_t *np;
+
+ int status = UU_WALK_NEXT;
+
+ int robust = (flags & UU_WALK_ROBUST);
+ int reverse = (flags & UU_WALK_REVERSE);
+
+ if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
+ uu_set_error(UU_ERROR_UNKNOWN_FLAG);
+ return (-1);
+ }
+
+ if (lp->ul_debug || robust) {
+ uu_list_walk_t my_walk;
+ void *e;
+
+ list_walk_init(&my_walk, lp, flags);
+ while (status == UU_WALK_NEXT &&
+ (e = uu_list_walk_next(&my_walk)) != NULL)
+ status = (*func)(e, private);
+ list_walk_fini(&my_walk);
+ } else {
+ if (!reverse) {
+ for (np = lp->ul_null_node.uln_next;
+ status == UU_WALK_NEXT && np != &lp->ul_null_node;
+ np = np->uln_next) {
+ status = (*func)(NODE_TO_ELEM(lp, np), private);
+ }
+ } else {
+ for (np = lp->ul_null_node.uln_prev;
+ status == UU_WALK_NEXT && np != &lp->ul_null_node;
+ np = np->uln_prev) {
+ status = (*func)(NODE_TO_ELEM(lp, np), private);
+ }
+ }
+ }
+ if (status >= 0)
+ return (0);
+ uu_set_error(UU_ERROR_CALLBACK_FAILED);
+ return (-1);
+}
+
+void
+uu_list_remove(uu_list_t *lp, void *elem)
+{
+ uu_list_node_impl_t *np = ELEM_TO_NODE(lp, elem);
+ uu_list_walk_t *wp;
+
+ if (lp->ul_debug) {
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_remove(%p, %p): elem not on list\n",
+ (void *)lp, elem);
+ /*
+ * invalidate outstanding uu_list_index_ts.
+ */
+ lp->ul_index = INDEX_NEXT(lp->ul_index);
+ }
+
+ /*
+ * robust walkers must be advanced. In debug mode, non-robust
+ * walkers are also on the list. If there are any, it's an error.
+ */
+ for (wp = lp->ul_null_walk.ulw_next; wp != &lp->ul_null_walk;
+ wp = wp->ulw_next) {
+ if (wp->ulw_robust) {
+ if (np == wp->ulw_next_result)
+ (void) list_walk_advance(wp, lp);
+ } else if (wp->ulw_next_result != NULL) {
+ uu_panic("uu_list_remove(%p, %p): active non-robust "
+ "walker\n", (void *)lp, elem);
+ }
+ }
+
+ np->uln_next->uln_prev = np->uln_prev;
+ np->uln_prev->uln_next = np->uln_next;
+
+ lp->ul_numnodes--;
+
+ np->uln_next = POOL_TO_MARKER(lp->ul_pool);
+ np->uln_prev = NULL;
+}
+
+void *
+uu_list_teardown(uu_list_t *lp, void **cookie)
+{
+ void *ep;
+
+ /*
+ * XXX: disable list modification until list is empty
+ */
+ if (lp->ul_debug && *cookie != NULL)
+ uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n",
+ (void *)lp, (void *)cookie);
+
+ ep = uu_list_first(lp);
+ if (ep)
+ uu_list_remove(lp, ep);
+ return (ep);
+}
+
+int
+uu_list_insert_before(uu_list_t *lp, void *target, void *elem)
+{
+ uu_list_node_impl_t *np = ELEM_TO_NODE(lp, target);
+
+ if (target == NULL)
+ np = &lp->ul_null_node;
+
+ if (lp->ul_debug) {
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_insert_before(%p, %p, %p): %p is "
+ "not currently on a list\n",
+ (void *)lp, target, elem, target);
+ }
+ if (lp->ul_sorted) {
+ if (lp->ul_debug)
+ uu_panic("uu_list_insert_before(%p, ...): list is "
+ "UU_LIST_SORTED\n", (void *)lp);
+ uu_set_error(UU_ERROR_NOT_SUPPORTED);
+ return (-1);
+ }
+
+ list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
+ return (0);
+}
+
+int
+uu_list_insert_after(uu_list_t *lp, void *target, void *elem)
+{
+ uu_list_node_impl_t *np = ELEM_TO_NODE(lp, target);
+
+ if (target == NULL)
+ np = &lp->ul_null_node;
+
+ if (lp->ul_debug) {
+ if (np->uln_prev == NULL)
+ uu_panic("uu_list_insert_after(%p, %p, %p): %p is "
+ "not currently on a list\n",
+ (void *)lp, target, elem, target);
+ }
+ if (lp->ul_sorted) {
+ if (lp->ul_debug)
+ uu_panic("uu_list_insert_after(%p, ...): list is "
+ "UU_LIST_SORTED\n", (void *)lp);
+ uu_set_error(UU_ERROR_NOT_SUPPORTED);
+ return (-1);
+ }
+
+ list_insert(lp, ELEM_TO_NODE(lp, elem), np, np->uln_next);
+ return (0);
+}
+
+size_t
+uu_list_numnodes(uu_list_t *lp)
+{
+ return (lp->ul_numnodes);
+}
+
+void *
+uu_list_first(uu_list_t *lp)
+{
+ uu_list_node_impl_t *n = lp->ul_null_node.uln_next;
+ if (n == &lp->ul_null_node)
+ return (NULL);
+ return (NODE_TO_ELEM(lp, n));
+}
+
+void *
+uu_list_last(uu_list_t *lp)
+{
+ uu_list_node_impl_t *n = lp->ul_null_node.uln_prev;
+ if (n == &lp->ul_null_node)
+ return (NULL);
+ return (NODE_TO_ELEM(lp, n));
+}
+
+void *
+uu_list_next(uu_list_t *lp, void *elem)
+{
+ uu_list_node_impl_t *n = ELEM_TO_NODE(lp, elem);
+
+ n = n->uln_next;
+ if (n == &lp->ul_null_node)
+ return (NULL);
+ return (NODE_TO_ELEM(lp, n));
+}
+
+void *
+uu_list_prev(uu_list_t *lp, void *elem)
+{
+ uu_list_node_impl_t *n = ELEM_TO_NODE(lp, elem);
+
+ n = n->uln_prev;
+ if (n == &lp->ul_null_node)
+ return (NULL);
+ return (NODE_TO_ELEM(lp, n));
+}
+
+/*
+ * called from uu_lockup() and uu_release(), as part of our fork1()-safety.
+ */
+void
+uu_list_lockup(void)
+{
+ uu_list_pool_t *pp;
+
+ (void) pthread_mutex_lock(&uu_lpool_list_lock);
+ for (pp = uu_null_lpool.ulp_next; pp != &uu_null_lpool;
+ pp = pp->ulp_next)
+ (void) pthread_mutex_lock(&pp->ulp_lock);
+}
+
+void
+uu_list_release(void)
+{
+ uu_list_pool_t *pp;
+
+ for (pp = uu_null_lpool.ulp_next; pp != &uu_null_lpool;
+ pp = pp->ulp_next)
+ (void) pthread_mutex_unlock(&pp->ulp_lock);
+ (void) pthread_mutex_unlock(&uu_lpool_list_lock);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_misc.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_misc.c
new file mode 100644
index 0000000..b673834
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_misc.c
@@ -0,0 +1,277 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include "libuutil_common.h"
+
+#define HAVE_ASSFAIL 1
+
+#include <assert.h>
+#include <errno.h>
+#include <libintl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/debug.h>
+#include <thread.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+/*
+ * All of the old code under !defined(PTHREAD_ONCE_KEY_NP)
+ * is here to enable the building of a native version of
+ * libuutil.so when the build machine has not yet been upgraded
+ * to a version of libc that provides pthread_key_create_once_np().
+ * It should all be deleted when solaris_nevada ships.
+ * The code is not MT-safe in a relaxed memory model.
+ */
+
+#if defined(PTHREAD_ONCE_KEY_NP)
+static pthread_key_t uu_error_key = PTHREAD_ONCE_KEY_NP;
+#else /* PTHREAD_ONCE_KEY_NP */
+static pthread_key_t uu_error_key = 0;
+static pthread_mutex_t uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif /* PTHREAD_ONCE_KEY_NP */
+
+static int uu_error_key_setup = 0;
+
+static pthread_mutex_t uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
+/* LINTED static unused */
+static const char *uu_panic_format;
+/* LINTED static unused */
+static va_list uu_panic_args;
+static pthread_t uu_panic_thread;
+
+static uint32_t _uu_main_error;
+
+void
+uu_set_error(uint_t code)
+{
+
+#if defined(PTHREAD_ONCE_KEY_NP)
+ if (pthread_key_create_once_np(&uu_error_key, NULL) != 0)
+ uu_error_key_setup = -1;
+ else
+ uu_error_key_setup = 1;
+#else /* PTHREAD_ONCE_KEY_NP */
+ if (uu_error_key_setup == 0) {
+ (void) pthread_mutex_lock(&uu_key_lock);
+ if (uu_error_key_setup == 0) {
+ if (pthread_key_create(&uu_error_key, NULL) != 0)
+ uu_error_key_setup = -1;
+ else
+ uu_error_key_setup = 1;
+ }
+ (void) pthread_mutex_unlock(&uu_key_lock);
+ }
+#endif /* PTHREAD_ONCE_KEY_NP */
+ if (uu_error_key_setup > 0)
+ (void) pthread_setspecific(uu_error_key,
+ (void *)(uintptr_t)code);
+}
+
+uint32_t
+uu_error(void)
+{
+
+ if (uu_error_key_setup < 0) /* can't happen? */
+ return (UU_ERROR_UNKNOWN);
+
+ /*
+ * Because UU_ERROR_NONE == 0, if uu_set_error() was
+ * never called, then this will return UU_ERROR_NONE:
+ */
+ return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
+}
+
+const char *
+uu_strerror(uint32_t code)
+{
+ const char *str;
+
+ switch (code) {
+ case UU_ERROR_NONE:
+ str = dgettext(TEXT_DOMAIN, "No error");
+ break;
+
+ case UU_ERROR_INVALID_ARGUMENT:
+ str = dgettext(TEXT_DOMAIN, "Invalid argument");
+ break;
+
+ case UU_ERROR_UNKNOWN_FLAG:
+ str = dgettext(TEXT_DOMAIN, "Unknown flag passed");
+ break;
+
+ case UU_ERROR_NO_MEMORY:
+ str = dgettext(TEXT_DOMAIN, "Out of memory");
+ break;
+
+ case UU_ERROR_CALLBACK_FAILED:
+ str = dgettext(TEXT_DOMAIN, "Callback-initiated failure");
+ break;
+
+ case UU_ERROR_NOT_SUPPORTED:
+ str = dgettext(TEXT_DOMAIN, "Operation not supported");
+ break;
+
+ case UU_ERROR_EMPTY:
+ str = dgettext(TEXT_DOMAIN, "No value provided");
+ break;
+
+ case UU_ERROR_UNDERFLOW:
+ str = dgettext(TEXT_DOMAIN, "Value too small");
+ break;
+
+ case UU_ERROR_OVERFLOW:
+ str = dgettext(TEXT_DOMAIN, "Value too large");
+ break;
+
+ case UU_ERROR_INVALID_CHAR:
+ str = dgettext(TEXT_DOMAIN,
+ "Value contains unexpected character");
+ break;
+
+ case UU_ERROR_INVALID_DIGIT:
+ str = dgettext(TEXT_DOMAIN,
+ "Value contains digit not in base");
+ break;
+
+ case UU_ERROR_SYSTEM:
+ str = dgettext(TEXT_DOMAIN, "Underlying system error");
+ break;
+
+ case UU_ERROR_UNKNOWN:
+ str = dgettext(TEXT_DOMAIN, "Error status not known");
+ break;
+
+ default:
+ errno = ESRCH;
+ str = NULL;
+ break;
+ }
+ return (str);
+}
+
+void
+uu_panic(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ (void) pthread_mutex_lock(&uu_panic_lock);
+ if (uu_panic_thread == 0) {
+ uu_panic_thread = pthread_self();
+ uu_panic_format = format;
+ va_copy(uu_panic_args, args);
+ }
+ (void) pthread_mutex_unlock(&uu_panic_lock);
+
+ (void) vfprintf(stderr, format, args);
+
+ if (uu_panic_thread == pthread_self())
+ abort();
+ else
+ for (;;)
+ (void) pause();
+}
+
+int
+assfail(const char *astring, const char *file, int line)
+{
+ __assert(astring, file, line);
+ /*NOTREACHED*/
+ return (0);
+}
+
+static void
+uu_lockup(void)
+{
+ (void) pthread_mutex_lock(&uu_panic_lock);
+#if !defined(PTHREAD_ONCE_KEY_NP)
+ (void) pthread_mutex_lock(&uu_key_lock);
+#endif
+ uu_avl_lockup();
+ uu_list_lockup();
+}
+
+static void
+uu_release(void)
+{
+ (void) pthread_mutex_unlock(&uu_panic_lock);
+#if !defined(PTHREAD_ONCE_KEY_NP)
+ (void) pthread_mutex_unlock(&uu_key_lock);
+#endif
+ uu_avl_release();
+ uu_list_release();
+}
+
+static void
+uu_release_child(void)
+{
+ uu_panic_format = NULL;
+ uu_panic_thread = 0;
+
+ uu_release();
+}
+
+#pragma init(uu_init)
+static void
+uu_init(void)
+{
+ (void) pthread_atfork(uu_lockup, uu_release, uu_release_child);
+}
+
+/*
+ * Dump a block of memory in hex+ascii, for debugging
+ */
+void
+uu_dump(FILE *out, const char *prefix, const void *buf, size_t len)
+{
+ const unsigned char *p = buf;
+ int i;
+
+ for (i = 0; i < len; i += 16) {
+ int j;
+
+ (void) fprintf(out, "%s", prefix);
+ for (j = 0; j < 16 && i + j < len; j++) {
+ (void) fprintf(out, "%2.2x ", p[i + j]);
+ }
+ for (; j < 16; j++) {
+ (void) fprintf(out, " ");
+ }
+ for (j = 0; j < 16 && i + j < len; j++) {
+ (void) fprintf(out, "%c",
+ isprint(p[i + j]) ? p[i + j] : '.');
+ }
+ (void) fprintf(out, "\n");
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_open.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_open.c
new file mode 100644
index 0000000..7256662
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_open.c
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <sys/time.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef _LP64
+#define TMPPATHFMT "%s/uu%ld"
+#else /* _LP64 */
+#define TMPPATHFMT "%s/uu%lld"
+#endif /* _LP64 */
+
+/*ARGSUSED*/
+int
+uu_open_tmp(const char *dir, uint_t uflags)
+{
+ int f;
+ char *fname = uu_zalloc(PATH_MAX);
+
+ if (fname == NULL)
+ return (-1);
+
+ for (;;) {
+ (void) snprintf(fname, PATH_MAX, "%s/uu%lld", dir, gethrtime());
+
+ f = open(fname, O_CREAT | O_EXCL | O_RDWR, 0600);
+
+ if (f >= 0 || errno != EEXIST)
+ break;
+ }
+
+ if (f >= 0)
+ (void) unlink(fname);
+
+ uu_free(fname);
+
+ return (f);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_pname.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_pname.c
new file mode 100644
index 0000000..20626ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_pname.c
@@ -0,0 +1,205 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <libintl.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <wchar.h>
+#include <unistd.h>
+
+static const char PNAME_FMT[] = "%s: ";
+static const char ERRNO_FMT[] = ": %s\n";
+
+static const char *pname;
+
+static void
+uu_die_internal(int status, const char *format, va_list alist) __NORETURN;
+
+int uu_exit_ok_value = EXIT_SUCCESS;
+int uu_exit_fatal_value = EXIT_FAILURE;
+int uu_exit_usage_value = 2;
+
+int *
+uu_exit_ok(void)
+{
+ return (&uu_exit_ok_value);
+}
+
+int *
+uu_exit_fatal(void)
+{
+ return (&uu_exit_fatal_value);
+}
+
+int *
+uu_exit_usage(void)
+{
+ return (&uu_exit_usage_value);
+}
+
+void
+uu_alt_exit(int profile)
+{
+ switch (profile) {
+ case UU_PROFILE_DEFAULT:
+ uu_exit_ok_value = EXIT_SUCCESS;
+ uu_exit_fatal_value = EXIT_FAILURE;
+ uu_exit_usage_value = 2;
+ break;
+ case UU_PROFILE_LAUNCHER:
+ uu_exit_ok_value = EXIT_SUCCESS;
+ uu_exit_fatal_value = 124;
+ uu_exit_usage_value = 125;
+ break;
+ }
+}
+
+static void
+uu_warn_internal(int err, const char *format, va_list alist)
+{
+ if (pname != NULL)
+ (void) fprintf(stderr, PNAME_FMT, pname);
+
+ (void) vfprintf(stderr, format, alist);
+
+ if (strrchr(format, '\n') == NULL)
+ (void) fprintf(stderr, ERRNO_FMT, strerror(err));
+}
+
+void
+uu_vwarn(const char *format, va_list alist)
+{
+ uu_warn_internal(errno, format, alist);
+}
+
+/*PRINTFLIKE1*/
+void
+uu_warn(const char *format, ...)
+{
+ va_list alist;
+ va_start(alist, format);
+ uu_warn_internal(errno, format, alist);
+ va_end(alist);
+}
+
+static void
+uu_die_internal(int status, const char *format, va_list alist)
+{
+ uu_warn_internal(errno, format, alist);
+#ifdef DEBUG
+ {
+ char *cp;
+
+ if (!issetugid()) {
+ cp = getenv("UU_DIE_ABORTS");
+ if (cp != NULL && *cp != '\0')
+ abort();
+ }
+ }
+#endif
+ exit(status);
+}
+
+void
+uu_vdie(const char *format, va_list alist)
+{
+ uu_die_internal(UU_EXIT_FATAL, format, alist);
+}
+
+/*PRINTFLIKE1*/
+void
+uu_die(const char *format, ...)
+{
+ va_list alist;
+ va_start(alist, format);
+ uu_die_internal(UU_EXIT_FATAL, format, alist);
+ va_end(alist);
+}
+
+void
+uu_vxdie(int status, const char *format, va_list alist)
+{
+ uu_die_internal(status, format, alist);
+}
+
+/*PRINTFLIKE2*/
+void
+uu_xdie(int status, const char *format, ...)
+{
+ va_list alist;
+ va_start(alist, format);
+ uu_die_internal(status, format, alist);
+ va_end(alist);
+}
+
+const char *
+uu_setpname(char *arg0)
+{
+ /*
+ * Having a NULL argv[0], while uncommon, is possible. It
+ * makes more sense to handle this event in uu_setpname rather
+ * than in each of its consumers.
+ */
+ if (arg0 == NULL) {
+ pname = "unknown_command";
+ return (pname);
+ }
+
+ /*
+ * Guard against '/' at end of command invocation.
+ */
+ for (;;) {
+ char *p = strrchr(arg0, '/');
+ if (p == NULL) {
+ pname = arg0;
+ break;
+ } else {
+ if (*(p + 1) == '\0') {
+ *p = '\0';
+ continue;
+ }
+
+ pname = p + 1;
+ break;
+ }
+ }
+
+ return (pname);
+}
+
+const char *
+uu_getpname(void)
+{
+ return (pname);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_string.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_string.c
new file mode 100644
index 0000000..66afba0
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_string.c
@@ -0,0 +1,56 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * String helper functions
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <ctype.h>
+#include "libuutil.h"
+
+/* Return true if strings are equal */
+boolean_t
+uu_streq(const char *a, const char *b)
+{
+ return (strcmp(a, b) == 0);
+}
+
+/* Return true if strings are equal, case-insensitively */
+boolean_t
+uu_strcaseeq(const char *a, const char *b)
+{
+ return (strcasecmp(a, b) == 0);
+}
+
+/* Return true if string a Begins With string b */
+boolean_t
+uu_strbw(const char *a, const char *b)
+{
+ return (strncmp(a, b, strlen(b)) == 0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libuutil/common/uu_strtoint.c b/cddl/contrib/opensolaris/lib/libuutil/common/uu_strtoint.c
new file mode 100644
index 0000000..8fd1148
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libuutil/common/uu_strtoint.c
@@ -0,0 +1,300 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libuutil_common.h"
+
+#include <limits.h>
+#include <ctype.h>
+
+#define MAX_BASE 36
+
+#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
+
+#define CTOI(x) (((x) >= '0' && (x) <= '9') ? (x) - '0' : \
+ ((x) >= 'a' && (x) <= 'z') ? (x) + 10 - 'a' : (x) + 10 - 'A')
+
+static int
+strtoint(const char *s_arg, uint64_t *out, uint32_t base, int sign)
+{
+ const unsigned char *s = (const unsigned char *)s_arg;
+
+ uint64_t val = 0;
+ uint64_t multmax;
+
+ unsigned c, i;
+
+ int neg = 0;
+
+ int bad_digit = 0;
+ int bad_char = 0;
+ int overflow = 0;
+
+ if (s == NULL || base == 1 || base > MAX_BASE) {
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (-1);
+ }
+
+ while ((c = *s) != 0 && isspace(c))
+ s++;
+
+ switch (c) {
+ case '-':
+ if (!sign)
+ overflow = 1; /* becomes underflow below */
+ neg = 1;
+ /*FALLTHRU*/
+ case '+':
+ c = *++s;
+ break;
+ default:
+ break;
+ }
+
+ if (c == '\0') {
+ uu_set_error(UU_ERROR_EMPTY);
+ return (-1);
+ }
+
+ if (base == 0) {
+ if (c != '0')
+ base = 10;
+ else if (s[1] == 'x' || s[1] == 'X')
+ base = 16;
+ else
+ base = 8;
+ }
+
+ if (base == 16 && c == '0' && (s[1] == 'x' || s[1] == 'X'))
+ c = *(s += 2);
+
+ if ((val = CTOI(c)) >= base) {
+ if (IS_DIGIT(c))
+ bad_digit = 1;
+ else
+ bad_char = 1;
+ val = 0;
+ }
+
+ multmax = (uint64_t)UINT64_MAX / (uint64_t)base;
+
+ for (c = *++s; c != '\0'; c = *++s) {
+ if ((i = CTOI(c)) >= base) {
+ if (isspace(c))
+ break;
+ if (IS_DIGIT(c))
+ bad_digit = 1;
+ else
+ bad_char = 1;
+ i = 0;
+ }
+
+ if (val > multmax)
+ overflow = 1;
+
+ val *= base;
+ if ((uint64_t)UINT64_MAX - val < (uint64_t)i)
+ overflow = 1;
+
+ val += i;
+ }
+
+ while ((c = *s) != 0) {
+ if (!isspace(c))
+ bad_char = 1;
+ s++;
+ }
+
+ if (sign) {
+ if (neg) {
+ if (val > -(uint64_t)INT64_MIN)
+ overflow = 1;
+ } else {
+ if (val > INT64_MAX)
+ overflow = 1;
+ }
+ }
+
+ if (neg)
+ val = -val;
+
+ if (bad_char | bad_digit | overflow) {
+ if (bad_char)
+ uu_set_error(UU_ERROR_INVALID_CHAR);
+ else if (bad_digit)
+ uu_set_error(UU_ERROR_INVALID_DIGIT);
+ else if (overflow) {
+ if (neg)
+ uu_set_error(UU_ERROR_UNDERFLOW);
+ else
+ uu_set_error(UU_ERROR_OVERFLOW);
+ }
+ return (-1);
+ }
+
+ *out = val;
+ return (0);
+}
+
+int
+uu_strtoint(const char *s, void *v, size_t sz, int base,
+ int64_t min, int64_t max)
+{
+ uint64_t val_u;
+ int64_t val;
+
+ if (min > max)
+ goto bad_argument;
+
+ switch (sz) {
+ case 1:
+ if (max > INT8_MAX || min < INT8_MIN)
+ goto bad_argument;
+ break;
+ case 2:
+ if (max > INT16_MAX || min < INT16_MIN)
+ goto bad_argument;
+ break;
+ case 4:
+ if (max > INT32_MAX || min < INT32_MIN)
+ goto bad_argument;
+ break;
+ case 8:
+ if (max > INT64_MAX || min < INT64_MIN)
+ goto bad_argument;
+ break;
+ default:
+ goto bad_argument;
+ }
+
+ if (min == 0 && max == 0) {
+ min = -(1ULL << (8 * sz - 1));
+ max = (1ULL << (8 * sz - 1)) - 1;
+ }
+
+ if (strtoint(s, &val_u, base, 1) == -1)
+ return (-1);
+
+ val = (int64_t)val_u;
+
+ if (val < min) {
+ uu_set_error(UU_ERROR_UNDERFLOW);
+ return (-1);
+ } else if (val > max) {
+ uu_set_error(UU_ERROR_OVERFLOW);
+ return (-1);
+ }
+
+ switch (sz) {
+ case 1:
+ *(int8_t *)v = val;
+ return (0);
+ case 2:
+ *(int16_t *)v = val;
+ return (0);
+ case 4:
+ *(int32_t *)v = val;
+ return (0);
+ case 8:
+ *(int64_t *)v = val;
+ return (0);
+ default:
+ break; /* fall through to bad_argument */
+ }
+
+bad_argument:
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (-1);
+}
+
+int
+uu_strtouint(const char *s, void *v, size_t sz, int base,
+ uint64_t min, uint64_t max)
+{
+ uint64_t val;
+
+ if (min > max)
+ goto bad_argument;
+
+ switch (sz) {
+ case 1:
+ if (max > UINT8_MAX)
+ goto bad_argument;
+ break;
+ case 2:
+ if (max > UINT16_MAX)
+ goto bad_argument;
+ break;
+ case 4:
+ if (max > UINT32_MAX)
+ goto bad_argument;
+ break;
+ case 8:
+ if (max > UINT64_MAX)
+ goto bad_argument;
+ break;
+ default:
+ goto bad_argument;
+ }
+
+ if (min == 0 && max == 0) {
+ /* we have to be careful, since << can overflow */
+ max = (1ULL << (8 * sz - 1)) * 2 - 1;
+ }
+
+ if (strtoint(s, &val, base, 0) == -1)
+ return (-1);
+
+ if (val < min) {
+ uu_set_error(UU_ERROR_UNDERFLOW);
+ return (-1);
+ } else if (val > max) {
+ uu_set_error(UU_ERROR_OVERFLOW);
+ return (-1);
+ }
+
+ switch (sz) {
+ case 1:
+ *(uint8_t *)v = val;
+ return (0);
+ case 2:
+ *(uint16_t *)v = val;
+ return (0);
+ case 4:
+ *(uint32_t *)v = val;
+ return (0);
+ case 8:
+ *(uint64_t *)v = val;
+ return (0);
+ default:
+ break; /* shouldn't happen, fall through */
+ }
+
+bad_argument:
+ uu_set_error(UU_ERROR_INVALID_ARGUMENT);
+ return (-1);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
new file mode 100644
index 0000000..274b47b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -0,0 +1,786 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_H
+#define _LIBZFS_H
+
+#include <assert.h>
+#include <libnvpair.h>
+#include <sys/mnttab.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/varargs.h>
+#include <sys/fs/zfs.h>
+#include <sys/avl.h>
+#include <sys/zfs_ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Miscellaneous ZFS constants
+ */
+#define ZFS_MAXNAMELEN MAXNAMELEN
+#define ZPOOL_MAXNAMELEN MAXNAMELEN
+#define ZFS_MAXPROPLEN MAXPATHLEN
+#define ZPOOL_MAXPROPLEN MAXPATHLEN
+
+/*
+ * libzfs errors
+ */
+typedef enum zfs_error {
+ EZFS_SUCCESS = 0, /* no error -- success */
+ EZFS_NOMEM = 2000, /* out of memory */
+ EZFS_BADPROP, /* invalid property value */
+ EZFS_PROPREADONLY, /* cannot set readonly property */
+ EZFS_PROPTYPE, /* property does not apply to dataset type */
+ EZFS_PROPNONINHERIT, /* property is not inheritable */
+ EZFS_PROPSPACE, /* bad quota or reservation */
+ EZFS_BADTYPE, /* dataset is not of appropriate type */
+ EZFS_BUSY, /* pool or dataset is busy */
+ EZFS_EXISTS, /* pool or dataset already exists */
+ EZFS_NOENT, /* no such pool or dataset */
+ EZFS_BADSTREAM, /* bad backup stream */
+ EZFS_DSREADONLY, /* dataset is readonly */
+ EZFS_VOLTOOBIG, /* volume is too large for 32-bit system */
+ EZFS_INVALIDNAME, /* invalid dataset name */
+ EZFS_BADRESTORE, /* unable to restore to destination */
+ EZFS_BADBACKUP, /* backup failed */
+ EZFS_BADTARGET, /* bad attach/detach/replace target */
+ EZFS_NODEVICE, /* no such device in pool */
+ EZFS_BADDEV, /* invalid device to add */
+ EZFS_NOREPLICAS, /* no valid replicas */
+ EZFS_RESILVERING, /* currently resilvering */
+ EZFS_BADVERSION, /* unsupported version */
+ EZFS_POOLUNAVAIL, /* pool is currently unavailable */
+ EZFS_DEVOVERFLOW, /* too many devices in one vdev */
+ EZFS_BADPATH, /* must be an absolute path */
+ EZFS_CROSSTARGET, /* rename or clone across pool or dataset */
+ EZFS_ZONED, /* used improperly in local zone */
+ EZFS_MOUNTFAILED, /* failed to mount dataset */
+ EZFS_UMOUNTFAILED, /* failed to unmount dataset */
+ EZFS_UNSHARENFSFAILED, /* unshare(1M) failed */
+ EZFS_SHARENFSFAILED, /* share(1M) failed */
+ EZFS_PERM, /* permission denied */
+ EZFS_NOSPC, /* out of space */
+ EZFS_FAULT, /* bad address */
+ EZFS_IO, /* I/O error */
+ EZFS_INTR, /* signal received */
+ EZFS_ISSPARE, /* device is a hot spare */
+ EZFS_INVALCONFIG, /* invalid vdev configuration */
+ EZFS_RECURSIVE, /* recursive dependency */
+ EZFS_NOHISTORY, /* no history object */
+ EZFS_POOLPROPS, /* couldn't retrieve pool props */
+ EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
+ EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
+ EZFS_NAMETOOLONG, /* dataset name is too long */
+ EZFS_OPENFAILED, /* open of device failed */
+ EZFS_NOCAP, /* couldn't get capacity */
+ EZFS_LABELFAILED, /* write of label failed */
+ EZFS_BADWHO, /* invalid permission who */
+ EZFS_BADPERM, /* invalid permission */
+ EZFS_BADPERMSET, /* invalid permission set name */
+ EZFS_NODELEGATION, /* delegated administration is disabled */
+ EZFS_UNSHARESMBFAILED, /* failed to unshare over smb */
+ EZFS_SHARESMBFAILED, /* failed to share over smb */
+ EZFS_BADCACHE, /* bad cache file */
+ EZFS_ISL2CACHE, /* device is for the level 2 ARC */
+ EZFS_VDEVNOTSUP, /* unsupported vdev type */
+ EZFS_NOTSUP, /* ops not supported on this dataset */
+ EZFS_ACTIVE_SPARE, /* pool has active shared spare devices */
+ EZFS_UNPLAYED_LOGS, /* log device has unplayed logs */
+ EZFS_REFTAG_RELE, /* snapshot release: tag not found */
+ EZFS_REFTAG_HOLD, /* snapshot hold: tag already exists */
+ EZFS_TAGTOOLONG, /* snapshot hold/rele: tag too long */
+ EZFS_PIPEFAILED, /* pipe create failed */
+ EZFS_THREADCREATEFAILED, /* thread create failed */
+ EZFS_POSTSPLIT_ONLINE, /* onlining a disk after splitting it */
+ EZFS_SCRUBBING, /* currently scrubbing */
+ EZFS_NO_SCRUB, /* no active scrub */
+ EZFS_DIFF, /* general failure of zfs diff */
+ EZFS_DIFFDATA, /* bad zfs diff data */
+ EZFS_POOLREADONLY, /* pool is in read-only mode */
+ EZFS_UNKNOWN
+} zfs_error_t;
+
+/*
+ * The following data structures are all part
+ * of the zfs_allow_t data structure which is
+ * used for printing 'allow' permissions.
+ * It is a linked list of zfs_allow_t's which
+ * then contain avl tree's for user/group/sets/...
+ * and each one of the entries in those trees have
+ * avl tree's for the permissions they belong to and
+ * whether they are local,descendent or local+descendent
+ * permissions. The AVL trees are used primarily for
+ * sorting purposes, but also so that we can quickly find
+ * a given user and or permission.
+ */
+typedef struct zfs_perm_node {
+ avl_node_t z_node;
+ char z_pname[MAXPATHLEN];
+} zfs_perm_node_t;
+
+typedef struct zfs_allow_node {
+ avl_node_t z_node;
+ char z_key[MAXPATHLEN]; /* name, such as joe */
+ avl_tree_t z_localdescend; /* local+descendent perms */
+ avl_tree_t z_local; /* local permissions */
+ avl_tree_t z_descend; /* descendent permissions */
+} zfs_allow_node_t;
+
+typedef struct zfs_allow {
+ struct zfs_allow *z_next;
+ char z_setpoint[MAXPATHLEN];
+ avl_tree_t z_sets;
+ avl_tree_t z_crperms;
+ avl_tree_t z_user;
+ avl_tree_t z_group;
+ avl_tree_t z_everyone;
+} zfs_allow_t;
+
+/*
+ * Basic handle types
+ */
+typedef struct zfs_handle zfs_handle_t;
+typedef struct zpool_handle zpool_handle_t;
+typedef struct libzfs_handle libzfs_handle_t;
+
+/*
+ * Library initialization
+ */
+extern libzfs_handle_t *libzfs_init(void);
+extern void libzfs_fini(libzfs_handle_t *);
+
+extern libzfs_handle_t *zpool_get_handle(zpool_handle_t *);
+extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *);
+
+extern void libzfs_print_on_error(libzfs_handle_t *, boolean_t);
+
+extern void zfs_save_arguments(int argc, char **, char *, int);
+extern int zpool_log_history(libzfs_handle_t *, const char *);
+
+extern int libzfs_errno(libzfs_handle_t *);
+extern const char *libzfs_error_action(libzfs_handle_t *);
+extern const char *libzfs_error_description(libzfs_handle_t *);
+extern void libzfs_mnttab_init(libzfs_handle_t *);
+extern void libzfs_mnttab_fini(libzfs_handle_t *);
+extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t);
+extern int libzfs_mnttab_find(libzfs_handle_t *, const char *,
+ struct mnttab *);
+extern void libzfs_mnttab_add(libzfs_handle_t *, const char *,
+ const char *, const char *);
+extern void libzfs_mnttab_remove(libzfs_handle_t *, const char *);
+
+/*
+ * Basic handle functions
+ */
+extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *);
+extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *);
+extern void zpool_close(zpool_handle_t *);
+extern const char *zpool_get_name(zpool_handle_t *);
+extern int zpool_get_state(zpool_handle_t *);
+extern const char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
+extern const char *zpool_pool_state_to_name(pool_state_t);
+extern void zpool_free_handles(libzfs_handle_t *);
+
+/*
+ * Iterate over all active pools in the system.
+ */
+typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
+extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
+
+/*
+ * Functions to create and destroy pools
+ */
+extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
+ nvlist_t *, nvlist_t *);
+extern int zpool_destroy(zpool_handle_t *, const char *);
+extern int zpool_add(zpool_handle_t *, nvlist_t *);
+
+typedef struct splitflags {
+ /* do not split, but return the config that would be split off */
+ int dryrun : 1;
+
+ /* after splitting, import the pool */
+ int import : 1;
+} splitflags_t;
+
+/*
+ * Functions to manipulate pool and vdev state
+ */
+extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
+extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
+extern int zpool_reguid(zpool_handle_t *);
+extern int zpool_reopen(zpool_handle_t *);
+
+extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
+ vdev_state_t *);
+extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
+extern int zpool_vdev_attach(zpool_handle_t *, const char *,
+ const char *, nvlist_t *, int);
+extern int zpool_vdev_detach(zpool_handle_t *, const char *);
+extern int zpool_vdev_remove(zpool_handle_t *, const char *);
+extern int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, nvlist_t *,
+ splitflags_t);
+
+extern int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
+extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
+extern int zpool_vdev_clear(zpool_handle_t *, uint64_t);
+
+extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
+ boolean_t *, boolean_t *);
+extern nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *,
+ boolean_t *, boolean_t *, boolean_t *);
+extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, const char *);
+
+/*
+ * Functions to manage pool properties
+ */
+extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
+extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
+ size_t proplen, zprop_source_t *);
+extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
+ zprop_source_t *);
+
+extern const char *zpool_prop_to_name(zpool_prop_t);
+extern const char *zpool_prop_values(zpool_prop_t);
+
+/*
+ * Pool health statistics.
+ */
+typedef enum {
+ /*
+ * The following correspond to faults as defined in the (fault.fs.zfs.*)
+ * event namespace. Each is associated with a corresponding message ID.
+ */
+ ZPOOL_STATUS_CORRUPT_CACHE, /* corrupt /kernel/drv/zpool.cache */
+ ZPOOL_STATUS_MISSING_DEV_R, /* missing device with replicas */
+ ZPOOL_STATUS_MISSING_DEV_NR, /* missing device with no replicas */
+ ZPOOL_STATUS_CORRUPT_LABEL_R, /* bad device label with replicas */
+ ZPOOL_STATUS_CORRUPT_LABEL_NR, /* bad device label with no replicas */
+ ZPOOL_STATUS_BAD_GUID_SUM, /* sum of device guids didn't match */
+ ZPOOL_STATUS_CORRUPT_POOL, /* pool metadata is corrupted */
+ ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */
+ ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
+ ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
+ ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */
+ ZPOOL_STATUS_IO_FAILURE_WAIT, /* failed I/O, failmode 'wait' */
+ ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */
+ ZPOOL_STATUS_BAD_LOG, /* cannot read log chain(s) */
+
+ /*
+ * If the pool has unsupported features but can still be opened in
+ * read-only mode, its status is ZPOOL_STATUS_UNSUP_FEAT_WRITE. If the
+ * pool has unsupported features but cannot be opened at all, its
+ * status is ZPOOL_STATUS_UNSUP_FEAT_READ.
+ */
+ ZPOOL_STATUS_UNSUP_FEAT_READ, /* unsupported features for read */
+ ZPOOL_STATUS_UNSUP_FEAT_WRITE, /* unsupported features for write */
+
+ /*
+ * These faults have no corresponding message ID. At the time we are
+ * checking the status, the original reason for the FMA fault (I/O or
+ * checksum errors) has been lost.
+ */
+ ZPOOL_STATUS_FAULTED_DEV_R, /* faulted device with replicas */
+ ZPOOL_STATUS_FAULTED_DEV_NR, /* faulted device with no replicas */
+
+ /*
+ * The following are not faults per se, but still an error possibly
+ * requiring administrative attention. There is no corresponding
+ * message ID.
+ */
+ ZPOOL_STATUS_VERSION_OLDER, /* older legacy on-disk version */
+ ZPOOL_STATUS_FEAT_DISABLED, /* supported features are disabled */
+ ZPOOL_STATUS_RESILVERING, /* device being resilvered */
+ ZPOOL_STATUS_OFFLINE_DEV, /* device online */
+ ZPOOL_STATUS_REMOVED_DEV, /* removed device */
+
+ /*
+ * Finally, the following indicates a healthy pool.
+ */
+ ZPOOL_STATUS_OK
+} zpool_status_t;
+
+extern zpool_status_t zpool_get_status(zpool_handle_t *, char **);
+extern zpool_status_t zpool_import_status(nvlist_t *, char **);
+extern void zpool_dump_ddt(const ddt_stat_t *dds, const ddt_histogram_t *ddh);
+
+/*
+ * Statistics and configuration functions.
+ */
+extern nvlist_t *zpool_get_config(zpool_handle_t *, nvlist_t **);
+extern nvlist_t *zpool_get_features(zpool_handle_t *);
+extern int zpool_refresh_stats(zpool_handle_t *, boolean_t *);
+extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
+
+/*
+ * Import and export functions
+ */
+extern int zpool_export(zpool_handle_t *, boolean_t, const char *);
+extern int zpool_export_force(zpool_handle_t *, const char *);
+extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
+ char *altroot);
+extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
+ nvlist_t *, int);
+extern void zpool_print_unsup_feat(nvlist_t *config);
+
+/*
+ * Search for pools to import
+ */
+
+typedef struct importargs {
+ char **path; /* a list of paths to search */
+ int paths; /* number of paths to search */
+ char *poolname; /* name of a pool to find */
+ uint64_t guid; /* guid of a pool to find */
+ char *cachefile; /* cachefile to use for import */
+ int can_be_active : 1; /* can the pool be active? */
+ int unique : 1; /* does 'poolname' already exist? */
+ int exists : 1; /* set on return if pool already exists */
+} importargs_t;
+
+extern nvlist_t *zpool_search_import(libzfs_handle_t *, importargs_t *);
+
+/* legacy pool search routines */
+extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **);
+extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
+ char *, uint64_t);
+
+/*
+ * Miscellaneous pool functions
+ */
+struct zfs_cmd;
+
+extern const char *zfs_history_event_names[];
+
+extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *,
+ boolean_t verbose);
+extern int zpool_upgrade(zpool_handle_t *, uint64_t);
+extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
+extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
+ nvlist_t ***, uint_t *);
+extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
+ size_t len);
+extern int zfs_ioctl(libzfs_handle_t *, int request, struct zfs_cmd *);
+extern int zpool_get_physpath(zpool_handle_t *, char *, size_t);
+extern void zpool_explain_recover(libzfs_handle_t *, const char *, int,
+ nvlist_t *);
+
+/*
+ * Basic handle manipulations. These functions do not create or destroy the
+ * underlying datasets, only the references to them.
+ */
+extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
+extern zfs_handle_t *zfs_handle_dup(zfs_handle_t *);
+extern void zfs_close(zfs_handle_t *);
+extern zfs_type_t zfs_get_type(const zfs_handle_t *);
+extern const char *zfs_get_name(const zfs_handle_t *);
+extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
+
+/*
+ * Property management functions. Some functions are shared with the kernel,
+ * and are found in sys/fs/zfs.h.
+ */
+
+/*
+ * zfs dataset property management
+ */
+extern const char *zfs_prop_default_string(zfs_prop_t);
+extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
+extern const char *zfs_prop_column_name(zfs_prop_t);
+extern boolean_t zfs_prop_align_right(zfs_prop_t);
+
+extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
+ nvlist_t *, uint64_t, zfs_handle_t *, const char *);
+
+extern const char *zfs_prop_to_name(zfs_prop_t);
+extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
+extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
+ zprop_source_t *, char *, size_t, boolean_t);
+extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t,
+ boolean_t);
+extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *,
+ zprop_source_t *, char *, size_t);
+extern int zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
+ uint64_t *propvalue);
+extern int zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
+ char *propbuf, int proplen, boolean_t literal);
+extern int zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
+ uint64_t *propvalue);
+extern int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
+ char *propbuf, int proplen, boolean_t literal);
+extern int zfs_prop_get_feature(zfs_handle_t *zhp, const char *propname,
+ char *buf, size_t len);
+extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
+extern int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t);
+extern const char *zfs_prop_values(zfs_prop_t);
+extern int zfs_prop_is_string(zfs_prop_t prop);
+extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
+extern nvlist_t *zfs_get_recvd_props(zfs_handle_t *);
+extern nvlist_t *zfs_get_clones_nvl(zfs_handle_t *);
+
+
+typedef struct zprop_list {
+ int pl_prop;
+ char *pl_user_prop;
+ struct zprop_list *pl_next;
+ boolean_t pl_all;
+ size_t pl_width;
+ size_t pl_recvd_width;
+ boolean_t pl_fixed;
+} zprop_list_t;
+
+extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t);
+extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
+
+#define ZFS_MOUNTPOINT_NONE "none"
+#define ZFS_MOUNTPOINT_LEGACY "legacy"
+
+#define ZFS_FEATURE_DISABLED "disabled"
+#define ZFS_FEATURE_ENABLED "enabled"
+#define ZFS_FEATURE_ACTIVE "active"
+
+#define ZFS_UNSUPPORTED_INACTIVE "inactive"
+#define ZFS_UNSUPPORTED_READONLY "readonly"
+
+/*
+ * zpool property management
+ */
+extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **);
+extern int zpool_prop_get_feature(zpool_handle_t *, const char *, char *,
+ size_t);
+extern const char *zpool_prop_default_string(zpool_prop_t);
+extern uint64_t zpool_prop_default_numeric(zpool_prop_t);
+extern const char *zpool_prop_column_name(zpool_prop_t);
+extern boolean_t zpool_prop_align_right(zpool_prop_t);
+
+/*
+ * Functions shared by zfs and zpool property management.
+ */
+extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all,
+ boolean_t ordered, zfs_type_t type);
+extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **,
+ zfs_type_t);
+extern void zprop_free_list(zprop_list_t *);
+
+#define ZFS_GET_NCOLS 5
+
+typedef enum {
+ GET_COL_NONE,
+ GET_COL_NAME,
+ GET_COL_PROPERTY,
+ GET_COL_VALUE,
+ GET_COL_RECVD,
+ GET_COL_SOURCE
+} zfs_get_column_t;
+
+/*
+ * Functions for printing zfs or zpool properties
+ */
+typedef struct zprop_get_cbdata {
+ int cb_sources;
+ zfs_get_column_t cb_columns[ZFS_GET_NCOLS];
+ int cb_colwidths[ZFS_GET_NCOLS + 1];
+ boolean_t cb_scripted;
+ boolean_t cb_literal;
+ boolean_t cb_first;
+ zprop_list_t *cb_proplist;
+ zfs_type_t cb_type;
+} zprop_get_cbdata_t;
+
+void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
+ const char *, const char *, zprop_source_t, const char *,
+ const char *);
+
+/*
+ * Iterator functions.
+ */
+typedef int (*zfs_iter_f)(zfs_handle_t *, void *);
+extern int zfs_iter_root(libzfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
+extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
+extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
+extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
+
+typedef struct get_all_cb {
+ zfs_handle_t **cb_handles;
+ size_t cb_alloc;
+ size_t cb_used;
+ boolean_t cb_verbose;
+ int (*cb_getone)(zfs_handle_t *, void *);
+} get_all_cb_t;
+
+void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *);
+int libzfs_dataset_cmp(const void *, const void *);
+
+/*
+ * Functions to create and destroy datasets.
+ */
+extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
+ nvlist_t *);
+extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
+extern int zfs_destroy(zfs_handle_t *, boolean_t);
+extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
+extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t);
+extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
+extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
+extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps,
+ nvlist_t *props);
+extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
+
+typedef struct renameflags {
+ /* recursive rename */
+ int recurse : 1;
+
+ /* don't unmount file systems */
+ int nounmount : 1;
+
+ /* force unmount file systems */
+ int forceunmount : 1;
+} renameflags_t;
+
+extern int zfs_rename(zfs_handle_t *, const char *, const char *,
+ renameflags_t flags);
+
+typedef struct sendflags {
+ /* print informational messages (ie, -v was specified) */
+ boolean_t verbose;
+
+ /* recursive send (ie, -R) */
+ boolean_t replicate;
+
+ /* for incrementals, do all intermediate snapshots */
+ boolean_t doall;
+
+ /* if dataset is a clone, do incremental from its origin */
+ boolean_t fromorigin;
+
+ /* do deduplication */
+ boolean_t dedup;
+
+ /* send properties (ie, -p) */
+ boolean_t props;
+
+ /* do not send (no-op, ie. -n) */
+ boolean_t dryrun;
+
+ /* parsable verbose output (ie. -P) */
+ boolean_t parsable;
+
+ /* show progress (ie. -v) */
+ boolean_t progress;
+} sendflags_t;
+
+typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
+
+extern int zfs_send(zfs_handle_t *, const char *, const char *,
+ sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
+
+extern int zfs_promote(zfs_handle_t *);
+extern int zfs_hold(zfs_handle_t *, const char *, const char *,
+ boolean_t, boolean_t, int);
+extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t);
+extern int zfs_get_holds(zfs_handle_t *, nvlist_t **);
+extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *);
+
+typedef int (*zfs_userspace_cb_t)(void *arg, const char *domain,
+ uid_t rid, uint64_t space);
+
+extern int zfs_userspace(zfs_handle_t *, zfs_userquota_prop_t,
+ zfs_userspace_cb_t, void *);
+
+extern int zfs_get_fsacl(zfs_handle_t *, nvlist_t **);
+extern int zfs_set_fsacl(zfs_handle_t *, boolean_t, nvlist_t *);
+
+typedef struct recvflags {
+ /* print informational messages (ie, -v was specified) */
+ boolean_t verbose;
+
+ /* the destination is a prefix, not the exact fs (ie, -d) */
+ boolean_t isprefix;
+
+ /*
+ * Only the tail of the sent snapshot path is appended to the
+ * destination to determine the received snapshot name (ie, -e).
+ */
+ boolean_t istail;
+
+ /* do not actually do the recv, just check if it would work (ie, -n) */
+ boolean_t dryrun;
+
+ /* rollback/destroy filesystems as necessary (eg, -F) */
+ boolean_t force;
+
+ /* set "canmount=off" on all modified filesystems */
+ boolean_t canmountoff;
+
+ /* byteswap flag is used internally; callers need not specify */
+ boolean_t byteswap;
+
+ /* do not mount file systems as they are extracted (private) */
+ boolean_t nomount;
+} recvflags_t;
+
+extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
+ int, avl_tree_t *);
+
+typedef enum diff_flags {
+ ZFS_DIFF_PARSEABLE = 0x1,
+ ZFS_DIFF_TIMESTAMP = 0x2,
+ ZFS_DIFF_CLASSIFY = 0x4
+} diff_flags_t;
+
+extern int zfs_show_diffs(zfs_handle_t *, int, const char *, const char *,
+ int);
+
+/*
+ * Miscellaneous functions.
+ */
+extern const char *zfs_type_to_name(zfs_type_t);
+extern void zfs_refresh_properties(zfs_handle_t *);
+extern int zfs_name_valid(const char *, zfs_type_t);
+extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
+extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
+ zfs_type_t);
+extern int zfs_spa_version(zfs_handle_t *, int *);
+
+/*
+ * Mount support functions.
+ */
+extern boolean_t is_mounted(libzfs_handle_t *, const char *special, char **);
+extern boolean_t zfs_is_mounted(zfs_handle_t *, char **);
+extern int zfs_mount(zfs_handle_t *, const char *, int);
+extern int zfs_unmount(zfs_handle_t *, const char *, int);
+extern int zfs_unmountall(zfs_handle_t *, int);
+
+/*
+ * Share support functions.
+ */
+extern boolean_t zfs_is_shared(zfs_handle_t *);
+extern int zfs_share(zfs_handle_t *);
+extern int zfs_unshare(zfs_handle_t *);
+
+/*
+ * Protocol-specific share support functions.
+ */
+extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **);
+extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **);
+extern int zfs_share_nfs(zfs_handle_t *);
+extern int zfs_share_smb(zfs_handle_t *);
+extern int zfs_shareall(zfs_handle_t *);
+extern int zfs_unshare_nfs(zfs_handle_t *, const char *);
+extern int zfs_unshare_smb(zfs_handle_t *, const char *);
+extern int zfs_unshareall_nfs(zfs_handle_t *);
+extern int zfs_unshareall_smb(zfs_handle_t *);
+extern int zfs_unshareall_bypath(zfs_handle_t *, const char *);
+extern int zfs_unshareall(zfs_handle_t *);
+extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *, char *,
+ void *, void *, int, zfs_share_op_t);
+
+/*
+ * FreeBSD-specific jail support function.
+ */
+extern int zfs_jail(zfs_handle_t *, int, int);
+
+/*
+ * When dealing with nvlists, verify() is extremely useful
+ */
+#ifndef verify
+#ifdef NDEBUG
+#define verify(EX) ((void)(EX))
+#else
+#define verify(EX) assert(EX)
+#endif
+#endif
+
+/*
+ * Utility function to convert a number to a human-readable form.
+ */
+extern void zfs_nicenum(uint64_t, char *, size_t);
+extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);
+
+/*
+ * Given a device or file, determine if it is part of a pool.
+ */
+extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
+ boolean_t *);
+
+/*
+ * Label manipulation.
+ */
+extern int zpool_read_label(int, nvlist_t **);
+extern int zpool_clear_label(int);
+
+/* is this zvol valid for use as a dump device? */
+extern int zvol_check_dump_config(char *);
+
+/*
+ * Management interfaces for SMB ACL files
+ */
+
+int zfs_smb_acl_add(libzfs_handle_t *, char *, char *, char *);
+int zfs_smb_acl_remove(libzfs_handle_t *, char *, char *, char *);
+int zfs_smb_acl_purge(libzfs_handle_t *, char *, char *);
+int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, char *);
+
+/*
+ * Enable and disable datasets within a pool by mounting/unmounting and
+ * sharing/unsharing them.
+ */
+extern int zpool_enable_datasets(zpool_handle_t *, const char *, int);
+extern int zpool_disable_datasets(zpool_handle_t *, boolean_t);
+
+/*
+ * Mappings between vdev and FRU.
+ */
+extern void libzfs_fru_refresh(libzfs_handle_t *);
+extern const char *libzfs_fru_lookup(libzfs_handle_t *, const char *);
+extern const char *libzfs_fru_devpath(libzfs_handle_t *, const char *);
+extern boolean_t libzfs_fru_compare(libzfs_handle_t *, const char *,
+ const char *);
+extern boolean_t libzfs_fru_notself(libzfs_handle_t *, const char *);
+extern int zpool_fru_set(zpool_handle_t *, uint64_t, const char *);
+
+#ifndef sun
+extern int zmount(const char *, const char *, int, char *, char *, int, char *,
+ int);
+#endif /* !sun */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
new file mode 100644
index 0000000..a899965
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c
@@ -0,0 +1,700 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Portions Copyright 2007 Ramprakash Jelari
+ *
+ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ */
+
+#include <libintl.h>
+#include <libuutil.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <zone.h>
+
+#include <libzfs.h>
+
+#include "libzfs_impl.h"
+
+/*
+ * Structure to keep track of dataset state. Before changing the 'sharenfs' or
+ * 'mountpoint' property, we record whether the filesystem was previously
+ * mounted/shared. This prior state dictates whether we remount/reshare the
+ * dataset after the property has been changed.
+ *
+ * The interface consists of the following sequence of functions:
+ *
+ * changelist_gather()
+ * changelist_prefix()
+ * < change property >
+ * changelist_postfix()
+ * changelist_free()
+ *
+ * Other interfaces:
+ *
+ * changelist_remove() - remove a node from a gathered list
+ * changelist_rename() - renames all datasets appropriately when doing a rename
+ * changelist_unshare() - unshares all the nodes in a given changelist
+ * changelist_haszonedchild() - check if there is any child exported to
+ * a local zone
+ */
+typedef struct prop_changenode {
+ zfs_handle_t *cn_handle;
+ int cn_shared;
+ int cn_mounted;
+ int cn_zoned;
+ boolean_t cn_needpost; /* is postfix() needed? */
+ uu_list_node_t cn_listnode;
+} prop_changenode_t;
+
+struct prop_changelist {
+ zfs_prop_t cl_prop;
+ zfs_prop_t cl_realprop;
+ zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
+ uu_list_pool_t *cl_pool;
+ uu_list_t *cl_list;
+ boolean_t cl_waslegacy;
+ boolean_t cl_allchildren;
+ boolean_t cl_alldependents;
+ int cl_mflags; /* Mount flags */
+ int cl_gflags; /* Gather request flags */
+ boolean_t cl_haszonedchild;
+ boolean_t cl_sorted;
+};
+
+/*
+ * If the property is 'mountpoint', go through and unmount filesystems as
+ * necessary. We don't do the same for 'sharenfs', because we can just re-share
+ * with different options without interrupting service. We do handle 'sharesmb'
+ * since there may be old resource names that need to be removed.
+ */
+int
+changelist_prefix(prop_changelist_t *clp)
+{
+ prop_changenode_t *cn;
+ int ret = 0;
+
+ if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
+ clp->cl_prop != ZFS_PROP_SHARESMB)
+ return (0);
+
+ for (cn = uu_list_first(clp->cl_list); cn != NULL;
+ cn = uu_list_next(clp->cl_list, cn)) {
+
+ /* if a previous loop failed, set the remaining to false */
+ if (ret == -1) {
+ cn->cn_needpost = B_FALSE;
+ continue;
+ }
+
+ /*
+ * If we are in the global zone, but this dataset is exported
+ * to a local zone, do nothing.
+ */
+ if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
+ continue;
+
+ if (!ZFS_IS_VOLUME(cn->cn_handle)) {
+ /*
+ * Do the property specific processing.
+ */
+ switch (clp->cl_prop) {
+ case ZFS_PROP_MOUNTPOINT:
+ if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
+ break;
+ if (zfs_unmount(cn->cn_handle, NULL,
+ clp->cl_mflags) != 0) {
+ ret = -1;
+ cn->cn_needpost = B_FALSE;
+ }
+ break;
+ case ZFS_PROP_SHARESMB:
+ (void) zfs_unshare_smb(cn->cn_handle, NULL);
+ break;
+ }
+ }
+ }
+
+ if (ret == -1)
+ (void) changelist_postfix(clp);
+
+ return (ret);
+}
+
+/*
+ * If the property is 'mountpoint' or 'sharenfs', go through and remount and/or
+ * reshare the filesystems as necessary. In changelist_gather() we recorded
+ * whether the filesystem was previously shared or mounted. The action we take
+ * depends on the previous state, and whether the value was previously 'legacy'.
+ * For non-legacy properties, we only remount/reshare the filesystem if it was
+ * previously mounted/shared. Otherwise, we always remount/reshare the
+ * filesystem.
+ */
+int
+changelist_postfix(prop_changelist_t *clp)
+{
+ prop_changenode_t *cn;
+ char shareopts[ZFS_MAXPROPLEN];
+ int errors = 0;
+ libzfs_handle_t *hdl;
+
+ /*
+ * If we're changing the mountpoint, attempt to destroy the underlying
+ * mountpoint. All other datasets will have inherited from this dataset
+ * (in which case their mountpoints exist in the filesystem in the new
+ * location), or have explicit mountpoints set (in which case they won't
+ * be in the changelist).
+ */
+ if ((cn = uu_list_last(clp->cl_list)) == NULL)
+ return (0);
+
+ if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
+ !(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)) {
+ remove_mountpoint(cn->cn_handle);
+ }
+
+ /*
+ * It is possible that the changelist_prefix() used libshare
+ * to unshare some entries. Since libshare caches data, an
+ * attempt to reshare during postfix can fail unless libshare
+ * is uninitialized here so that it will reinitialize later.
+ */
+ if (cn->cn_handle != NULL) {
+ hdl = cn->cn_handle->zfs_hdl;
+ assert(hdl != NULL);
+ zfs_uninit_libshare(hdl);
+ }
+
+ /*
+ * We walk the datasets in reverse, because we want to mount any parent
+ * datasets before mounting the children. We walk all datasets even if
+ * there are errors.
+ */
+ for (cn = uu_list_last(clp->cl_list); cn != NULL;
+ cn = uu_list_prev(clp->cl_list, cn)) {
+
+ boolean_t sharenfs;
+ boolean_t sharesmb;
+ boolean_t mounted;
+
+ /*
+ * If we are in the global zone, but this dataset is exported
+ * to a local zone, do nothing.
+ */
+ if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
+ continue;
+
+ /* Only do post-processing if it's required */
+ if (!cn->cn_needpost)
+ continue;
+ cn->cn_needpost = B_FALSE;
+
+ zfs_refresh_properties(cn->cn_handle);
+
+ if (ZFS_IS_VOLUME(cn->cn_handle))
+ continue;
+
+ /*
+ * Remount if previously mounted or mountpoint was legacy,
+ * or sharenfs or sharesmb property is set.
+ */
+ sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
+ shareopts, sizeof (shareopts), NULL, NULL, 0,
+ B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
+
+ sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB,
+ shareopts, sizeof (shareopts), NULL, NULL, 0,
+ B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
+
+ mounted = (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT) ||
+ zfs_is_mounted(cn->cn_handle, NULL);
+
+ if (!mounted && (cn->cn_mounted ||
+ ((sharenfs || sharesmb || clp->cl_waslegacy) &&
+ (zfs_prop_get_int(cn->cn_handle,
+ ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_ON)))) {
+
+ if (zfs_mount(cn->cn_handle, NULL, 0) != 0)
+ errors++;
+ else
+ mounted = TRUE;
+ }
+
+ /*
+ * If the file system is mounted we always re-share even
+ * if the filesystem is currently shared, so that we can
+ * adopt any new options.
+ */
+ if (sharenfs && mounted)
+ errors += zfs_share_nfs(cn->cn_handle);
+ else if (cn->cn_shared || clp->cl_waslegacy)
+ errors += zfs_unshare_nfs(cn->cn_handle, NULL);
+ if (sharesmb && mounted)
+ errors += zfs_share_smb(cn->cn_handle);
+ else if (cn->cn_shared || clp->cl_waslegacy)
+ errors += zfs_unshare_smb(cn->cn_handle, NULL);
+ }
+
+ return (errors ? -1 : 0);
+}
+
+/*
+ * Is this "dataset" a child of "parent"?
+ */
+boolean_t
+isa_child_of(const char *dataset, const char *parent)
+{
+ int len;
+
+ len = strlen(parent);
+
+ if (strncmp(dataset, parent, len) == 0 &&
+ (dataset[len] == '@' || dataset[len] == '/' ||
+ dataset[len] == '\0'))
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+
+}
+
+/*
+ * If we rename a filesystem, child filesystem handles are no longer valid
+ * since we identify each dataset by its name in the ZFS namespace. As a
+ * result, we have to go through and fix up all the names appropriately. We
+ * could do this automatically if libzfs kept track of all open handles, but
+ * this is a lot less work.
+ */
+void
+changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
+{
+ prop_changenode_t *cn;
+ char newname[ZFS_MAXNAMELEN];
+
+ for (cn = uu_list_first(clp->cl_list); cn != NULL;
+ cn = uu_list_next(clp->cl_list, cn)) {
+ /*
+ * Do not rename a clone that's not in the source hierarchy.
+ */
+ if (!isa_child_of(cn->cn_handle->zfs_name, src))
+ continue;
+
+ /*
+ * Destroy the previous mountpoint if needed.
+ */
+ remove_mountpoint(cn->cn_handle);
+
+ (void) strlcpy(newname, dst, sizeof (newname));
+ (void) strcat(newname, cn->cn_handle->zfs_name + strlen(src));
+
+ (void) strlcpy(cn->cn_handle->zfs_name, newname,
+ sizeof (cn->cn_handle->zfs_name));
+ }
+}
+
+/*
+ * Given a gathered changelist for the 'sharenfs' or 'sharesmb' property,
+ * unshare all the datasets in the list.
+ */
+int
+changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto)
+{
+ prop_changenode_t *cn;
+ int ret = 0;
+
+ if (clp->cl_prop != ZFS_PROP_SHARENFS &&
+ clp->cl_prop != ZFS_PROP_SHARESMB)
+ return (0);
+
+ for (cn = uu_list_first(clp->cl_list); cn != NULL;
+ cn = uu_list_next(clp->cl_list, cn)) {
+ if (zfs_unshare_proto(cn->cn_handle, NULL, proto) != 0)
+ ret = -1;
+ }
+
+ return (ret);
+}
+
+/*
+ * Check if there is any child exported to a local zone in a given changelist.
+ * This information has already been recorded while gathering the changelist
+ * via changelist_gather().
+ */
+int
+changelist_haszonedchild(prop_changelist_t *clp)
+{
+ return (clp->cl_haszonedchild);
+}
+
+/*
+ * Remove a node from a gathered list.
+ */
+void
+changelist_remove(prop_changelist_t *clp, const char *name)
+{
+ prop_changenode_t *cn;
+
+ for (cn = uu_list_first(clp->cl_list); cn != NULL;
+ cn = uu_list_next(clp->cl_list, cn)) {
+
+ if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
+ uu_list_remove(clp->cl_list, cn);
+ zfs_close(cn->cn_handle);
+ free(cn);
+ return;
+ }
+ }
+}
+
+/*
+ * Release any memory associated with a changelist.
+ */
+void
+changelist_free(prop_changelist_t *clp)
+{
+ prop_changenode_t *cn;
+ void *cookie;
+
+ if (clp->cl_list) {
+ cookie = NULL;
+ while ((cn = uu_list_teardown(clp->cl_list, &cookie)) != NULL) {
+ zfs_close(cn->cn_handle);
+ free(cn);
+ }
+
+ uu_list_destroy(clp->cl_list);
+ }
+ if (clp->cl_pool)
+ uu_list_pool_destroy(clp->cl_pool);
+
+ free(clp);
+}
+
+static int
+change_one(zfs_handle_t *zhp, void *data)
+{
+ prop_changelist_t *clp = data;
+ char property[ZFS_MAXPROPLEN];
+ char where[64];
+ prop_changenode_t *cn;
+ zprop_source_t sourcetype;
+ zprop_source_t share_sourcetype;
+
+ /*
+ * We only want to unmount/unshare those filesystems that may inherit
+ * from the target filesystem. If we find any filesystem with a
+ * locally set mountpoint, we ignore any children since changing the
+ * property will not affect them. If this is a rename, we iterate
+ * over all children regardless, since we need them unmounted in
+ * order to do the rename. Also, if this is a volume and we're doing
+ * a rename, then always add it to the changelist.
+ */
+
+ if (!(ZFS_IS_VOLUME(zhp) && clp->cl_realprop == ZFS_PROP_NAME) &&
+ zfs_prop_get(zhp, clp->cl_prop, property,
+ sizeof (property), &sourcetype, where, sizeof (where),
+ B_FALSE) != 0) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ /*
+ * If we are "watching" sharenfs or sharesmb
+ * then check out the companion property which is tracked
+ * in cl_shareprop
+ */
+ if (clp->cl_shareprop != ZPROP_INVAL &&
+ zfs_prop_get(zhp, clp->cl_shareprop, property,
+ sizeof (property), &share_sourcetype, where, sizeof (where),
+ B_FALSE) != 0) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (clp->cl_alldependents || clp->cl_allchildren ||
+ sourcetype == ZPROP_SRC_DEFAULT ||
+ sourcetype == ZPROP_SRC_INHERITED ||
+ (clp->cl_shareprop != ZPROP_INVAL &&
+ (share_sourcetype == ZPROP_SRC_DEFAULT ||
+ share_sourcetype == ZPROP_SRC_INHERITED))) {
+ if ((cn = zfs_alloc(zfs_get_handle(zhp),
+ sizeof (prop_changenode_t))) == NULL) {
+ zfs_close(zhp);
+ return (-1);
+ }
+
+ cn->cn_handle = zhp;
+ cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
+ zfs_is_mounted(zhp, NULL);
+ cn->cn_shared = zfs_is_shared(zhp);
+ cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
+ cn->cn_needpost = B_TRUE;
+
+ /* Indicate if any child is exported to a local zone. */
+ if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
+ clp->cl_haszonedchild = B_TRUE;
+
+ uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool);
+
+ if (clp->cl_sorted) {
+ uu_list_index_t idx;
+
+ (void) uu_list_find(clp->cl_list, cn, NULL,
+ &idx);
+ uu_list_insert(clp->cl_list, cn, idx);
+ } else {
+ /*
+ * Add this child to beginning of the list. Children
+ * below this one in the hierarchy will get added above
+ * this one in the list. This produces a list in
+ * reverse dataset name order.
+ * This is necessary when the original mountpoint
+ * is legacy or none.
+ */
+ verify(uu_list_insert_before(clp->cl_list,
+ uu_list_first(clp->cl_list), cn) == 0);
+ }
+
+ if (!clp->cl_alldependents)
+ return (zfs_iter_children(zhp, change_one, data));
+ } else {
+ zfs_close(zhp);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+compare_mountpoints(const void *a, const void *b, void *unused)
+{
+ const prop_changenode_t *ca = a;
+ const prop_changenode_t *cb = b;
+
+ char mounta[MAXPATHLEN];
+ char mountb[MAXPATHLEN];
+
+ boolean_t hasmounta, hasmountb;
+
+ /*
+ * When unsharing or unmounting filesystems, we need to do it in
+ * mountpoint order. This allows the user to have a mountpoint
+ * hierarchy that is different from the dataset hierarchy, and still
+ * allow it to be changed. However, if either dataset doesn't have a
+ * mountpoint (because it is a volume or a snapshot), we place it at the
+ * end of the list, because it doesn't affect our change at all.
+ */
+ hasmounta = (zfs_prop_get(ca->cn_handle, ZFS_PROP_MOUNTPOINT, mounta,
+ sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
+ hasmountb = (zfs_prop_get(cb->cn_handle, ZFS_PROP_MOUNTPOINT, mountb,
+ sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
+
+ if (!hasmounta && hasmountb)
+ return (-1);
+ else if (hasmounta && !hasmountb)
+ return (1);
+ else if (!hasmounta && !hasmountb)
+ return (0);
+ else
+ return (strcmp(mountb, mounta));
+}
+
+/*
+ * Given a ZFS handle and a property, construct a complete list of datasets
+ * that need to be modified as part of this process. For anything but the
+ * 'mountpoint' and 'sharenfs' properties, this just returns an empty list.
+ * Otherwise, we iterate over all children and look for any datasets that
+ * inherit the property. For each such dataset, we add it to the list and
+ * mark whether it was shared beforehand.
+ */
+prop_changelist_t *
+changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
+ int mnt_flags)
+{
+ prop_changelist_t *clp;
+ prop_changenode_t *cn;
+ zfs_handle_t *temp;
+ char property[ZFS_MAXPROPLEN];
+ uu_compare_fn_t *compare = NULL;
+ boolean_t legacy = B_FALSE;
+
+ if ((clp = zfs_alloc(zhp->zfs_hdl, sizeof (prop_changelist_t))) == NULL)
+ return (NULL);
+
+ /*
+ * For mountpoint-related tasks, we want to sort everything by
+ * mountpoint, so that we mount and unmount them in the appropriate
+ * order, regardless of their position in the hierarchy.
+ */
+ if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
+ prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
+ prop == ZFS_PROP_SHARESMB) {
+
+ if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
+ property, sizeof (property),
+ NULL, NULL, 0, B_FALSE) == 0 &&
+ (strcmp(property, "legacy") == 0 ||
+ strcmp(property, "none") == 0)) {
+
+ legacy = B_TRUE;
+ }
+ if (!legacy) {
+ compare = compare_mountpoints;
+ clp->cl_sorted = B_TRUE;
+ }
+ }
+
+ clp->cl_pool = uu_list_pool_create("changelist_pool",
+ sizeof (prop_changenode_t),
+ offsetof(prop_changenode_t, cn_listnode),
+ compare, 0);
+ if (clp->cl_pool == NULL) {
+ assert(uu_error() == UU_ERROR_NO_MEMORY);
+ (void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
+ changelist_free(clp);
+ return (NULL);
+ }
+
+ clp->cl_list = uu_list_create(clp->cl_pool, NULL,
+ clp->cl_sorted ? UU_LIST_SORTED : 0);
+ clp->cl_gflags = gather_flags;
+ clp->cl_mflags = mnt_flags;
+
+ if (clp->cl_list == NULL) {
+ assert(uu_error() == UU_ERROR_NO_MEMORY);
+ (void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
+ changelist_free(clp);
+ return (NULL);
+ }
+
+ /*
+ * If this is a rename or the 'zoned' property, we pretend we're
+ * changing the mountpoint and flag it so we can catch all children in
+ * change_one().
+ *
+ * Flag cl_alldependents to catch all children plus the dependents
+ * (clones) that are not in the hierarchy.
+ */
+ if (prop == ZFS_PROP_NAME) {
+ clp->cl_prop = ZFS_PROP_MOUNTPOINT;
+ clp->cl_alldependents = B_TRUE;
+ } else if (prop == ZFS_PROP_ZONED) {
+ clp->cl_prop = ZFS_PROP_MOUNTPOINT;
+ clp->cl_allchildren = B_TRUE;
+ } else if (prop == ZFS_PROP_CANMOUNT) {
+ clp->cl_prop = ZFS_PROP_MOUNTPOINT;
+ } else if (prop == ZFS_PROP_VOLSIZE) {
+ clp->cl_prop = ZFS_PROP_MOUNTPOINT;
+ } else {
+ clp->cl_prop = prop;
+ }
+ clp->cl_realprop = prop;
+
+ if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
+ clp->cl_prop != ZFS_PROP_SHARENFS &&
+ clp->cl_prop != ZFS_PROP_SHARESMB)
+ return (clp);
+
+ /*
+ * If watching SHARENFS or SHARESMB then
+ * also watch its companion property.
+ */
+ if (clp->cl_prop == ZFS_PROP_SHARENFS)
+ clp->cl_shareprop = ZFS_PROP_SHARESMB;
+ else if (clp->cl_prop == ZFS_PROP_SHARESMB)
+ clp->cl_shareprop = ZFS_PROP_SHARENFS;
+
+ if (clp->cl_alldependents) {
+ if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) {
+ changelist_free(clp);
+ return (NULL);
+ }
+ } else if (zfs_iter_children(zhp, change_one, clp) != 0) {
+ changelist_free(clp);
+ return (NULL);
+ }
+
+ /*
+ * We have to re-open ourselves because we auto-close all the handles
+ * and can't tell the difference.
+ */
+ if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp),
+ ZFS_TYPE_DATASET)) == NULL) {
+ changelist_free(clp);
+ return (NULL);
+ }
+
+ /*
+ * Always add ourself to the list. We add ourselves to the end so that
+ * we're the last to be unmounted.
+ */
+ if ((cn = zfs_alloc(zhp->zfs_hdl,
+ sizeof (prop_changenode_t))) == NULL) {
+ zfs_close(temp);
+ changelist_free(clp);
+ return (NULL);
+ }
+
+ cn->cn_handle = temp;
+ cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
+ zfs_is_mounted(temp, NULL);
+ cn->cn_shared = zfs_is_shared(temp);
+ cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
+ cn->cn_needpost = B_TRUE;
+
+ uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool);
+ if (clp->cl_sorted) {
+ uu_list_index_t idx;
+ (void) uu_list_find(clp->cl_list, cn, NULL, &idx);
+ uu_list_insert(clp->cl_list, cn, idx);
+ } else {
+ /*
+ * Add the target dataset to the end of the list.
+ * The list is not really unsorted. The list will be
+ * in reverse dataset name order. This is necessary
+ * when the original mountpoint is legacy or none.
+ */
+ verify(uu_list_insert_after(clp->cl_list,
+ uu_list_last(clp->cl_list), cn) == 0);
+ }
+
+ /*
+ * If the mountpoint property was previously 'legacy', or 'none',
+ * record it as the behavior of changelist_postfix() will be different.
+ */
+ if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) && legacy) {
+ /*
+ * do not automatically mount ex-legacy datasets if
+ * we specifically set canmount to noauto
+ */
+ if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) !=
+ ZFS_CANMOUNT_NOAUTO)
+ clp->cl_waslegacy = B_TRUE;
+ }
+
+ return (clp);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
new file mode 100644
index 0000000..2a2ae76
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include "libzfs_compat.h"
+
+int zfs_ioctl_version = ZFS_IOCVER_UNDEF;
+static int zfs_spa_version = -1;
+
+/*
+ * Get zfs_ioctl_version
+ */
+int
+get_zfs_ioctl_version(void)
+{
+ size_t ver_size;
+ int ver = ZFS_IOCVER_NONE;
+
+ ver_size = sizeof(ver);
+ sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0);
+
+ return (ver);
+}
+
+/*
+ * Get the SPA version
+ */
+static int
+get_zfs_spa_version(void)
+{
+ size_t ver_size;
+ int ver = 0;
+
+ ver_size = sizeof(ver);
+ sysctlbyname("vfs.zfs.version.spa", &ver, &ver_size, NULL, 0);
+
+ return (ver);
+}
+
+/*
+ * This is FreeBSD version of ioctl, because Solaris' ioctl() updates
+ * zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
+ * error is returned zc_nvlist_dst_size won't be updated.
+ */
+int
+zcmd_ioctl(int fd, int request, zfs_cmd_t *zc)
+{
+ size_t oldsize;
+ int ret, cflag = ZFS_CMD_COMPAT_NONE;
+
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+
+ if (zfs_ioctl_version == ZFS_IOCVER_DEADMAN)
+ cflag = ZFS_CMD_COMPAT_DEADMAN;
+
+ /*
+ * If vfs.zfs.version.ioctl is not defined, assume we have v28
+ * compatible binaries and use vfs.zfs.version.spa to test for v15
+ */
+ if (zfs_ioctl_version < ZFS_IOCVER_DEADMAN) {
+ cflag = ZFS_CMD_COMPAT_V28;
+
+ if (zfs_spa_version < 0)
+ zfs_spa_version = get_zfs_spa_version();
+
+ if (zfs_spa_version == SPA_VERSION_15 ||
+ zfs_spa_version == SPA_VERSION_14 ||
+ zfs_spa_version == SPA_VERSION_13)
+ cflag = ZFS_CMD_COMPAT_V15;
+ }
+
+ oldsize = zc->zc_nvlist_dst_size;
+ ret = zcmd_ioctl_compat(fd, request, zc, cflag);
+
+ if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) {
+ ret = -1;
+ errno = ENOMEM;
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
new file mode 100644
index 0000000..3761668
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_COMPAT_H
+#define _LIBZFS_COMPAT_H
+
+#include <zfs_ioctl_compat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int get_zfs_ioctl_version(void);
+int zcmd_ioctl(int fd, int request, zfs_cmd_t *zc);
+
+#define ioctl(fd, ioc, zc) zcmd_ioctl((fd), (ioc), (zc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_COMPAT_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c
new file mode 100644
index 0000000..d5ba20f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c
@@ -0,0 +1,453 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
+ * single packed nvlist. While it would be nice to just read in this
+ * file from userland, this wouldn't work from a local zone. So we have to have
+ * a zpool ioctl to return the complete configuration for all pools. In the
+ * global zone, this will be identical to reading the file and unpacking it in
+ * userland.
+ */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <libuutil.h>
+
+#include "libzfs_impl.h"
+
+typedef struct config_node {
+ char *cn_name;
+ nvlist_t *cn_config;
+ uu_avl_node_t cn_avl;
+} config_node_t;
+
+/* ARGSUSED */
+static int
+config_node_compare(const void *a, const void *b, void *unused)
+{
+ int ret;
+
+ const config_node_t *ca = (config_node_t *)a;
+ const config_node_t *cb = (config_node_t *)b;
+
+ ret = strcmp(ca->cn_name, cb->cn_name);
+
+ if (ret < 0)
+ return (-1);
+ else if (ret > 0)
+ return (1);
+ else
+ return (0);
+}
+
+void
+namespace_clear(libzfs_handle_t *hdl)
+{
+ if (hdl->libzfs_ns_avl) {
+ config_node_t *cn;
+ void *cookie = NULL;
+
+ while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
+ &cookie)) != NULL) {
+ nvlist_free(cn->cn_config);
+ free(cn->cn_name);
+ free(cn);
+ }
+
+ uu_avl_destroy(hdl->libzfs_ns_avl);
+ hdl->libzfs_ns_avl = NULL;
+ }
+
+ if (hdl->libzfs_ns_avlpool) {
+ uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
+ hdl->libzfs_ns_avlpool = NULL;
+ }
+}
+
+/*
+ * Loads the pool namespace, or re-loads it if the cache has changed.
+ */
+static int
+namespace_reload(libzfs_handle_t *hdl)
+{
+ nvlist_t *config;
+ config_node_t *cn;
+ nvpair_t *elem;
+ zfs_cmd_t zc = { 0 };
+ void *cookie;
+
+ if (hdl->libzfs_ns_gen == 0) {
+ /*
+ * This is the first time we've accessed the configuration
+ * cache. Initialize the AVL tree and then fall through to the
+ * common code.
+ */
+ if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
+ sizeof (config_node_t),
+ offsetof(config_node_t, cn_avl),
+ config_node_compare, UU_DEFAULT)) == NULL)
+ return (no_memory(hdl));
+
+ if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
+ NULL, UU_DEFAULT)) == NULL)
+ return (no_memory(hdl));
+ }
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
+ return (-1);
+
+ for (;;) {
+ zc.zc_cookie = hdl->libzfs_ns_gen;
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CONFIGS, &zc) != 0) {
+ switch (errno) {
+ case EEXIST:
+ /*
+ * The namespace hasn't changed.
+ */
+ zcmd_free_nvlists(&zc);
+ return (0);
+
+ case ENOMEM:
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ break;
+
+ default:
+ zcmd_free_nvlists(&zc);
+ return (zfs_standard_error(hdl, errno,
+ dgettext(TEXT_DOMAIN, "failed to read "
+ "pool configuration")));
+ }
+ } else {
+ hdl->libzfs_ns_gen = zc.zc_cookie;
+ break;
+ }
+ }
+
+ if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+
+ zcmd_free_nvlists(&zc);
+
+ /*
+ * Clear out any existing configuration information.
+ */
+ cookie = NULL;
+ while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) {
+ nvlist_free(cn->cn_config);
+ free(cn->cn_name);
+ free(cn);
+ }
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
+ nvlist_t *child;
+ uu_avl_index_t where;
+
+ if ((cn = zfs_alloc(hdl, sizeof (config_node_t))) == NULL) {
+ nvlist_free(config);
+ return (-1);
+ }
+
+ if ((cn->cn_name = zfs_strdup(hdl,
+ nvpair_name(elem))) == NULL) {
+ free(cn);
+ nvlist_free(config);
+ return (-1);
+ }
+
+ verify(nvpair_value_nvlist(elem, &child) == 0);
+ if (nvlist_dup(child, &cn->cn_config, 0) != 0) {
+ free(cn->cn_name);
+ free(cn);
+ nvlist_free(config);
+ return (no_memory(hdl));
+ }
+ verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
+ == NULL);
+
+ uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
+ }
+
+ nvlist_free(config);
+ return (0);
+}
+
+/*
+ * Retrieve the configuration for the given pool. The configuration is a nvlist
+ * describing the vdevs, as well as the statistics associated with each one.
+ */
+nvlist_t *
+zpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig)
+{
+ if (oldconfig)
+ *oldconfig = zhp->zpool_old_config;
+ return (zhp->zpool_config);
+}
+
+/*
+ * Retrieves a list of enabled features and their refcounts and caches it in
+ * the pool handle.
+ */
+nvlist_t *
+zpool_get_features(zpool_handle_t *zhp)
+{
+ nvlist_t *config, *features;
+
+ config = zpool_get_config(zhp, NULL);
+
+ if (config == NULL || !nvlist_exists(config,
+ ZPOOL_CONFIG_FEATURE_STATS)) {
+ int error;
+ boolean_t missing = B_FALSE;
+
+ error = zpool_refresh_stats(zhp, &missing);
+
+ if (error != 0 || missing)
+ return (NULL);
+
+ config = zpool_get_config(zhp, NULL);
+ }
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
+ &features) == 0);
+
+ return (features);
+}
+
+/*
+ * Refresh the vdev statistics associated with the given pool. This is used in
+ * iostat to show configuration changes and determine the delta from the last
+ * time the function was called. This function can fail, in case the pool has
+ * been destroyed.
+ */
+int
+zpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing)
+{
+ zfs_cmd_t zc = { 0 };
+ int error;
+ nvlist_t *config;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ *missing = B_FALSE;
+ (void) strcpy(zc.zc_name, zhp->zpool_name);
+
+ if (zhp->zpool_config_size == 0)
+ zhp->zpool_config_size = 1 << 16;
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size) != 0)
+ return (-1);
+
+ for (;;) {
+ if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_STATS,
+ &zc) == 0) {
+ /*
+ * The real error is returned in the zc_cookie field.
+ */
+ error = zc.zc_cookie;
+ break;
+ }
+
+ if (errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ } else {
+ zcmd_free_nvlists(&zc);
+ if (errno == ENOENT || errno == EINVAL)
+ *missing = B_TRUE;
+ zhp->zpool_state = POOL_STATE_UNAVAIL;
+ return (0);
+ }
+ }
+
+ if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+
+ zcmd_free_nvlists(&zc);
+
+ zhp->zpool_config_size = zc.zc_nvlist_dst_size;
+
+ if (zhp->zpool_config != NULL) {
+ uint64_t oldtxg, newtxg;
+
+ verify(nvlist_lookup_uint64(zhp->zpool_config,
+ ZPOOL_CONFIG_POOL_TXG, &oldtxg) == 0);
+ verify(nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_TXG, &newtxg) == 0);
+
+ if (zhp->zpool_old_config != NULL)
+ nvlist_free(zhp->zpool_old_config);
+
+ if (oldtxg != newtxg) {
+ nvlist_free(zhp->zpool_config);
+ zhp->zpool_old_config = NULL;
+ } else {
+ zhp->zpool_old_config = zhp->zpool_config;
+ }
+ }
+
+ zhp->zpool_config = config;
+ if (error)
+ zhp->zpool_state = POOL_STATE_UNAVAIL;
+ else
+ zhp->zpool_state = POOL_STATE_ACTIVE;
+
+ return (0);
+}
+
+/*
+ * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over
+ * pools it lists.
+ *
+ * This is an undocumented feature for use during testing only.
+ *
+ * This function returns B_TRUE if the pool should be skipped
+ * during iteration.
+ */
+static boolean_t
+check_restricted(const char *poolname)
+{
+ static boolean_t initialized = B_FALSE;
+ static char *restricted = NULL;
+
+ const char *cur, *end;
+ int len, namelen;
+
+ if (!initialized) {
+ initialized = B_TRUE;
+ restricted = getenv("__ZFS_POOL_RESTRICT");
+ }
+
+ if (NULL == restricted)
+ return (B_FALSE);
+
+ cur = restricted;
+ namelen = strlen(poolname);
+ do {
+ end = strchr(cur, ' ');
+ len = (NULL == end) ? strlen(cur) : (end - cur);
+
+ if (len == namelen && 0 == strncmp(cur, poolname, len)) {
+ return (B_FALSE);
+ }
+
+ cur += (len + 1);
+ } while (NULL != end);
+
+ return (B_TRUE);
+}
+
+/*
+ * Iterate over all pools in the system.
+ */
+int
+zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
+{
+ config_node_t *cn;
+ zpool_handle_t *zhp;
+ int ret;
+
+ /*
+ * If someone makes a recursive call to zpool_iter(), we want to avoid
+ * refreshing the namespace because that will invalidate the parent
+ * context. We allow recursive calls, but simply re-use the same
+ * namespace AVL tree.
+ */
+ if (!hdl->libzfs_pool_iter && namespace_reload(hdl) != 0)
+ return (-1);
+
+ hdl->libzfs_pool_iter++;
+ for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
+ cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
+
+ if (check_restricted(cn->cn_name))
+ continue;
+
+ if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) {
+ hdl->libzfs_pool_iter--;
+ return (-1);
+ }
+
+ if (zhp == NULL)
+ continue;
+
+ if ((ret = func(zhp, data)) != 0) {
+ hdl->libzfs_pool_iter--;
+ return (ret);
+ }
+ }
+ hdl->libzfs_pool_iter--;
+
+ return (0);
+}
+
+/*
+ * Iterate over root datasets, calling the given function for each. The zfs
+ * handle passed each time must be explicitly closed by the callback.
+ */
+int
+zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
+{
+ config_node_t *cn;
+ zfs_handle_t *zhp;
+ int ret;
+
+ if (namespace_reload(hdl) != 0)
+ return (-1);
+
+ for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
+ cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
+
+ if (check_restricted(cn->cn_name))
+ continue;
+
+ if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL)
+ continue;
+
+ if ((ret = func(zhp, data)) != 0)
+ return (ret);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
new file mode 100644
index 0000000..c64d1c3
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -0,0 +1,4597 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <libintl.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <zone.h>
+#include <fcntl.h>
+#include <sys/mntent.h>
+#include <sys/mount.h>
+#include <priv.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stddef.h>
+#include <idmap.h>
+
+#include <sys/dnode.h>
+#include <sys/spa.h>
+#include <sys/zap.h>
+#include <sys/misc.h>
+#include <libzfs.h>
+
+#include "zfs_namecheck.h"
+#include "zfs_prop.h"
+#include "libzfs_impl.h"
+#include "zfs_deleg.h"
+
+static int userquota_propname_decode(const char *propname, boolean_t zoned,
+ zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
+
+/*
+ * Given a single type (not a mask of types), return the type in a human
+ * readable form.
+ */
+const char *
+zfs_type_to_name(zfs_type_t type)
+{
+ switch (type) {
+ case ZFS_TYPE_FILESYSTEM:
+ return (dgettext(TEXT_DOMAIN, "filesystem"));
+ case ZFS_TYPE_SNAPSHOT:
+ return (dgettext(TEXT_DOMAIN, "snapshot"));
+ case ZFS_TYPE_VOLUME:
+ return (dgettext(TEXT_DOMAIN, "volume"));
+ }
+
+ return (NULL);
+}
+
+/*
+ * Given a path and mask of ZFS types, return a string describing this dataset.
+ * This is used when we fail to open a dataset and we cannot get an exact type.
+ * We guess what the type would have been based on the path and the mask of
+ * acceptable types.
+ */
+static const char *
+path_to_str(const char *path, int types)
+{
+ /*
+ * When given a single type, always report the exact type.
+ */
+ if (types == ZFS_TYPE_SNAPSHOT)
+ return (dgettext(TEXT_DOMAIN, "snapshot"));
+ if (types == ZFS_TYPE_FILESYSTEM)
+ return (dgettext(TEXT_DOMAIN, "filesystem"));
+ if (types == ZFS_TYPE_VOLUME)
+ return (dgettext(TEXT_DOMAIN, "volume"));
+
+ /*
+ * The user is requesting more than one type of dataset. If this is the
+ * case, consult the path itself. If we're looking for a snapshot, and
+ * a '@' is found, then report it as "snapshot". Otherwise, remove the
+ * snapshot attribute and try again.
+ */
+ if (types & ZFS_TYPE_SNAPSHOT) {
+ if (strchr(path, '@') != NULL)
+ return (dgettext(TEXT_DOMAIN, "snapshot"));
+ return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
+ }
+
+ /*
+ * The user has requested either filesystems or volumes.
+ * We have no way of knowing a priori what type this would be, so always
+ * report it as "filesystem" or "volume", our two primitive types.
+ */
+ if (types & ZFS_TYPE_FILESYSTEM)
+ return (dgettext(TEXT_DOMAIN, "filesystem"));
+
+ assert(types & ZFS_TYPE_VOLUME);
+ return (dgettext(TEXT_DOMAIN, "volume"));
+}
+
+/*
+ * Validate a ZFS path. This is used even before trying to open the dataset, to
+ * provide a more meaningful error message. We call zfs_error_aux() to
+ * explain exactly why the name was not valid.
+ */
+int
+zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
+ boolean_t modifying)
+{
+ namecheck_err_t why;
+ char what;
+
+ (void) zfs_prop_get_table();
+ if (dataset_namecheck(path, &why, &what) != 0) {
+ if (hdl != NULL) {
+ switch (why) {
+ case NAME_ERR_TOOLONG:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "name is too long"));
+ break;
+
+ case NAME_ERR_LEADING_SLASH:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "leading slash in name"));
+ break;
+
+ case NAME_ERR_EMPTY_COMPONENT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "empty component in name"));
+ break;
+
+ case NAME_ERR_TRAILING_SLASH:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "trailing slash in name"));
+ break;
+
+ case NAME_ERR_INVALCHAR:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "invalid character "
+ "'%c' in name"), what);
+ break;
+
+ case NAME_ERR_MULTIPLE_AT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "multiple '@' delimiters in name"));
+ break;
+
+ case NAME_ERR_NOLETTER:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool doesn't begin with a letter"));
+ break;
+
+ case NAME_ERR_RESERVED:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "name is reserved"));
+ break;
+
+ case NAME_ERR_DISKLIKE:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "reserved disk name"));
+ break;
+ }
+ }
+
+ return (0);
+ }
+
+ if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "snapshot delimiter '@' in filesystem name"));
+ return (0);
+ }
+
+ if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "missing '@' delimiter in snapshot name"));
+ return (0);
+ }
+
+ if (modifying && strchr(path, '%') != NULL) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid character %c in name"), '%');
+ return (0);
+ }
+
+ return (-1);
+}
+
+int
+zfs_name_valid(const char *name, zfs_type_t type)
+{
+ if (type == ZFS_TYPE_POOL)
+ return (zpool_name_valid(NULL, B_FALSE, name));
+ return (zfs_validate_name(NULL, name, type, B_FALSE));
+}
+
+/*
+ * This function takes the raw DSL properties, and filters out the user-defined
+ * properties into a separate nvlist.
+ */
+static nvlist_t *
+process_user_props(zfs_handle_t *zhp, nvlist_t *props)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ nvpair_t *elem;
+ nvlist_t *propval;
+ nvlist_t *nvl;
+
+ if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
+ if (!zfs_prop_user(nvpair_name(elem)))
+ continue;
+
+ verify(nvpair_value_nvlist(elem, &propval) == 0);
+ if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
+ nvlist_free(nvl);
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+ }
+
+ return (nvl);
+}
+
+static zpool_handle_t *
+zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zpool_handle_t *zph;
+
+ if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
+ if (hdl->libzfs_pool_handles != NULL)
+ zph->zpool_next = hdl->libzfs_pool_handles;
+ hdl->libzfs_pool_handles = zph;
+ }
+ return (zph);
+}
+
+static zpool_handle_t *
+zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zpool_handle_t *zph = hdl->libzfs_pool_handles;
+
+ while ((zph != NULL) &&
+ (strncmp(pool_name, zpool_get_name(zph), len) != 0))
+ zph = zph->zpool_next;
+ return (zph);
+}
+
+/*
+ * Returns a handle to the pool that contains the provided dataset.
+ * If a handle to that pool already exists then that handle is returned.
+ * Otherwise, a new handle is created and added to the list of handles.
+ */
+static zpool_handle_t *
+zpool_handle(zfs_handle_t *zhp)
+{
+ char *pool_name;
+ int len;
+ zpool_handle_t *zph;
+
+ len = strcspn(zhp->zfs_name, "/@") + 1;
+ pool_name = zfs_alloc(zhp->zfs_hdl, len);
+ (void) strlcpy(pool_name, zhp->zfs_name, len);
+
+ zph = zpool_find_handle(zhp, pool_name, len);
+ if (zph == NULL)
+ zph = zpool_add_handle(zhp, pool_name);
+
+ free(pool_name);
+ return (zph);
+}
+
+void
+zpool_free_handles(libzfs_handle_t *hdl)
+{
+ zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
+
+ while (zph != NULL) {
+ next = zph->zpool_next;
+ zpool_close(zph);
+ zph = next;
+ }
+ hdl->libzfs_pool_handles = NULL;
+}
+
+/*
+ * Utility function to gather stats (objset and zpl) for the given object.
+ */
+static int
+get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+
+ (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
+
+ while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, zc) != 0) {
+ if (errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, zc) != 0) {
+ return (-1);
+ }
+ } else {
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Utility function to get the received properties of the given object.
+ */
+static int
+get_recvd_props_ioctl(zfs_handle_t *zhp)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ nvlist_t *recvdprops;
+ zfs_cmd_t zc = { 0 };
+ int err;
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
+ return (-1);
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
+ if (errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ return (-1);
+ }
+ } else {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ }
+
+ err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
+ zcmd_free_nvlists(&zc);
+ if (err != 0)
+ return (-1);
+
+ nvlist_free(zhp->zfs_recvd_props);
+ zhp->zfs_recvd_props = recvdprops;
+
+ return (0);
+}
+
+static int
+put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
+{
+ nvlist_t *allprops, *userprops;
+
+ zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */
+
+ if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) {
+ return (-1);
+ }
+
+ /*
+ * XXX Why do we store the user props separately, in addition to
+ * storing them in zfs_props?
+ */
+ if ((userprops = process_user_props(zhp, allprops)) == NULL) {
+ nvlist_free(allprops);
+ return (-1);
+ }
+
+ nvlist_free(zhp->zfs_props);
+ nvlist_free(zhp->zfs_user_props);
+
+ zhp->zfs_props = allprops;
+ zhp->zfs_user_props = userprops;
+
+ return (0);
+}
+
+static int
+get_stats(zfs_handle_t *zhp)
+{
+ int rc = 0;
+ zfs_cmd_t zc = { 0 };
+
+ if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
+ return (-1);
+ if (get_stats_ioctl(zhp, &zc) != 0)
+ rc = -1;
+ else if (put_stats_zhdl(zhp, &zc) != 0)
+ rc = -1;
+ zcmd_free_nvlists(&zc);
+ return (rc);
+}
+
+/*
+ * Refresh the properties currently stored in the handle.
+ */
+void
+zfs_refresh_properties(zfs_handle_t *zhp)
+{
+ (void) get_stats(zhp);
+}
+
+/*
+ * Makes a handle from the given dataset name. Used by zfs_open() and
+ * zfs_iter_* to create child handles on the fly.
+ */
+static int
+make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
+{
+ if (put_stats_zhdl(zhp, zc) != 0)
+ return (-1);
+
+ /*
+ * We've managed to open the dataset and gather statistics. Determine
+ * the high-level type.
+ */
+ if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
+ zhp->zfs_head_type = ZFS_TYPE_VOLUME;
+ else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
+ zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
+ else
+ abort();
+
+ if (zhp->zfs_dmustats.dds_is_snapshot)
+ zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
+ else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
+ zhp->zfs_type = ZFS_TYPE_VOLUME;
+ else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
+ zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
+ else
+ abort(); /* we should never see any other types */
+
+ if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
+ return (-1);
+
+ return (0);
+}
+
+zfs_handle_t *
+make_dataset_handle(libzfs_handle_t *hdl, const char *path)
+{
+ zfs_cmd_t zc = { 0 };
+
+ zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
+
+ if (zhp == NULL)
+ return (NULL);
+
+ zhp->zfs_hdl = hdl;
+ (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) {
+ free(zhp);
+ return (NULL);
+ }
+ if (get_stats_ioctl(zhp, &zc) == -1) {
+ zcmd_free_nvlists(&zc);
+ free(zhp);
+ return (NULL);
+ }
+ if (make_dataset_handle_common(zhp, &zc) == -1) {
+ free(zhp);
+ zhp = NULL;
+ }
+ zcmd_free_nvlists(&zc);
+ return (zhp);
+}
+
+zfs_handle_t *
+make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
+{
+ zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
+
+ if (zhp == NULL)
+ return (NULL);
+
+ zhp->zfs_hdl = hdl;
+ (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
+ if (make_dataset_handle_common(zhp, zc) == -1) {
+ free(zhp);
+ return (NULL);
+ }
+ return (zhp);
+}
+
+zfs_handle_t *
+make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
+{
+ zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
+
+ if (zhp == NULL)
+ return (NULL);
+
+ zhp->zfs_hdl = pzhp->zfs_hdl;
+ (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
+ zhp->zfs_head_type = pzhp->zfs_type;
+ zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
+ zhp->zpool_hdl = zpool_handle(zhp);
+ return (zhp);
+}
+
+zfs_handle_t *
+zfs_handle_dup(zfs_handle_t *zhp_orig)
+{
+ zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
+
+ if (zhp == NULL)
+ return (NULL);
+
+ zhp->zfs_hdl = zhp_orig->zfs_hdl;
+ zhp->zpool_hdl = zhp_orig->zpool_hdl;
+ (void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
+ sizeof (zhp->zfs_name));
+ zhp->zfs_type = zhp_orig->zfs_type;
+ zhp->zfs_head_type = zhp_orig->zfs_head_type;
+ zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
+ if (zhp_orig->zfs_props != NULL) {
+ if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
+ (void) no_memory(zhp->zfs_hdl);
+ zfs_close(zhp);
+ return (NULL);
+ }
+ }
+ if (zhp_orig->zfs_user_props != NULL) {
+ if (nvlist_dup(zhp_orig->zfs_user_props,
+ &zhp->zfs_user_props, 0) != 0) {
+ (void) no_memory(zhp->zfs_hdl);
+ zfs_close(zhp);
+ return (NULL);
+ }
+ }
+ if (zhp_orig->zfs_recvd_props != NULL) {
+ if (nvlist_dup(zhp_orig->zfs_recvd_props,
+ &zhp->zfs_recvd_props, 0)) {
+ (void) no_memory(zhp->zfs_hdl);
+ zfs_close(zhp);
+ return (NULL);
+ }
+ }
+ zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
+ if (zhp_orig->zfs_mntopts != NULL) {
+ zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
+ zhp_orig->zfs_mntopts);
+ }
+ zhp->zfs_props_table = zhp_orig->zfs_props_table;
+ return (zhp);
+}
+
+/*
+ * Opens the given snapshot, filesystem, or volume. The 'types'
+ * argument is a mask of acceptable types. The function will print an
+ * appropriate error message and return NULL if it can't be opened.
+ */
+zfs_handle_t *
+zfs_open(libzfs_handle_t *hdl, const char *path, int types)
+{
+ zfs_handle_t *zhp;
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
+
+ /*
+ * Validate the name before we even try to open it.
+ */
+ if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid dataset name"));
+ (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
+ return (NULL);
+ }
+
+ /*
+ * Try to get stats for the dataset, which will tell us if it exists.
+ */
+ errno = 0;
+ if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
+ (void) zfs_standard_error(hdl, errno, errbuf);
+ return (NULL);
+ }
+
+ if (zhp == NULL) {
+ char *at = strchr(path, '@');
+
+ if (at != NULL)
+ *at = '\0';
+ errno = 0;
+ if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
+ (void) zfs_standard_error(hdl, errno, errbuf);
+ return (NULL);
+ }
+ if (at != NULL)
+ *at = '@';
+ (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
+ zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
+ }
+
+ if (!(types & zhp->zfs_type)) {
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ zfs_close(zhp);
+ return (NULL);
+ }
+
+ return (zhp);
+}
+
+/*
+ * Release a ZFS handle. Nothing to do but free the associated memory.
+ */
+void
+zfs_close(zfs_handle_t *zhp)
+{
+ if (zhp->zfs_mntopts)
+ free(zhp->zfs_mntopts);
+ nvlist_free(zhp->zfs_props);
+ nvlist_free(zhp->zfs_user_props);
+ nvlist_free(zhp->zfs_recvd_props);
+ free(zhp);
+}
+
+typedef struct mnttab_node {
+ struct mnttab mtn_mt;
+ avl_node_t mtn_node;
+} mnttab_node_t;
+
+static int
+libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
+{
+ const mnttab_node_t *mtn1 = arg1;
+ const mnttab_node_t *mtn2 = arg2;
+ int rv;
+
+ rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
+
+ if (rv == 0)
+ return (0);
+ return (rv > 0 ? 1 : -1);
+}
+
+void
+libzfs_mnttab_init(libzfs_handle_t *hdl)
+{
+ assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
+ avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
+ sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
+}
+
+void
+libzfs_mnttab_update(libzfs_handle_t *hdl)
+{
+ struct mnttab entry;
+
+ rewind(hdl->libzfs_mnttab);
+ while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
+ mnttab_node_t *mtn;
+
+ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
+ continue;
+ mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
+ mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
+ mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
+ mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
+ mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
+ avl_add(&hdl->libzfs_mnttab_cache, mtn);
+ }
+}
+
+void
+libzfs_mnttab_fini(libzfs_handle_t *hdl)
+{
+ void *cookie = NULL;
+ mnttab_node_t *mtn;
+
+ while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) {
+ free(mtn->mtn_mt.mnt_special);
+ free(mtn->mtn_mt.mnt_mountp);
+ free(mtn->mtn_mt.mnt_fstype);
+ free(mtn->mtn_mt.mnt_mntopts);
+ free(mtn);
+ }
+ avl_destroy(&hdl->libzfs_mnttab_cache);
+}
+
+void
+libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
+{
+ hdl->libzfs_mnttab_enable = enable;
+}
+
+int
+libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
+ struct mnttab *entry)
+{
+ mnttab_node_t find;
+ mnttab_node_t *mtn;
+
+ if (!hdl->libzfs_mnttab_enable) {
+ struct mnttab srch = { 0 };
+
+ if (avl_numnodes(&hdl->libzfs_mnttab_cache))
+ libzfs_mnttab_fini(hdl);
+ rewind(hdl->libzfs_mnttab);
+ srch.mnt_special = (char *)fsname;
+ srch.mnt_fstype = MNTTYPE_ZFS;
+ if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0)
+ return (0);
+ else
+ return (ENOENT);
+ }
+
+ if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
+ libzfs_mnttab_update(hdl);
+
+ find.mtn_mt.mnt_special = (char *)fsname;
+ mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
+ if (mtn) {
+ *entry = mtn->mtn_mt;
+ return (0);
+ }
+ return (ENOENT);
+}
+
+void
+libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
+ const char *mountp, const char *mntopts)
+{
+ mnttab_node_t *mtn;
+
+ if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
+ return;
+ mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
+ mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
+ mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
+ mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
+ mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
+ avl_add(&hdl->libzfs_mnttab_cache, mtn);
+}
+
+void
+libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
+{
+ mnttab_node_t find;
+ mnttab_node_t *ret;
+
+ find.mtn_mt.mnt_special = (char *)fsname;
+ if (ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) {
+ avl_remove(&hdl->libzfs_mnttab_cache, ret);
+ free(ret->mtn_mt.mnt_special);
+ free(ret->mtn_mt.mnt_mountp);
+ free(ret->mtn_mt.mnt_fstype);
+ free(ret->mtn_mt.mnt_mntopts);
+ free(ret);
+ }
+}
+
+int
+zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
+{
+ zpool_handle_t *zpool_handle = zhp->zpool_hdl;
+
+ if (zpool_handle == NULL)
+ return (-1);
+
+ *spa_version = zpool_get_prop_int(zpool_handle,
+ ZPOOL_PROP_VERSION, NULL);
+ return (0);
+}
+
+/*
+ * The choice of reservation property depends on the SPA version.
+ */
+static int
+zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
+{
+ int spa_version;
+
+ if (zfs_spa_version(zhp, &spa_version) < 0)
+ return (-1);
+
+ if (spa_version >= SPA_VERSION_REFRESERVATION)
+ *resv_prop = ZFS_PROP_REFRESERVATION;
+ else
+ *resv_prop = ZFS_PROP_RESERVATION;
+
+ return (0);
+}
+
+/*
+ * Given an nvlist of properties to set, validates that they are correct, and
+ * parses any numeric properties (index, boolean, etc) if they are specified as
+ * strings.
+ */
+nvlist_t *
+zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
+ uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
+{
+ nvpair_t *elem;
+ uint64_t intval;
+ char *strval;
+ zfs_prop_t prop;
+ nvlist_t *ret;
+ int chosen_normal = -1;
+ int chosen_utf = -1;
+
+ if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+
+ /*
+ * Make sure this property is valid and applies to this type.
+ */
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
+ const char *propname = nvpair_name(elem);
+
+ prop = zfs_name_to_prop(propname);
+ if (prop == ZPROP_INVAL && zfs_prop_user(propname)) {
+ /*
+ * This is a user property: make sure it's a
+ * string, and that it's less than ZAP_MAXNAMELEN.
+ */
+ if (nvpair_type(elem) != DATA_TYPE_STRING) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a string"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property name '%s' is too long"),
+ propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ (void) nvpair_value_string(elem, &strval);
+ if (nvlist_add_string(ret, propname, strval) != 0) {
+ (void) no_memory(hdl);
+ goto error;
+ }
+ continue;
+ }
+
+ /*
+ * Currently, only user properties can be modified on
+ * snapshots.
+ */
+ if (type == ZFS_TYPE_SNAPSHOT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "this property can not be modified for snapshots"));
+ (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
+ goto error;
+ }
+
+ if (prop == ZPROP_INVAL && zfs_prop_userquota(propname)) {
+ zfs_userquota_prop_t uqtype;
+ char newpropname[128];
+ char domain[128];
+ uint64_t rid;
+ uint64_t valary[3];
+
+ if (userquota_propname_decode(propname, zoned,
+ &uqtype, domain, sizeof (domain), &rid) != 0) {
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN,
+ "'%s' has an invalid user/group name"),
+ propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (uqtype != ZFS_PROP_USERQUOTA &&
+ uqtype != ZFS_PROP_GROUPQUOTA) {
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "'%s' is readonly"),
+ propname);
+ (void) zfs_error(hdl, EZFS_PROPREADONLY,
+ errbuf);
+ goto error;
+ }
+
+ if (nvpair_type(elem) == DATA_TYPE_STRING) {
+ (void) nvpair_value_string(elem, &strval);
+ if (strcmp(strval, "none") == 0) {
+ intval = 0;
+ } else if (zfs_nicestrtonum(hdl,
+ strval, &intval) != 0) {
+ (void) zfs_error(hdl,
+ EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ } else if (nvpair_type(elem) ==
+ DATA_TYPE_UINT64) {
+ (void) nvpair_value_uint64(elem, &intval);
+ if (intval == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "use 'none' to disable "
+ "userquota/groupquota"));
+ goto error;
+ }
+ } else {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a number"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ /*
+ * Encode the prop name as
+ * userquota@<hex-rid>-domain, to make it easy
+ * for the kernel to decode.
+ */
+ (void) snprintf(newpropname, sizeof (newpropname),
+ "%s%llx-%s", zfs_userquota_prop_prefixes[uqtype],
+ (longlong_t)rid, domain);
+ valary[0] = uqtype;
+ valary[1] = rid;
+ valary[2] = intval;
+ if (nvlist_add_uint64_array(ret, newpropname,
+ valary, 3) != 0) {
+ (void) no_memory(hdl);
+ goto error;
+ }
+ continue;
+ } else if (prop == ZPROP_INVAL && zfs_prop_written(propname)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is readonly"),
+ propname);
+ (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
+ goto error;
+ }
+
+ if (prop == ZPROP_INVAL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid property '%s'"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (!zfs_prop_valid_for_type(prop, type)) {
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "'%s' does not "
+ "apply to datasets of this type"), propname);
+ (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
+ goto error;
+ }
+
+ if (zfs_prop_readonly(prop) &&
+ (!zfs_prop_setonce(prop) || zhp != NULL)) {
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "'%s' is readonly"),
+ propname);
+ (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
+ goto error;
+ }
+
+ if (zprop_parse_value(hdl, elem, prop, type, ret,
+ &strval, &intval, errbuf) != 0)
+ goto error;
+
+ /*
+ * Perform some additional checks for specific properties.
+ */
+ switch (prop) {
+ case ZFS_PROP_VERSION:
+ {
+ int version;
+
+ if (zhp == NULL)
+ break;
+ version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ if (intval < version) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "Can not downgrade; already at version %u"),
+ version);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ break;
+ }
+
+ case ZFS_PROP_RECORDSIZE:
+ case ZFS_PROP_VOLBLOCKSIZE:
+ /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
+ if (intval < SPA_MINBLOCKSIZE ||
+ intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be power of 2 from %u "
+ "to %uk"), propname,
+ (uint_t)SPA_MINBLOCKSIZE,
+ (uint_t)SPA_MAXBLOCKSIZE >> 10);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ break;
+
+ case ZFS_PROP_MLSLABEL:
+ {
+#ifdef sun
+ /*
+ * Verify the mlslabel string and convert to
+ * internal hex label string.
+ */
+
+ m_label_t *new_sl;
+ char *hex = NULL; /* internal label string */
+
+ /* Default value is already OK. */
+ if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
+ break;
+
+ /* Verify the label can be converted to binary form */
+ if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
+ (str_to_label(strval, &new_sl, MAC_LABEL,
+ L_NO_CORRECTION, NULL) == -1)) {
+ goto badlabel;
+ }
+
+ /* Now translate to hex internal label string */
+ if (label_to_str(new_sl, &hex, M_INTERNAL,
+ DEF_NAMES) != 0) {
+ if (hex)
+ free(hex);
+ goto badlabel;
+ }
+ m_label_free(new_sl);
+
+ /* If string is already in internal form, we're done. */
+ if (strcmp(strval, hex) == 0) {
+ free(hex);
+ break;
+ }
+
+ /* Replace the label string with the internal form. */
+ (void) nvlist_remove(ret, zfs_prop_to_name(prop),
+ DATA_TYPE_STRING);
+ verify(nvlist_add_string(ret, zfs_prop_to_name(prop),
+ hex) == 0);
+ free(hex);
+
+ break;
+
+badlabel:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid mlslabel '%s'"), strval);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ m_label_free(new_sl); /* OK if null */
+#else /* !sun */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "mlslabel is not supported on FreeBSD"));
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+#endif /* !sun */
+ goto error;
+
+ }
+
+ case ZFS_PROP_MOUNTPOINT:
+ {
+ namecheck_err_t why;
+
+ if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
+ strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
+ break;
+
+ if (mountpoint_namecheck(strval, &why)) {
+ switch (why) {
+ case NAME_ERR_LEADING_SLASH:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN,
+ "'%s' must be an absolute path, "
+ "'none', or 'legacy'"), propname);
+ break;
+ case NAME_ERR_TOOLONG:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN,
+ "component of '%s' is too long"),
+ propname);
+ break;
+ }
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ }
+
+ /*FALLTHRU*/
+
+ case ZFS_PROP_SHARESMB:
+ case ZFS_PROP_SHARENFS:
+ /*
+ * For the mountpoint and sharenfs or sharesmb
+ * properties, check if it can be set in a
+ * global/non-global zone based on
+ * the zoned property value:
+ *
+ * global zone non-global zone
+ * --------------------------------------------------
+ * zoned=on mountpoint (no) mountpoint (yes)
+ * sharenfs (no) sharenfs (no)
+ * sharesmb (no) sharesmb (no)
+ *
+ * zoned=off mountpoint (yes) N/A
+ * sharenfs (yes)
+ * sharesmb (yes)
+ */
+ if (zoned) {
+ if (getzoneid() == GLOBAL_ZONEID) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be set on "
+ "dataset in a non-global zone"),
+ propname);
+ (void) zfs_error(hdl, EZFS_ZONED,
+ errbuf);
+ goto error;
+ } else if (prop == ZFS_PROP_SHARENFS ||
+ prop == ZFS_PROP_SHARESMB) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be set in "
+ "a non-global zone"), propname);
+ (void) zfs_error(hdl, EZFS_ZONED,
+ errbuf);
+ goto error;
+ }
+ } else if (getzoneid() != GLOBAL_ZONEID) {
+ /*
+ * If zoned property is 'off', this must be in
+ * a global zone. If not, something is wrong.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be set while dataset "
+ "'zoned' property is set"), propname);
+ (void) zfs_error(hdl, EZFS_ZONED, errbuf);
+ goto error;
+ }
+
+ /*
+ * At this point, it is legitimate to set the
+ * property. Now we want to make sure that the
+ * property value is valid if it is sharenfs.
+ */
+ if ((prop == ZFS_PROP_SHARENFS ||
+ prop == ZFS_PROP_SHARESMB) &&
+ strcmp(strval, "on") != 0 &&
+ strcmp(strval, "off") != 0) {
+ zfs_share_proto_t proto;
+
+ if (prop == ZFS_PROP_SHARESMB)
+ proto = PROTO_SMB;
+ else
+ proto = PROTO_NFS;
+
+ /*
+ * Must be an valid sharing protocol
+ * option string so init the libshare
+ * in order to enable the parser and
+ * then parse the options. We use the
+ * control API since we don't care about
+ * the current configuration and don't
+ * want the overhead of loading it
+ * until we actually do something.
+ */
+
+ if (zfs_init_libshare(hdl,
+ SA_INIT_CONTROL_API) != SA_OK) {
+ /*
+ * An error occurred so we can't do
+ * anything
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be set: problem "
+ "in share initialization"),
+ propname);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+
+ if (zfs_parse_options(strval, proto) != SA_OK) {
+ /*
+ * There was an error in parsing so
+ * deal with it by issuing an error
+ * message and leaving after
+ * uninitializing the the libshare
+ * interface.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be set to invalid "
+ "options"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ zfs_uninit_libshare(hdl);
+ goto error;
+ }
+ zfs_uninit_libshare(hdl);
+ }
+
+ break;
+ case ZFS_PROP_UTF8ONLY:
+ chosen_utf = (int)intval;
+ break;
+ case ZFS_PROP_NORMALIZE:
+ chosen_normal = (int)intval;
+ break;
+ }
+
+ /*
+ * For changes to existing volumes, we have some additional
+ * checks to enforce.
+ */
+ if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
+ uint64_t volsize = zfs_prop_get_int(zhp,
+ ZFS_PROP_VOLSIZE);
+ uint64_t blocksize = zfs_prop_get_int(zhp,
+ ZFS_PROP_VOLBLOCKSIZE);
+ char buf[64];
+
+ switch (prop) {
+ case ZFS_PROP_RESERVATION:
+ case ZFS_PROP_REFRESERVATION:
+ if (intval > volsize) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is greater than current "
+ "volume size"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+ break;
+
+ case ZFS_PROP_VOLSIZE:
+ if (intval % blocksize != 0) {
+ zfs_nicenum(blocksize, buf,
+ sizeof (buf));
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a multiple of "
+ "volume block size (%s)"),
+ propname, buf);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+
+ if (intval == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' cannot be zero"),
+ propname);
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * If normalization was chosen, but no UTF8 choice was made,
+ * enforce rejection of non-UTF8 names.
+ *
+ * If normalization was chosen, but rejecting non-UTF8 names
+ * was explicitly not chosen, it is an error.
+ */
+ if (chosen_normal > 0 && chosen_utf < 0) {
+ if (nvlist_add_uint64(ret,
+ zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
+ (void) no_memory(hdl);
+ goto error;
+ }
+ } else if (chosen_normal > 0 && chosen_utf == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be set 'on' if normalization chosen"),
+ zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ return (ret);
+
+error:
+ nvlist_free(ret);
+ return (NULL);
+}
+
+int
+zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
+{
+ uint64_t old_volsize;
+ uint64_t new_volsize;
+ uint64_t old_reservation;
+ uint64_t new_reservation;
+ zfs_prop_t resv_prop;
+
+ /*
+ * If this is an existing volume, and someone is setting the volsize,
+ * make sure that it matches the reservation, or add it if necessary.
+ */
+ old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
+ if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
+ return (-1);
+ old_reservation = zfs_prop_get_int(zhp, resv_prop);
+ if ((zvol_volsize_to_reservation(old_volsize, zhp->zfs_props) !=
+ old_reservation) || nvlist_lookup_uint64(nvl,
+ zfs_prop_to_name(resv_prop), &new_reservation) != ENOENT) {
+ return (0);
+ }
+ if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
+ &new_volsize) != 0)
+ return (-1);
+ new_reservation = zvol_volsize_to_reservation(new_volsize,
+ zhp->zfs_props);
+ if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
+ new_reservation) != 0) {
+ (void) no_memory(zhp->zfs_hdl);
+ return (-1);
+ }
+ return (1);
+}
+
+void
+zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
+ char *errbuf)
+{
+ switch (err) {
+
+ case ENOSPC:
+ /*
+ * For quotas and reservations, ENOSPC indicates
+ * something different; setting a quota or reservation
+ * doesn't use any disk space.
+ */
+ switch (prop) {
+ case ZFS_PROP_QUOTA:
+ case ZFS_PROP_REFQUOTA:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "size is less than current used or "
+ "reserved space"));
+ (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
+ break;
+
+ case ZFS_PROP_RESERVATION:
+ case ZFS_PROP_REFRESERVATION:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "size is greater than available space"));
+ (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
+ break;
+
+ default:
+ (void) zfs_standard_error(hdl, err, errbuf);
+ break;
+ }
+ break;
+
+ case EBUSY:
+ (void) zfs_standard_error(hdl, EBUSY, errbuf);
+ break;
+
+ case EROFS:
+ (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
+ break;
+
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool and or dataset must be upgraded to set this "
+ "property or value"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+
+ case ERANGE:
+ if (prop == ZFS_PROP_COMPRESSION) {
+ (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property setting is not allowed on "
+ "bootable datasets"));
+ (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
+ } else {
+ (void) zfs_standard_error(hdl, err, errbuf);
+ }
+ break;
+
+ case EINVAL:
+ if (prop == ZPROP_INVAL) {
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ } else {
+ (void) zfs_standard_error(hdl, err, errbuf);
+ }
+ break;
+
+ case EOVERFLOW:
+ /*
+ * This platform can't address a volume this big.
+ */
+#ifdef _ILP32
+ if (prop == ZFS_PROP_VOLSIZE) {
+ (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
+ break;
+ }
+#endif
+ /* FALLTHROUGH */
+ default:
+ (void) zfs_standard_error(hdl, err, errbuf);
+ }
+}
+
+/*
+ * Given a property name and value, set the property for the given dataset.
+ */
+int
+zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
+{
+ zfs_cmd_t zc = { 0 };
+ int ret = -1;
+ prop_changelist_t *cl = NULL;
+ char errbuf[1024];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ nvlist_t *nvl = NULL, *realprops;
+ zfs_prop_t prop;
+ boolean_t do_prefix = B_TRUE;
+ int added_resv;
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
+ zhp->zfs_name);
+
+ if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
+ nvlist_add_string(nvl, propname, propval) != 0) {
+ (void) no_memory(hdl);
+ goto error;
+ }
+
+ if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
+ zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
+ goto error;
+
+ nvlist_free(nvl);
+ nvl = realprops;
+
+ prop = zfs_name_to_prop(propname);
+
+ /* We don't support those properties on FreeBSD. */
+ switch (prop) {
+ case ZFS_PROP_DEVICES:
+ case ZFS_PROP_ISCSIOPTIONS:
+ case ZFS_PROP_XATTR:
+ case ZFS_PROP_VSCAN:
+ case ZFS_PROP_NBMAND:
+ case ZFS_PROP_MLSLABEL:
+ (void) snprintf(errbuf, sizeof (errbuf),
+ "property '%s' not supported on FreeBSD", propname);
+ ret = zfs_error(hdl, EZFS_PERM, errbuf);
+ goto error;
+ }
+
+ if (prop == ZFS_PROP_VOLSIZE) {
+ if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
+ goto error;
+ }
+
+ if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
+ goto error;
+
+ if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "child dataset with inherited mountpoint is used "
+ "in a non-global zone"));
+ ret = zfs_error(hdl, EZFS_ZONED, errbuf);
+ goto error;
+ }
+
+ /*
+ * We don't want to unmount & remount the dataset when changing
+ * its canmount property to 'on' or 'noauto'. We only use
+ * the changelist logic to unmount when setting canmount=off.
+ */
+ if (prop == ZFS_PROP_CANMOUNT) {
+ uint64_t idx;
+ int err = zprop_string_to_index(prop, propval, &idx,
+ ZFS_TYPE_DATASET);
+ if (err == 0 && idx != ZFS_CANMOUNT_OFF)
+ do_prefix = B_FALSE;
+ }
+
+ if (do_prefix && (ret = changelist_prefix(cl)) != 0)
+ goto error;
+
+ /*
+ * Execute the corresponding ioctl() to set this property.
+ */
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
+ goto error;
+
+ ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
+
+ if (ret != 0) {
+ zfs_setprop_error(hdl, prop, errno, errbuf);
+ if (added_resv && errno == ENOSPC) {
+ /* clean up the volsize property we tried to set */
+ uint64_t old_volsize = zfs_prop_get_int(zhp,
+ ZFS_PROP_VOLSIZE);
+ nvlist_free(nvl);
+ zcmd_free_nvlists(&zc);
+ if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
+ goto error;
+ if (nvlist_add_uint64(nvl,
+ zfs_prop_to_name(ZFS_PROP_VOLSIZE),
+ old_volsize) != 0)
+ goto error;
+ if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
+ goto error;
+ (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
+ }
+ } else {
+ if (do_prefix)
+ ret = changelist_postfix(cl);
+
+ /*
+ * Refresh the statistics so the new property value
+ * is reflected.
+ */
+ if (ret == 0)
+ (void) get_stats(zhp);
+ }
+
+error:
+ nvlist_free(nvl);
+ zcmd_free_nvlists(&zc);
+ if (cl)
+ changelist_free(cl);
+ return (ret);
+}
+
+/*
+ * Given a property, inherit the value from the parent dataset, or if received
+ * is TRUE, revert to the received value, if any.
+ */
+int
+zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
+{
+ zfs_cmd_t zc = { 0 };
+ int ret;
+ prop_changelist_t *cl;
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
+ zfs_prop_t prop;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
+
+ zc.zc_cookie = received;
+ if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
+ /*
+ * For user properties, the amount of work we have to do is very
+ * small, so just do it here.
+ */
+ if (!zfs_prop_user(propname)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid property"));
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
+
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
+ return (zfs_standard_error(hdl, errno, errbuf));
+
+ return (0);
+ }
+
+ /*
+ * Verify that this property is inheritable.
+ */
+ if (zfs_prop_readonly(prop))
+ return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
+
+ if (!zfs_prop_inheritable(prop) && !received)
+ return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
+
+ /*
+ * Check to see if the value applies to this type
+ */
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
+ return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
+
+ /*
+ * Normalize the name, to get rid of shorthand abbreviations.
+ */
+ propname = zfs_prop_to_name(prop);
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
+
+ if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
+ zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset is used in a non-global zone"));
+ return (zfs_error(hdl, EZFS_ZONED, errbuf));
+ }
+
+ /*
+ * Determine datasets which will be affected by this change, if any.
+ */
+ if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
+ return (-1);
+
+ if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "child dataset with inherited mountpoint is used "
+ "in a non-global zone"));
+ ret = zfs_error(hdl, EZFS_ZONED, errbuf);
+ goto error;
+ }
+
+ if ((ret = changelist_prefix(cl)) != 0)
+ goto error;
+
+ if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
+ return (zfs_standard_error(hdl, errno, errbuf));
+ } else {
+
+ if ((ret = changelist_postfix(cl)) != 0)
+ goto error;
+
+ /*
+ * Refresh the statistics so the new property is reflected.
+ */
+ (void) get_stats(zhp);
+ }
+
+error:
+ changelist_free(cl);
+ return (ret);
+}
+
+/*
+ * True DSL properties are stored in an nvlist. The following two functions
+ * extract them appropriately.
+ */
+static uint64_t
+getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
+{
+ nvlist_t *nv;
+ uint64_t value;
+
+ *source = NULL;
+ if (nvlist_lookup_nvlist(zhp->zfs_props,
+ zfs_prop_to_name(prop), &nv) == 0) {
+ verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
+ (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
+ } else {
+ verify(!zhp->zfs_props_table ||
+ zhp->zfs_props_table[prop] == B_TRUE);
+ value = zfs_prop_default_numeric(prop);
+ *source = "";
+ }
+
+ return (value);
+}
+
+static char *
+getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
+{
+ nvlist_t *nv;
+ char *value;
+
+ *source = NULL;
+ if (nvlist_lookup_nvlist(zhp->zfs_props,
+ zfs_prop_to_name(prop), &nv) == 0) {
+ verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
+ (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
+ } else {
+ verify(!zhp->zfs_props_table ||
+ zhp->zfs_props_table[prop] == B_TRUE);
+ if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
+ value = "";
+ *source = "";
+ }
+
+ return (value);
+}
+
+static boolean_t
+zfs_is_recvd_props_mode(zfs_handle_t *zhp)
+{
+ return (zhp->zfs_props == zhp->zfs_recvd_props);
+}
+
+static void
+zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+{
+ *cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
+ zhp->zfs_props = zhp->zfs_recvd_props;
+}
+
+static void
+zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+{
+ zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
+ *cookie = 0;
+}
+
+/*
+ * Internal function for getting a numeric property. Both zfs_prop_get() and
+ * zfs_prop_get_int() are built using this interface.
+ *
+ * Certain properties can be overridden using 'mount -o'. In this case, scan
+ * the contents of the /etc/mnttab entry, searching for the appropriate options.
+ * If they differ from the on-disk values, report the current values and mark
+ * the source "temporary".
+ */
+static int
+get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
+ char **source, uint64_t *val)
+{
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *zplprops = NULL;
+ struct mnttab mnt;
+ char *mntopt_on = NULL;
+ char *mntopt_off = NULL;
+ boolean_t received = zfs_is_recvd_props_mode(zhp);
+
+ *source = NULL;
+
+ switch (prop) {
+ case ZFS_PROP_ATIME:
+ mntopt_on = MNTOPT_ATIME;
+ mntopt_off = MNTOPT_NOATIME;
+ break;
+
+ case ZFS_PROP_DEVICES:
+ mntopt_on = MNTOPT_DEVICES;
+ mntopt_off = MNTOPT_NODEVICES;
+ break;
+
+ case ZFS_PROP_EXEC:
+ mntopt_on = MNTOPT_EXEC;
+ mntopt_off = MNTOPT_NOEXEC;
+ break;
+
+ case ZFS_PROP_READONLY:
+ mntopt_on = MNTOPT_RO;
+ mntopt_off = MNTOPT_RW;
+ break;
+
+ case ZFS_PROP_SETUID:
+ mntopt_on = MNTOPT_SETUID;
+ mntopt_off = MNTOPT_NOSETUID;
+ break;
+
+ case ZFS_PROP_XATTR:
+ mntopt_on = MNTOPT_XATTR;
+ mntopt_off = MNTOPT_NOXATTR;
+ break;
+
+ case ZFS_PROP_NBMAND:
+ mntopt_on = MNTOPT_NBMAND;
+ mntopt_off = MNTOPT_NONBMAND;
+ break;
+ }
+
+ /*
+ * Because looking up the mount options is potentially expensive
+ * (iterating over all of /etc/mnttab), we defer its calculation until
+ * we're looking up a property which requires its presence.
+ */
+ if (!zhp->zfs_mntcheck &&
+ (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ struct mnttab entry;
+
+ if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) {
+ zhp->zfs_mntopts = zfs_strdup(hdl,
+ entry.mnt_mntopts);
+ if (zhp->zfs_mntopts == NULL)
+ return (-1);
+ }
+
+ zhp->zfs_mntcheck = B_TRUE;
+ }
+
+ if (zhp->zfs_mntopts == NULL)
+ mnt.mnt_mntopts = "";
+ else
+ mnt.mnt_mntopts = zhp->zfs_mntopts;
+
+ switch (prop) {
+ case ZFS_PROP_ATIME:
+ case ZFS_PROP_DEVICES:
+ case ZFS_PROP_EXEC:
+ case ZFS_PROP_READONLY:
+ case ZFS_PROP_SETUID:
+ case ZFS_PROP_XATTR:
+ case ZFS_PROP_NBMAND:
+ *val = getprop_uint64(zhp, prop, source);
+
+ if (received)
+ break;
+
+ if (hasmntopt(&mnt, mntopt_on) && !*val) {
+ *val = B_TRUE;
+ if (src)
+ *src = ZPROP_SRC_TEMPORARY;
+ } else if (hasmntopt(&mnt, mntopt_off) && *val) {
+ *val = B_FALSE;
+ if (src)
+ *src = ZPROP_SRC_TEMPORARY;
+ }
+ break;
+
+ case ZFS_PROP_CANMOUNT:
+ case ZFS_PROP_VOLSIZE:
+ case ZFS_PROP_QUOTA:
+ case ZFS_PROP_REFQUOTA:
+ case ZFS_PROP_RESERVATION:
+ case ZFS_PROP_REFRESERVATION:
+ *val = getprop_uint64(zhp, prop, source);
+
+ if (*source == NULL) {
+ /* not default, must be local */
+ *source = zhp->zfs_name;
+ }
+ break;
+
+ case ZFS_PROP_MOUNTED:
+ *val = (zhp->zfs_mntopts != NULL);
+ break;
+
+ case ZFS_PROP_NUMCLONES:
+ *val = zhp->zfs_dmustats.dds_num_clones;
+ break;
+
+ case ZFS_PROP_VERSION:
+ case ZFS_PROP_NORMALIZE:
+ case ZFS_PROP_UTF8ONLY:
+ case ZFS_PROP_CASE:
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) ||
+ zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
+ return (-1);
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
+ nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
+ val) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ if (zplprops)
+ nvlist_free(zplprops);
+ zcmd_free_nvlists(&zc);
+ break;
+
+ default:
+ switch (zfs_prop_get_type(prop)) {
+ case PROP_TYPE_NUMBER:
+ case PROP_TYPE_INDEX:
+ *val = getprop_uint64(zhp, prop, source);
+ /*
+ * If we tried to use a default value for a
+ * readonly property, it means that it was not
+ * present.
+ */
+ if (zfs_prop_readonly(prop) &&
+ *source != NULL && (*source)[0] == '\0') {
+ *source = NULL;
+ }
+ break;
+
+ case PROP_TYPE_STRING:
+ default:
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "cannot get non-numeric property"));
+ return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
+ dgettext(TEXT_DOMAIN, "internal error")));
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Calculate the source type, given the raw source string.
+ */
+static void
+get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
+ char *statbuf, size_t statlen)
+{
+ if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
+ return;
+
+ if (source == NULL) {
+ *srctype = ZPROP_SRC_NONE;
+ } else if (source[0] == '\0') {
+ *srctype = ZPROP_SRC_DEFAULT;
+ } else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
+ *srctype = ZPROP_SRC_RECEIVED;
+ } else {
+ if (strcmp(source, zhp->zfs_name) == 0) {
+ *srctype = ZPROP_SRC_LOCAL;
+ } else {
+ (void) strlcpy(statbuf, source, statlen);
+ *srctype = ZPROP_SRC_INHERITED;
+ }
+ }
+
+}
+
+int
+zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
+ size_t proplen, boolean_t literal)
+{
+ zfs_prop_t prop;
+ int err = 0;
+
+ if (zhp->zfs_recvd_props == NULL)
+ if (get_recvd_props_ioctl(zhp) != 0)
+ return (-1);
+
+ prop = zfs_name_to_prop(propname);
+
+ if (prop != ZPROP_INVAL) {
+ uint64_t cookie;
+ if (!nvlist_exists(zhp->zfs_recvd_props, propname))
+ return (-1);
+ zfs_set_recvd_props_mode(zhp, &cookie);
+ err = zfs_prop_get(zhp, prop, propbuf, proplen,
+ NULL, NULL, 0, literal);
+ zfs_unset_recvd_props_mode(zhp, &cookie);
+ } else {
+ nvlist_t *propval;
+ char *recvdval;
+ if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
+ propname, &propval) != 0)
+ return (-1);
+ verify(nvlist_lookup_string(propval, ZPROP_VALUE,
+ &recvdval) == 0);
+ (void) strlcpy(propbuf, recvdval, proplen);
+ }
+
+ return (err == 0 ? 0 : -1);
+}
+
+static int
+get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
+{
+ nvlist_t *value;
+ nvpair_t *pair;
+
+ value = zfs_get_clones_nvl(zhp);
+ if (value == NULL)
+ return (-1);
+
+ propbuf[0] = '\0';
+ for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
+ pair = nvlist_next_nvpair(value, pair)) {
+ if (propbuf[0] != '\0')
+ (void) strlcat(propbuf, ",", proplen);
+ (void) strlcat(propbuf, nvpair_name(pair), proplen);
+ }
+
+ return (0);
+}
+
+struct get_clones_arg {
+ uint64_t numclones;
+ nvlist_t *value;
+ const char *origin;
+ char buf[ZFS_MAXNAMELEN];
+};
+
+int
+get_clones_cb(zfs_handle_t *zhp, void *arg)
+{
+ struct get_clones_arg *gca = arg;
+
+ if (gca->numclones == 0) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
+ NULL, NULL, 0, B_TRUE) != 0)
+ goto out;
+ if (strcmp(gca->buf, gca->origin) == 0) {
+ fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
+ gca->numclones--;
+ }
+
+out:
+ (void) zfs_iter_children(zhp, get_clones_cb, gca);
+ zfs_close(zhp);
+ return (0);
+}
+
+nvlist_t *
+zfs_get_clones_nvl(zfs_handle_t *zhp)
+{
+ nvlist_t *nv, *value;
+
+ if (nvlist_lookup_nvlist(zhp->zfs_props,
+ zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
+ struct get_clones_arg gca;
+
+ /*
+ * if this is a snapshot, then the kernel wasn't able
+ * to get the clones. Do it by slowly iterating.
+ */
+ if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
+ return (NULL);
+ if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
+ return (NULL);
+ if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
+ nvlist_free(nv);
+ return (NULL);
+ }
+
+ gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
+ gca.value = value;
+ gca.origin = zhp->zfs_name;
+
+ if (gca.numclones != 0) {
+ zfs_handle_t *root;
+ char pool[ZFS_MAXNAMELEN];
+ char *cp = pool;
+
+ /* get the pool name */
+ (void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
+ (void) strsep(&cp, "/@");
+ root = zfs_open(zhp->zfs_hdl, pool,
+ ZFS_TYPE_FILESYSTEM);
+
+ (void) get_clones_cb(root, &gca);
+ }
+
+ if (gca.numclones != 0 ||
+ nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
+ nvlist_add_nvlist(zhp->zfs_props,
+ zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
+ nvlist_free(nv);
+ nvlist_free(value);
+ return (NULL);
+ }
+ nvlist_free(nv);
+ nvlist_free(value);
+ verify(0 == nvlist_lookup_nvlist(zhp->zfs_props,
+ zfs_prop_to_name(ZFS_PROP_CLONES), &nv));
+ }
+
+ verify(nvlist_lookup_nvlist(nv, ZPROP_VALUE, &value) == 0);
+
+ return (value);
+}
+
+/*
+ * Retrieve a property from the given object. If 'literal' is specified, then
+ * numbers are left as exact values. Otherwise, numbers are converted to a
+ * human-readable form.
+ *
+ * Returns 0 on success, or -1 on error.
+ */
+int
+zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
+ zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
+{
+ char *source = NULL;
+ uint64_t val;
+ char *str;
+ const char *strval;
+ boolean_t received = zfs_is_recvd_props_mode(zhp);
+
+ /*
+ * Check to see if this property applies to our object
+ */
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
+ return (-1);
+
+ if (received && zfs_prop_readonly(prop))
+ return (-1);
+
+ if (src)
+ *src = ZPROP_SRC_NONE;
+
+ switch (prop) {
+ case ZFS_PROP_CREATION:
+ /*
+ * 'creation' is a time_t stored in the statistics. We convert
+ * this into a string unless 'literal' is specified.
+ */
+ {
+ val = getprop_uint64(zhp, prop, &source);
+ time_t time = (time_t)val;
+ struct tm t;
+
+ if (literal ||
+ localtime_r(&time, &t) == NULL ||
+ strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
+ &t) == 0)
+ (void) snprintf(propbuf, proplen, "%llu", val);
+ }
+ break;
+
+ case ZFS_PROP_MOUNTPOINT:
+ /*
+ * Getting the precise mountpoint can be tricky.
+ *
+ * - for 'none' or 'legacy', return those values.
+ * - for inherited mountpoints, we want to take everything
+ * after our ancestor and append it to the inherited value.
+ *
+ * If the pool has an alternate root, we want to prepend that
+ * root to any values we return.
+ */
+
+ str = getprop_string(zhp, prop, &source);
+
+ if (str[0] == '/') {
+ char buf[MAXPATHLEN];
+ char *root = buf;
+ const char *relpath;
+
+ /*
+ * If we inherit the mountpoint, even from a dataset
+ * with a received value, the source will be the path of
+ * the dataset we inherit from. If source is
+ * ZPROP_SOURCE_VAL_RECVD, the received value is not
+ * inherited.
+ */
+ if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
+ relpath = "";
+ } else {
+ relpath = zhp->zfs_name + strlen(source);
+ if (relpath[0] == '/')
+ relpath++;
+ }
+
+ if ((zpool_get_prop(zhp->zpool_hdl,
+ ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) ||
+ (strcmp(root, "-") == 0))
+ root[0] = '\0';
+ /*
+ * Special case an alternate root of '/'. This will
+ * avoid having multiple leading slashes in the
+ * mountpoint path.
+ */
+ if (strcmp(root, "/") == 0)
+ root++;
+
+ /*
+ * If the mountpoint is '/' then skip over this
+ * if we are obtaining either an alternate root or
+ * an inherited mountpoint.
+ */
+ if (str[1] == '\0' && (root[0] != '\0' ||
+ relpath[0] != '\0'))
+ str++;
+
+ if (relpath[0] == '\0')
+ (void) snprintf(propbuf, proplen, "%s%s",
+ root, str);
+ else
+ (void) snprintf(propbuf, proplen, "%s%s%s%s",
+ root, str, relpath[0] == '@' ? "" : "/",
+ relpath);
+ } else {
+ /* 'legacy' or 'none' */
+ (void) strlcpy(propbuf, str, proplen);
+ }
+
+ break;
+
+ case ZFS_PROP_ORIGIN:
+ (void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
+ proplen);
+ /*
+ * If there is no parent at all, return failure to indicate that
+ * it doesn't apply to this dataset.
+ */
+ if (propbuf[0] == '\0')
+ return (-1);
+ break;
+
+ case ZFS_PROP_CLONES:
+ if (get_clones_string(zhp, propbuf, proplen) != 0)
+ return (-1);
+ break;
+
+ case ZFS_PROP_QUOTA:
+ case ZFS_PROP_REFQUOTA:
+ case ZFS_PROP_RESERVATION:
+ case ZFS_PROP_REFRESERVATION:
+
+ if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
+ return (-1);
+
+ /*
+ * If quota or reservation is 0, we translate this into 'none'
+ * (unless literal is set), and indicate that it's the default
+ * value. Otherwise, we print the number nicely and indicate
+ * that its set locally.
+ */
+ if (val == 0) {
+ if (literal)
+ (void) strlcpy(propbuf, "0", proplen);
+ else
+ (void) strlcpy(propbuf, "none", proplen);
+ } else {
+ if (literal)
+ (void) snprintf(propbuf, proplen, "%llu",
+ (u_longlong_t)val);
+ else
+ zfs_nicenum(val, propbuf, proplen);
+ }
+ break;
+
+ case ZFS_PROP_REFRATIO:
+ case ZFS_PROP_COMPRESSRATIO:
+ if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
+ return (-1);
+ (void) snprintf(propbuf, proplen, "%llu.%02llux",
+ (u_longlong_t)(val / 100),
+ (u_longlong_t)(val % 100));
+ break;
+
+ case ZFS_PROP_TYPE:
+ switch (zhp->zfs_type) {
+ case ZFS_TYPE_FILESYSTEM:
+ str = "filesystem";
+ break;
+ case ZFS_TYPE_VOLUME:
+ str = "volume";
+ break;
+ case ZFS_TYPE_SNAPSHOT:
+ str = "snapshot";
+ break;
+ default:
+ abort();
+ }
+ (void) snprintf(propbuf, proplen, "%s", str);
+ break;
+
+ case ZFS_PROP_MOUNTED:
+ /*
+ * The 'mounted' property is a pseudo-property that described
+ * whether the filesystem is currently mounted. Even though
+ * it's a boolean value, the typical values of "on" and "off"
+ * don't make sense, so we translate to "yes" and "no".
+ */
+ if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
+ src, &source, &val) != 0)
+ return (-1);
+ if (val)
+ (void) strlcpy(propbuf, "yes", proplen);
+ else
+ (void) strlcpy(propbuf, "no", proplen);
+ break;
+
+ case ZFS_PROP_NAME:
+ /*
+ * The 'name' property is a pseudo-property derived from the
+ * dataset name. It is presented as a real property to simplify
+ * consumers.
+ */
+ (void) strlcpy(propbuf, zhp->zfs_name, proplen);
+ break;
+
+ case ZFS_PROP_MLSLABEL:
+ {
+#ifdef sun
+ m_label_t *new_sl = NULL;
+ char *ascii = NULL; /* human readable label */
+
+ (void) strlcpy(propbuf,
+ getprop_string(zhp, prop, &source), proplen);
+
+ if (literal || (strcasecmp(propbuf,
+ ZFS_MLSLABEL_DEFAULT) == 0))
+ break;
+
+ /*
+ * Try to translate the internal hex string to
+ * human-readable output. If there are any
+ * problems just use the hex string.
+ */
+
+ if (str_to_label(propbuf, &new_sl, MAC_LABEL,
+ L_NO_CORRECTION, NULL) == -1) {
+ m_label_free(new_sl);
+ break;
+ }
+
+ if (label_to_str(new_sl, &ascii, M_LABEL,
+ DEF_NAMES) != 0) {
+ if (ascii)
+ free(ascii);
+ m_label_free(new_sl);
+ break;
+ }
+ m_label_free(new_sl);
+
+ (void) strlcpy(propbuf, ascii, proplen);
+ free(ascii);
+#else /* !sun */
+ propbuf[0] = '\0';
+#endif /* !sun */
+ }
+ break;
+
+ case ZFS_PROP_GUID:
+ /*
+ * GUIDs are stored as numbers, but they are identifiers.
+ * We don't want them to be pretty printed, because pretty
+ * printing mangles the ID into a truncated and useless value.
+ */
+ if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
+ return (-1);
+ (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
+ break;
+
+ default:
+ switch (zfs_prop_get_type(prop)) {
+ case PROP_TYPE_NUMBER:
+ if (get_numeric_property(zhp, prop, src,
+ &source, &val) != 0)
+ return (-1);
+ if (literal)
+ (void) snprintf(propbuf, proplen, "%llu",
+ (u_longlong_t)val);
+ else
+ zfs_nicenum(val, propbuf, proplen);
+ break;
+
+ case PROP_TYPE_STRING:
+ (void) strlcpy(propbuf,
+ getprop_string(zhp, prop, &source), proplen);
+ break;
+
+ case PROP_TYPE_INDEX:
+ if (get_numeric_property(zhp, prop, src,
+ &source, &val) != 0)
+ return (-1);
+ if (zfs_prop_index_to_string(prop, val, &strval) != 0)
+ return (-1);
+ (void) strlcpy(propbuf, strval, proplen);
+ break;
+
+ default:
+ abort();
+ }
+ }
+
+ get_source(zhp, src, source, statbuf, statlen);
+
+ return (0);
+}
+
+/*
+ * Utility function to get the given numeric property. Does no validation that
+ * the given property is the appropriate type; should only be used with
+ * hard-coded property types.
+ */
+uint64_t
+zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
+{
+ char *source;
+ uint64_t val;
+
+ (void) get_numeric_property(zhp, prop, NULL, &source, &val);
+
+ return (val);
+}
+
+int
+zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
+{
+ char buf[64];
+
+ (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
+ return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
+}
+
+/*
+ * Similar to zfs_prop_get(), but returns the value as an integer.
+ */
+int
+zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
+ zprop_source_t *src, char *statbuf, size_t statlen)
+{
+ char *source;
+
+ /*
+ * Check to see if this property applies to our object
+ */
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) {
+ return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
+ dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
+ zfs_prop_to_name(prop)));
+ }
+
+ if (src)
+ *src = ZPROP_SRC_NONE;
+
+ if (get_numeric_property(zhp, prop, src, &source, value) != 0)
+ return (-1);
+
+ get_source(zhp, src, source, statbuf, statlen);
+
+ return (0);
+}
+
+static int
+idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
+ char **domainp, idmap_rid_t *ridp)
+{
+#ifdef sun
+ idmap_get_handle_t *get_hdl = NULL;
+ idmap_stat status;
+ int err = EINVAL;
+
+ if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
+ goto out;
+
+ if (isuser) {
+ err = idmap_get_sidbyuid(get_hdl, id,
+ IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
+ } else {
+ err = idmap_get_sidbygid(get_hdl, id,
+ IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
+ }
+ if (err == IDMAP_SUCCESS &&
+ idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
+ status == IDMAP_SUCCESS)
+ err = 0;
+ else
+ err = EINVAL;
+out:
+ if (get_hdl)
+ idmap_get_destroy(get_hdl);
+ return (err);
+#else /* !sun */
+ assert(!"invalid code path");
+#endif /* !sun */
+}
+
+/*
+ * convert the propname into parameters needed by kernel
+ * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
+ * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
+ */
+static int
+userquota_propname_decode(const char *propname, boolean_t zoned,
+ zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
+{
+ zfs_userquota_prop_t type;
+ char *cp, *end;
+ char *numericsid = NULL;
+ boolean_t isuser;
+
+ domain[0] = '\0';
+
+ /* Figure out the property type ({user|group}{quota|space}) */
+ for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
+ if (strncmp(propname, zfs_userquota_prop_prefixes[type],
+ strlen(zfs_userquota_prop_prefixes[type])) == 0)
+ break;
+ }
+ if (type == ZFS_NUM_USERQUOTA_PROPS)
+ return (EINVAL);
+ *typep = type;
+
+ isuser = (type == ZFS_PROP_USERQUOTA ||
+ type == ZFS_PROP_USERUSED);
+
+ cp = strchr(propname, '@') + 1;
+
+ if (strchr(cp, '@')) {
+#ifdef sun
+ /*
+ * It's a SID name (eg "user@domain") that needs to be
+ * turned into S-1-domainID-RID.
+ */
+ directory_error_t e;
+ if (zoned && getzoneid() == GLOBAL_ZONEID)
+ return (ENOENT);
+ if (isuser) {
+ e = directory_sid_from_user_name(NULL,
+ cp, &numericsid);
+ } else {
+ e = directory_sid_from_group_name(NULL,
+ cp, &numericsid);
+ }
+ if (e != NULL) {
+ directory_error_free(e);
+ return (ENOENT);
+ }
+ if (numericsid == NULL)
+ return (ENOENT);
+ cp = numericsid;
+ /* will be further decoded below */
+#else /* !sun */
+ return (ENOENT);
+#endif /* !sun */
+ }
+
+ if (strncmp(cp, "S-1-", 4) == 0) {
+ /* It's a numeric SID (eg "S-1-234-567-89") */
+ (void) strlcpy(domain, cp, domainlen);
+ cp = strrchr(domain, '-');
+ *cp = '\0';
+ cp++;
+
+ errno = 0;
+ *ridp = strtoull(cp, &end, 10);
+ if (numericsid) {
+ free(numericsid);
+ numericsid = NULL;
+ }
+ if (errno != 0 || *end != '\0')
+ return (EINVAL);
+ } else if (!isdigit(*cp)) {
+ /*
+ * It's a user/group name (eg "user") that needs to be
+ * turned into a uid/gid
+ */
+ if (zoned && getzoneid() == GLOBAL_ZONEID)
+ return (ENOENT);
+ if (isuser) {
+ struct passwd *pw;
+ pw = getpwnam(cp);
+ if (pw == NULL)
+ return (ENOENT);
+ *ridp = pw->pw_uid;
+ } else {
+ struct group *gr;
+ gr = getgrnam(cp);
+ if (gr == NULL)
+ return (ENOENT);
+ *ridp = gr->gr_gid;
+ }
+ } else {
+ /* It's a user/group ID (eg "12345"). */
+ uid_t id = strtoul(cp, &end, 10);
+ idmap_rid_t rid;
+ char *mapdomain;
+
+ if (*end != '\0')
+ return (EINVAL);
+ if (id > MAXUID) {
+ /* It's an ephemeral ID. */
+ if (idmap_id_to_numeric_domain_rid(id, isuser,
+ &mapdomain, &rid) != 0)
+ return (ENOENT);
+ (void) strlcpy(domain, mapdomain, domainlen);
+ *ridp = rid;
+ } else {
+ *ridp = id;
+ }
+ }
+
+ ASSERT3P(numericsid, ==, NULL);
+ return (0);
+}
+
+static int
+zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
+ uint64_t *propvalue, zfs_userquota_prop_t *typep)
+{
+ int err;
+ zfs_cmd_t zc = { 0 };
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ err = userquota_propname_decode(propname,
+ zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
+ typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
+ zc.zc_objset_type = *typep;
+ if (err)
+ return (err);
+
+ err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_USERSPACE_ONE, &zc);
+ if (err)
+ return (err);
+
+ *propvalue = zc.zc_cookie;
+ return (0);
+}
+
+int
+zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
+ uint64_t *propvalue)
+{
+ zfs_userquota_prop_t type;
+
+ return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
+ &type));
+}
+
+int
+zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
+ char *propbuf, int proplen, boolean_t literal)
+{
+ int err;
+ uint64_t propvalue;
+ zfs_userquota_prop_t type;
+
+ err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
+ &type);
+
+ if (err)
+ return (err);
+
+ if (literal) {
+ (void) snprintf(propbuf, proplen, "%llu", propvalue);
+ } else if (propvalue == 0 &&
+ (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA)) {
+ (void) strlcpy(propbuf, "none", proplen);
+ } else {
+ zfs_nicenum(propvalue, propbuf, proplen);
+ }
+ return (0);
+}
+
+int
+zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
+ uint64_t *propvalue)
+{
+ int err;
+ zfs_cmd_t zc = { 0 };
+ const char *snapname;
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ snapname = strchr(propname, '@') + 1;
+ if (strchr(snapname, '@')) {
+ (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
+ } else {
+ /* snapname is the short name, append it to zhp's fsname */
+ char *cp;
+
+ (void) strlcpy(zc.zc_value, zhp->zfs_name,
+ sizeof (zc.zc_value));
+ cp = strchr(zc.zc_value, '@');
+ if (cp != NULL)
+ *cp = '\0';
+ (void) strlcat(zc.zc_value, "@", sizeof (zc.zc_value));
+ (void) strlcat(zc.zc_value, snapname, sizeof (zc.zc_value));
+ }
+
+ err = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_WRITTEN, &zc);
+ if (err)
+ return (err);
+
+ *propvalue = zc.zc_cookie;
+ return (0);
+}
+
+int
+zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
+ char *propbuf, int proplen, boolean_t literal)
+{
+ int err;
+ uint64_t propvalue;
+
+ err = zfs_prop_get_written_int(zhp, propname, &propvalue);
+
+ if (err)
+ return (err);
+
+ if (literal) {
+ (void) snprintf(propbuf, proplen, "%llu", propvalue);
+ } else {
+ zfs_nicenum(propvalue, propbuf, proplen);
+ }
+ return (0);
+}
+
+/*
+ * Returns the name of the given zfs handle.
+ */
+const char *
+zfs_get_name(const zfs_handle_t *zhp)
+{
+ return (zhp->zfs_name);
+}
+
+/*
+ * Returns the type of the given zfs handle.
+ */
+zfs_type_t
+zfs_get_type(const zfs_handle_t *zhp)
+{
+ return (zhp->zfs_type);
+}
+
+/*
+ * Is one dataset name a child dataset of another?
+ *
+ * Needs to handle these cases:
+ * Dataset 1 "a/foo" "a/foo" "a/foo" "a/foo"
+ * Dataset 2 "a/fo" "a/foobar" "a/bar/baz" "a/foo/bar"
+ * Descendant? No. No. No. Yes.
+ */
+static boolean_t
+is_descendant(const char *ds1, const char *ds2)
+{
+ size_t d1len = strlen(ds1);
+
+ /* ds2 can't be a descendant if it's smaller */
+ if (strlen(ds2) < d1len)
+ return (B_FALSE);
+
+ /* otherwise, compare strings and verify that there's a '/' char */
+ return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
+}
+
+/*
+ * Given a complete name, return just the portion that refers to the parent.
+ * Will return -1 if there is no parent (path is just the name of the
+ * pool).
+ */
+static int
+parent_name(const char *path, char *buf, size_t buflen)
+{
+ char *slashp;
+
+ (void) strlcpy(buf, path, buflen);
+
+ if ((slashp = strrchr(buf, '/')) == NULL)
+ return (-1);
+ *slashp = '\0';
+
+ return (0);
+}
+
+/*
+ * If accept_ancestor is false, then check to make sure that the given path has
+ * a parent, and that it exists. If accept_ancestor is true, then find the
+ * closest existing ancestor for the given path. In prefixlen return the
+ * length of already existing prefix of the given path. We also fetch the
+ * 'zoned' property, which is used to validate property settings when creating
+ * new datasets.
+ */
+static int
+check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
+ boolean_t accept_ancestor, int *prefixlen)
+{
+ zfs_cmd_t zc = { 0 };
+ char parent[ZFS_MAXNAMELEN];
+ char *slash;
+ zfs_handle_t *zhp;
+ char errbuf[1024];
+ uint64_t is_zoned;
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
+
+ /* get parent, and check to see if this is just a pool */
+ if (parent_name(path, parent, sizeof (parent)) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "missing dataset name"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
+ /* check to see if the pool exists */
+ if ((slash = strchr(parent, '/')) == NULL)
+ slash = parent + strlen(parent);
+ (void) strncpy(zc.zc_name, parent, slash - parent);
+ zc.zc_name[slash - parent] = '\0';
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
+ errno == ENOENT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "no such pool '%s'"), zc.zc_name);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ }
+
+ /* check to see if the parent dataset exists */
+ while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
+ if (errno == ENOENT && accept_ancestor) {
+ /*
+ * Go deeper to find an ancestor, give up on top level.
+ */
+ if (parent_name(parent, parent, sizeof (parent)) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "no such pool '%s'"), zc.zc_name);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ }
+ } else if (errno == ENOENT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "parent does not exist"));
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ } else
+ return (zfs_standard_error(hdl, errno, errbuf));
+ }
+
+ is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
+ if (zoned != NULL)
+ *zoned = is_zoned;
+
+ /* we are in a non-global zone, but parent is in the global zone */
+ if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
+ (void) zfs_standard_error(hdl, EPERM, errbuf);
+ zfs_close(zhp);
+ return (-1);
+ }
+
+ /* make sure parent is a filesystem */
+ if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "parent is not a filesystem"));
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ zfs_close(zhp);
+ return (-1);
+ }
+
+ zfs_close(zhp);
+ if (prefixlen != NULL)
+ *prefixlen = strlen(parent);
+ return (0);
+}
+
+/*
+ * Finds whether the dataset of the given type(s) exists.
+ */
+boolean_t
+zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
+{
+ zfs_handle_t *zhp;
+
+ if (!zfs_validate_name(hdl, path, types, B_FALSE))
+ return (B_FALSE);
+
+ /*
+ * Try to get stats for the dataset, which will tell us if it exists.
+ */
+ if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
+ int ds_type = zhp->zfs_type;
+
+ zfs_close(zhp);
+ if (types & ds_type)
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
+/*
+ * Given a path to 'target', create all the ancestors between
+ * the prefixlen portion of the path, and the target itself.
+ * Fail if the initial prefixlen-ancestor does not already exist.
+ */
+int
+create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
+{
+ zfs_handle_t *h;
+ char *cp;
+ const char *opname;
+
+ /* make sure prefix exists */
+ cp = target + prefixlen;
+ if (*cp != '/') {
+ assert(strchr(cp, '/') == NULL);
+ h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
+ } else {
+ *cp = '\0';
+ h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
+ *cp = '/';
+ }
+ if (h == NULL)
+ return (-1);
+ zfs_close(h);
+
+ /*
+ * Attempt to create, mount, and share any ancestor filesystems,
+ * up to the prefixlen-long one.
+ */
+ for (cp = target + prefixlen + 1;
+ cp = strchr(cp, '/'); *cp = '/', cp++) {
+
+ *cp = '\0';
+
+ h = make_dataset_handle(hdl, target);
+ if (h) {
+ /* it already exists, nothing to do here */
+ zfs_close(h);
+ continue;
+ }
+
+ if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
+ NULL) != 0) {
+ opname = dgettext(TEXT_DOMAIN, "create");
+ goto ancestorerr;
+ }
+
+ h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
+ if (h == NULL) {
+ opname = dgettext(TEXT_DOMAIN, "open");
+ goto ancestorerr;
+ }
+
+ if (zfs_mount(h, NULL, 0) != 0) {
+ opname = dgettext(TEXT_DOMAIN, "mount");
+ goto ancestorerr;
+ }
+
+ if (zfs_share(h) != 0) {
+ opname = dgettext(TEXT_DOMAIN, "share");
+ goto ancestorerr;
+ }
+
+ zfs_close(h);
+ }
+
+ return (0);
+
+ancestorerr:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "failed to %s ancestor '%s'"), opname, target);
+ return (-1);
+}
+
+/*
+ * Creates non-existing ancestors of the given path.
+ */
+int
+zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
+{
+ int prefix;
+ char *path_copy;
+ int rc;
+
+ if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
+ return (-1);
+
+ if ((path_copy = strdup(path)) != NULL) {
+ rc = create_parents(hdl, path_copy, prefix);
+ free(path_copy);
+ }
+ if (path_copy == NULL || rc != 0)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Create a new filesystem or volume.
+ */
+int
+zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
+ nvlist_t *props)
+{
+ int ret;
+ uint64_t size = 0;
+ uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
+ char errbuf[1024];
+ uint64_t zoned;
+ dmu_objset_type_t ost;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot create '%s'"), path);
+
+ /* validate the path, taking care to note the extended error message */
+ if (!zfs_validate_name(hdl, path, type, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+
+ /* validate parents exist */
+ if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
+ return (-1);
+
+ /*
+ * The failure modes when creating a dataset of a different type over
+ * one that already exists is a little strange. In particular, if you
+ * try to create a dataset on top of an existing dataset, the ioctl()
+ * will return ENOENT, not EEXIST. To prevent this from happening, we
+ * first try to see if the dataset exists.
+ */
+ if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset already exists"));
+ return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+ }
+
+ if (type == ZFS_TYPE_VOLUME)
+ ost = DMU_OST_ZVOL;
+ else
+ ost = DMU_OST_ZFS;
+
+ if (props && (props = zfs_valid_proplist(hdl, type, props,
+ zoned, NULL, errbuf)) == 0)
+ return (-1);
+
+ if (type == ZFS_TYPE_VOLUME) {
+ /*
+ * If we are creating a volume, the size and block size must
+ * satisfy a few restraints. First, the blocksize must be a
+ * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the
+ * volsize must be a multiple of the block size, and cannot be
+ * zero.
+ */
+ if (props == NULL || nvlist_lookup_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
+ nvlist_free(props);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "missing volume size"));
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+
+ if ((ret = nvlist_lookup_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+ &blocksize)) != 0) {
+ if (ret == ENOENT) {
+ blocksize = zfs_prop_default_numeric(
+ ZFS_PROP_VOLBLOCKSIZE);
+ } else {
+ nvlist_free(props);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "missing volume block size"));
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+ }
+
+ if (size == 0) {
+ nvlist_free(props);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "volume size cannot be zero"));
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+
+ if (size % blocksize != 0) {
+ nvlist_free(props);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "volume size must be a multiple of volume block "
+ "size"));
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+ }
+ }
+
+ /* create the dataset */
+ ret = lzc_create(path, ost, props);
+ nvlist_free(props);
+
+ /* check for failure */
+ if (ret != 0) {
+ char parent[ZFS_MAXNAMELEN];
+ (void) parent_name(path, parent, sizeof (parent));
+
+ switch (errno) {
+ case ENOENT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "no such parent '%s'"), parent);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+
+ case EINVAL:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "parent '%s' is not a filesystem"), parent);
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+
+ case EDOM:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "volume block size must be power of 2 from "
+ "%u to %uk"),
+ (uint_t)SPA_MINBLOCKSIZE,
+ (uint_t)SPA_MAXBLOCKSIZE >> 10);
+
+ return (zfs_error(hdl, EZFS_BADPROP, errbuf));
+
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded to set this "
+ "property or value"));
+ return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
+#ifdef _ILP32
+ case EOVERFLOW:
+ /*
+ * This platform can't address a volume this big.
+ */
+ if (type == ZFS_TYPE_VOLUME)
+ return (zfs_error(hdl, EZFS_VOLTOOBIG,
+ errbuf));
+#endif
+ /* FALLTHROUGH */
+ default:
+ return (zfs_standard_error(hdl, errno, errbuf));
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Destroys the given dataset. The caller must make sure that the filesystem
+ * isn't mounted, and that there are no active dependents. If the file system
+ * does not exist this function does nothing.
+ */
+int
+zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
+{
+ zfs_cmd_t zc = { 0 };
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ if (ZFS_IS_VOLUME(zhp)) {
+ zc.zc_objset_type = DMU_OST_ZVOL;
+ } else {
+ zc.zc_objset_type = DMU_OST_ZFS;
+ }
+
+ zc.zc_defer_destroy = defer;
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0 &&
+ errno != ENOENT) {
+ return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
+ dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
+ zhp->zfs_name));
+ }
+
+ remove_mountpoint(zhp);
+
+ return (0);
+}
+
+struct destroydata {
+ nvlist_t *nvl;
+ const char *snapname;
+};
+
+static int
+zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
+{
+ struct destroydata *dd = arg;
+ zfs_handle_t *szhp;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zhp->zfs_name, dd->snapname);
+
+ szhp = make_dataset_handle(zhp->zfs_hdl, name);
+ if (szhp) {
+ verify(nvlist_add_boolean(dd->nvl, name) == 0);
+ zfs_close(szhp);
+ }
+
+ rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
+ zfs_close(zhp);
+ return (rv);
+}
+
+/*
+ * Destroys all snapshots with the given name in zhp & descendants.
+ */
+int
+zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
+{
+ int ret;
+ struct destroydata dd = { 0 };
+
+ dd.snapname = snapname;
+ verify(nvlist_alloc(&dd.nvl, NV_UNIQUE_NAME, 0) == 0);
+ (void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
+
+ if (nvlist_next_nvpair(dd.nvl, NULL) == NULL) {
+ ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
+ dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
+ zhp->zfs_name, snapname);
+ } else {
+ ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
+ }
+ nvlist_free(dd.nvl);
+ return (ret);
+}
+
+/*
+ * Destroys all the snapshots named in the nvlist.
+ */
+int
+zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
+{
+ int ret;
+ nvlist_t *errlist;
+
+ ret = lzc_destroy_snaps(snaps, defer, &errlist);
+
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errlist, NULL) == NULL) {
+ char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
+
+ ret = zfs_standard_error(hdl, ret, errbuf);
+ }
+ for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL);
+ pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
+ char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
+ nvpair_name(pair));
+
+ switch (fnvpair_value_int32(pair)) {
+ case EEXIST:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "snapshot is cloned"));
+ ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
+ break;
+ default:
+ ret = zfs_standard_error(hdl, errno, errbuf);
+ break;
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * Clones the given dataset. The target must be of the same type as the source.
+ */
+int
+zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
+{
+ char parent[ZFS_MAXNAMELEN];
+ int ret;
+ char errbuf[1024];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ uint64_t zoned;
+
+ assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot create '%s'"), target);
+
+ /* validate the target/clone name */
+ if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+
+ /* validate parents exist */
+ if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
+ return (-1);
+
+ (void) parent_name(target, parent, sizeof (parent));
+
+ /* do the clone */
+
+ if (props) {
+ zfs_type_t type;
+ if (ZFS_IS_VOLUME(zhp)) {
+ type = ZFS_TYPE_VOLUME;
+ } else {
+ type = ZFS_TYPE_FILESYSTEM;
+ }
+ if ((props = zfs_valid_proplist(hdl, type, props, zoned,
+ zhp, errbuf)) == NULL)
+ return (-1);
+ }
+
+ ret = lzc_clone(target, zhp->zfs_name, props);
+ nvlist_free(props);
+
+ if (ret != 0) {
+ switch (errno) {
+
+ case ENOENT:
+ /*
+ * The parent doesn't exist. We should have caught this
+ * above, but there may a race condition that has since
+ * destroyed the parent.
+ *
+ * At this point, we don't know whether it's the source
+ * that doesn't exist anymore, or whether the target
+ * dataset doesn't exist.
+ */
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "no such parent '%s'"), parent);
+ return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
+
+ case EXDEV:
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "source and target pools differ"));
+ return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
+ errbuf));
+
+ default:
+ return (zfs_standard_error(zhp->zfs_hdl, errno,
+ errbuf));
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * Promotes the given clone fs to be the clone parent.
+ */
+int
+zfs_promote(zfs_handle_t *zhp)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zfs_cmd_t zc = { 0 };
+ char parent[MAXPATHLEN];
+ int ret;
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot promote '%s'"), zhp->zfs_name);
+
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "snapshots can not be promoted"));
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ }
+
+ (void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent));
+ if (parent[0] == '\0') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "not a cloned filesystem"));
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ }
+
+ (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin,
+ sizeof (zc.zc_value));
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
+
+ if (ret != 0) {
+ int save_errno = errno;
+
+ switch (save_errno) {
+ case EEXIST:
+ /* There is a conflicting snapshot name. */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "conflicting snapshot '%s' from parent '%s'"),
+ zc.zc_string, parent);
+ return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+
+ default:
+ return (zfs_standard_error(hdl, save_errno, errbuf));
+ }
+ }
+ return (ret);
+}
+
+typedef struct snapdata {
+ nvlist_t *sd_nvl;
+ const char *sd_snapname;
+} snapdata_t;
+
+static int
+zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
+{
+ snapdata_t *sd = arg;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+
+ fnvlist_add_boolean(sd->sd_nvl, name);
+
+ rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ zfs_close(zhp);
+ return (rv);
+}
+
+/*
+ * Creates snapshots. The keys in the snaps nvlist are the snapshots to be
+ * created.
+ */
+int
+zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
+{
+ int ret;
+ char errbuf[1024];
+ nvpair_t *elem;
+ nvlist_t *errors;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot create snapshots "));
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
+ const char *snapname = nvpair_name(elem);
+
+ /* validate the target name */
+ if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
+ B_TRUE)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot create snapshot '%s'"), snapname);
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+ }
+
+ if (props != NULL &&
+ (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
+ props, B_FALSE, NULL, errbuf)) == NULL) {
+ return (-1);
+ }
+
+ ret = lzc_snapshot(snaps, props, &errors);
+
+ if (ret != 0) {
+ boolean_t printed = B_FALSE;
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot create snapshot '%s'"), nvpair_name(elem));
+ (void) zfs_standard_error(hdl,
+ fnvpair_value_int32(elem), errbuf);
+ printed = B_TRUE;
+ }
+ if (!printed) {
+ switch (ret) {
+ case EXDEV:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "multiple snapshots of same "
+ "fs not allowed"));
+ (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
+
+ break;
+ default:
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ }
+ }
+ }
+
+ nvlist_free(props);
+ nvlist_free(errors);
+ return (ret);
+}
+
+int
+zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
+ nvlist_t *props)
+{
+ int ret;
+ snapdata_t sd = { 0 };
+ char fsname[ZFS_MAXNAMELEN];
+ char *cp;
+ zfs_handle_t *zhp;
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot snapshot %s"), path);
+
+ if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+
+ (void) strlcpy(fsname, path, sizeof (fsname));
+ cp = strchr(fsname, '@');
+ *cp = '\0';
+ sd.sd_snapname = cp + 1;
+
+ if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
+ ZFS_TYPE_VOLUME)) == NULL) {
+ return (-1);
+ }
+
+ verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
+ if (recursive) {
+ (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
+ } else {
+ fnvlist_add_boolean(sd.sd_nvl, path);
+ }
+
+ ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
+ nvlist_free(sd.sd_nvl);
+ zfs_close(zhp);
+ return (ret);
+}
+
+/*
+ * Destroy any more recent snapshots. We invoke this callback on any dependents
+ * of the snapshot first. If the 'cb_dependent' member is non-zero, then this
+ * is a dependent and we should just destroy it without checking the transaction
+ * group.
+ */
+typedef struct rollback_data {
+ const char *cb_target; /* the snapshot */
+ uint64_t cb_create; /* creation time reference */
+ boolean_t cb_error;
+ boolean_t cb_dependent;
+ boolean_t cb_force;
+} rollback_data_t;
+
+static int
+rollback_destroy(zfs_handle_t *zhp, void *data)
+{
+ rollback_data_t *cbp = data;
+
+ if (!cbp->cb_dependent) {
+ if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
+ zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
+ zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
+ cbp->cb_create) {
+
+ cbp->cb_dependent = B_TRUE;
+ cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
+ rollback_destroy, cbp);
+ cbp->cb_dependent = B_FALSE;
+
+ cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
+ }
+ } else {
+ /* We must destroy this clone; first unmount it */
+ prop_changelist_t *clp;
+
+ clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
+ cbp->cb_force ? MS_FORCE: 0);
+ if (clp == NULL || changelist_prefix(clp) != 0) {
+ cbp->cb_error = B_TRUE;
+ zfs_close(zhp);
+ return (0);
+ }
+ if (zfs_destroy(zhp, B_FALSE) != 0)
+ cbp->cb_error = B_TRUE;
+ else
+ changelist_remove(clp, zhp->zfs_name);
+ (void) changelist_postfix(clp);
+ changelist_free(clp);
+ }
+
+ zfs_close(zhp);
+ return (0);
+}
+
+/*
+ * Given a dataset, rollback to a specific snapshot, discarding any
+ * data changes since then and making it the active dataset.
+ *
+ * Any snapshots more recent than the target are destroyed, along with
+ * their dependents.
+ */
+int
+zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
+{
+ rollback_data_t cb = { 0 };
+ int err;
+ zfs_cmd_t zc = { 0 };
+ boolean_t restore_resv = 0;
+ uint64_t old_volsize, new_volsize;
+ zfs_prop_t resv_prop;
+
+ assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
+ zhp->zfs_type == ZFS_TYPE_VOLUME);
+
+ /*
+ * Destroy all recent snapshots and their dependents.
+ */
+ cb.cb_force = force;
+ cb.cb_target = snap->zfs_name;
+ cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
+ (void) zfs_iter_children(zhp, rollback_destroy, &cb);
+
+ if (cb.cb_error)
+ return (-1);
+
+ /*
+ * Now that we have verified that the snapshot is the latest,
+ * rollback to the given snapshot.
+ */
+
+ if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
+ if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
+ return (-1);
+ old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
+ restore_resv =
+ (old_volsize == zfs_prop_get_int(zhp, resv_prop));
+ }
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ if (ZFS_IS_VOLUME(zhp))
+ zc.zc_objset_type = DMU_OST_ZVOL;
+ else
+ zc.zc_objset_type = DMU_OST_ZFS;
+
+ /*
+ * We rely on zfs_iter_children() to verify that there are no
+ * newer snapshots for the given dataset. Therefore, we can
+ * simply pass the name on to the ioctl() call. There is still
+ * an unlikely race condition where the user has taken a
+ * snapshot since we verified that this was the most recent.
+ *
+ */
+ if ((err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_ROLLBACK, &zc)) != 0) {
+ (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
+ dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
+ zhp->zfs_name);
+ return (err);
+ }
+
+ /*
+ * For volumes, if the pre-rollback volsize matched the pre-
+ * rollback reservation and the volsize has changed then set
+ * the reservation property to the post-rollback volsize.
+ * Make a new handle since the rollback closed the dataset.
+ */
+ if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
+ (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
+ if (restore_resv) {
+ new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
+ if (old_volsize != new_volsize)
+ err = zfs_prop_set_int(zhp, resv_prop,
+ new_volsize);
+ }
+ zfs_close(zhp);
+ }
+ return (err);
+}
+
+/*
+ * Renames the given dataset.
+ */
+int
+zfs_rename(zfs_handle_t *zhp, const char *source, const char *target,
+ renameflags_t flags)
+{
+ int ret;
+ zfs_cmd_t zc = { 0 };
+ char *delim;
+ prop_changelist_t *cl = NULL;
+ zfs_handle_t *zhrp = NULL;
+ char *parentname = NULL;
+ char parent[ZFS_MAXNAMELEN];
+ char property[ZFS_MAXPROPLEN];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
+
+ /* if we have the same exact name, just return success */
+ if (strcmp(zhp->zfs_name, target) == 0)
+ return (0);
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot rename to '%s'"), target);
+
+ if (source != NULL) {
+ /*
+ * This is recursive snapshots rename, put snapshot name
+ * (that might not exist) into zfs_name.
+ */
+ assert(flags.recurse);
+
+ (void) strlcat(zhp->zfs_name, "@", sizeof(zhp->zfs_name));
+ (void) strlcat(zhp->zfs_name, source, sizeof(zhp->zfs_name));
+ zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
+ }
+
+ /*
+ * Make sure the target name is valid
+ */
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
+ if ((strchr(target, '@') == NULL) ||
+ *target == '@') {
+ /*
+ * Snapshot target name is abbreviated,
+ * reconstruct full dataset name
+ */
+ (void) strlcpy(parent, zhp->zfs_name,
+ sizeof (parent));
+ delim = strchr(parent, '@');
+ if (strchr(target, '@') == NULL)
+ *(++delim) = '\0';
+ else
+ *delim = '\0';
+ (void) strlcat(parent, target, sizeof (parent));
+ target = parent;
+ } else {
+ /*
+ * Make sure we're renaming within the same dataset.
+ */
+ delim = strchr(target, '@');
+ if (strncmp(zhp->zfs_name, target, delim - target)
+ != 0 || zhp->zfs_name[delim - target] != '@') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "snapshots must be part of same "
+ "dataset"));
+ return (zfs_error(hdl, EZFS_CROSSTARGET,
+ errbuf));
+ }
+ }
+ if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ } else {
+ if (flags.recurse) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "recursive rename must be a snapshot"));
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ }
+
+ if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+
+ /* validate parents */
+ if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
+ return (-1);
+
+ /* make sure we're in the same pool */
+ verify((delim = strchr(target, '/')) != NULL);
+ if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
+ zhp->zfs_name[delim - target] != '/') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "datasets must be within same pool"));
+ return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
+ }
+
+ /* new name cannot be a child of the current dataset name */
+ if (is_descendant(zhp->zfs_name, target)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "New dataset name cannot be a descendant of "
+ "current dataset name"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+ }
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
+
+ if (getzoneid() == GLOBAL_ZONEID &&
+ zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset is used in a non-global zone"));
+ return (zfs_error(hdl, EZFS_ZONED, errbuf));
+ }
+
+ /*
+ * Avoid unmounting file systems with mountpoint property set to
+ * 'legacy' or 'none' even if -u option is not given.
+ */
+ if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
+ !flags.recurse && !flags.nounmount &&
+ zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
+ sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
+ (strcmp(property, "legacy") == 0 ||
+ strcmp(property, "none") == 0)) {
+ flags.nounmount = B_TRUE;
+ }
+
+ if (flags.recurse) {
+
+ parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
+ if (parentname == NULL) {
+ ret = -1;
+ goto error;
+ }
+ delim = strchr(parentname, '@');
+ *delim = '\0';
+ zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
+ if (zhrp == NULL) {
+ ret = -1;
+ goto error;
+ }
+
+ } else {
+ if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
+ flags.nounmount ? CL_GATHER_DONT_UNMOUNT : 0,
+ flags.forceunmount ? MS_FORCE : 0)) == NULL) {
+ return (-1);
+ }
+
+ if (changelist_haszonedchild(cl)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "child dataset with inherited mountpoint is used "
+ "in a non-global zone"));
+ (void) zfs_error(hdl, EZFS_ZONED, errbuf);
+ goto error;
+ }
+
+ if ((ret = changelist_prefix(cl)) != 0)
+ goto error;
+ }
+
+ if (ZFS_IS_VOLUME(zhp))
+ zc.zc_objset_type = DMU_OST_ZVOL;
+ else
+ zc.zc_objset_type = DMU_OST_ZFS;
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
+
+ zc.zc_cookie = flags.recurse ? 1 : 0;
+ if (flags.nounmount)
+ zc.zc_cookie |= 2;
+
+ if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
+ /*
+ * if it was recursive, the one that actually failed will
+ * be in zc.zc_name
+ */
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot rename '%s'"), zc.zc_name);
+
+ if (flags.recurse && errno == EEXIST) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "a child dataset already has a snapshot "
+ "with the new name"));
+ (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
+ } else {
+ (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
+ }
+
+ /*
+ * On failure, we still want to remount any filesystems that
+ * were previously mounted, so we don't alter the system state.
+ */
+ if (!flags.recurse)
+ (void) changelist_postfix(cl);
+ } else {
+ if (!flags.recurse) {
+ changelist_rename(cl, zfs_get_name(zhp), target);
+ ret = changelist_postfix(cl);
+ }
+ }
+
+error:
+ if (parentname) {
+ free(parentname);
+ }
+ if (zhrp) {
+ zfs_close(zhrp);
+ }
+ if (cl) {
+ changelist_free(cl);
+ }
+ return (ret);
+}
+
+nvlist_t *
+zfs_get_user_props(zfs_handle_t *zhp)
+{
+ return (zhp->zfs_user_props);
+}
+
+nvlist_t *
+zfs_get_recvd_props(zfs_handle_t *zhp)
+{
+ if (zhp->zfs_recvd_props == NULL)
+ if (get_recvd_props_ioctl(zhp) != 0)
+ return (NULL);
+ return (zhp->zfs_recvd_props);
+}
+
+/*
+ * This function is used by 'zfs list' to determine the exact set of columns to
+ * display, and their maximum widths. This does two main things:
+ *
+ * - If this is a list of all properties, then expand the list to include
+ * all native properties, and set a flag so that for each dataset we look
+ * for new unique user properties and add them to the list.
+ *
+ * - For non fixed-width properties, keep track of the maximum width seen
+ * so that we can size the column appropriately. If the user has
+ * requested received property values, we also need to compute the width
+ * of the RECEIVED column.
+ */
+int
+zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zprop_list_t *entry;
+ zprop_list_t **last, **start;
+ nvlist_t *userprops, *propval;
+ nvpair_t *elem;
+ char *strval;
+ char buf[ZFS_MAXPROPLEN];
+
+ if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
+ return (-1);
+
+ userprops = zfs_get_user_props(zhp);
+
+ entry = *plp;
+ if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
+ /*
+ * Go through and add any user properties as necessary. We
+ * start by incrementing our list pointer to the first
+ * non-native property.
+ */
+ start = plp;
+ while (*start != NULL) {
+ if ((*start)->pl_prop == ZPROP_INVAL)
+ break;
+ start = &(*start)->pl_next;
+ }
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
+ /*
+ * See if we've already found this property in our list.
+ */
+ for (last = start; *last != NULL;
+ last = &(*last)->pl_next) {
+ if (strcmp((*last)->pl_user_prop,
+ nvpair_name(elem)) == 0)
+ break;
+ }
+
+ if (*last == NULL) {
+ if ((entry = zfs_alloc(hdl,
+ sizeof (zprop_list_t))) == NULL ||
+ ((entry->pl_user_prop = zfs_strdup(hdl,
+ nvpair_name(elem)))) == NULL) {
+ free(entry);
+ return (-1);
+ }
+
+ entry->pl_prop = ZPROP_INVAL;
+ entry->pl_width = strlen(nvpair_name(elem));
+ entry->pl_all = B_TRUE;
+ *last = entry;
+ }
+ }
+ }
+
+ /*
+ * Now go through and check the width of any non-fixed columns
+ */
+ for (entry = *plp; entry != NULL; entry = entry->pl_next) {
+ if (entry->pl_fixed)
+ continue;
+
+ if (entry->pl_prop != ZPROP_INVAL) {
+ if (zfs_prop_get(zhp, entry->pl_prop,
+ buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
+ if (strlen(buf) > entry->pl_width)
+ entry->pl_width = strlen(buf);
+ }
+ if (received && zfs_prop_get_recvd(zhp,
+ zfs_prop_to_name(entry->pl_prop),
+ buf, sizeof (buf), B_FALSE) == 0)
+ if (strlen(buf) > entry->pl_recvd_width)
+ entry->pl_recvd_width = strlen(buf);
+ } else {
+ if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
+ &propval) == 0) {
+ verify(nvlist_lookup_string(propval,
+ ZPROP_VALUE, &strval) == 0);
+ if (strlen(strval) > entry->pl_width)
+ entry->pl_width = strlen(strval);
+ }
+ if (received && zfs_prop_get_recvd(zhp,
+ entry->pl_user_prop,
+ buf, sizeof (buf), B_FALSE) == 0)
+ if (strlen(buf) > entry->pl_recvd_width)
+ entry->pl_recvd_width = strlen(buf);
+ }
+ }
+
+ return (0);
+}
+
+int
+zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
+ char *resource, void *export, void *sharetab,
+ int sharemax, zfs_share_op_t operation)
+{
+ zfs_cmd_t zc = { 0 };
+ int error;
+
+ (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
+ if (resource)
+ (void) strlcpy(zc.zc_string, resource, sizeof (zc.zc_string));
+ zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab;
+ zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export;
+ zc.zc_share.z_sharetype = operation;
+ zc.zc_share.z_sharemax = sharemax;
+ error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc);
+ return (error);
+}
+
+void
+zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
+{
+ nvpair_t *curr;
+
+ /*
+ * Keep a reference to the props-table against which we prune the
+ * properties.
+ */
+ zhp->zfs_props_table = props;
+
+ curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
+
+ while (curr) {
+ zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
+ nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
+
+ /*
+ * User properties will result in ZPROP_INVAL, and since we
+ * only know how to prune standard ZFS properties, we always
+ * leave these in the list. This can also happen if we
+ * encounter an unknown DSL property (when running older
+ * software, for example).
+ */
+ if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
+ (void) nvlist_remove(zhp->zfs_props,
+ nvpair_name(curr), nvpair_type(curr));
+ curr = next;
+ }
+}
+
+#ifdef sun
+static int
+zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
+ zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
+{
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *nvlist = NULL;
+ int error;
+
+ (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
+ zc.zc_cookie = (uint64_t)cmd;
+
+ if (cmd == ZFS_SMB_ACL_RENAME) {
+ if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+ }
+
+ switch (cmd) {
+ case ZFS_SMB_ACL_ADD:
+ case ZFS_SMB_ACL_REMOVE:
+ (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
+ break;
+ case ZFS_SMB_ACL_RENAME:
+ if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
+ resource1) != 0) {
+ (void) no_memory(hdl);
+ return (-1);
+ }
+ if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
+ resource2) != 0) {
+ (void) no_memory(hdl);
+ return (-1);
+ }
+ if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) {
+ nvlist_free(nvlist);
+ return (-1);
+ }
+ break;
+ case ZFS_SMB_ACL_PURGE:
+ break;
+ default:
+ return (-1);
+ }
+ error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
+ if (nvlist)
+ nvlist_free(nvlist);
+ return (error);
+}
+
+int
+zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
+ char *path, char *resource)
+{
+ return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
+ resource, NULL));
+}
+
+int
+zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
+ char *path, char *resource)
+{
+ return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
+ resource, NULL));
+}
+
+int
+zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
+{
+ return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
+ NULL, NULL));
+}
+
+int
+zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
+ char *oldname, char *newname)
+{
+ return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
+ oldname, newname));
+}
+#endif /* sun */
+
+int
+zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
+ zfs_userspace_cb_t func, void *arg)
+{
+ zfs_cmd_t zc = { 0 };
+ zfs_useracct_t buf[100];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ int ret;
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ zc.zc_objset_type = type;
+ zc.zc_nvlist_dst = (uintptr_t)buf;
+
+ for (;;) {
+ zfs_useracct_t *zua = buf;
+
+ zc.zc_nvlist_dst_size = sizeof (buf);
+ if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot get used/quota for %s"), zc.zc_name);
+ return (zfs_standard_error_fmt(hdl, errno, errbuf));
+ }
+ if (zc.zc_nvlist_dst_size == 0)
+ break;
+
+ while (zc.zc_nvlist_dst_size > 0) {
+ if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
+ zua->zu_space)) != 0)
+ return (ret);
+ zua++;
+ zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
+ }
+ }
+
+ return (0);
+}
+
+struct holdarg {
+ nvlist_t *nvl;
+ const char *snapname;
+ const char *tag;
+ boolean_t recursive;
+};
+
+static int
+zfs_hold_one(zfs_handle_t *zhp, void *arg)
+{
+ struct holdarg *ha = arg;
+ zfs_handle_t *szhp;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zhp->zfs_name, ha->snapname);
+
+ szhp = make_dataset_handle(zhp->zfs_hdl, name);
+ if (szhp) {
+ fnvlist_add_string(ha->nvl, name, ha->tag);
+ zfs_close(szhp);
+ }
+
+ if (ha->recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
+ zfs_close(zhp);
+ return (rv);
+}
+
+int
+zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
+ boolean_t recursive, boolean_t enoent_ok, int cleanup_fd)
+{
+ int ret;
+ struct holdarg ha;
+ nvlist_t *errors;
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char errbuf[1024];
+ nvpair_t *elem;
+
+ ha.nvl = fnvlist_alloc();
+ ha.snapname = snapname;
+ ha.tag = tag;
+ ha.recursive = recursive;
+ (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
+ ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
+ fnvlist_free(ha.nvl);
+
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ /* no hold-specific errors */
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot hold"));
+ switch (ret) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error(hdl, ret, errbuf);
+ }
+ }
+
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot hold snapshot '%s'"), nvpair_name(elem));
+ switch (fnvpair_value_int32(elem)) {
+ case E2BIG:
+ /*
+ * Temporary tags wind up having the ds object id
+ * prepended. So even if we passed the length check
+ * above, it's still possible for the tag to wind
+ * up being slightly too long.
+ */
+ (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ case EEXIST:
+ (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
+ break;
+ case ENOENT:
+ if (enoent_ok)
+ return (ENOENT);
+ /* FALLTHROUGH */
+ default:
+ (void) zfs_standard_error(hdl,
+ fnvpair_value_int32(elem), errbuf);
+ }
+ }
+
+ fnvlist_free(errors);
+ return (ret);
+}
+
+struct releasearg {
+ nvlist_t *nvl;
+ const char *snapname;
+ const char *tag;
+ boolean_t recursive;
+};
+
+static int
+zfs_release_one(zfs_handle_t *zhp, void *arg)
+{
+ struct holdarg *ha = arg;
+ zfs_handle_t *szhp;
+ char name[ZFS_MAXNAMELEN];
+ int rv = 0;
+
+ (void) snprintf(name, sizeof (name),
+ "%s@%s", zhp->zfs_name, ha->snapname);
+
+ szhp = make_dataset_handle(zhp->zfs_hdl, name);
+ if (szhp) {
+ nvlist_t *holds = fnvlist_alloc();
+ fnvlist_add_boolean(holds, ha->tag);
+ fnvlist_add_nvlist(ha->nvl, name, holds);
+ zfs_close(szhp);
+ }
+
+ if (ha->recursive)
+ rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
+ zfs_close(zhp);
+ return (rv);
+}
+
+int
+zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
+ boolean_t recursive)
+{
+ int ret;
+ struct holdarg ha;
+ nvlist_t *errors;
+ nvpair_t *elem;
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+
+ ha.nvl = fnvlist_alloc();
+ ha.snapname = snapname;
+ ha.tag = tag;
+ ha.recursive = recursive;
+ (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
+ ret = lzc_release(ha.nvl, &errors);
+ fnvlist_free(ha.nvl);
+
+ if (ret == 0)
+ return (0);
+
+ if (nvlist_next_nvpair(errors, NULL) == NULL) {
+ /* no hold-specific errors */
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot release"));
+ switch (errno) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error_fmt(hdl, errno, errbuf);
+ }
+ }
+
+ for (elem = nvlist_next_nvpair(errors, NULL);
+ elem != NULL;
+ elem = nvlist_next_nvpair(errors, elem)) {
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot release hold from snapshot '%s'"),
+ nvpair_name(elem));
+ switch (fnvpair_value_int32(elem)) {
+ case ESRCH:
+ (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error_fmt(hdl,
+ fnvpair_value_int32(elem), errbuf);
+ }
+ }
+
+ fnvlist_free(errors);
+ return (ret);
+}
+
+int
+zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ int nvsz = 2048;
+ void *nvbuf;
+ int err = 0;
+ char errbuf[1024];
+
+ assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
+ zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
+
+tryagain:
+
+ nvbuf = malloc(nvsz);
+ if (nvbuf == NULL) {
+ err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
+ goto out;
+ }
+
+ zc.zc_nvlist_dst_size = nvsz;
+ zc.zc_nvlist_dst = (uintptr_t)nvbuf;
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN);
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
+ zc.zc_name);
+ switch (errno) {
+ case ENOMEM:
+ free(nvbuf);
+ nvsz = zc.zc_nvlist_dst_size;
+ goto tryagain;
+
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ case ENOENT:
+ err = zfs_error(hdl, EZFS_NOENT, errbuf);
+ break;
+ default:
+ err = zfs_standard_error_fmt(hdl, errno, errbuf);
+ break;
+ }
+ } else {
+ /* success */
+ int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
+ if (rc) {
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(
+ TEXT_DOMAIN, "cannot get permissions on '%s'"),
+ zc.zc_name);
+ err = zfs_standard_error_fmt(hdl, rc, errbuf);
+ }
+ }
+
+ free(nvbuf);
+out:
+ return (err);
+}
+
+int
+zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ char *nvbuf;
+ char errbuf[1024];
+ size_t nvsz;
+ int err;
+
+ assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
+ zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
+
+ err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
+ assert(err == 0);
+
+ nvbuf = malloc(nvsz);
+
+ err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
+ assert(err == 0);
+
+ zc.zc_nvlist_src_size = nvsz;
+ zc.zc_nvlist_src = (uintptr_t)nvbuf;
+ zc.zc_perm_action = un;
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
+ zc.zc_name);
+ switch (errno) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ case ENOENT:
+ err = zfs_error(hdl, EZFS_NOENT, errbuf);
+ break;
+ default:
+ err = zfs_standard_error_fmt(hdl, errno, errbuf);
+ break;
+ }
+ }
+
+ free(nvbuf);
+
+ return (err);
+}
+
+int
+zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
+{
+ int err;
+ char errbuf[1024];
+
+ err = lzc_get_holds(zhp->zfs_name, nvl);
+
+ if (err != 0) {
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
+ zhp->zfs_name);
+ switch (err) {
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded"));
+ err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EINVAL:
+ err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
+ break;
+ case ENOENT:
+ err = zfs_error(hdl, EZFS_NOENT, errbuf);
+ break;
+ default:
+ err = zfs_standard_error_fmt(hdl, errno, errbuf);
+ break;
+ }
+ }
+
+ return (err);
+}
+
+uint64_t
+zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
+{
+ uint64_t numdb;
+ uint64_t nblocks, volblocksize;
+ int ncopies;
+ char *strval;
+
+ if (nvlist_lookup_string(props,
+ zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
+ ncopies = atoi(strval);
+ else
+ ncopies = 1;
+ if (nvlist_lookup_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+ &volblocksize) != 0)
+ volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
+ nblocks = volsize/volblocksize;
+ /* start with metadnode L0-L6 */
+ numdb = 7;
+ /* calculate number of indirects */
+ while (nblocks > 1) {
+ nblocks += DNODES_PER_LEVEL - 1;
+ nblocks /= DNODES_PER_LEVEL;
+ numdb += nblocks;
+ }
+ numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
+ volsize *= ncopies;
+ /*
+ * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
+ * compressed, but in practice they compress down to about
+ * 1100 bytes
+ */
+ numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
+ volsize += numdb;
+ return (volsize);
+}
+
+/*
+ * Attach/detach the given filesystem to/from the given jail.
+ */
+int
+zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zfs_cmd_t zc = { 0 };
+ char errbuf[1024];
+ unsigned long cmd;
+ int ret;
+
+ if (attach) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
+ } else {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
+ }
+
+ switch (zhp->zfs_type) {
+ case ZFS_TYPE_VOLUME:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "volumes can not be jailed"));
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ case ZFS_TYPE_SNAPSHOT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "snapshots can not be jailed"));
+ return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
+ }
+ assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ zc.zc_objset_type = DMU_OST_ZFS;
+ zc.zc_jailid = jailid;
+
+ cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
+ if ((ret = ioctl(hdl->libzfs_fd, cmd, &zc)) != 0)
+ zfs_standard_error(hdl, errno, errbuf);
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c
new file mode 100644
index 0000000..ab2007d
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c
@@ -0,0 +1,834 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * zfs diff support
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <libintl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/zfs_ioctl.h>
+#include <libzfs.h>
+#include "libzfs_impl.h"
+
+#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
+#define ZDIFF_SHARESDIR "/.zfs/shares/"
+#define ZDIFF_PREFIX "zfs-diff-%d"
+
+#define ZDIFF_ADDED '+'
+#define ZDIFF_MODIFIED 'M'
+#define ZDIFF_REMOVED '-'
+#define ZDIFF_RENAMED 'R'
+
+static boolean_t
+do_name_cmp(const char *fpath, const char *tpath)
+{
+ char *fname, *tname;
+ fname = strrchr(fpath, '/') + 1;
+ tname = strrchr(tpath, '/') + 1;
+ return (strcmp(fname, tname) == 0);
+}
+
+typedef struct differ_info {
+ zfs_handle_t *zhp;
+ char *fromsnap;
+ char *frommnt;
+ char *tosnap;
+ char *tomnt;
+ char *ds;
+ char *dsmnt;
+ char *tmpsnap;
+ char errbuf[1024];
+ boolean_t isclone;
+ boolean_t scripted;
+ boolean_t classify;
+ boolean_t timestamped;
+ uint64_t shares;
+ int zerr;
+ int cleanupfd;
+ int outputfd;
+ int datafd;
+} differ_info_t;
+
+/*
+ * Given a {dsname, object id}, get the object path
+ */
+static int
+get_stats_for_obj(differ_info_t *di, const char *dsname, uint64_t obj,
+ char *pn, int maxlen, zfs_stat_t *sb)
+{
+ zfs_cmd_t zc = { 0 };
+ int error;
+
+ (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
+ zc.zc_obj = obj;
+
+ errno = 0;
+ error = ioctl(di->zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_STATS, &zc);
+ di->zerr = errno;
+
+ /* we can get stats even if we failed to get a path */
+ (void) memcpy(sb, &zc.zc_stat, sizeof (zfs_stat_t));
+ if (error == 0) {
+ ASSERT(di->zerr == 0);
+ (void) strlcpy(pn, zc.zc_value, maxlen);
+ return (0);
+ }
+
+ if (di->zerr == EPERM) {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "The sys_config privilege or diff delegated permission "
+ "is needed\nto discover path names"));
+ return (-1);
+ } else {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Unable to determine path or stats for "
+ "object %lld in %s"), obj, dsname);
+ return (-1);
+ }
+}
+
+/*
+ * stream_bytes
+ *
+ * Prints a file name out a character at a time. If the character is
+ * not in the range of what we consider "printable" ASCII, display it
+ * as an escaped 3-digit octal value. ASCII values less than a space
+ * are all control characters and we declare the upper end as the
+ * DELete character. This also is the last 7-bit ASCII character.
+ * We choose to treat all 8-bit ASCII as not printable for this
+ * application.
+ */
+static void
+stream_bytes(FILE *fp, const char *string)
+{
+ while (*string) {
+ if (*string > ' ' && *string != '\\' && *string < '\177')
+ (void) fprintf(fp, "%c", *string++);
+ else {
+ (void) fprintf(fp, "\\%03hho",
+ (unsigned char)*string++);
+ }
+ }
+}
+
+static void
+print_what(FILE *fp, mode_t what)
+{
+ char symbol;
+
+ switch (what & S_IFMT) {
+ case S_IFBLK:
+ symbol = 'B';
+ break;
+ case S_IFCHR:
+ symbol = 'C';
+ break;
+ case S_IFDIR:
+ symbol = '/';
+ break;
+#ifdef S_IFDOOR
+ case S_IFDOOR:
+ symbol = '>';
+ break;
+#endif
+ case S_IFIFO:
+ symbol = '|';
+ break;
+ case S_IFLNK:
+ symbol = '@';
+ break;
+#ifdef S_IFPORT
+ case S_IFPORT:
+ symbol = 'P';
+ break;
+#endif
+ case S_IFSOCK:
+ symbol = '=';
+ break;
+ case S_IFREG:
+ symbol = 'F';
+ break;
+ default:
+ symbol = '?';
+ break;
+ }
+ (void) fprintf(fp, "%c", symbol);
+}
+
+static void
+print_cmn(FILE *fp, differ_info_t *di, const char *file)
+{
+ stream_bytes(fp, di->dsmnt);
+ stream_bytes(fp, file);
+}
+
+static void
+print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
+ zfs_stat_t *isb)
+{
+ if (di->timestamped)
+ (void) fprintf(fp, "%10lld.%09lld\t",
+ (longlong_t)isb->zs_ctime[0],
+ (longlong_t)isb->zs_ctime[1]);
+ (void) fprintf(fp, "%c\t", ZDIFF_RENAMED);
+ if (di->classify) {
+ print_what(fp, isb->zs_mode);
+ (void) fprintf(fp, "\t");
+ }
+ print_cmn(fp, di, old);
+ if (di->scripted)
+ (void) fprintf(fp, "\t");
+ else
+ (void) fprintf(fp, " -> ");
+ print_cmn(fp, di, new);
+ (void) fprintf(fp, "\n");
+}
+
+static void
+print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
+ zfs_stat_t *isb)
+{
+ if (di->timestamped)
+ (void) fprintf(fp, "%10lld.%09lld\t",
+ (longlong_t)isb->zs_ctime[0],
+ (longlong_t)isb->zs_ctime[1]);
+ (void) fprintf(fp, "%c\t", ZDIFF_MODIFIED);
+ if (di->classify) {
+ print_what(fp, isb->zs_mode);
+ (void) fprintf(fp, "\t");
+ }
+ print_cmn(fp, di, file);
+ (void) fprintf(fp, "\t(%+d)", delta);
+ (void) fprintf(fp, "\n");
+}
+
+static void
+print_file(FILE *fp, differ_info_t *di, char type, const char *file,
+ zfs_stat_t *isb)
+{
+ if (di->timestamped)
+ (void) fprintf(fp, "%10lld.%09lld\t",
+ (longlong_t)isb->zs_ctime[0],
+ (longlong_t)isb->zs_ctime[1]);
+ (void) fprintf(fp, "%c\t", type);
+ if (di->classify) {
+ print_what(fp, isb->zs_mode);
+ (void) fprintf(fp, "\t");
+ }
+ print_cmn(fp, di, file);
+ (void) fprintf(fp, "\n");
+}
+
+static int
+write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
+{
+ struct zfs_stat fsb, tsb;
+ boolean_t same_name;
+ mode_t fmode, tmode;
+ char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
+ int fobjerr, tobjerr;
+ int change;
+
+ if (dobj == di->shares)
+ return (0);
+
+ /*
+ * Check the from and to snapshots for info on the object. If
+ * we get ENOENT, then the object just didn't exist in that
+ * snapshot. If we get ENOTSUP, then we tried to get
+ * info on a non-ZPL object, which we don't care about anyway.
+ */
+ fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname,
+ MAXPATHLEN, &fsb);
+ if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
+ return (-1);
+
+ tobjerr = get_stats_for_obj(di, di->tosnap, dobj, tobjname,
+ MAXPATHLEN, &tsb);
+ if (tobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
+ return (-1);
+
+ /*
+ * Unallocated object sharing the same meta dnode block
+ */
+ if (fobjerr && tobjerr) {
+ ASSERT(di->zerr == ENOENT || di->zerr == ENOTSUP);
+ di->zerr = 0;
+ return (0);
+ }
+
+ di->zerr = 0; /* negate get_stats_for_obj() from side that failed */
+ fmode = fsb.zs_mode & S_IFMT;
+ tmode = tsb.zs_mode & S_IFMT;
+ if (fmode == S_IFDIR || tmode == S_IFDIR || fsb.zs_links == 0 ||
+ tsb.zs_links == 0)
+ change = 0;
+ else
+ change = tsb.zs_links - fsb.zs_links;
+
+ if (fobjerr) {
+ if (change) {
+ print_link_change(fp, di, change, tobjname, &tsb);
+ return (0);
+ }
+ print_file(fp, di, ZDIFF_ADDED, tobjname, &tsb);
+ return (0);
+ } else if (tobjerr) {
+ if (change) {
+ print_link_change(fp, di, change, fobjname, &fsb);
+ return (0);
+ }
+ print_file(fp, di, ZDIFF_REMOVED, fobjname, &fsb);
+ return (0);
+ }
+
+ if (fmode != tmode && fsb.zs_gen == tsb.zs_gen)
+ tsb.zs_gen++; /* Force a generational difference */
+ same_name = do_name_cmp(fobjname, tobjname);
+
+ /* Simple modification or no change */
+ if (fsb.zs_gen == tsb.zs_gen) {
+ /* No apparent changes. Could we assert !this? */
+ if (fsb.zs_ctime[0] == tsb.zs_ctime[0] &&
+ fsb.zs_ctime[1] == tsb.zs_ctime[1])
+ return (0);
+ if (change) {
+ print_link_change(fp, di, change,
+ change > 0 ? fobjname : tobjname, &tsb);
+ } else if (same_name) {
+ print_file(fp, di, ZDIFF_MODIFIED, fobjname, &tsb);
+ } else {
+ print_rename(fp, di, fobjname, tobjname, &tsb);
+ }
+ return (0);
+ } else {
+ /* file re-created or object re-used */
+ print_file(fp, di, ZDIFF_REMOVED, fobjname, &fsb);
+ print_file(fp, di, ZDIFF_ADDED, tobjname, &tsb);
+ return (0);
+ }
+}
+
+static int
+write_inuse_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
+{
+ uint64_t o;
+ int err;
+
+ for (o = dr->ddr_first; o <= dr->ddr_last; o++) {
+ if (err = write_inuse_diffs_one(fp, di, o))
+ return (err);
+ }
+ return (0);
+}
+
+static int
+describe_free(FILE *fp, differ_info_t *di, uint64_t object, char *namebuf,
+ int maxlen)
+{
+ struct zfs_stat sb;
+
+ if (get_stats_for_obj(di, di->fromsnap, object, namebuf,
+ maxlen, &sb) != 0) {
+ /* Let it slide, if in the delete queue on from side */
+ if (di->zerr == ENOENT && sb.zs_links == 0) {
+ di->zerr = 0;
+ return (0);
+ }
+ return (-1);
+ }
+
+ print_file(fp, di, ZDIFF_REMOVED, namebuf, &sb);
+ return (0);
+}
+
+static int
+write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *lhdl = di->zhp->zfs_hdl;
+ char fobjname[MAXPATHLEN];
+
+ (void) strlcpy(zc.zc_name, di->fromsnap, sizeof (zc.zc_name));
+ zc.zc_obj = dr->ddr_first - 1;
+
+ ASSERT(di->zerr == 0);
+
+ while (zc.zc_obj < dr->ddr_last) {
+ int err;
+
+ err = ioctl(lhdl->libzfs_fd, ZFS_IOC_NEXT_OBJ, &zc);
+ if (err == 0) {
+ if (zc.zc_obj == di->shares) {
+ zc.zc_obj++;
+ continue;
+ }
+ if (zc.zc_obj > dr->ddr_last) {
+ break;
+ }
+ err = describe_free(fp, di, zc.zc_obj, fobjname,
+ MAXPATHLEN);
+ if (err)
+ break;
+ } else if (errno == ESRCH) {
+ break;
+ } else {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "next allocated object (> %lld) find failure"),
+ zc.zc_obj);
+ di->zerr = errno;
+ break;
+ }
+ }
+ if (di->zerr)
+ return (-1);
+ return (0);
+}
+
+static void *
+differ(void *arg)
+{
+ differ_info_t *di = arg;
+ dmu_diff_record_t dr;
+ FILE *ofp;
+ int err = 0;
+
+ if ((ofp = fdopen(di->outputfd, "w")) == NULL) {
+ di->zerr = errno;
+ (void) strerror_r(errno, di->errbuf, sizeof (di->errbuf));
+ (void) close(di->datafd);
+ return ((void *)-1);
+ }
+
+ for (;;) {
+ char *cp = (char *)&dr;
+ int len = sizeof (dr);
+ int rv;
+
+ do {
+ rv = read(di->datafd, cp, len);
+ cp += rv;
+ len -= rv;
+ } while (len > 0 && rv > 0);
+
+ if (rv < 0 || (rv == 0 && len != sizeof (dr))) {
+ di->zerr = EPIPE;
+ break;
+ } else if (rv == 0) {
+ /* end of file at a natural breaking point */
+ break;
+ }
+
+ switch (dr.ddr_type) {
+ case DDR_FREE:
+ err = write_free_diffs(ofp, di, &dr);
+ break;
+ case DDR_INUSE:
+ err = write_inuse_diffs(ofp, di, &dr);
+ break;
+ default:
+ di->zerr = EPIPE;
+ break;
+ }
+
+ if (err || di->zerr)
+ break;
+ }
+
+ (void) fclose(ofp);
+ (void) close(di->datafd);
+ if (err)
+ return ((void *)-1);
+ if (di->zerr) {
+ ASSERT(di->zerr == EINVAL);
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Internal error: bad data from diff IOCTL"));
+ return ((void *)-1);
+ }
+ return ((void *)0);
+}
+
+static int
+find_shares_object(differ_info_t *di)
+{
+ char fullpath[MAXPATHLEN];
+ struct stat64 sb = { 0 };
+
+ (void) strlcpy(fullpath, di->dsmnt, MAXPATHLEN);
+ (void) strlcat(fullpath, ZDIFF_SHARESDIR, MAXPATHLEN);
+
+ if (stat64(fullpath, &sb) != 0) {
+#ifdef sun
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN, "Cannot stat %s"), fullpath);
+ return (zfs_error(di->zhp->zfs_hdl, EZFS_DIFF, di->errbuf));
+#else
+ return (0);
+#endif
+ }
+
+ di->shares = (uint64_t)sb.st_ino;
+ return (0);
+}
+
+static int
+make_temp_snapshot(differ_info_t *di)
+{
+ libzfs_handle_t *hdl = di->zhp->zfs_hdl;
+ zfs_cmd_t zc = { 0 };
+
+ (void) snprintf(zc.zc_value, sizeof (zc.zc_value),
+ ZDIFF_PREFIX, getpid());
+ (void) strlcpy(zc.zc_name, di->ds, sizeof (zc.zc_name));
+ zc.zc_cleanup_fd = di->cleanupfd;
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_TMP_SNAPSHOT, &zc) != 0) {
+ int err = errno;
+ if (err == EPERM) {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN, "The diff delegated "
+ "permission is needed in order\nto create a "
+ "just-in-time snapshot for diffing\n"));
+ return (zfs_error(hdl, EZFS_DIFF, di->errbuf));
+ } else {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN, "Cannot create just-in-time "
+ "snapshot of '%s'"), zc.zc_name);
+ return (zfs_standard_error(hdl, err, di->errbuf));
+ }
+ }
+
+ di->tmpsnap = zfs_strdup(hdl, zc.zc_value);
+ di->tosnap = zfs_asprintf(hdl, "%s@%s", di->ds, di->tmpsnap);
+ return (0);
+}
+
+static void
+teardown_differ_info(differ_info_t *di)
+{
+ free(di->ds);
+ free(di->dsmnt);
+ free(di->fromsnap);
+ free(di->frommnt);
+ free(di->tosnap);
+ free(di->tmpsnap);
+ free(di->tomnt);
+ (void) close(di->cleanupfd);
+}
+
+static int
+get_snapshot_names(differ_info_t *di, const char *fromsnap,
+ const char *tosnap)
+{
+ libzfs_handle_t *hdl = di->zhp->zfs_hdl;
+ char *atptrf = NULL;
+ char *atptrt = NULL;
+ int fdslen, fsnlen;
+ int tdslen, tsnlen;
+
+ /*
+ * Can accept
+ * dataset@snap1
+ * dataset@snap1 dataset@snap2
+ * dataset@snap1 @snap2
+ * dataset@snap1 dataset
+ * @snap1 dataset@snap2
+ */
+ if (tosnap == NULL) {
+ /* only a from snapshot given, must be valid */
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Badly formed snapshot name %s"), fromsnap);
+
+ if (!zfs_validate_name(hdl, fromsnap, ZFS_TYPE_SNAPSHOT,
+ B_FALSE)) {
+ return (zfs_error(hdl, EZFS_INVALIDNAME,
+ di->errbuf));
+ }
+
+ atptrf = strchr(fromsnap, '@');
+ ASSERT(atptrf != NULL);
+ fdslen = atptrf - fromsnap;
+
+ di->fromsnap = zfs_strdup(hdl, fromsnap);
+ di->ds = zfs_strdup(hdl, fromsnap);
+ di->ds[fdslen] = '\0';
+
+ /* the to snap will be a just-in-time snap of the head */
+ return (make_temp_snapshot(di));
+ }
+
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Unable to determine which snapshots to compare"));
+
+ atptrf = strchr(fromsnap, '@');
+ atptrt = strchr(tosnap, '@');
+ fdslen = atptrf ? atptrf - fromsnap : strlen(fromsnap);
+ tdslen = atptrt ? atptrt - tosnap : strlen(tosnap);
+ fsnlen = strlen(fromsnap) - fdslen; /* includes @ sign */
+ tsnlen = strlen(tosnap) - tdslen; /* includes @ sign */
+
+ if (fsnlen <= 1 || tsnlen == 1 || (fdslen == 0 && tdslen == 0) ||
+ (fsnlen == 0 && tsnlen == 0)) {
+ return (zfs_error(hdl, EZFS_INVALIDNAME, di->errbuf));
+ } else if ((fdslen > 0 && tdslen > 0) &&
+ ((tdslen != fdslen || strncmp(fromsnap, tosnap, fdslen) != 0))) {
+ /*
+ * not the same dataset name, might be okay if
+ * tosnap is a clone of a fromsnap descendant.
+ */
+ char origin[ZFS_MAXNAMELEN];
+ zprop_source_t src;
+ zfs_handle_t *zhp;
+
+ di->ds = zfs_alloc(di->zhp->zfs_hdl, tdslen + 1);
+ (void) strncpy(di->ds, tosnap, tdslen);
+ di->ds[tdslen] = '\0';
+
+ zhp = zfs_open(hdl, di->ds, ZFS_TYPE_FILESYSTEM);
+ while (zhp != NULL) {
+ (void) zfs_prop_get(zhp, ZFS_PROP_ORIGIN,
+ origin, sizeof (origin), &src, NULL, 0, B_FALSE);
+
+ if (strncmp(origin, fromsnap, fsnlen) == 0)
+ break;
+
+ (void) zfs_close(zhp);
+ zhp = zfs_open(hdl, origin, ZFS_TYPE_FILESYSTEM);
+ }
+
+ if (zhp == NULL) {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Not an earlier snapshot from the same fs"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, di->errbuf));
+ } else {
+ (void) zfs_close(zhp);
+ }
+
+ di->isclone = B_TRUE;
+ di->fromsnap = zfs_strdup(hdl, fromsnap);
+ if (tsnlen) {
+ di->tosnap = zfs_strdup(hdl, tosnap);
+ } else {
+ return (make_temp_snapshot(di));
+ }
+ } else {
+ int dslen = fdslen ? fdslen : tdslen;
+
+ di->ds = zfs_alloc(hdl, dslen + 1);
+ (void) strncpy(di->ds, fdslen ? fromsnap : tosnap, dslen);
+ di->ds[dslen] = '\0';
+
+ di->fromsnap = zfs_asprintf(hdl, "%s%s", di->ds, atptrf);
+ if (tsnlen) {
+ di->tosnap = zfs_asprintf(hdl, "%s%s", di->ds, atptrt);
+ } else {
+ return (make_temp_snapshot(di));
+ }
+ }
+ return (0);
+}
+
+static int
+get_mountpoint(differ_info_t *di, char *dsnm, char **mntpt)
+{
+ boolean_t mounted;
+
+ mounted = is_mounted(di->zhp->zfs_hdl, dsnm, mntpt);
+ if (mounted == B_FALSE) {
+ (void) snprintf(di->errbuf, sizeof (di->errbuf),
+ dgettext(TEXT_DOMAIN,
+ "Cannot diff an unmounted snapshot"));
+ return (zfs_error(di->zhp->zfs_hdl, EZFS_BADTYPE, di->errbuf));
+ }
+
+ /* Avoid a double slash at the beginning of root-mounted datasets */
+ if (**mntpt == '/' && *(*mntpt + 1) == '\0')
+ **mntpt = '\0';
+ return (0);
+}
+
+static int
+get_mountpoints(differ_info_t *di)
+{
+ char *strptr;
+ char *frommntpt;
+
+ /*
+ * first get the mountpoint for the parent dataset
+ */
+ if (get_mountpoint(di, di->ds, &di->dsmnt) != 0)
+ return (-1);
+
+ strptr = strchr(di->tosnap, '@');
+ ASSERT3P(strptr, !=, NULL);
+ di->tomnt = zfs_asprintf(di->zhp->zfs_hdl, "%s%s%s", di->dsmnt,
+ ZDIFF_SNAPDIR, ++strptr);
+
+ strptr = strchr(di->fromsnap, '@');
+ ASSERT3P(strptr, !=, NULL);
+
+ frommntpt = di->dsmnt;
+ if (di->isclone) {
+ char *mntpt;
+ int err;
+
+ *strptr = '\0';
+ err = get_mountpoint(di, di->fromsnap, &mntpt);
+ *strptr = '@';
+ if (err != 0)
+ return (-1);
+ frommntpt = mntpt;
+ }
+
+ di->frommnt = zfs_asprintf(di->zhp->zfs_hdl, "%s%s%s", frommntpt,
+ ZDIFF_SNAPDIR, ++strptr);
+
+ if (di->isclone)
+ free(frommntpt);
+
+ return (0);
+}
+
+static int
+setup_differ_info(zfs_handle_t *zhp, const char *fromsnap,
+ const char *tosnap, differ_info_t *di)
+{
+ di->zhp = zhp;
+
+ di->cleanupfd = open(ZFS_DEV, O_RDWR|O_EXCL);
+ VERIFY(di->cleanupfd >= 0);
+
+ if (get_snapshot_names(di, fromsnap, tosnap) != 0)
+ return (-1);
+
+ if (get_mountpoints(di) != 0)
+ return (-1);
+
+ if (find_shares_object(di) != 0)
+ return (-1);
+
+ return (0);
+}
+
+int
+zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap,
+ const char *tosnap, int flags)
+{
+ zfs_cmd_t zc = { 0 };
+ char errbuf[1024];
+ differ_info_t di = { 0 };
+ pthread_t tid;
+ int pipefd[2];
+ int iocerr;
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "zfs diff failed"));
+
+ if (setup_differ_info(zhp, fromsnap, tosnap, &di)) {
+ teardown_differ_info(&di);
+ return (-1);
+ }
+
+ if (pipe(pipefd)) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(errno));
+ teardown_differ_info(&di);
+ return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf));
+ }
+
+ di.scripted = (flags & ZFS_DIFF_PARSEABLE);
+ di.classify = (flags & ZFS_DIFF_CLASSIFY);
+ di.timestamped = (flags & ZFS_DIFF_TIMESTAMP);
+
+ di.outputfd = outfd;
+ di.datafd = pipefd[0];
+
+ if (pthread_create(&tid, NULL, differ, &di)) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(errno));
+ (void) close(pipefd[0]);
+ (void) close(pipefd[1]);
+ teardown_differ_info(&di);
+ return (zfs_error(zhp->zfs_hdl,
+ EZFS_THREADCREATEFAILED, errbuf));
+ }
+
+ /* do the ioctl() */
+ (void) strlcpy(zc.zc_value, di.fromsnap, strlen(di.fromsnap) + 1);
+ (void) strlcpy(zc.zc_name, di.tosnap, strlen(di.tosnap) + 1);
+ zc.zc_cookie = pipefd[1];
+
+ iocerr = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DIFF, &zc);
+ if (iocerr != 0) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "Unable to obtain diffs"));
+ if (errno == EPERM) {
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "\n The sys_mount privilege or diff delegated "
+ "permission is needed\n to execute the "
+ "diff ioctl"));
+ } else if (errno == EXDEV) {
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "\n Not an earlier snapshot from the same fs"));
+ } else if (errno != EPIPE || di.zerr == 0) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(errno));
+ }
+ (void) close(pipefd[1]);
+ (void) pthread_cancel(tid);
+ (void) pthread_join(tid, NULL);
+ teardown_differ_info(&di);
+ if (di.zerr != 0 && di.zerr != EPIPE) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(di.zerr));
+ return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf));
+ } else {
+ return (zfs_error(zhp->zfs_hdl, EZFS_DIFFDATA, errbuf));
+ }
+ }
+
+ (void) close(pipefd[1]);
+ (void) pthread_join(tid, NULL);
+
+ if (di.zerr != 0) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(di.zerr));
+ return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf));
+ }
+ teardown_differ_info(&di);
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_fru.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_fru.c
new file mode 100644
index 0000000..788fa2c
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_fru.c
@@ -0,0 +1,452 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <libintl.h>
+#include <link.h>
+#include <pthread.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <libzfs.h>
+
+#include <fm/libtopo.h>
+#include <sys/fm/protocol.h>
+#include <sys/systeminfo.h>
+
+#include "libzfs_impl.h"
+
+/*
+ * This file is responsible for determining the relationship between I/O
+ * devices paths and physical locations. In the world of MPxIO and external
+ * enclosures, the device path is not synonymous with the physical location.
+ * If you remove a drive and insert it into a different slot, it will end up
+ * with the same path under MPxIO. If you recable storage enclosures, the
+ * device paths may change. All of this makes it difficult to implement the
+ * 'autoreplace' property, which is supposed to automatically manage disk
+ * replacement based on physical slot.
+ *
+ * In order to work around these limitations, we have a per-vdev FRU property
+ * that is the libtopo path (minus disk-specific authority information) to the
+ * physical location of the device on the system. This is an optional
+ * property, and is only needed when using the 'autoreplace' property or when
+ * generating FMA faults against vdevs.
+ */
+
+/*
+ * Because the FMA packages depend on ZFS, we have to dlopen() libtopo in case
+ * it is not present. We only need this once per library instance, so it is
+ * not part of the libzfs handle.
+ */
+static void *_topo_dlhandle;
+static topo_hdl_t *(*_topo_open)(int, const char *, int *);
+static void (*_topo_close)(topo_hdl_t *);
+static char *(*_topo_snap_hold)(topo_hdl_t *, const char *, int *);
+static void (*_topo_snap_release)(topo_hdl_t *);
+static topo_walk_t *(*_topo_walk_init)(topo_hdl_t *, const char *,
+ topo_walk_cb_t, void *, int *);
+static int (*_topo_walk_step)(topo_walk_t *, int);
+static void (*_topo_walk_fini)(topo_walk_t *);
+static void (*_topo_hdl_strfree)(topo_hdl_t *, char *);
+static char *(*_topo_node_name)(tnode_t *);
+static int (*_topo_prop_get_string)(tnode_t *, const char *, const char *,
+ char **, int *);
+static int (*_topo_node_fru)(tnode_t *, nvlist_t **, nvlist_t *, int *);
+static int (*_topo_fmri_nvl2str)(topo_hdl_t *, nvlist_t *, char **, int *);
+static int (*_topo_fmri_strcmp_noauth)(topo_hdl_t *, const char *,
+ const char *);
+
+#define ZFS_FRU_HASH_SIZE 257
+
+static size_t
+fru_strhash(const char *key)
+{
+ ulong_t g, h = 0;
+ const char *p;
+
+ for (p = key; *p != '\0'; p++) {
+ h = (h << 4) + *p;
+
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ return (h % ZFS_FRU_HASH_SIZE);
+}
+
+static int
+libzfs_fru_gather(topo_hdl_t *thp, tnode_t *tn, void *arg)
+{
+ libzfs_handle_t *hdl = arg;
+ nvlist_t *fru;
+ char *devpath, *frustr;
+ int err;
+ libzfs_fru_t *frup;
+ size_t idx;
+
+ /*
+ * If this is the chassis node, and we don't yet have the system
+ * chassis ID, then fill in this value now.
+ */
+ if (hdl->libzfs_chassis_id[0] == '\0' &&
+ strcmp(_topo_node_name(tn), "chassis") == 0) {
+ if (_topo_prop_get_string(tn, FM_FMRI_AUTHORITY,
+ FM_FMRI_AUTH_CHASSIS, &devpath, &err) == 0)
+ (void) strlcpy(hdl->libzfs_chassis_id, devpath,
+ sizeof (hdl->libzfs_chassis_id));
+ }
+
+ /*
+ * Skip non-disk nodes.
+ */
+ if (strcmp(_topo_node_name(tn), "disk") != 0)
+ return (TOPO_WALK_NEXT);
+
+ /*
+ * Get the devfs path and FRU.
+ */
+ if (_topo_prop_get_string(tn, "io", "devfs-path", &devpath, &err) != 0)
+ return (TOPO_WALK_NEXT);
+
+ if (libzfs_fru_lookup(hdl, devpath) != NULL) {
+ _topo_hdl_strfree(thp, devpath);
+ return (TOPO_WALK_NEXT);
+ }
+
+ if (_topo_node_fru(tn, &fru, NULL, &err) != 0) {
+ _topo_hdl_strfree(thp, devpath);
+ return (TOPO_WALK_NEXT);
+ }
+
+ /*
+ * Convert the FRU into a string.
+ */
+ if (_topo_fmri_nvl2str(thp, fru, &frustr, &err) != 0) {
+ nvlist_free(fru);
+ _topo_hdl_strfree(thp, devpath);
+ return (TOPO_WALK_NEXT);
+ }
+
+ nvlist_free(fru);
+
+ /*
+ * Finally, we have a FRU string and device path. Add it to the hash.
+ */
+ if ((frup = calloc(sizeof (libzfs_fru_t), 1)) == NULL) {
+ _topo_hdl_strfree(thp, devpath);
+ _topo_hdl_strfree(thp, frustr);
+ return (TOPO_WALK_NEXT);
+ }
+
+ if ((frup->zf_device = strdup(devpath)) == NULL ||
+ (frup->zf_fru = strdup(frustr)) == NULL) {
+ free(frup->zf_device);
+ free(frup);
+ _topo_hdl_strfree(thp, devpath);
+ _topo_hdl_strfree(thp, frustr);
+ return (TOPO_WALK_NEXT);
+ }
+
+ _topo_hdl_strfree(thp, devpath);
+ _topo_hdl_strfree(thp, frustr);
+
+ idx = fru_strhash(frup->zf_device);
+ frup->zf_chain = hdl->libzfs_fru_hash[idx];
+ hdl->libzfs_fru_hash[idx] = frup;
+ frup->zf_next = hdl->libzfs_fru_list;
+ hdl->libzfs_fru_list = frup;
+
+ return (TOPO_WALK_NEXT);
+}
+
+/*
+ * Called during initialization to setup the dynamic libtopo connection.
+ */
+#pragma init(libzfs_init_fru)
+static void
+libzfs_init_fru(void)
+{
+ char path[MAXPATHLEN];
+ char isa[257];
+
+#if defined(_LP64)
+ if (sysinfo(SI_ARCHITECTURE_64, isa, sizeof (isa)) < 0)
+ isa[0] = '\0';
+#else
+ isa[0] = '\0';
+#endif
+ (void) snprintf(path, sizeof (path),
+ "/usr/lib/fm/%s/libtopo.so", isa);
+
+ if ((_topo_dlhandle = dlopen(path, RTLD_LAZY)) == NULL)
+ return;
+
+ _topo_open = (topo_hdl_t *(*)())
+ dlsym(_topo_dlhandle, "topo_open");
+ _topo_close = (void (*)())
+ dlsym(_topo_dlhandle, "topo_close");
+ _topo_snap_hold = (char *(*)())
+ dlsym(_topo_dlhandle, "topo_snap_hold");
+ _topo_snap_release = (void (*)())
+ dlsym(_topo_dlhandle, "topo_snap_release");
+ _topo_walk_init = (topo_walk_t *(*)())
+ dlsym(_topo_dlhandle, "topo_walk_init");
+ _topo_walk_step = (int (*)())
+ dlsym(_topo_dlhandle, "topo_walk_step");
+ _topo_walk_fini = (void (*)())
+ dlsym(_topo_dlhandle, "topo_walk_fini");
+ _topo_hdl_strfree = (void (*)())
+ dlsym(_topo_dlhandle, "topo_hdl_strfree");
+ _topo_node_name = (char *(*)())
+ dlsym(_topo_dlhandle, "topo_node_name");
+ _topo_prop_get_string = (int (*)())
+ dlsym(_topo_dlhandle, "topo_prop_get_string");
+ _topo_node_fru = (int (*)())
+ dlsym(_topo_dlhandle, "topo_node_fru");
+ _topo_fmri_nvl2str = (int (*)())
+ dlsym(_topo_dlhandle, "topo_fmri_nvl2str");
+ _topo_fmri_strcmp_noauth = (int (*)())
+ dlsym(_topo_dlhandle, "topo_fmri_strcmp_noauth");
+
+ if (_topo_open == NULL || _topo_close == NULL ||
+ _topo_snap_hold == NULL || _topo_snap_release == NULL ||
+ _topo_walk_init == NULL || _topo_walk_step == NULL ||
+ _topo_walk_fini == NULL || _topo_hdl_strfree == NULL ||
+ _topo_node_name == NULL || _topo_prop_get_string == NULL ||
+ _topo_node_fru == NULL || _topo_fmri_nvl2str == NULL ||
+ _topo_fmri_strcmp_noauth == NULL) {
+ (void) dlclose(_topo_dlhandle);
+ _topo_dlhandle = NULL;
+ }
+}
+
+/*
+ * Refresh the mappings from device path -> FMRI. We do this by walking the
+ * hc topology looking for disk nodes, and recording the io/devfs-path and FRU.
+ * Note that we strip out the disk-specific authority information (serial,
+ * part, revision, etc) so that we are left with only the identifying
+ * characteristics of the slot (hc path and chassis-id).
+ */
+void
+libzfs_fru_refresh(libzfs_handle_t *hdl)
+{
+ int err;
+ char *uuid;
+ topo_hdl_t *thp;
+ topo_walk_t *twp;
+
+ if (_topo_dlhandle == NULL)
+ return;
+
+ /*
+ * Clear the FRU hash and initialize our basic structures.
+ */
+ libzfs_fru_clear(hdl, B_FALSE);
+
+ if ((hdl->libzfs_topo_hdl = _topo_open(TOPO_VERSION,
+ NULL, &err)) == NULL)
+ return;
+
+ thp = hdl->libzfs_topo_hdl;
+
+ if ((uuid = _topo_snap_hold(thp, NULL, &err)) == NULL)
+ return;
+
+ _topo_hdl_strfree(thp, uuid);
+
+ if (hdl->libzfs_fru_hash == NULL &&
+ (hdl->libzfs_fru_hash =
+ calloc(ZFS_FRU_HASH_SIZE * sizeof (void *), 1)) == NULL)
+ return;
+
+ /*
+ * We now have a topo snapshot, so iterate over the hc topology looking
+ * for disks to add to the hash.
+ */
+ twp = _topo_walk_init(thp, FM_FMRI_SCHEME_HC,
+ libzfs_fru_gather, hdl, &err);
+ if (twp != NULL) {
+ (void) _topo_walk_step(twp, TOPO_WALK_CHILD);
+ _topo_walk_fini(twp);
+ }
+}
+
+/*
+ * Given a devfs path, return the FRU for the device, if known. This will
+ * automatically call libzfs_fru_refresh() if it hasn't already been called by
+ * the consumer. The string returned is valid until the next call to
+ * libzfs_fru_refresh().
+ */
+const char *
+libzfs_fru_lookup(libzfs_handle_t *hdl, const char *devpath)
+{
+ size_t idx = fru_strhash(devpath);
+ libzfs_fru_t *frup;
+
+ if (hdl->libzfs_fru_hash == NULL)
+ libzfs_fru_refresh(hdl);
+
+ if (hdl->libzfs_fru_hash == NULL)
+ return (NULL);
+
+ for (frup = hdl->libzfs_fru_hash[idx]; frup != NULL;
+ frup = frup->zf_chain) {
+ if (strcmp(devpath, frup->zf_device) == 0)
+ return (frup->zf_fru);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Given a fru path, return the device path. This will automatically call
+ * libzfs_fru_refresh() if it hasn't already been called by the consumer. The
+ * string returned is valid until the next call to libzfs_fru_refresh().
+ */
+const char *
+libzfs_fru_devpath(libzfs_handle_t *hdl, const char *fru)
+{
+ libzfs_fru_t *frup;
+ size_t idx;
+
+ if (hdl->libzfs_fru_hash == NULL)
+ libzfs_fru_refresh(hdl);
+
+ if (hdl->libzfs_fru_hash == NULL)
+ return (NULL);
+
+ for (idx = 0; idx < ZFS_FRU_HASH_SIZE; idx++) {
+ for (frup = hdl->libzfs_fru_hash[idx]; frup != NULL;
+ frup = frup->zf_next) {
+ if (_topo_fmri_strcmp_noauth(hdl->libzfs_topo_hdl,
+ fru, frup->zf_fru))
+ return (frup->zf_device);
+ }
+ }
+
+ return (NULL);
+}
+
+/*
+ * Change the stored FRU for the given vdev.
+ */
+int
+zpool_fru_set(zpool_handle_t *zhp, uint64_t vdev_guid, const char *fru)
+{
+ zfs_cmd_t zc = { 0 };
+
+ (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ (void) strncpy(zc.zc_value, fru, sizeof (zc.zc_value));
+ zc.zc_guid = vdev_guid;
+
+ if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SETFRU, &zc) != 0)
+ return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
+ dgettext(TEXT_DOMAIN, "cannot set FRU")));
+
+ return (0);
+}
+
+/*
+ * Compare to two FRUs, ignoring any authority information.
+ */
+boolean_t
+libzfs_fru_compare(libzfs_handle_t *hdl, const char *a, const char *b)
+{
+ if (hdl->libzfs_fru_hash == NULL)
+ libzfs_fru_refresh(hdl);
+
+ if (hdl->libzfs_fru_hash == NULL)
+ return (strcmp(a, b) == 0);
+
+ return (_topo_fmri_strcmp_noauth(hdl->libzfs_topo_hdl, a, b));
+}
+
+/*
+ * This special function checks to see whether the FRU indicates it's supposed
+ * to be in the system chassis, but the chassis-id doesn't match. This can
+ * happen in a clustered case, where both head nodes have the same logical
+ * disk, but opening the device on the other head node is meaningless.
+ */
+boolean_t
+libzfs_fru_notself(libzfs_handle_t *hdl, const char *fru)
+{
+ const char *chassisid;
+ size_t len;
+
+ if (hdl->libzfs_fru_hash == NULL)
+ libzfs_fru_refresh(hdl);
+
+ if (hdl->libzfs_chassis_id[0] == '\0')
+ return (B_FALSE);
+
+ if (strstr(fru, "/chassis=0/") == NULL)
+ return (B_FALSE);
+
+ if ((chassisid = strstr(fru, ":chassis-id=")) == NULL)
+ return (B_FALSE);
+
+ chassisid += 12;
+ len = strlen(hdl->libzfs_chassis_id);
+ if (strncmp(chassisid, hdl->libzfs_chassis_id, len) == 0 &&
+ (chassisid[len] == '/' || chassisid[len] == ':'))
+ return (B_FALSE);
+
+ return (B_TRUE);
+}
+
+/*
+ * Clear memory associated with the FRU hash.
+ */
+void
+libzfs_fru_clear(libzfs_handle_t *hdl, boolean_t final)
+{
+ libzfs_fru_t *frup;
+
+ while ((frup = hdl->libzfs_fru_list) != NULL) {
+ hdl->libzfs_fru_list = frup->zf_next;
+ free(frup->zf_device);
+ free(frup->zf_fru);
+ free(frup);
+ }
+
+ hdl->libzfs_fru_list = NULL;
+
+ if (hdl->libzfs_topo_hdl != NULL) {
+ _topo_snap_release(hdl->libzfs_topo_hdl);
+ _topo_close(hdl->libzfs_topo_hdl);
+ hdl->libzfs_topo_hdl = NULL;
+ }
+
+ if (final) {
+ free(hdl->libzfs_fru_hash);
+ } else if (hdl->libzfs_fru_hash != NULL) {
+ bzero(hdl->libzfs_fru_hash,
+ ZFS_FRU_HASH_SIZE * sizeof (void *));
+ }
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
new file mode 100644
index 0000000..11a57a9
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -0,0 +1,221 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_IMPL_H
+#define _LIBZFS_IMPL_H
+
+#include <sys/dmu.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/spa.h>
+#include <sys/nvpair.h>
+
+#include <libshare.h>
+#include <libuutil.h>
+#include <libzfs.h>
+#include <libzfs_core.h>
+#include <libzfs_compat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef VERIFY
+#undef VERIFY
+#endif
+#define VERIFY verify
+
+typedef struct libzfs_fru {
+ char *zf_device;
+ char *zf_fru;
+ struct libzfs_fru *zf_chain;
+ struct libzfs_fru *zf_next;
+} libzfs_fru_t;
+
+struct libzfs_handle {
+ int libzfs_error;
+ int libzfs_fd;
+ FILE *libzfs_mnttab;
+ FILE *libzfs_sharetab;
+ zpool_handle_t *libzfs_pool_handles;
+ uu_avl_pool_t *libzfs_ns_avlpool;
+ uu_avl_t *libzfs_ns_avl;
+ uint64_t libzfs_ns_gen;
+ int libzfs_desc_active;
+ char libzfs_action[1024];
+ char libzfs_desc[1024];
+ int libzfs_printerr;
+ int libzfs_storeerr; /* stuff error messages into buffer */
+ void *libzfs_sharehdl; /* libshare handle */
+ uint_t libzfs_shareflags;
+ boolean_t libzfs_mnttab_enable;
+ avl_tree_t libzfs_mnttab_cache;
+ int libzfs_pool_iter;
+ libzfs_fru_t **libzfs_fru_hash;
+ libzfs_fru_t *libzfs_fru_list;
+ char libzfs_chassis_id[256];
+};
+
+#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */
+
+struct zfs_handle {
+ libzfs_handle_t *zfs_hdl;
+ zpool_handle_t *zpool_hdl;
+ char zfs_name[ZFS_MAXNAMELEN];
+ zfs_type_t zfs_type; /* type including snapshot */
+ zfs_type_t zfs_head_type; /* type excluding snapshot */
+ dmu_objset_stats_t zfs_dmustats;
+ nvlist_t *zfs_props;
+ nvlist_t *zfs_user_props;
+ nvlist_t *zfs_recvd_props;
+ boolean_t zfs_mntcheck;
+ char *zfs_mntopts;
+ uint8_t *zfs_props_table;
+};
+
+/*
+ * This is different from checking zfs_type, because it will also catch
+ * snapshots of volumes.
+ */
+#define ZFS_IS_VOLUME(zhp) ((zhp)->zfs_head_type == ZFS_TYPE_VOLUME)
+
+struct zpool_handle {
+ libzfs_handle_t *zpool_hdl;
+ zpool_handle_t *zpool_next;
+ char zpool_name[ZPOOL_MAXNAMELEN];
+ int zpool_state;
+ size_t zpool_config_size;
+ nvlist_t *zpool_config;
+ nvlist_t *zpool_old_config;
+ nvlist_t *zpool_props;
+ diskaddr_t zpool_start_block;
+};
+
+typedef enum {
+ PROTO_NFS = 0,
+ PROTO_SMB = 1,
+ PROTO_END = 2
+} zfs_share_proto_t;
+
+/*
+ * The following can be used as a bitmask and any new values
+ * added must preserve that capability.
+ */
+typedef enum {
+ SHARED_NOT_SHARED = 0x0,
+ SHARED_NFS = 0x2,
+ SHARED_SMB = 0x4
+} zfs_share_type_t;
+
+int zfs_error(libzfs_handle_t *, int, const char *);
+int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
+void zfs_error_aux(libzfs_handle_t *, const char *, ...);
+void *zfs_alloc(libzfs_handle_t *, size_t);
+void *zfs_realloc(libzfs_handle_t *, void *, size_t, size_t);
+char *zfs_asprintf(libzfs_handle_t *, const char *, ...);
+char *zfs_strdup(libzfs_handle_t *, const char *);
+int no_memory(libzfs_handle_t *);
+
+int zfs_standard_error(libzfs_handle_t *, int, const char *);
+int zfs_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
+int zpool_standard_error(libzfs_handle_t *, int, const char *);
+int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
+
+int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
+ size_t *);
+zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *);
+zfs_handle_t *make_dataset_simple_handle_zc(zfs_handle_t *, zfs_cmd_t *);
+
+int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
+ nvlist_t *, char **, uint64_t *, const char *);
+int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
+ zfs_type_t type);
+
+/*
+ * Use this changelist_gather() flag to force attempting mounts
+ * on each change node regardless of whether or not it is currently
+ * mounted.
+ */
+#define CL_GATHER_MOUNT_ALWAYS 0x01
+/*
+ * Use this changelist_gather() flag to prevent unmounting of file systems.
+ */
+#define CL_GATHER_DONT_UNMOUNT 0x02
+
+typedef struct prop_changelist prop_changelist_t;
+
+int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
+int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
+int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
+int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
+int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
+void zcmd_free_nvlists(zfs_cmd_t *);
+
+int changelist_prefix(prop_changelist_t *);
+int changelist_postfix(prop_changelist_t *);
+void changelist_rename(prop_changelist_t *, const char *, const char *);
+void changelist_remove(prop_changelist_t *, const char *);
+void changelist_free(prop_changelist_t *);
+prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int);
+int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
+int changelist_haszonedchild(prop_changelist_t *);
+
+void remove_mountpoint(zfs_handle_t *);
+int create_parents(libzfs_handle_t *, char *, int);
+boolean_t isa_child_of(const char *dataset, const char *parent);
+
+zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
+
+int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
+
+boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
+
+int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
+ boolean_t modifying);
+
+void namespace_clear(libzfs_handle_t *);
+
+/*
+ * libshare (sharemgr) interfaces used internally.
+ */
+
+extern int zfs_init_libshare(libzfs_handle_t *, int);
+extern void zfs_uninit_libshare(libzfs_handle_t *);
+extern int zfs_parse_options(char *, zfs_share_proto_t);
+
+extern int zfs_unshare_proto(zfs_handle_t *,
+ const char *, zfs_share_proto_t *);
+
+extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_IMPL_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
new file mode 100644
index 0000000..fa3d609
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
@@ -0,0 +1,1729 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Pool import support functions.
+ *
+ * To import a pool, we rely on reading the configuration information from the
+ * ZFS label of each device. If we successfully read the label, then we
+ * organize the configuration information in the following hierarchy:
+ *
+ * pool guid -> toplevel vdev guid -> label txg
+ *
+ * Duplicate entries matching this same tuple will be discarded. Once we have
+ * examined every device, we pick the best label txg config for each toplevel
+ * vdev. We then arrange these toplevel vdevs into a complete pool config, and
+ * update any paths that have changed. Finally, we attempt to import the pool
+ * using our derived config, and record the results.
+ */
+
+#include <ctype.h>
+#include <devid.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libintl.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <thread_pool.h>
+#include <libgeom.h>
+
+#include <sys/vdev_impl.h>
+
+#include "libzfs.h"
+#include "libzfs_impl.h"
+
+/*
+ * Intermediate structures used to gather configuration information.
+ */
+typedef struct config_entry {
+ uint64_t ce_txg;
+ nvlist_t *ce_config;
+ struct config_entry *ce_next;
+} config_entry_t;
+
+typedef struct vdev_entry {
+ uint64_t ve_guid;
+ config_entry_t *ve_configs;
+ struct vdev_entry *ve_next;
+} vdev_entry_t;
+
+typedef struct pool_entry {
+ uint64_t pe_guid;
+ vdev_entry_t *pe_vdevs;
+ struct pool_entry *pe_next;
+} pool_entry_t;
+
+typedef struct name_entry {
+ char *ne_name;
+ uint64_t ne_guid;
+ struct name_entry *ne_next;
+} name_entry_t;
+
+typedef struct pool_list {
+ pool_entry_t *pools;
+ name_entry_t *names;
+} pool_list_t;
+
+static char *
+get_devid(const char *path)
+{
+ int fd;
+ ddi_devid_t devid;
+ char *minor, *ret;
+
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return (NULL);
+
+ minor = NULL;
+ ret = NULL;
+ if (devid_get(fd, &devid) == 0) {
+ if (devid_get_minor_name(fd, &minor) == 0)
+ ret = devid_str_encode(devid, minor);
+ if (minor != NULL)
+ devid_str_free(minor);
+ devid_free(devid);
+ }
+ (void) close(fd);
+
+ return (ret);
+}
+
+
+/*
+ * Go through and fix up any path and/or devid information for the given vdev
+ * configuration.
+ */
+static int
+fix_paths(nvlist_t *nv, name_entry_t *names)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ uint64_t guid;
+ name_entry_t *ne, *best;
+ char *path, *devid;
+ int matched;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if (fix_paths(child[c], names) != 0)
+ return (-1);
+ return (0);
+ }
+
+ /*
+ * This is a leaf (file or disk) vdev. In either case, go through
+ * the name list and see if we find a matching guid. If so, replace
+ * the path and see if we can calculate a new devid.
+ *
+ * There may be multiple names associated with a particular guid, in
+ * which case we have overlapping slices or multiple paths to the same
+ * disk. If this is the case, then we want to pick the path that is
+ * the most similar to the original, where "most similar" is the number
+ * of matching characters starting from the end of the path. This will
+ * preserve slice numbers even if the disks have been reorganized, and
+ * will also catch preferred disk names if multiple paths exist.
+ */
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0);
+ if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
+ path = NULL;
+
+ matched = 0;
+ best = NULL;
+ for (ne = names; ne != NULL; ne = ne->ne_next) {
+ if (ne->ne_guid == guid) {
+ const char *src, *dst;
+ int count;
+
+ if (path == NULL) {
+ best = ne;
+ break;
+ }
+
+ src = ne->ne_name + strlen(ne->ne_name) - 1;
+ dst = path + strlen(path) - 1;
+ for (count = 0; src >= ne->ne_name && dst >= path;
+ src--, dst--, count++)
+ if (*src != *dst)
+ break;
+
+ /*
+ * At this point, 'count' is the number of characters
+ * matched from the end.
+ */
+ if (count > matched || best == NULL) {
+ best = ne;
+ matched = count;
+ }
+ }
+ }
+
+ if (best == NULL)
+ return (0);
+
+ if (nvlist_add_string(nv, ZPOOL_CONFIG_PATH, best->ne_name) != 0)
+ return (-1);
+
+ if ((devid = get_devid(best->ne_name)) == NULL) {
+ (void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
+ } else {
+ if (nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, devid) != 0)
+ return (-1);
+ devid_str_free(devid);
+ }
+
+ return (0);
+}
+
+/*
+ * Add the given configuration to the list of known devices.
+ */
+static int
+add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
+ nvlist_t *config)
+{
+ uint64_t pool_guid, vdev_guid, top_guid, txg, state;
+ pool_entry_t *pe;
+ vdev_entry_t *ve;
+ config_entry_t *ce;
+ name_entry_t *ne;
+
+ /*
+ * If this is a hot spare not currently in use or level 2 cache
+ * device, add it to the list of names to translate, but don't do
+ * anything else.
+ */
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &state) == 0 &&
+ (state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) &&
+ nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) {
+ if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
+ return (-1);
+
+ if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) {
+ free(ne);
+ return (-1);
+ }
+ ne->ne_guid = vdev_guid;
+ ne->ne_next = pl->names;
+ pl->names = ne;
+ return (0);
+ }
+
+ /*
+ * If we have a valid config but cannot read any of these fields, then
+ * it means we have a half-initialized label. In vdev_label_init()
+ * we write a label with txg == 0 so that we can identify the device
+ * in case the user refers to the same disk later on. If we fail to
+ * create the pool, we'll be left with a label in this state
+ * which should not be considered part of a valid pool.
+ */
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &pool_guid) != 0 ||
+ nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
+ &vdev_guid) != 0 ||
+ nvlist_lookup_uint64(config, ZPOOL_CONFIG_TOP_GUID,
+ &top_guid) != 0 ||
+ nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
+ &txg) != 0 || txg == 0) {
+ nvlist_free(config);
+ return (0);
+ }
+
+ /*
+ * First, see if we know about this pool. If not, then add it to the
+ * list of known pools.
+ */
+ for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
+ if (pe->pe_guid == pool_guid)
+ break;
+ }
+
+ if (pe == NULL) {
+ if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) {
+ nvlist_free(config);
+ return (-1);
+ }
+ pe->pe_guid = pool_guid;
+ pe->pe_next = pl->pools;
+ pl->pools = pe;
+ }
+
+ /*
+ * Second, see if we know about this toplevel vdev. Add it if its
+ * missing.
+ */
+ for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) {
+ if (ve->ve_guid == top_guid)
+ break;
+ }
+
+ if (ve == NULL) {
+ if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) {
+ nvlist_free(config);
+ return (-1);
+ }
+ ve->ve_guid = top_guid;
+ ve->ve_next = pe->pe_vdevs;
+ pe->pe_vdevs = ve;
+ }
+
+ /*
+ * Third, see if we have a config with a matching transaction group. If
+ * so, then we do nothing. Otherwise, add it to the list of known
+ * configs.
+ */
+ for (ce = ve->ve_configs; ce != NULL; ce = ce->ce_next) {
+ if (ce->ce_txg == txg)
+ break;
+ }
+
+ if (ce == NULL) {
+ if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) {
+ nvlist_free(config);
+ return (-1);
+ }
+ ce->ce_txg = txg;
+ ce->ce_config = config;
+ ce->ce_next = ve->ve_configs;
+ ve->ve_configs = ce;
+ } else {
+ nvlist_free(config);
+ }
+
+ /*
+ * At this point we've successfully added our config to the list of
+ * known configs. The last thing to do is add the vdev guid -> path
+ * mappings so that we can fix up the configuration as necessary before
+ * doing the import.
+ */
+ if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
+ return (-1);
+
+ if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) {
+ free(ne);
+ return (-1);
+ }
+
+ ne->ne_guid = vdev_guid;
+ ne->ne_next = pl->names;
+ pl->names = ne;
+
+ return (0);
+}
+
+/*
+ * Returns true if the named pool matches the given GUID.
+ */
+static int
+pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
+ boolean_t *isactive)
+{
+ zpool_handle_t *zhp;
+ uint64_t theguid;
+
+ if (zpool_open_silent(hdl, name, &zhp) != 0)
+ return (-1);
+
+ if (zhp == NULL) {
+ *isactive = B_FALSE;
+ return (0);
+ }
+
+ verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID,
+ &theguid) == 0);
+
+ zpool_close(zhp);
+
+ *isactive = (theguid == guid);
+ return (0);
+}
+
+static nvlist_t *
+refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
+{
+ nvlist_t *nvl;
+ zfs_cmd_t zc = { 0 };
+ int err;
+
+ if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
+ return (NULL);
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc,
+ zc.zc_nvlist_conf_size * 2) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (NULL);
+ }
+
+ while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
+ &zc)) != 0 && errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (NULL);
+ }
+ }
+
+ if (err) {
+ zcmd_free_nvlists(&zc);
+ return (NULL);
+ }
+
+ if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (NULL);
+ }
+
+ zcmd_free_nvlists(&zc);
+ return (nvl);
+}
+
+/*
+ * Determine if the vdev id is a hole in the namespace.
+ */
+boolean_t
+vdev_is_hole(uint64_t *hole_array, uint_t holes, uint_t id)
+{
+ for (int c = 0; c < holes; c++) {
+
+ /* Top-level is a hole */
+ if (hole_array[c] == id)
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
+/*
+ * Convert our list of pools into the definitive set of configurations. We
+ * start by picking the best config for each toplevel vdev. Once that's done,
+ * we assemble the toplevel vdevs into a full config for the pool. We make a
+ * pass to fix up any incorrect paths, and then add it to the main list to
+ * return to the user.
+ */
+static nvlist_t *
+get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
+{
+ pool_entry_t *pe;
+ vdev_entry_t *ve;
+ config_entry_t *ce;
+ nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
+ nvlist_t **spares, **l2cache;
+ uint_t i, nspares, nl2cache;
+ boolean_t config_seen;
+ uint64_t best_txg;
+ char *name, *hostname;
+ uint64_t guid;
+ uint_t children = 0;
+ nvlist_t **child = NULL;
+ uint_t holes;
+ uint64_t *hole_array, max_id;
+ uint_t c;
+ boolean_t isactive;
+ uint64_t hostid;
+ nvlist_t *nvl;
+ boolean_t found_one = B_FALSE;
+ boolean_t valid_top_config = B_FALSE;
+
+ if (nvlist_alloc(&ret, 0, 0) != 0)
+ goto nomem;
+
+ for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
+ uint64_t id, max_txg = 0;
+
+ if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0)
+ goto nomem;
+ config_seen = B_FALSE;
+
+ /*
+ * Iterate over all toplevel vdevs. Grab the pool configuration
+ * from the first one we find, and then go through the rest and
+ * add them as necessary to the 'vdevs' member of the config.
+ */
+ for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) {
+
+ /*
+ * Determine the best configuration for this vdev by
+ * selecting the config with the latest transaction
+ * group.
+ */
+ best_txg = 0;
+ for (ce = ve->ve_configs; ce != NULL;
+ ce = ce->ce_next) {
+
+ if (ce->ce_txg > best_txg) {
+ tmp = ce->ce_config;
+ best_txg = ce->ce_txg;
+ }
+ }
+
+ /*
+ * We rely on the fact that the max txg for the
+ * pool will contain the most up-to-date information
+ * about the valid top-levels in the vdev namespace.
+ */
+ if (best_txg > max_txg) {
+ (void) nvlist_remove(config,
+ ZPOOL_CONFIG_VDEV_CHILDREN,
+ DATA_TYPE_UINT64);
+ (void) nvlist_remove(config,
+ ZPOOL_CONFIG_HOLE_ARRAY,
+ DATA_TYPE_UINT64_ARRAY);
+
+ max_txg = best_txg;
+ hole_array = NULL;
+ holes = 0;
+ max_id = 0;
+ valid_top_config = B_FALSE;
+
+ if (nvlist_lookup_uint64(tmp,
+ ZPOOL_CONFIG_VDEV_CHILDREN, &max_id) == 0) {
+ verify(nvlist_add_uint64(config,
+ ZPOOL_CONFIG_VDEV_CHILDREN,
+ max_id) == 0);
+ valid_top_config = B_TRUE;
+ }
+
+ if (nvlist_lookup_uint64_array(tmp,
+ ZPOOL_CONFIG_HOLE_ARRAY, &hole_array,
+ &holes) == 0) {
+ verify(nvlist_add_uint64_array(config,
+ ZPOOL_CONFIG_HOLE_ARRAY,
+ hole_array, holes) == 0);
+ }
+ }
+
+ if (!config_seen) {
+ /*
+ * Copy the relevant pieces of data to the pool
+ * configuration:
+ *
+ * version
+ * pool guid
+ * name
+ * comment (if available)
+ * pool state
+ * hostid (if available)
+ * hostname (if available)
+ */
+ uint64_t state, version;
+ char *comment = NULL;
+
+ version = fnvlist_lookup_uint64(tmp,
+ ZPOOL_CONFIG_VERSION);
+ fnvlist_add_uint64(config,
+ ZPOOL_CONFIG_VERSION, version);
+ guid = fnvlist_lookup_uint64(tmp,
+ ZPOOL_CONFIG_POOL_GUID);
+ fnvlist_add_uint64(config,
+ ZPOOL_CONFIG_POOL_GUID, guid);
+ name = fnvlist_lookup_string(tmp,
+ ZPOOL_CONFIG_POOL_NAME);
+ fnvlist_add_string(config,
+ ZPOOL_CONFIG_POOL_NAME, name);
+
+ if (nvlist_lookup_string(tmp,
+ ZPOOL_CONFIG_COMMENT, &comment) == 0)
+ fnvlist_add_string(config,
+ ZPOOL_CONFIG_COMMENT, comment);
+
+ state = fnvlist_lookup_uint64(tmp,
+ ZPOOL_CONFIG_POOL_STATE);
+ fnvlist_add_uint64(config,
+ ZPOOL_CONFIG_POOL_STATE, state);
+
+ hostid = 0;
+ if (nvlist_lookup_uint64(tmp,
+ ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
+ fnvlist_add_uint64(config,
+ ZPOOL_CONFIG_HOSTID, hostid);
+ hostname = fnvlist_lookup_string(tmp,
+ ZPOOL_CONFIG_HOSTNAME);
+ fnvlist_add_string(config,
+ ZPOOL_CONFIG_HOSTNAME, hostname);
+ }
+
+ config_seen = B_TRUE;
+ }
+
+ /*
+ * Add this top-level vdev to the child array.
+ */
+ verify(nvlist_lookup_nvlist(tmp,
+ ZPOOL_CONFIG_VDEV_TREE, &nvtop) == 0);
+ verify(nvlist_lookup_uint64(nvtop, ZPOOL_CONFIG_ID,
+ &id) == 0);
+
+ if (id >= children) {
+ nvlist_t **newchild;
+
+ newchild = zfs_alloc(hdl, (id + 1) *
+ sizeof (nvlist_t *));
+ if (newchild == NULL)
+ goto nomem;
+
+ for (c = 0; c < children; c++)
+ newchild[c] = child[c];
+
+ free(child);
+ child = newchild;
+ children = id + 1;
+ }
+ if (nvlist_dup(nvtop, &child[id], 0) != 0)
+ goto nomem;
+
+ }
+
+ /*
+ * If we have information about all the top-levels then
+ * clean up the nvlist which we've constructed. This
+ * means removing any extraneous devices that are
+ * beyond the valid range or adding devices to the end
+ * of our array which appear to be missing.
+ */
+ if (valid_top_config) {
+ if (max_id < children) {
+ for (c = max_id; c < children; c++)
+ nvlist_free(child[c]);
+ children = max_id;
+ } else if (max_id > children) {
+ nvlist_t **newchild;
+
+ newchild = zfs_alloc(hdl, (max_id) *
+ sizeof (nvlist_t *));
+ if (newchild == NULL)
+ goto nomem;
+
+ for (c = 0; c < children; c++)
+ newchild[c] = child[c];
+
+ free(child);
+ child = newchild;
+ children = max_id;
+ }
+ }
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &guid) == 0);
+
+ /*
+ * The vdev namespace may contain holes as a result of
+ * device removal. We must add them back into the vdev
+ * tree before we process any missing devices.
+ */
+ if (holes > 0) {
+ ASSERT(valid_top_config);
+
+ for (c = 0; c < children; c++) {
+ nvlist_t *holey;
+
+ if (child[c] != NULL ||
+ !vdev_is_hole(hole_array, holes, c))
+ continue;
+
+ if (nvlist_alloc(&holey, NV_UNIQUE_NAME,
+ 0) != 0)
+ goto nomem;
+
+ /*
+ * Holes in the namespace are treated as
+ * "hole" top-level vdevs and have a
+ * special flag set on them.
+ */
+ if (nvlist_add_string(holey,
+ ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_HOLE) != 0 ||
+ nvlist_add_uint64(holey,
+ ZPOOL_CONFIG_ID, c) != 0 ||
+ nvlist_add_uint64(holey,
+ ZPOOL_CONFIG_GUID, 0ULL) != 0)
+ goto nomem;
+ child[c] = holey;
+ }
+ }
+
+ /*
+ * Look for any missing top-level vdevs. If this is the case,
+ * create a faked up 'missing' vdev as a placeholder. We cannot
+ * simply compress the child array, because the kernel performs
+ * certain checks to make sure the vdev IDs match their location
+ * in the configuration.
+ */
+ for (c = 0; c < children; c++) {
+ if (child[c] == NULL) {
+ nvlist_t *missing;
+ if (nvlist_alloc(&missing, NV_UNIQUE_NAME,
+ 0) != 0)
+ goto nomem;
+ if (nvlist_add_string(missing,
+ ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_MISSING) != 0 ||
+ nvlist_add_uint64(missing,
+ ZPOOL_CONFIG_ID, c) != 0 ||
+ nvlist_add_uint64(missing,
+ ZPOOL_CONFIG_GUID, 0ULL) != 0) {
+ nvlist_free(missing);
+ goto nomem;
+ }
+ child[c] = missing;
+ }
+ }
+
+ /*
+ * Put all of this pool's top-level vdevs into a root vdev.
+ */
+ if (nvlist_alloc(&nvroot, NV_UNIQUE_NAME, 0) != 0)
+ goto nomem;
+ if (nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_ROOT) != 0 ||
+ nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) != 0 ||
+ nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, guid) != 0 ||
+ nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ child, children) != 0) {
+ nvlist_free(nvroot);
+ goto nomem;
+ }
+
+ for (c = 0; c < children; c++)
+ nvlist_free(child[c]);
+ free(child);
+ children = 0;
+ child = NULL;
+
+ /*
+ * Go through and fix up any paths and/or devids based on our
+ * known list of vdev GUID -> path mappings.
+ */
+ if (fix_paths(nvroot, pl->names) != 0) {
+ nvlist_free(nvroot);
+ goto nomem;
+ }
+
+ /*
+ * Add the root vdev to this pool's configuration.
+ */
+ if (nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ nvroot) != 0) {
+ nvlist_free(nvroot);
+ goto nomem;
+ }
+ nvlist_free(nvroot);
+
+ /*
+ * zdb uses this path to report on active pools that were
+ * imported or created using -R.
+ */
+ if (active_ok)
+ goto add_pool;
+
+ /*
+ * Determine if this pool is currently active, in which case we
+ * can't actually import it.
+ */
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &guid) == 0);
+
+ if (pool_active(hdl, name, guid, &isactive) != 0)
+ goto error;
+
+ if (isactive) {
+ nvlist_free(config);
+ config = NULL;
+ continue;
+ }
+
+ if ((nvl = refresh_config(hdl, config)) == NULL) {
+ nvlist_free(config);
+ config = NULL;
+ continue;
+ }
+
+ nvlist_free(config);
+ config = nvl;
+
+ /*
+ * Go through and update the paths for spares, now that we have
+ * them.
+ */
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ &spares, &nspares) == 0) {
+ for (i = 0; i < nspares; i++) {
+ if (fix_paths(spares[i], pl->names) != 0)
+ goto nomem;
+ }
+ }
+
+ /*
+ * Update the paths for l2cache devices.
+ */
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+ &l2cache, &nl2cache) == 0) {
+ for (i = 0; i < nl2cache; i++) {
+ if (fix_paths(l2cache[i], pl->names) != 0)
+ goto nomem;
+ }
+ }
+
+ /*
+ * Restore the original information read from the actual label.
+ */
+ (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTID,
+ DATA_TYPE_UINT64);
+ (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTNAME,
+ DATA_TYPE_STRING);
+ if (hostid != 0) {
+ verify(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
+ hostid) == 0);
+ verify(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME,
+ hostname) == 0);
+ }
+
+add_pool:
+ /*
+ * Add this pool to the list of configs.
+ */
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+ if (nvlist_add_nvlist(ret, name, config) != 0)
+ goto nomem;
+
+ found_one = B_TRUE;
+ nvlist_free(config);
+ config = NULL;
+ }
+
+ if (!found_one) {
+ nvlist_free(ret);
+ ret = NULL;
+ }
+
+ return (ret);
+
+nomem:
+ (void) no_memory(hdl);
+error:
+ nvlist_free(config);
+ nvlist_free(ret);
+ for (c = 0; c < children; c++)
+ nvlist_free(child[c]);
+ free(child);
+
+ return (NULL);
+}
+
+/*
+ * Return the offset of the given label.
+ */
+static uint64_t
+label_offset(uint64_t size, int l)
+{
+ ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
+ return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
+ 0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
+}
+
+/*
+ * Given a file descriptor, read the label information and return an nvlist
+ * describing the configuration, if there is one.
+ */
+int
+zpool_read_label(int fd, nvlist_t **config)
+{
+ struct stat64 statbuf;
+ int l;
+ vdev_label_t *label;
+ uint64_t state, txg, size;
+
+ *config = NULL;
+
+ if (fstat64(fd, &statbuf) == -1)
+ return (0);
+ size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
+
+ if ((label = malloc(sizeof (vdev_label_t))) == NULL)
+ return (-1);
+
+ for (l = 0; l < VDEV_LABELS; l++) {
+ if (pread64(fd, label, sizeof (vdev_label_t),
+ label_offset(size, l)) != sizeof (vdev_label_t))
+ continue;
+
+ if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
+ sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0)
+ continue;
+
+ if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
+ &state) != 0 || state > POOL_STATE_L2CACHE) {
+ nvlist_free(*config);
+ continue;
+ }
+
+ if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+ (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
+ &txg) != 0 || txg == 0)) {
+ nvlist_free(*config);
+ continue;
+ }
+
+ free(label);
+ return (0);
+ }
+
+ free(label);
+ *config = NULL;
+ return (0);
+}
+
+typedef struct rdsk_node {
+ char *rn_name;
+ int rn_dfd;
+ libzfs_handle_t *rn_hdl;
+ nvlist_t *rn_config;
+ avl_tree_t *rn_avl;
+ avl_node_t rn_node;
+ boolean_t rn_nozpool;
+} rdsk_node_t;
+
+static int
+slice_cache_compare(const void *arg1, const void *arg2)
+{
+ const char *nm1 = ((rdsk_node_t *)arg1)->rn_name;
+ const char *nm2 = ((rdsk_node_t *)arg2)->rn_name;
+ char *nm1slice, *nm2slice;
+ int rv;
+
+ /*
+ * slices zero and two are the most likely to provide results,
+ * so put those first
+ */
+ nm1slice = strstr(nm1, "s0");
+ nm2slice = strstr(nm2, "s0");
+ if (nm1slice && !nm2slice) {
+ return (-1);
+ }
+ if (!nm1slice && nm2slice) {
+ return (1);
+ }
+ nm1slice = strstr(nm1, "s2");
+ nm2slice = strstr(nm2, "s2");
+ if (nm1slice && !nm2slice) {
+ return (-1);
+ }
+ if (!nm1slice && nm2slice) {
+ return (1);
+ }
+
+ rv = strcmp(nm1, nm2);
+ if (rv == 0)
+ return (0);
+ return (rv > 0 ? 1 : -1);
+}
+
+#ifdef sun
+static void
+check_one_slice(avl_tree_t *r, char *diskname, uint_t partno,
+ diskaddr_t size, uint_t blksz)
+{
+ rdsk_node_t tmpnode;
+ rdsk_node_t *node;
+ char sname[MAXNAMELEN];
+
+ tmpnode.rn_name = &sname[0];
+ (void) snprintf(tmpnode.rn_name, MAXNAMELEN, "%s%u",
+ diskname, partno);
+ /*
+ * protect against division by zero for disk labels that
+ * contain a bogus sector size
+ */
+ if (blksz == 0)
+ blksz = DEV_BSIZE;
+ /* too small to contain a zpool? */
+ if ((size < (SPA_MINDEVSIZE / blksz)) &&
+ (node = avl_find(r, &tmpnode, NULL)))
+ node->rn_nozpool = B_TRUE;
+}
+#endif /* sun */
+
+static void
+nozpool_all_slices(avl_tree_t *r, const char *sname)
+{
+#ifdef sun
+ char diskname[MAXNAMELEN];
+ char *ptr;
+ int i;
+
+ (void) strncpy(diskname, sname, MAXNAMELEN);
+ if (((ptr = strrchr(diskname, 's')) == NULL) &&
+ ((ptr = strrchr(diskname, 'p')) == NULL))
+ return;
+ ptr[0] = 's';
+ ptr[1] = '\0';
+ for (i = 0; i < NDKMAP; i++)
+ check_one_slice(r, diskname, i, 0, 1);
+ ptr[0] = 'p';
+ for (i = 0; i <= FD_NUMPART; i++)
+ check_one_slice(r, diskname, i, 0, 1);
+#endif /* sun */
+}
+
+static void
+check_slices(avl_tree_t *r, int fd, const char *sname)
+{
+#ifdef sun
+ struct extvtoc vtoc;
+ struct dk_gpt *gpt;
+ char diskname[MAXNAMELEN];
+ char *ptr;
+ int i;
+
+ (void) strncpy(diskname, sname, MAXNAMELEN);
+ if ((ptr = strrchr(diskname, 's')) == NULL || !isdigit(ptr[1]))
+ return;
+ ptr[1] = '\0';
+
+ if (read_extvtoc(fd, &vtoc) >= 0) {
+ for (i = 0; i < NDKMAP; i++)
+ check_one_slice(r, diskname, i,
+ vtoc.v_part[i].p_size, vtoc.v_sectorsz);
+ } else if (efi_alloc_and_read(fd, &gpt) >= 0) {
+ /*
+ * on x86 we'll still have leftover links that point
+ * to slices s[9-15], so use NDKMAP instead
+ */
+ for (i = 0; i < NDKMAP; i++)
+ check_one_slice(r, diskname, i,
+ gpt->efi_parts[i].p_size, gpt->efi_lbasize);
+ /* nodes p[1-4] are never used with EFI labels */
+ ptr[0] = 'p';
+ for (i = 1; i <= FD_NUMPART; i++)
+ check_one_slice(r, diskname, i, 0, 1);
+ efi_free(gpt);
+ }
+#endif /* sun */
+}
+
+static void
+zpool_open_func(void *arg)
+{
+ rdsk_node_t *rn = arg;
+ struct stat64 statbuf;
+ nvlist_t *config;
+ int fd;
+
+ if (rn->rn_nozpool)
+ return;
+ if ((fd = openat64(rn->rn_dfd, rn->rn_name, O_RDONLY)) < 0) {
+ /* symlink to a device that's no longer there */
+ if (errno == ENOENT)
+ nozpool_all_slices(rn->rn_avl, rn->rn_name);
+ return;
+ }
+ /*
+ * Ignore failed stats. We only want regular
+ * files, character devs and block devs.
+ */
+ if (fstat64(fd, &statbuf) != 0 ||
+ (!S_ISREG(statbuf.st_mode) &&
+ !S_ISCHR(statbuf.st_mode) &&
+ !S_ISBLK(statbuf.st_mode))) {
+ (void) close(fd);
+ return;
+ }
+ /* this file is too small to hold a zpool */
+ if (S_ISREG(statbuf.st_mode) &&
+ statbuf.st_size < SPA_MINDEVSIZE) {
+ (void) close(fd);
+ return;
+ } else if (!S_ISREG(statbuf.st_mode)) {
+ /*
+ * Try to read the disk label first so we don't have to
+ * open a bunch of minor nodes that can't have a zpool.
+ */
+ check_slices(rn->rn_avl, fd, rn->rn_name);
+ }
+
+ if ((zpool_read_label(fd, &config)) != 0) {
+ (void) close(fd);
+ (void) no_memory(rn->rn_hdl);
+ return;
+ }
+ (void) close(fd);
+
+
+ rn->rn_config = config;
+ if (config != NULL) {
+ assert(rn->rn_nozpool == B_FALSE);
+ }
+}
+
+/*
+ * Given a file descriptor, clear (zero) the label information. This function
+ * is used in the appliance stack as part of the ZFS sysevent module and
+ * to implement the "zpool labelclear" command.
+ */
+int
+zpool_clear_label(int fd)
+{
+ struct stat64 statbuf;
+ int l;
+ vdev_label_t *label;
+ uint64_t size;
+
+ if (fstat64(fd, &statbuf) == -1)
+ return (0);
+ size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
+
+ if ((label = calloc(sizeof (vdev_label_t), 1)) == NULL)
+ return (-1);
+
+ for (l = 0; l < VDEV_LABELS; l++) {
+ if (pwrite64(fd, label, sizeof (vdev_label_t),
+ label_offset(size, l)) != sizeof (vdev_label_t))
+ return (-1);
+ }
+
+ free(label);
+ return (0);
+}
+
+/*
+ * Given a list of directories to search, find all pools stored on disk. This
+ * includes partial pools which are not available to import. If no args are
+ * given (argc is 0), then the default directory (/dev/dsk) is searched.
+ * poolname or guid (but not both) are provided by the caller when trying
+ * to import a specific pool.
+ */
+static nvlist_t *
+zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
+{
+ int i, dirs = iarg->paths;
+ DIR *dirp = NULL;
+ struct dirent64 *dp;
+ char path[MAXPATHLEN];
+ char *end, **dir = iarg->path;
+ size_t pathleft;
+ nvlist_t *ret = NULL;
+ static char *default_dir = "/dev";
+ pool_list_t pools = { 0 };
+ pool_entry_t *pe, *penext;
+ vdev_entry_t *ve, *venext;
+ config_entry_t *ce, *cenext;
+ name_entry_t *ne, *nenext;
+ avl_tree_t slice_cache;
+ rdsk_node_t *slice;
+ void *cookie;
+
+ if (dirs == 0) {
+ dirs = 1;
+ dir = &default_dir;
+ }
+
+ /*
+ * Go through and read the label configuration information from every
+ * possible device, organizing the information according to pool GUID
+ * and toplevel GUID.
+ */
+ for (i = 0; i < dirs; i++) {
+ tpool_t *t;
+ char *rdsk;
+ int dfd;
+
+ /* use realpath to normalize the path */
+ if (realpath(dir[i], path) == 0) {
+ (void) zfs_error_fmt(hdl, EZFS_BADPATH,
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]);
+ goto error;
+ }
+ end = &path[strlen(path)];
+ *end++ = '/';
+ *end = 0;
+ pathleft = &path[sizeof (path)] - end;
+
+ /*
+ * Using raw devices instead of block devices when we're
+ * reading the labels skips a bunch of slow operations during
+ * close(2) processing, so we replace /dev/dsk with /dev/rdsk.
+ */
+ if (strcmp(path, "/dev/dsk/") == 0)
+ rdsk = "/dev/";
+ else
+ rdsk = path;
+
+ if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
+ (dirp = fdopendir(dfd)) == NULL) {
+ zfs_error_aux(hdl, strerror(errno));
+ (void) zfs_error_fmt(hdl, EZFS_BADPATH,
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"),
+ rdsk);
+ goto error;
+ }
+
+ avl_create(&slice_cache, slice_cache_compare,
+ sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node));
+
+ if (strcmp(rdsk, "/dev/") == 0) {
+ struct gmesh mesh;
+ struct gclass *mp;
+ struct ggeom *gp;
+ struct gprovider *pp;
+
+ errno = geom_gettree(&mesh);
+ if (errno != 0) {
+ zfs_error_aux(hdl, strerror(errno));
+ (void) zfs_error_fmt(hdl, EZFS_BADPATH,
+ dgettext(TEXT_DOMAIN, "cannot get GEOM tree"));
+ goto error;
+ }
+
+ LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
+ LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ slice = zfs_alloc(hdl, sizeof (rdsk_node_t));
+ slice->rn_name = zfs_strdup(hdl, pp->lg_name);
+ slice->rn_avl = &slice_cache;
+ slice->rn_dfd = dfd;
+ slice->rn_hdl = hdl;
+ slice->rn_nozpool = B_FALSE;
+ avl_add(&slice_cache, slice);
+ }
+ }
+ }
+
+ geom_deletetree(&mesh);
+ goto skipdir;
+ }
+
+ /*
+ * This is not MT-safe, but we have no MT consumers of libzfs
+ */
+ while ((dp = readdir64(dirp)) != NULL) {
+ const char *name = dp->d_name;
+ if (name[0] == '.' &&
+ (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
+ continue;
+
+ slice = zfs_alloc(hdl, sizeof (rdsk_node_t));
+ slice->rn_name = zfs_strdup(hdl, name);
+ slice->rn_avl = &slice_cache;
+ slice->rn_dfd = dfd;
+ slice->rn_hdl = hdl;
+ slice->rn_nozpool = B_FALSE;
+ avl_add(&slice_cache, slice);
+ }
+skipdir:
+ /*
+ * create a thread pool to do all of this in parallel;
+ * rn_nozpool is not protected, so this is racy in that
+ * multiple tasks could decide that the same slice can
+ * not hold a zpool, which is benign. Also choose
+ * double the number of processors; we hold a lot of
+ * locks in the kernel, so going beyond this doesn't
+ * buy us much.
+ */
+ t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN),
+ 0, NULL);
+ for (slice = avl_first(&slice_cache); slice;
+ (slice = avl_walk(&slice_cache, slice,
+ AVL_AFTER)))
+ (void) tpool_dispatch(t, zpool_open_func, slice);
+ tpool_wait(t);
+ tpool_destroy(t);
+
+ cookie = NULL;
+ while ((slice = avl_destroy_nodes(&slice_cache,
+ &cookie)) != NULL) {
+ if (slice->rn_config != NULL) {
+ nvlist_t *config = slice->rn_config;
+ boolean_t matched = B_TRUE;
+
+ if (iarg->poolname != NULL) {
+ char *pname;
+
+ matched = nvlist_lookup_string(config,
+ ZPOOL_CONFIG_POOL_NAME,
+ &pname) == 0 &&
+ strcmp(iarg->poolname, pname) == 0;
+ } else if (iarg->guid != 0) {
+ uint64_t this_guid;
+
+ matched = nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_GUID,
+ &this_guid) == 0 &&
+ iarg->guid == this_guid;
+ }
+ if (!matched) {
+ nvlist_free(config);
+ config = NULL;
+ continue;
+ }
+ /* use the non-raw path for the config */
+ (void) strlcpy(end, slice->rn_name, pathleft);
+ if (add_config(hdl, &pools, path, config) != 0)
+ goto error;
+ }
+ free(slice->rn_name);
+ free(slice);
+ }
+ avl_destroy(&slice_cache);
+
+ (void) closedir(dirp);
+ dirp = NULL;
+ }
+
+ ret = get_configs(hdl, &pools, iarg->can_be_active);
+
+error:
+ for (pe = pools.pools; pe != NULL; pe = penext) {
+ penext = pe->pe_next;
+ for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
+ venext = ve->ve_next;
+ for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
+ cenext = ce->ce_next;
+ if (ce->ce_config)
+ nvlist_free(ce->ce_config);
+ free(ce);
+ }
+ free(ve);
+ }
+ free(pe);
+ }
+
+ for (ne = pools.names; ne != NULL; ne = nenext) {
+ nenext = ne->ne_next;
+ if (ne->ne_name)
+ free(ne->ne_name);
+ free(ne);
+ }
+
+ if (dirp)
+ (void) closedir(dirp);
+
+ return (ret);
+}
+
+nvlist_t *
+zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
+{
+ importargs_t iarg = { 0 };
+
+ iarg.paths = argc;
+ iarg.path = argv;
+
+ return (zpool_find_import_impl(hdl, &iarg));
+}
+
+/*
+ * Given a cache file, return the contents as a list of importable pools.
+ * poolname or guid (but not both) are provided by the caller when trying
+ * to import a specific pool.
+ */
+nvlist_t *
+zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
+ char *poolname, uint64_t guid)
+{
+ char *buf;
+ int fd;
+ struct stat64 statbuf;
+ nvlist_t *raw, *src, *dst;
+ nvlist_t *pools;
+ nvpair_t *elem;
+ char *name;
+ uint64_t this_guid;
+ boolean_t active;
+
+ verify(poolname == NULL || guid == 0);
+
+ if ((fd = open(cachefile, O_RDONLY)) < 0) {
+ zfs_error_aux(hdl, "%s", strerror(errno));
+ (void) zfs_error(hdl, EZFS_BADCACHE,
+ dgettext(TEXT_DOMAIN, "failed to open cache file"));
+ return (NULL);
+ }
+
+ if (fstat64(fd, &statbuf) != 0) {
+ zfs_error_aux(hdl, "%s", strerror(errno));
+ (void) close(fd);
+ (void) zfs_error(hdl, EZFS_BADCACHE,
+ dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
+ return (NULL);
+ }
+
+ if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
+ (void) close(fd);
+ return (NULL);
+ }
+
+ if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
+ (void) close(fd);
+ free(buf);
+ (void) zfs_error(hdl, EZFS_BADCACHE,
+ dgettext(TEXT_DOMAIN,
+ "failed to read cache file contents"));
+ return (NULL);
+ }
+
+ (void) close(fd);
+
+ if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
+ free(buf);
+ (void) zfs_error(hdl, EZFS_BADCACHE,
+ dgettext(TEXT_DOMAIN,
+ "invalid or corrupt cache file contents"));
+ return (NULL);
+ }
+
+ free(buf);
+
+ /*
+ * Go through and get the current state of the pools and refresh their
+ * state.
+ */
+ if (nvlist_alloc(&pools, 0, 0) != 0) {
+ (void) no_memory(hdl);
+ nvlist_free(raw);
+ return (NULL);
+ }
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
+ verify(nvpair_value_nvlist(elem, &src) == 0);
+
+ verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+ if (poolname != NULL && strcmp(poolname, name) != 0)
+ continue;
+
+ verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
+ &this_guid) == 0);
+ if (guid != 0) {
+ verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
+ &this_guid) == 0);
+ if (guid != this_guid)
+ continue;
+ }
+
+ if (pool_active(hdl, name, this_guid, &active) != 0) {
+ nvlist_free(raw);
+ nvlist_free(pools);
+ return (NULL);
+ }
+
+ if (active)
+ continue;
+
+ if ((dst = refresh_config(hdl, src)) == NULL) {
+ nvlist_free(raw);
+ nvlist_free(pools);
+ return (NULL);
+ }
+
+ if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
+ (void) no_memory(hdl);
+ nvlist_free(dst);
+ nvlist_free(raw);
+ nvlist_free(pools);
+ return (NULL);
+ }
+ nvlist_free(dst);
+ }
+
+ nvlist_free(raw);
+ return (pools);
+}
+
+static int
+name_or_guid_exists(zpool_handle_t *zhp, void *data)
+{
+ importargs_t *import = data;
+ int found = 0;
+
+ if (import->poolname != NULL) {
+ char *pool_name;
+
+ verify(nvlist_lookup_string(zhp->zpool_config,
+ ZPOOL_CONFIG_POOL_NAME, &pool_name) == 0);
+ if (strcmp(pool_name, import->poolname) == 0)
+ found = 1;
+ } else {
+ uint64_t pool_guid;
+
+ verify(nvlist_lookup_uint64(zhp->zpool_config,
+ ZPOOL_CONFIG_POOL_GUID, &pool_guid) == 0);
+ if (pool_guid == import->guid)
+ found = 1;
+ }
+
+ zpool_close(zhp);
+ return (found);
+}
+
+nvlist_t *
+zpool_search_import(libzfs_handle_t *hdl, importargs_t *import)
+{
+ verify(import->poolname == NULL || import->guid == 0);
+
+ if (import->unique)
+ import->exists = zpool_iter(hdl, name_or_guid_exists, import);
+
+ if (import->cachefile != NULL)
+ return (zpool_find_import_cached(hdl, import->cachefile,
+ import->poolname, import->guid));
+
+ return (zpool_find_import_impl(hdl, import));
+}
+
+boolean_t
+find_guid(nvlist_t *nv, uint64_t guid)
+{
+ uint64_t tmp;
+ nvlist_t **child;
+ uint_t c, children;
+
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &tmp) == 0);
+ if (tmp == guid)
+ return (B_TRUE);
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++)
+ if (find_guid(child[c], guid))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+typedef struct aux_cbdata {
+ const char *cb_type;
+ uint64_t cb_guid;
+ zpool_handle_t *cb_zhp;
+} aux_cbdata_t;
+
+static int
+find_aux(zpool_handle_t *zhp, void *data)
+{
+ aux_cbdata_t *cbp = data;
+ nvlist_t **list;
+ uint_t i, count;
+ uint64_t guid;
+ nvlist_t *nvroot;
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+
+ if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
+ &list, &count) == 0) {
+ for (i = 0; i < count; i++) {
+ verify(nvlist_lookup_uint64(list[i],
+ ZPOOL_CONFIG_GUID, &guid) == 0);
+ if (guid == cbp->cb_guid) {
+ cbp->cb_zhp = zhp;
+ return (1);
+ }
+ }
+ }
+
+ zpool_close(zhp);
+ return (0);
+}
+
+/*
+ * Determines if the pool is in use. If so, it returns true and the state of
+ * the pool as well as the name of the pool. Both strings are allocated and
+ * must be freed by the caller.
+ */
+int
+zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
+ boolean_t *inuse)
+{
+ nvlist_t *config;
+ char *name;
+ boolean_t ret;
+ uint64_t guid, vdev_guid;
+ zpool_handle_t *zhp;
+ nvlist_t *pool_config;
+ uint64_t stateval, isspare;
+ aux_cbdata_t cb = { 0 };
+ boolean_t isactive;
+
+ *inuse = B_FALSE;
+
+ if (zpool_read_label(fd, &config) != 0) {
+ (void) no_memory(hdl);
+ return (-1);
+ }
+
+ if (config == NULL)
+ return (0);
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &stateval) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
+ &vdev_guid) == 0);
+
+ if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &guid) == 0);
+ }
+
+ switch (stateval) {
+ case POOL_STATE_EXPORTED:
+ /*
+ * A pool with an exported state may in fact be imported
+ * read-only, so check the in-core state to see if it's
+ * active and imported read-only. If it is, set
+ * its state to active.
+ */
+ if (pool_active(hdl, name, guid, &isactive) == 0 && isactive &&
+ (zhp = zpool_open_canfail(hdl, name)) != NULL &&
+ zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL))
+ stateval = POOL_STATE_ACTIVE;
+
+ ret = B_TRUE;
+ break;
+
+ case POOL_STATE_ACTIVE:
+ /*
+ * For an active pool, we have to determine if it's really part
+ * of a currently active pool (in which case the pool will exist
+ * and the guid will be the same), or whether it's part of an
+ * active pool that was disconnected without being explicitly
+ * exported.
+ */
+ if (pool_active(hdl, name, guid, &isactive) != 0) {
+ nvlist_free(config);
+ return (-1);
+ }
+
+ if (isactive) {
+ /*
+ * Because the device may have been removed while
+ * offlined, we only report it as active if the vdev is
+ * still present in the config. Otherwise, pretend like
+ * it's not in use.
+ */
+ if ((zhp = zpool_open_canfail(hdl, name)) != NULL &&
+ (pool_config = zpool_get_config(zhp, NULL))
+ != NULL) {
+ nvlist_t *nvroot;
+
+ verify(nvlist_lookup_nvlist(pool_config,
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+ ret = find_guid(nvroot, vdev_guid);
+ } else {
+ ret = B_FALSE;
+ }
+
+ /*
+ * If this is an active spare within another pool, we
+ * treat it like an unused hot spare. This allows the
+ * user to create a pool with a hot spare that currently
+ * in use within another pool. Since we return B_TRUE,
+ * libdiskmgt will continue to prevent generic consumers
+ * from using the device.
+ */
+ if (ret && nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
+ stateval = POOL_STATE_SPARE;
+
+ if (zhp != NULL)
+ zpool_close(zhp);
+ } else {
+ stateval = POOL_STATE_POTENTIALLY_ACTIVE;
+ ret = B_TRUE;
+ }
+ break;
+
+ case POOL_STATE_SPARE:
+ /*
+ * For a hot spare, it can be either definitively in use, or
+ * potentially active. To determine if it's in use, we iterate
+ * over all pools in the system and search for one with a spare
+ * with a matching guid.
+ *
+ * Due to the shared nature of spares, we don't actually report
+ * the potentially active case as in use. This means the user
+ * can freely create pools on the hot spares of exported pools,
+ * but to do otherwise makes the resulting code complicated, and
+ * we end up having to deal with this case anyway.
+ */
+ cb.cb_zhp = NULL;
+ cb.cb_guid = vdev_guid;
+ cb.cb_type = ZPOOL_CONFIG_SPARES;
+ if (zpool_iter(hdl, find_aux, &cb) == 1) {
+ name = (char *)zpool_get_name(cb.cb_zhp);
+ ret = TRUE;
+ } else {
+ ret = FALSE;
+ }
+ break;
+
+ case POOL_STATE_L2CACHE:
+
+ /*
+ * Check if any pool is currently using this l2cache device.
+ */
+ cb.cb_zhp = NULL;
+ cb.cb_guid = vdev_guid;
+ cb.cb_type = ZPOOL_CONFIG_L2CACHE;
+ if (zpool_iter(hdl, find_aux, &cb) == 1) {
+ name = (char *)zpool_get_name(cb.cb_zhp);
+ ret = TRUE;
+ } else {
+ ret = FALSE;
+ }
+ break;
+
+ default:
+ ret = B_FALSE;
+ }
+
+
+ if (ret) {
+ if ((*namestr = zfs_strdup(hdl, name)) == NULL) {
+ if (cb.cb_zhp)
+ zpool_close(cb.cb_zhp);
+ nvlist_free(config);
+ return (-1);
+ }
+ *state = (pool_state_t)stateval;
+ }
+
+ if (cb.cb_zhp)
+ zpool_close(cb.cb_zhp);
+
+ nvlist_free(config);
+ *inuse = ret;
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
new file mode 100644
index 0000000..278bfd4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
@@ -0,0 +1,471 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <libintl.h>
+#include <libzfs.h>
+
+#include "libzfs_impl.h"
+
+int
+zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
+{
+ nvlist_t *nvl = zfs_get_clones_nvl(zhp);
+ nvpair_t *pair;
+
+ if (nvl == NULL)
+ return (0);
+
+ for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
+ pair = nvlist_next_nvpair(nvl, pair)) {
+ zfs_handle_t *clone = zfs_open(zhp->zfs_hdl, nvpair_name(pair),
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (clone != NULL) {
+ int err = func(clone, data);
+ if (err != 0)
+ return (err);
+ }
+ }
+ return (0);
+}
+
+static int
+zfs_do_list_ioctl(zfs_handle_t *zhp, unsigned long arg, zfs_cmd_t *zc)
+{
+ int rc;
+ uint64_t orig_cookie;
+
+ orig_cookie = zc->zc_cookie;
+top:
+ (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
+ rc = ioctl(zhp->zfs_hdl->libzfs_fd, arg, zc);
+
+ if (rc == -1) {
+ switch (errno) {
+ case ENOMEM:
+ /* expand nvlist memory and try again */
+ if (zcmd_expand_dst_nvlist(zhp->zfs_hdl, zc) != 0) {
+ zcmd_free_nvlists(zc);
+ return (-1);
+ }
+ zc->zc_cookie = orig_cookie;
+ goto top;
+ /*
+ * An errno value of ESRCH indicates normal completion.
+ * If ENOENT is returned, then the underlying dataset
+ * has been removed since we obtained the handle.
+ */
+ case ESRCH:
+ case ENOENT:
+ rc = 1;
+ break;
+ default:
+ rc = zfs_standard_error(zhp->zfs_hdl, errno,
+ dgettext(TEXT_DOMAIN,
+ "cannot iterate filesystems"));
+ break;
+ }
+ }
+ return (rc);
+}
+
+/*
+ * Iterate over all child filesystems
+ */
+int
+zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
+{
+ zfs_cmd_t zc = { 0 };
+ zfs_handle_t *nzhp;
+ int ret;
+
+ if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
+ return (0);
+
+ if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
+ return (-1);
+
+ while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT,
+ &zc)) == 0) {
+ /*
+ * Silently ignore errors, as the only plausible explanation is
+ * that the pool has since been removed.
+ */
+ if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
+ &zc)) == NULL) {
+ continue;
+ }
+
+ if ((ret = func(nzhp, data)) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (ret);
+ }
+ }
+ zcmd_free_nvlists(&zc);
+ return ((ret < 0) ? ret : 0);
+}
+
+/*
+ * Iterate over all snapshots
+ */
+int
+zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
+ void *data)
+{
+ zfs_cmd_t zc = { 0 };
+ zfs_handle_t *nzhp;
+ int ret;
+
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
+ return (0);
+
+ zc.zc_simple = simple;
+
+ if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
+ return (-1);
+ while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
+ &zc)) == 0) {
+
+ if (simple)
+ nzhp = make_dataset_simple_handle_zc(zhp, &zc);
+ else
+ nzhp = make_dataset_handle_zc(zhp->zfs_hdl, &zc);
+ if (nzhp == NULL)
+ continue;
+
+ if ((ret = func(nzhp, data)) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (ret);
+ }
+ }
+ zcmd_free_nvlists(&zc);
+ return ((ret < 0) ? ret : 0);
+}
+
+/*
+ * Routines for dealing with the sorted snapshot functionality
+ */
+typedef struct zfs_node {
+ zfs_handle_t *zn_handle;
+ avl_node_t zn_avlnode;
+} zfs_node_t;
+
+static int
+zfs_sort_snaps(zfs_handle_t *zhp, void *data)
+{
+ avl_tree_t *avl = data;
+ zfs_node_t *node;
+ zfs_node_t search;
+
+ search.zn_handle = zhp;
+ node = avl_find(avl, &search, NULL);
+ if (node) {
+ /*
+ * If this snapshot was renamed while we were creating the
+ * AVL tree, it's possible that we already inserted it under
+ * its old name. Remove the old handle before adding the new
+ * one.
+ */
+ zfs_close(node->zn_handle);
+ avl_remove(avl, node);
+ free(node);
+ }
+
+ node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t));
+ node->zn_handle = zhp;
+ avl_add(avl, node);
+
+ return (0);
+}
+
+static int
+zfs_snapshot_compare(const void *larg, const void *rarg)
+{
+ zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
+ zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
+ uint64_t lcreate, rcreate;
+
+ /*
+ * Sort them according to creation time. We use the hidden
+ * CREATETXG property to get an absolute ordering of snapshots.
+ */
+ lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
+ rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
+
+ if (lcreate < rcreate)
+ return (-1);
+ else if (lcreate > rcreate)
+ return (+1);
+ else
+ return (0);
+}
+
+int
+zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
+{
+ int ret = 0;
+ zfs_node_t *node;
+ avl_tree_t avl;
+ void *cookie = NULL;
+
+ avl_create(&avl, zfs_snapshot_compare,
+ sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
+
+ ret = zfs_iter_snapshots(zhp, B_FALSE, zfs_sort_snaps, &avl);
+
+ for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
+ ret |= callback(node->zn_handle, data);
+
+ while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL)
+ free(node);
+
+ avl_destroy(&avl);
+
+ return (ret);
+}
+
+typedef struct {
+ char *ssa_first;
+ char *ssa_last;
+ boolean_t ssa_seenfirst;
+ boolean_t ssa_seenlast;
+ zfs_iter_f ssa_func;
+ void *ssa_arg;
+} snapspec_arg_t;
+
+static int
+snapspec_cb(zfs_handle_t *zhp, void *arg) {
+ snapspec_arg_t *ssa = arg;
+ char *shortsnapname;
+ int err = 0;
+
+ if (ssa->ssa_seenlast)
+ return (0);
+ shortsnapname = zfs_strdup(zhp->zfs_hdl,
+ strchr(zfs_get_name(zhp), '@') + 1);
+
+ if (!ssa->ssa_seenfirst && strcmp(shortsnapname, ssa->ssa_first) == 0)
+ ssa->ssa_seenfirst = B_TRUE;
+
+ if (ssa->ssa_seenfirst) {
+ err = ssa->ssa_func(zhp, ssa->ssa_arg);
+ } else {
+ zfs_close(zhp);
+ }
+
+ if (strcmp(shortsnapname, ssa->ssa_last) == 0)
+ ssa->ssa_seenlast = B_TRUE;
+ free(shortsnapname);
+
+ return (err);
+}
+
+/*
+ * spec is a string like "A,B%C,D"
+ *
+ * <snaps>, where <snaps> can be:
+ * <snap> (single snapshot)
+ * <snap>%<snap> (range of snapshots, inclusive)
+ * %<snap> (range of snapshots, starting with earliest)
+ * <snap>% (range of snapshots, ending with last)
+ * % (all snapshots)
+ * <snaps>[,...] (comma separated list of the above)
+ *
+ * If a snapshot can not be opened, continue trying to open the others, but
+ * return ENOENT at the end.
+ */
+int
+zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
+ zfs_iter_f func, void *arg)
+{
+ char *buf, *comma_separated, *cp;
+ int err = 0;
+ int ret = 0;
+
+ buf = zfs_strdup(fs_zhp->zfs_hdl, spec_orig);
+ cp = buf;
+
+ while ((comma_separated = strsep(&cp, ",")) != NULL) {
+ char *pct = strchr(comma_separated, '%');
+ if (pct != NULL) {
+ snapspec_arg_t ssa = { 0 };
+ ssa.ssa_func = func;
+ ssa.ssa_arg = arg;
+
+ if (pct == comma_separated)
+ ssa.ssa_seenfirst = B_TRUE;
+ else
+ ssa.ssa_first = comma_separated;
+ *pct = '\0';
+ ssa.ssa_last = pct + 1;
+
+ /*
+ * If there is a lastname specified, make sure it
+ * exists.
+ */
+ if (ssa.ssa_last[0] != '\0') {
+ char snapname[ZFS_MAXNAMELEN];
+ (void) snprintf(snapname, sizeof (snapname),
+ "%s@%s", zfs_get_name(fs_zhp),
+ ssa.ssa_last);
+ if (!zfs_dataset_exists(fs_zhp->zfs_hdl,
+ snapname, ZFS_TYPE_SNAPSHOT)) {
+ ret = ENOENT;
+ continue;
+ }
+ }
+
+ err = zfs_iter_snapshots_sorted(fs_zhp,
+ snapspec_cb, &ssa);
+ if (ret == 0)
+ ret = err;
+ if (ret == 0 && (!ssa.ssa_seenfirst ||
+ (ssa.ssa_last[0] != '\0' && !ssa.ssa_seenlast))) {
+ ret = ENOENT;
+ }
+ } else {
+ char snapname[ZFS_MAXNAMELEN];
+ zfs_handle_t *snap_zhp;
+ (void) snprintf(snapname, sizeof (snapname), "%s@%s",
+ zfs_get_name(fs_zhp), comma_separated);
+ snap_zhp = make_dataset_handle(fs_zhp->zfs_hdl,
+ snapname);
+ if (snap_zhp == NULL) {
+ ret = ENOENT;
+ continue;
+ }
+ err = func(snap_zhp, arg);
+ if (ret == 0)
+ ret = err;
+ }
+ }
+
+ free(buf);
+ return (ret);
+}
+
+/*
+ * Iterate over all children, snapshots and filesystems
+ */
+int
+zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
+{
+ int ret;
+
+ if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
+ return (ret);
+
+ return (zfs_iter_snapshots(zhp, B_FALSE, func, data));
+}
+
+
+typedef struct iter_stack_frame {
+ struct iter_stack_frame *next;
+ zfs_handle_t *zhp;
+} iter_stack_frame_t;
+
+typedef struct iter_dependents_arg {
+ boolean_t first;
+ boolean_t allowrecursion;
+ iter_stack_frame_t *stack;
+ zfs_iter_f func;
+ void *data;
+} iter_dependents_arg_t;
+
+static int
+iter_dependents_cb(zfs_handle_t *zhp, void *arg)
+{
+ iter_dependents_arg_t *ida = arg;
+ int err;
+ boolean_t first = ida->first;
+ ida->first = B_FALSE;
+
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
+ err = zfs_iter_clones(zhp, iter_dependents_cb, ida);
+ } else {
+ iter_stack_frame_t isf;
+ iter_stack_frame_t *f;
+
+ /*
+ * check if there is a cycle by seeing if this fs is already
+ * on the stack.
+ */
+ for (f = ida->stack; f != NULL; f = f->next) {
+ if (f->zhp->zfs_dmustats.dds_guid ==
+ zhp->zfs_dmustats.dds_guid) {
+ if (ida->allowrecursion) {
+ zfs_close(zhp);
+ return (0);
+ } else {
+ zfs_error_aux(zhp->zfs_hdl,
+ dgettext(TEXT_DOMAIN,
+ "recursive dependency at '%s'"),
+ zfs_get_name(zhp));
+ err = zfs_error(zhp->zfs_hdl,
+ EZFS_RECURSIVE,
+ dgettext(TEXT_DOMAIN,
+ "cannot determine dependent "
+ "datasets"));
+ zfs_close(zhp);
+ return (err);
+ }
+ }
+ }
+
+ isf.zhp = zhp;
+ isf.next = ida->stack;
+ ida->stack = &isf;
+ err = zfs_iter_filesystems(zhp, iter_dependents_cb, ida);
+ if (err == 0) {
+ err = zfs_iter_snapshots(zhp, B_FALSE,
+ iter_dependents_cb, ida);
+ }
+ ida->stack = isf.next;
+ }
+ if (!first && err == 0)
+ err = ida->func(zhp, ida->data);
+ return (err);
+}
+
+int
+zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
+ zfs_iter_f func, void *data)
+{
+ iter_dependents_arg_t ida;
+ ida.allowrecursion = allowrecursion;
+ ida.stack = NULL;
+ ida.func = func;
+ ida.data = data;
+ ida.first = B_TRUE;
+ return (iter_dependents_cb(zfs_handle_dup(zhp), &ida));
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
new file mode 100644
index 0000000..b2959dd
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
@@ -0,0 +1,1323 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Routines to manage ZFS mounts. We separate all the nasty routines that have
+ * to deal with the OS. The following functions are the main entry points --
+ * they are used by mount and unmount and when changing a filesystem's
+ * mountpoint.
+ *
+ * zfs_is_mounted()
+ * zfs_mount()
+ * zfs_unmount()
+ * zfs_unmountall()
+ *
+ * This file also contains the functions used to manage sharing filesystems via
+ * NFS and iSCSI:
+ *
+ * zfs_is_shared()
+ * zfs_share()
+ * zfs_unshare()
+ *
+ * zfs_is_shared_nfs()
+ * zfs_is_shared_smb()
+ * zfs_share_proto()
+ * zfs_shareall();
+ * zfs_unshare_nfs()
+ * zfs_unshare_smb()
+ * zfs_unshareall_nfs()
+ * zfs_unshareall_smb()
+ * zfs_unshareall()
+ * zfs_unshareall_bypath()
+ *
+ * The following functions are available for pool consumers, and will
+ * mount/unmount and share/unshare all datasets within pool:
+ *
+ * zpool_enable_datasets()
+ * zpool_disable_datasets()
+ */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <zone.h>
+#include <sys/mntent.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <libzfs.h>
+
+#include "libzfs_impl.h"
+
+#include <libshare.h>
+#define MAXISALEN 257 /* based on sysinfo(2) man page */
+
+static int zfs_share_proto(zfs_handle_t *, zfs_share_proto_t *);
+zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
+ zfs_share_proto_t);
+
+/*
+ * The share protocols table must be in the same order as the zfs_share_prot_t
+ * enum in libzfs_impl.h
+ */
+typedef struct {
+ zfs_prop_t p_prop;
+ char *p_name;
+ int p_share_err;
+ int p_unshare_err;
+} proto_table_t;
+
+proto_table_t proto_table[PROTO_END] = {
+ {ZFS_PROP_SHARENFS, "nfs", EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED},
+ {ZFS_PROP_SHARESMB, "smb", EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED},
+};
+
+zfs_share_proto_t nfs_only[] = {
+ PROTO_NFS,
+ PROTO_END
+};
+
+zfs_share_proto_t smb_only[] = {
+ PROTO_SMB,
+ PROTO_END
+};
+zfs_share_proto_t share_all_proto[] = {
+ PROTO_NFS,
+ PROTO_SMB,
+ PROTO_END
+};
+
+/*
+ * Search the sharetab for the given mountpoint and protocol, returning
+ * a zfs_share_type_t value.
+ */
+static zfs_share_type_t
+is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto)
+{
+ char buf[MAXPATHLEN], *tab;
+ char *ptr;
+
+ if (hdl->libzfs_sharetab == NULL)
+ return (SHARED_NOT_SHARED);
+
+ (void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET);
+
+ while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) {
+
+ /* the mountpoint is the first entry on each line */
+ if ((tab = strchr(buf, '\t')) == NULL)
+ continue;
+
+ *tab = '\0';
+ if (strcmp(buf, mountpoint) == 0) {
+#ifdef sun
+ /*
+ * the protocol field is the third field
+ * skip over second field
+ */
+ ptr = ++tab;
+ if ((tab = strchr(ptr, '\t')) == NULL)
+ continue;
+ ptr = ++tab;
+ if ((tab = strchr(ptr, '\t')) == NULL)
+ continue;
+ *tab = '\0';
+ if (strcmp(ptr,
+ proto_table[proto].p_name) == 0) {
+ switch (proto) {
+ case PROTO_NFS:
+ return (SHARED_NFS);
+ case PROTO_SMB:
+ return (SHARED_SMB);
+ default:
+ return (0);
+ }
+ }
+#else
+ if (proto == PROTO_NFS)
+ return (SHARED_NFS);
+#endif
+ }
+ }
+
+ return (SHARED_NOT_SHARED);
+}
+
+#ifdef sun
+/*
+ * Returns true if the specified directory is empty. If we can't open the
+ * directory at all, return true so that the mount can fail with a more
+ * informative error message.
+ */
+static boolean_t
+dir_is_empty(const char *dirname)
+{
+ DIR *dirp;
+ struct dirent64 *dp;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return (B_TRUE);
+
+ while ((dp = readdir64(dirp)) != NULL) {
+
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ (void) closedir(dirp);
+ return (B_FALSE);
+ }
+
+ (void) closedir(dirp);
+ return (B_TRUE);
+}
+#endif
+
+/*
+ * Checks to see if the mount is active. If the filesystem is mounted, we fill
+ * in 'where' with the current mountpoint, and return 1. Otherwise, we return
+ * 0.
+ */
+boolean_t
+is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
+{
+ struct mnttab entry;
+
+ if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
+ return (B_FALSE);
+
+ if (where != NULL)
+ *where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
+
+ return (B_TRUE);
+}
+
+boolean_t
+zfs_is_mounted(zfs_handle_t *zhp, char **where)
+{
+ return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
+}
+
+/*
+ * Returns true if the given dataset is mountable, false otherwise. Returns the
+ * mountpoint in 'buf'.
+ */
+static boolean_t
+zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
+ zprop_source_t *source)
+{
+ char sourceloc[ZFS_MAXNAMELEN];
+ zprop_source_t sourcetype;
+
+ if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type))
+ return (B_FALSE);
+
+ verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
+ &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
+
+ if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
+ strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
+ return (B_FALSE);
+
+ if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
+ return (B_FALSE);
+
+ if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
+ getzoneid() == GLOBAL_ZONEID)
+ return (B_FALSE);
+
+ if (source)
+ *source = sourcetype;
+
+ return (B_TRUE);
+}
+
+/*
+ * Mount the given filesystem.
+ */
+int
+zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
+{
+ struct stat buf;
+ char mountpoint[ZFS_MAXPROPLEN];
+ char mntopts[MNT_LINE_MAX];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+
+ if (options == NULL)
+ mntopts[0] = '\0';
+ else
+ (void) strlcpy(mntopts, options, sizeof (mntopts));
+
+ /*
+ * If the pool is imported read-only then all mounts must be read-only
+ */
+ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
+ flags |= MS_RDONLY;
+
+ if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
+ return (0);
+
+ /* Create the directory if it doesn't already exist */
+ if (lstat(mountpoint, &buf) != 0) {
+ if (mkdirp(mountpoint, 0755) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "failed to create mountpoint"));
+ return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
+ dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
+ mountpoint));
+ }
+ }
+
+#ifdef sun /* FreeBSD: overlay mounts are not checked. */
+ /*
+ * Determine if the mountpoint is empty. If so, refuse to perform the
+ * mount. We don't perform this check if MS_OVERLAY is specified, which
+ * would defeat the point. We also avoid this check if 'remount' is
+ * specified.
+ */
+ if ((flags & MS_OVERLAY) == 0 &&
+ strstr(mntopts, MNTOPT_REMOUNT) == NULL &&
+ !dir_is_empty(mountpoint)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "directory is not empty"));
+ return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
+ dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
+ }
+#endif
+
+ /* perform the mount */
+ if (zmount(zfs_get_name(zhp), mountpoint, flags,
+ MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) {
+ /*
+ * Generic errors are nasty, but there are just way too many
+ * from mount(), and they're well-understood. We pick a few
+ * common ones to improve upon.
+ */
+ if (errno == EBUSY) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "mountpoint or dataset is busy"));
+ } else if (errno == EPERM) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "Insufficient privileges"));
+ } else if (errno == ENOTSUP) {
+ char buf[256];
+ int spa_version;
+
+ VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
+ (void) snprintf(buf, sizeof (buf),
+ dgettext(TEXT_DOMAIN, "Can't mount a version %lld "
+ "file system on a version %d pool. Pool must be"
+ " upgraded to mount this file system."),
+ (u_longlong_t)zfs_prop_get_int(zhp,
+ ZFS_PROP_VERSION), spa_version);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf));
+ } else {
+ zfs_error_aux(hdl, strerror(errno));
+ }
+ return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
+ dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
+ zhp->zfs_name));
+ }
+
+ /* add the mounted entry into our cache */
+ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint,
+ mntopts);
+ return (0);
+}
+
+/*
+ * Unmount a single filesystem.
+ */
+static int
+unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
+{
+ if (umount2(mountpoint, flags) != 0) {
+ zfs_error_aux(hdl, strerror(errno));
+ return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED,
+ dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
+ mountpoint));
+ }
+
+ return (0);
+}
+
+/*
+ * Unmount the given filesystem.
+ */
+int
+zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ struct mnttab entry;
+ char *mntpt = NULL;
+
+ /* check to see if we need to unmount the filesystem */
+ if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
+ libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
+ /*
+ * mountpoint may have come from a call to
+ * getmnt/getmntany if it isn't NULL. If it is NULL,
+ * we know it comes from libzfs_mnttab_find which can
+ * then get freed later. We strdup it to play it safe.
+ */
+ if (mountpoint == NULL)
+ mntpt = zfs_strdup(hdl, entry.mnt_mountp);
+ else
+ mntpt = zfs_strdup(hdl, mountpoint);
+
+ /*
+ * Unshare and unmount the filesystem
+ */
+ if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0)
+ return (-1);
+
+ if (unmount_one(hdl, mntpt, flags) != 0) {
+ free(mntpt);
+ (void) zfs_shareall(zhp);
+ return (-1);
+ }
+ libzfs_mnttab_remove(hdl, zhp->zfs_name);
+ free(mntpt);
+ }
+
+ return (0);
+}
+
+/*
+ * Unmount this filesystem and any children inheriting the mountpoint property.
+ * To do this, just act like we're changing the mountpoint property, but don't
+ * remount the filesystems afterwards.
+ */
+int
+zfs_unmountall(zfs_handle_t *zhp, int flags)
+{
+ prop_changelist_t *clp;
+ int ret;
+
+ clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, 0, flags);
+ if (clp == NULL)
+ return (-1);
+
+ ret = changelist_prefix(clp);
+ changelist_free(clp);
+
+ return (ret);
+}
+
+boolean_t
+zfs_is_shared(zfs_handle_t *zhp)
+{
+ zfs_share_type_t rc = 0;
+ zfs_share_proto_t *curr_proto;
+
+ if (ZFS_IS_VOLUME(zhp))
+ return (B_FALSE);
+
+ for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
+ curr_proto++)
+ rc |= zfs_is_shared_proto(zhp, NULL, *curr_proto);
+
+ return (rc ? B_TRUE : B_FALSE);
+}
+
+int
+zfs_share(zfs_handle_t *zhp)
+{
+ assert(!ZFS_IS_VOLUME(zhp));
+ return (zfs_share_proto(zhp, share_all_proto));
+}
+
+int
+zfs_unshare(zfs_handle_t *zhp)
+{
+ assert(!ZFS_IS_VOLUME(zhp));
+ return (zfs_unshareall(zhp));
+}
+
+/*
+ * Check to see if the filesystem is currently shared.
+ */
+zfs_share_type_t
+zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto)
+{
+ char *mountpoint;
+ zfs_share_type_t rc;
+
+ if (!zfs_is_mounted(zhp, &mountpoint))
+ return (SHARED_NOT_SHARED);
+
+ if (rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) {
+ if (where != NULL)
+ *where = mountpoint;
+ else
+ free(mountpoint);
+ return (rc);
+ } else {
+ free(mountpoint);
+ return (SHARED_NOT_SHARED);
+ }
+}
+
+boolean_t
+zfs_is_shared_nfs(zfs_handle_t *zhp, char **where)
+{
+ return (zfs_is_shared_proto(zhp, where,
+ PROTO_NFS) != SHARED_NOT_SHARED);
+}
+
+boolean_t
+zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
+{
+ return (zfs_is_shared_proto(zhp, where,
+ PROTO_SMB) != SHARED_NOT_SHARED);
+}
+
+/*
+ * Make sure things will work if libshare isn't installed by using
+ * wrapper functions that check to see that the pointers to functions
+ * initialized in _zfs_init_libshare() are actually present.
+ */
+
+#ifdef sun
+static sa_handle_t (*_sa_init)(int);
+static void (*_sa_fini)(sa_handle_t);
+static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
+static int (*_sa_enable_share)(sa_share_t, char *);
+static int (*_sa_disable_share)(sa_share_t, char *);
+static char *(*_sa_errorstr)(int);
+static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
+static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
+static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
+static int (*_sa_zfs_process_share)(sa_handle_t, sa_group_t, sa_share_t,
+ char *, char *, zprop_source_t, char *, char *, char *);
+static void (*_sa_update_sharetab_ts)(sa_handle_t);
+#endif
+
+/*
+ * _zfs_init_libshare()
+ *
+ * Find the libshare.so.1 entry points that we use here and save the
+ * values to be used later. This is triggered by the runtime loader.
+ * Make sure the correct ISA version is loaded.
+ */
+
+#pragma init(_zfs_init_libshare)
+static void
+_zfs_init_libshare(void)
+{
+#ifdef sun
+ void *libshare;
+ char path[MAXPATHLEN];
+ char isa[MAXISALEN];
+
+#if defined(_LP64)
+ if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
+ isa[0] = '\0';
+#else
+ isa[0] = '\0';
+#endif
+ (void) snprintf(path, MAXPATHLEN,
+ "/usr/lib/%s/libshare.so.1", isa);
+
+ if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
+ _sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
+ _sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
+ _sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
+ dlsym(libshare, "sa_find_share");
+ _sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
+ "sa_enable_share");
+ _sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
+ "sa_disable_share");
+ _sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
+ _sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
+ dlsym(libshare, "sa_parse_legacy_options");
+ _sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
+ dlsym(libshare, "sa_needs_refresh");
+ _sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
+ dlsym(libshare, "sa_get_zfs_handle");
+ _sa_zfs_process_share = (int (*)(sa_handle_t, sa_group_t,
+ sa_share_t, char *, char *, zprop_source_t, char *,
+ char *, char *))dlsym(libshare, "sa_zfs_process_share");
+ _sa_update_sharetab_ts = (void (*)(sa_handle_t))
+ dlsym(libshare, "sa_update_sharetab_ts");
+ if (_sa_init == NULL || _sa_fini == NULL ||
+ _sa_find_share == NULL || _sa_enable_share == NULL ||
+ _sa_disable_share == NULL || _sa_errorstr == NULL ||
+ _sa_parse_legacy_options == NULL ||
+ _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
+ _sa_zfs_process_share == NULL ||
+ _sa_update_sharetab_ts == NULL) {
+ _sa_init = NULL;
+ _sa_fini = NULL;
+ _sa_disable_share = NULL;
+ _sa_enable_share = NULL;
+ _sa_errorstr = NULL;
+ _sa_parse_legacy_options = NULL;
+ (void) dlclose(libshare);
+ _sa_needs_refresh = NULL;
+ _sa_get_zfs_handle = NULL;
+ _sa_zfs_process_share = NULL;
+ _sa_update_sharetab_ts = NULL;
+ }
+ }
+#endif
+}
+
+/*
+ * zfs_init_libshare(zhandle, service)
+ *
+ * Initialize the libshare API if it hasn't already been initialized.
+ * In all cases it returns 0 if it succeeded and an error if not. The
+ * service value is which part(s) of the API to initialize and is a
+ * direct map to the libshare sa_init(service) interface.
+ */
+int
+zfs_init_libshare(libzfs_handle_t *zhandle, int service)
+{
+ int ret = SA_OK;
+
+#ifdef sun
+ if (_sa_init == NULL)
+ ret = SA_CONFIG_ERR;
+
+ if (ret == SA_OK && zhandle->libzfs_shareflags & ZFSSHARE_MISS) {
+ /*
+ * We had a cache miss. Most likely it is a new ZFS
+ * dataset that was just created. We want to make sure
+ * so check timestamps to see if a different process
+ * has updated any of the configuration. If there was
+ * some non-ZFS change, we need to re-initialize the
+ * internal cache.
+ */
+ zhandle->libzfs_shareflags &= ~ZFSSHARE_MISS;
+ if (_sa_needs_refresh != NULL &&
+ _sa_needs_refresh(zhandle->libzfs_sharehdl)) {
+ zfs_uninit_libshare(zhandle);
+ zhandle->libzfs_sharehdl = _sa_init(service);
+ }
+ }
+
+ if (ret == SA_OK && zhandle && zhandle->libzfs_sharehdl == NULL)
+ zhandle->libzfs_sharehdl = _sa_init(service);
+
+ if (ret == SA_OK && zhandle->libzfs_sharehdl == NULL)
+ ret = SA_NO_MEMORY;
+#endif
+
+ return (ret);
+}
+
+/*
+ * zfs_uninit_libshare(zhandle)
+ *
+ * Uninitialize the libshare API if it hasn't already been
+ * uninitialized. It is OK to call multiple times.
+ */
+void
+zfs_uninit_libshare(libzfs_handle_t *zhandle)
+{
+ if (zhandle != NULL && zhandle->libzfs_sharehdl != NULL) {
+#ifdef sun
+ if (_sa_fini != NULL)
+ _sa_fini(zhandle->libzfs_sharehdl);
+#endif
+ zhandle->libzfs_sharehdl = NULL;
+ }
+}
+
+/*
+ * zfs_parse_options(options, proto)
+ *
+ * Call the legacy parse interface to get the protocol specific
+ * options using the NULL arg to indicate that this is a "parse" only.
+ */
+int
+zfs_parse_options(char *options, zfs_share_proto_t proto)
+{
+#ifdef sun
+ if (_sa_parse_legacy_options != NULL) {
+ return (_sa_parse_legacy_options(NULL, options,
+ proto_table[proto].p_name));
+ }
+ return (SA_CONFIG_ERR);
+#else
+ return (SA_OK);
+#endif
+}
+
+#ifdef sun
+/*
+ * zfs_sa_find_share(handle, path)
+ *
+ * wrapper around sa_find_share to find a share path in the
+ * configuration.
+ */
+static sa_share_t
+zfs_sa_find_share(sa_handle_t handle, char *path)
+{
+ if (_sa_find_share != NULL)
+ return (_sa_find_share(handle, path));
+ return (NULL);
+}
+
+/*
+ * zfs_sa_enable_share(share, proto)
+ *
+ * Wrapper for sa_enable_share which enables a share for a specified
+ * protocol.
+ */
+static int
+zfs_sa_enable_share(sa_share_t share, char *proto)
+{
+ if (_sa_enable_share != NULL)
+ return (_sa_enable_share(share, proto));
+ return (SA_CONFIG_ERR);
+}
+
+/*
+ * zfs_sa_disable_share(share, proto)
+ *
+ * Wrapper for sa_enable_share which disables a share for a specified
+ * protocol.
+ */
+static int
+zfs_sa_disable_share(sa_share_t share, char *proto)
+{
+ if (_sa_disable_share != NULL)
+ return (_sa_disable_share(share, proto));
+ return (SA_CONFIG_ERR);
+}
+#endif /* sun */
+
+/*
+ * Share the given filesystem according to the options in the specified
+ * protocol specific properties (sharenfs, sharesmb). We rely
+ * on "libshare" to the dirty work for us.
+ */
+static int
+zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
+{
+ char mountpoint[ZFS_MAXPROPLEN];
+ char shareopts[ZFS_MAXPROPLEN];
+ char sourcestr[ZFS_MAXPROPLEN];
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ zfs_share_proto_t *curr_proto;
+ zprop_source_t sourcetype;
+ int error, ret;
+
+ if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
+ return (0);
+
+#ifdef sun
+ if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
+ (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
+ dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
+ zfs_get_name(zhp), _sa_errorstr != NULL ?
+ _sa_errorstr(ret) : "");
+ return (-1);
+ }
+#endif
+
+ for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
+ /*
+ * Return success if there are no share options.
+ */
+ if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
+ shareopts, sizeof (shareopts), &sourcetype, sourcestr,
+ ZFS_MAXPROPLEN, B_FALSE) != 0 ||
+ strcmp(shareopts, "off") == 0)
+ continue;
+
+ /*
+ * If the 'zoned' property is set, then zfs_is_mountable()
+ * will have already bailed out if we are in the global zone.
+ * But local zones cannot be NFS servers, so we ignore it for
+ * local zones as well.
+ */
+ if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
+ continue;
+
+#ifdef sun
+ share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
+ if (share == NULL) {
+ /*
+ * This may be a new file system that was just
+ * created so isn't in the internal cache
+ * (second time through). Rather than
+ * reloading the entire configuration, we can
+ * assume ZFS has done the checking and it is
+ * safe to add this to the internal
+ * configuration.
+ */
+ if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
+ NULL, NULL, mountpoint,
+ proto_table[*curr_proto].p_name, sourcetype,
+ shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
+ (void) zfs_error_fmt(hdl,
+ proto_table[*curr_proto].p_share_err,
+ dgettext(TEXT_DOMAIN, "cannot share '%s'"),
+ zfs_get_name(zhp));
+ return (-1);
+ }
+ hdl->libzfs_shareflags |= ZFSSHARE_MISS;
+ share = zfs_sa_find_share(hdl->libzfs_sharehdl,
+ mountpoint);
+ }
+ if (share != NULL) {
+ int err;
+ err = zfs_sa_enable_share(share,
+ proto_table[*curr_proto].p_name);
+ if (err != SA_OK) {
+ (void) zfs_error_fmt(hdl,
+ proto_table[*curr_proto].p_share_err,
+ dgettext(TEXT_DOMAIN, "cannot share '%s'"),
+ zfs_get_name(zhp));
+ return (-1);
+ }
+ } else
+#else
+ if (*curr_proto != PROTO_NFS) {
+ fprintf(stderr, "Unsupported share protocol: %d.\n",
+ *curr_proto);
+ continue;
+ }
+
+ if (strcmp(shareopts, "on") == 0)
+ error = fsshare(ZFS_EXPORTS_PATH, mountpoint, "");
+ else
+ error = fsshare(ZFS_EXPORTS_PATH, mountpoint, shareopts);
+ if (error != 0)
+#endif
+ {
+ (void) zfs_error_fmt(hdl,
+ proto_table[*curr_proto].p_share_err,
+ dgettext(TEXT_DOMAIN, "cannot share '%s'"),
+ zfs_get_name(zhp));
+ return (-1);
+ }
+
+ }
+ return (0);
+}
+
+
+int
+zfs_share_nfs(zfs_handle_t *zhp)
+{
+ return (zfs_share_proto(zhp, nfs_only));
+}
+
+int
+zfs_share_smb(zfs_handle_t *zhp)
+{
+ return (zfs_share_proto(zhp, smb_only));
+}
+
+int
+zfs_shareall(zfs_handle_t *zhp)
+{
+ return (zfs_share_proto(zhp, share_all_proto));
+}
+
+/*
+ * Unshare a filesystem by mountpoint.
+ */
+static int
+unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
+ zfs_share_proto_t proto)
+{
+#ifdef sun
+ sa_share_t share;
+ int err;
+ char *mntpt;
+ /*
+ * Mountpoint could get trashed if libshare calls getmntany
+ * which it does during API initialization, so strdup the
+ * value.
+ */
+ mntpt = zfs_strdup(hdl, mountpoint);
+
+ /* make sure libshare initialized */
+ if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
+ free(mntpt); /* don't need the copy anymore */
+ return (zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
+ dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
+ name, _sa_errorstr(err)));
+ }
+
+ share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
+ free(mntpt); /* don't need the copy anymore */
+
+ if (share != NULL) {
+ err = zfs_sa_disable_share(share, proto_table[proto].p_name);
+ if (err != SA_OK) {
+ return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
+ dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
+ name, _sa_errorstr(err)));
+ }
+ } else {
+ return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
+ dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
+ name));
+ }
+#else
+ char buf[MAXPATHLEN];
+ FILE *fp;
+ int err;
+
+ if (proto != PROTO_NFS) {
+ fprintf(stderr, "No SMB support in FreeBSD yet.\n");
+ return (EOPNOTSUPP);
+ }
+
+ err = fsunshare(ZFS_EXPORTS_PATH, mountpoint);
+ if (err != 0) {
+ zfs_error_aux(hdl, "%s", strerror(err));
+ return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
+ dgettext(TEXT_DOMAIN,
+ "cannot unshare '%s'"), name));
+ }
+#endif
+ return (0);
+}
+
+/*
+ * Unshare the given filesystem.
+ */
+int
+zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint,
+ zfs_share_proto_t *proto)
+{
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ struct mnttab entry;
+ char *mntpt = NULL;
+
+ /* check to see if need to unmount the filesystem */
+ rewind(zhp->zfs_hdl->libzfs_mnttab);
+ if (mountpoint != NULL)
+ mountpoint = mntpt = zfs_strdup(hdl, mountpoint);
+
+ if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
+ libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
+ zfs_share_proto_t *curr_proto;
+
+ if (mountpoint == NULL)
+ mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp);
+
+ for (curr_proto = proto; *curr_proto != PROTO_END;
+ curr_proto++) {
+
+ if (is_shared(hdl, mntpt, *curr_proto) &&
+ unshare_one(hdl, zhp->zfs_name,
+ mntpt, *curr_proto) != 0) {
+ if (mntpt != NULL)
+ free(mntpt);
+ return (-1);
+ }
+ }
+ }
+ if (mntpt != NULL)
+ free(mntpt);
+
+ return (0);
+}
+
+int
+zfs_unshare_nfs(zfs_handle_t *zhp, const char *mountpoint)
+{
+ return (zfs_unshare_proto(zhp, mountpoint, nfs_only));
+}
+
+int
+zfs_unshare_smb(zfs_handle_t *zhp, const char *mountpoint)
+{
+ return (zfs_unshare_proto(zhp, mountpoint, smb_only));
+}
+
+/*
+ * Same as zfs_unmountall(), but for NFS and SMB unshares.
+ */
+int
+zfs_unshareall_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
+{
+ prop_changelist_t *clp;
+ int ret;
+
+ clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0);
+ if (clp == NULL)
+ return (-1);
+
+ ret = changelist_unshare(clp, proto);
+ changelist_free(clp);
+
+ return (ret);
+}
+
+int
+zfs_unshareall_nfs(zfs_handle_t *zhp)
+{
+ return (zfs_unshareall_proto(zhp, nfs_only));
+}
+
+int
+zfs_unshareall_smb(zfs_handle_t *zhp)
+{
+ return (zfs_unshareall_proto(zhp, smb_only));
+}
+
+int
+zfs_unshareall(zfs_handle_t *zhp)
+{
+ return (zfs_unshareall_proto(zhp, share_all_proto));
+}
+
+int
+zfs_unshareall_bypath(zfs_handle_t *zhp, const char *mountpoint)
+{
+ return (zfs_unshare_proto(zhp, mountpoint, share_all_proto));
+}
+
+/*
+ * Remove the mountpoint associated with the current dataset, if necessary.
+ * We only remove the underlying directory if:
+ *
+ * - The mountpoint is not 'none' or 'legacy'
+ * - The mountpoint is non-empty
+ * - The mountpoint is the default or inherited
+ * - The 'zoned' property is set, or we're in a local zone
+ *
+ * Any other directories we leave alone.
+ */
+void
+remove_mountpoint(zfs_handle_t *zhp)
+{
+ char mountpoint[ZFS_MAXPROPLEN];
+ zprop_source_t source;
+
+ if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
+ &source))
+ return;
+
+ if (source == ZPROP_SRC_DEFAULT ||
+ source == ZPROP_SRC_INHERITED) {
+ /*
+ * Try to remove the directory, silently ignoring any errors.
+ * The filesystem may have since been removed or moved around,
+ * and this error isn't really useful to the administrator in
+ * any way.
+ */
+ (void) rmdir(mountpoint);
+ }
+}
+
+void
+libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
+{
+ if (cbp->cb_alloc == cbp->cb_used) {
+ size_t newsz;
+ void *ptr;
+
+ newsz = cbp->cb_alloc ? cbp->cb_alloc * 2 : 64;
+ ptr = zfs_realloc(zhp->zfs_hdl,
+ cbp->cb_handles, cbp->cb_alloc * sizeof (void *),
+ newsz * sizeof (void *));
+ cbp->cb_handles = ptr;
+ cbp->cb_alloc = newsz;
+ }
+ cbp->cb_handles[cbp->cb_used++] = zhp;
+}
+
+static int
+mount_cb(zfs_handle_t *zhp, void *data)
+{
+ get_all_cb_t *cbp = data;
+
+ if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ libzfs_add_handle(cbp, zhp);
+ if (zfs_iter_filesystems(zhp, mount_cb, cbp) != 0) {
+ zfs_close(zhp);
+ return (-1);
+ }
+ return (0);
+}
+
+int
+libzfs_dataset_cmp(const void *a, const void *b)
+{
+ zfs_handle_t **za = (zfs_handle_t **)a;
+ zfs_handle_t **zb = (zfs_handle_t **)b;
+ char mounta[MAXPATHLEN];
+ char mountb[MAXPATHLEN];
+ boolean_t gota, gotb;
+
+ if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0)
+ verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
+ sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
+ if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0)
+ verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
+ sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
+
+ if (gota && gotb)
+ return (strcmp(mounta, mountb));
+
+ if (gota)
+ return (-1);
+ if (gotb)
+ return (1);
+
+ return (strcmp(zfs_get_name(a), zfs_get_name(b)));
+}
+
+/*
+ * Mount and share all datasets within the given pool. This assumes that no
+ * datasets within the pool are currently mounted. Because users can create
+ * complicated nested hierarchies of mountpoints, we first gather all the
+ * datasets and mountpoints within the pool, and sort them by mountpoint. Once
+ * we have the list of all filesystems, we iterate over them in order and mount
+ * and/or share each one.
+ */
+#pragma weak zpool_mount_datasets = zpool_enable_datasets
+int
+zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
+{
+ get_all_cb_t cb = { 0 };
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ zfs_handle_t *zfsp;
+ int i, ret = -1;
+ int *good;
+
+ /*
+ * Gather all non-snap datasets within the pool.
+ */
+ if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL)
+ goto out;
+
+ libzfs_add_handle(&cb, zfsp);
+ if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0)
+ goto out;
+ /*
+ * Sort the datasets by mountpoint.
+ */
+ qsort(cb.cb_handles, cb.cb_used, sizeof (void *),
+ libzfs_dataset_cmp);
+
+ /*
+ * And mount all the datasets, keeping track of which ones
+ * succeeded or failed.
+ */
+ if ((good = zfs_alloc(zhp->zpool_hdl,
+ cb.cb_used * sizeof (int))) == NULL)
+ goto out;
+
+ ret = 0;
+ for (i = 0; i < cb.cb_used; i++) {
+ if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0)
+ ret = -1;
+ else
+ good[i] = 1;
+ }
+
+ /*
+ * Then share all the ones that need to be shared. This needs
+ * to be a separate pass in order to avoid excessive reloading
+ * of the configuration. Good should never be NULL since
+ * zfs_alloc is supposed to exit if memory isn't available.
+ */
+ for (i = 0; i < cb.cb_used; i++) {
+ if (good[i] && zfs_share(cb.cb_handles[i]) != 0)
+ ret = -1;
+ }
+
+ free(good);
+
+out:
+ for (i = 0; i < cb.cb_used; i++)
+ zfs_close(cb.cb_handles[i]);
+ free(cb.cb_handles);
+
+ return (ret);
+}
+
+static int
+mountpoint_compare(const void *a, const void *b)
+{
+ const char *mounta = *((char **)a);
+ const char *mountb = *((char **)b);
+
+ return (strcmp(mountb, mounta));
+}
+
+/* alias for 2002/240 */
+#pragma weak zpool_unmount_datasets = zpool_disable_datasets
+/*
+ * Unshare and unmount all datasets within the given pool. We don't want to
+ * rely on traversing the DSL to discover the filesystems within the pool,
+ * because this may be expensive (if not all of them are mounted), and can fail
+ * arbitrarily (on I/O error, for example). Instead, we walk /etc/mnttab and
+ * gather all the filesystems that are currently mounted.
+ */
+int
+zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
+{
+ int used, alloc;
+ struct mnttab entry;
+ size_t namelen;
+ char **mountpoints = NULL;
+ zfs_handle_t **datasets = NULL;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ int i;
+ int ret = -1;
+ int flags = (force ? MS_FORCE : 0);
+
+ namelen = strlen(zhp->zpool_name);
+
+ rewind(hdl->libzfs_mnttab);
+ used = alloc = 0;
+ while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
+ /*
+ * Ignore non-ZFS entries.
+ */
+ if (entry.mnt_fstype == NULL ||
+ strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
+ continue;
+
+ /*
+ * Ignore filesystems not within this pool.
+ */
+ if (entry.mnt_mountp == NULL ||
+ strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
+ (entry.mnt_special[namelen] != '/' &&
+ entry.mnt_special[namelen] != '\0'))
+ continue;
+
+ /*
+ * At this point we've found a filesystem within our pool. Add
+ * it to our growing list.
+ */
+ if (used == alloc) {
+ if (alloc == 0) {
+ if ((mountpoints = zfs_alloc(hdl,
+ 8 * sizeof (void *))) == NULL)
+ goto out;
+
+ if ((datasets = zfs_alloc(hdl,
+ 8 * sizeof (void *))) == NULL)
+ goto out;
+
+ alloc = 8;
+ } else {
+ void *ptr;
+
+ if ((ptr = zfs_realloc(hdl, mountpoints,
+ alloc * sizeof (void *),
+ alloc * 2 * sizeof (void *))) == NULL)
+ goto out;
+ mountpoints = ptr;
+
+ if ((ptr = zfs_realloc(hdl, datasets,
+ alloc * sizeof (void *),
+ alloc * 2 * sizeof (void *))) == NULL)
+ goto out;
+ datasets = ptr;
+
+ alloc *= 2;
+ }
+ }
+
+ if ((mountpoints[used] = zfs_strdup(hdl,
+ entry.mnt_mountp)) == NULL)
+ goto out;
+
+ /*
+ * This is allowed to fail, in case there is some I/O error. It
+ * is only used to determine if we need to remove the underlying
+ * mountpoint, so failure is not fatal.
+ */
+ datasets[used] = make_dataset_handle(hdl, entry.mnt_special);
+
+ used++;
+ }
+
+ /*
+ * At this point, we have the entire list of filesystems, so sort it by
+ * mountpoint.
+ */
+ qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
+
+ /*
+ * Walk through and first unshare everything.
+ */
+ for (i = 0; i < used; i++) {
+ zfs_share_proto_t *curr_proto;
+ for (curr_proto = share_all_proto; *curr_proto != PROTO_END;
+ curr_proto++) {
+ if (is_shared(hdl, mountpoints[i], *curr_proto) &&
+ unshare_one(hdl, mountpoints[i],
+ mountpoints[i], *curr_proto) != 0)
+ goto out;
+ }
+ }
+
+ /*
+ * Now unmount everything, removing the underlying directories as
+ * appropriate.
+ */
+ for (i = 0; i < used; i++) {
+ if (unmount_one(hdl, mountpoints[i], flags) != 0)
+ goto out;
+ }
+
+ for (i = 0; i < used; i++) {
+ if (datasets[i])
+ remove_mountpoint(datasets[i]);
+ }
+
+ ret = 0;
+out:
+ for (i = 0; i < used; i++) {
+ if (datasets[i])
+ zfs_close(datasets[i]);
+ free(mountpoints[i]);
+ }
+ free(datasets);
+ free(mountpoints);
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
new file mode 100644
index 0000000..9b04e08
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -0,0 +1,4140 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <devid.h>
+#include <fcntl.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <sys/zfs_ioctl.h>
+#include <dlfcn.h>
+
+#include "zfs_namecheck.h"
+#include "zfs_prop.h"
+#include "libzfs_impl.h"
+#include "zfs_comutil.h"
+#include "zfeature_common.h"
+
+static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
+
+#define DISK_ROOT "/dev/dsk"
+#define RDISK_ROOT "/dev/rdsk"
+#define BACKUP_SLICE "s2"
+
+typedef struct prop_flags {
+ int create:1; /* Validate property on creation */
+ int import:1; /* Validate property on import */
+} prop_flags_t;
+
+/*
+ * ====================================================================
+ * zpool property functions
+ * ====================================================================
+ */
+
+static int
+zpool_get_all_props(zpool_handle_t *zhp)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
+ return (-1);
+
+ while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
+ if (errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ } else {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ }
+
+ if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+
+ zcmd_free_nvlists(&zc);
+
+ return (0);
+}
+
+static int
+zpool_props_refresh(zpool_handle_t *zhp)
+{
+ nvlist_t *old_props;
+
+ old_props = zhp->zpool_props;
+
+ if (zpool_get_all_props(zhp) != 0)
+ return (-1);
+
+ nvlist_free(old_props);
+ return (0);
+}
+
+static char *
+zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
+ zprop_source_t *src)
+{
+ nvlist_t *nv, *nvl;
+ uint64_t ival;
+ char *value;
+ zprop_source_t source;
+
+ nvl = zhp->zpool_props;
+ if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
+ verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
+ source = ival;
+ verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
+ } else {
+ source = ZPROP_SRC_DEFAULT;
+ if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
+ value = "-";
+ }
+
+ if (src)
+ *src = source;
+
+ return (value);
+}
+
+uint64_t
+zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
+{
+ nvlist_t *nv, *nvl;
+ uint64_t value;
+ zprop_source_t source;
+
+ if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
+ /*
+ * zpool_get_all_props() has most likely failed because
+ * the pool is faulted, but if all we need is the top level
+ * vdev's guid then get it from the zhp config nvlist.
+ */
+ if ((prop == ZPOOL_PROP_GUID) &&
+ (nvlist_lookup_nvlist(zhp->zpool_config,
+ ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
+ (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
+ == 0)) {
+ return (value);
+ }
+ return (zpool_prop_default_numeric(prop));
+ }
+
+ nvl = zhp->zpool_props;
+ if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
+ verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
+ source = value;
+ verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
+ } else {
+ source = ZPROP_SRC_DEFAULT;
+ value = zpool_prop_default_numeric(prop);
+ }
+
+ if (src)
+ *src = source;
+
+ return (value);
+}
+
+/*
+ * Map VDEV STATE to printed strings.
+ */
+const char *
+zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
+{
+ switch (state) {
+ case VDEV_STATE_CLOSED:
+ case VDEV_STATE_OFFLINE:
+ return (gettext("OFFLINE"));
+ case VDEV_STATE_REMOVED:
+ return (gettext("REMOVED"));
+ case VDEV_STATE_CANT_OPEN:
+ if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
+ return (gettext("FAULTED"));
+ else if (aux == VDEV_AUX_SPLIT_POOL)
+ return (gettext("SPLIT"));
+ else
+ return (gettext("UNAVAIL"));
+ case VDEV_STATE_FAULTED:
+ return (gettext("FAULTED"));
+ case VDEV_STATE_DEGRADED:
+ return (gettext("DEGRADED"));
+ case VDEV_STATE_HEALTHY:
+ return (gettext("ONLINE"));
+ }
+
+ return (gettext("UNKNOWN"));
+}
+
+/*
+ * Map POOL STATE to printed strings.
+ */
+const char *
+zpool_pool_state_to_name(pool_state_t state)
+{
+ switch (state) {
+ case POOL_STATE_ACTIVE:
+ return (gettext("ACTIVE"));
+ case POOL_STATE_EXPORTED:
+ return (gettext("EXPORTED"));
+ case POOL_STATE_DESTROYED:
+ return (gettext("DESTROYED"));
+ case POOL_STATE_SPARE:
+ return (gettext("SPARE"));
+ case POOL_STATE_L2CACHE:
+ return (gettext("L2CACHE"));
+ case POOL_STATE_UNINITIALIZED:
+ return (gettext("UNINITIALIZED"));
+ case POOL_STATE_UNAVAIL:
+ return (gettext("UNAVAIL"));
+ case POOL_STATE_POTENTIALLY_ACTIVE:
+ return (gettext("POTENTIALLY_ACTIVE"));
+ }
+
+ return (gettext("UNKNOWN"));
+}
+
+/*
+ * Get a zpool property value for 'prop' and return the value in
+ * a pre-allocated buffer.
+ */
+int
+zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
+ zprop_source_t *srctype)
+{
+ uint64_t intval;
+ const char *strval;
+ zprop_source_t src = ZPROP_SRC_NONE;
+ nvlist_t *nvroot;
+ vdev_stat_t *vs;
+ uint_t vsc;
+
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ switch (prop) {
+ case ZPOOL_PROP_NAME:
+ (void) strlcpy(buf, zpool_get_name(zhp), len);
+ break;
+
+ case ZPOOL_PROP_HEALTH:
+ (void) strlcpy(buf, "FAULTED", len);
+ break;
+
+ case ZPOOL_PROP_GUID:
+ intval = zpool_get_prop_int(zhp, prop, &src);
+ (void) snprintf(buf, len, "%llu", intval);
+ break;
+
+ case ZPOOL_PROP_ALTROOT:
+ case ZPOOL_PROP_CACHEFILE:
+ case ZPOOL_PROP_COMMENT:
+ if (zhp->zpool_props != NULL ||
+ zpool_get_all_props(zhp) == 0) {
+ (void) strlcpy(buf,
+ zpool_get_prop_string(zhp, prop, &src),
+ len);
+ if (srctype != NULL)
+ *srctype = src;
+ return (0);
+ }
+ /* FALLTHROUGH */
+ default:
+ (void) strlcpy(buf, "-", len);
+ break;
+ }
+
+ if (srctype != NULL)
+ *srctype = src;
+ return (0);
+ }
+
+ if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
+ prop != ZPOOL_PROP_NAME)
+ return (-1);
+
+ switch (zpool_prop_get_type(prop)) {
+ case PROP_TYPE_STRING:
+ (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
+ len);
+ break;
+
+ case PROP_TYPE_NUMBER:
+ intval = zpool_get_prop_int(zhp, prop, &src);
+
+ switch (prop) {
+ case ZPOOL_PROP_SIZE:
+ case ZPOOL_PROP_ALLOCATED:
+ case ZPOOL_PROP_FREE:
+ case ZPOOL_PROP_FREEING:
+ case ZPOOL_PROP_EXPANDSZ:
+ (void) zfs_nicenum(intval, buf, len);
+ break;
+
+ case ZPOOL_PROP_CAPACITY:
+ (void) snprintf(buf, len, "%llu%%",
+ (u_longlong_t)intval);
+ break;
+
+ case ZPOOL_PROP_DEDUPRATIO:
+ (void) snprintf(buf, len, "%llu.%02llux",
+ (u_longlong_t)(intval / 100),
+ (u_longlong_t)(intval % 100));
+ break;
+
+ case ZPOOL_PROP_HEALTH:
+ verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+ verify(nvlist_lookup_uint64_array(nvroot,
+ ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
+ == 0);
+
+ (void) strlcpy(buf, zpool_state_to_name(intval,
+ vs->vs_aux), len);
+ break;
+ case ZPOOL_PROP_VERSION:
+ if (intval >= SPA_VERSION_FEATURES) {
+ (void) snprintf(buf, len, "-");
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ (void) snprintf(buf, len, "%llu", intval);
+ }
+ break;
+
+ case PROP_TYPE_INDEX:
+ intval = zpool_get_prop_int(zhp, prop, &src);
+ if (zpool_prop_index_to_string(prop, intval, &strval)
+ != 0)
+ return (-1);
+ (void) strlcpy(buf, strval, len);
+ break;
+
+ default:
+ abort();
+ }
+
+ if (srctype)
+ *srctype = src;
+
+ return (0);
+}
+
+/*
+ * Check if the bootfs name has the same pool name as it is set to.
+ * Assuming bootfs is a valid dataset name.
+ */
+static boolean_t
+bootfs_name_valid(const char *pool, char *bootfs)
+{
+ int len = strlen(pool);
+
+ if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
+ return (B_FALSE);
+
+ if (strncmp(pool, bootfs, len) == 0 &&
+ (bootfs[len] == '/' || bootfs[len] == '\0'))
+ return (B_TRUE);
+
+ return (B_FALSE);
+}
+
+/*
+ * Inspect the configuration to determine if any of the devices contain
+ * an EFI label.
+ */
+static boolean_t
+pool_uses_efi(nvlist_t *config)
+{
+#ifdef sun
+ nvlist_t **child;
+ uint_t c, children;
+
+ if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return (read_efi_label(config, NULL) >= 0);
+
+ for (c = 0; c < children; c++) {
+ if (pool_uses_efi(child[c]))
+ return (B_TRUE);
+ }
+#endif /* sun */
+ return (B_FALSE);
+}
+
+boolean_t
+zpool_is_bootable(zpool_handle_t *zhp)
+{
+ char bootfs[ZPOOL_MAXNAMELEN];
+
+ return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
+ sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
+ sizeof (bootfs)) != 0);
+}
+
+
+/*
+ * Given an nvlist of zpool properties to be set, validate that they are
+ * correct, and parse any numeric properties (index, boolean, etc) if they are
+ * specified as strings.
+ */
+static nvlist_t *
+zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
+ nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
+{
+ nvpair_t *elem;
+ nvlist_t *retprops;
+ zpool_prop_t prop;
+ char *strval;
+ uint64_t intval;
+ char *slash, *check;
+ struct stat64 statbuf;
+ zpool_handle_t *zhp;
+ nvlist_t *nvroot;
+
+ if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+
+ elem = NULL;
+ while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
+ const char *propname = nvpair_name(elem);
+
+ prop = zpool_name_to_prop(propname);
+ if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
+ int err;
+ zfeature_info_t *feature;
+ char *fname = strchr(propname, '@') + 1;
+
+ err = zfeature_lookup_name(fname, &feature);
+ if (err != 0) {
+ ASSERT3U(err, ==, ENOENT);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid feature '%s'"), fname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (nvpair_type(elem) != DATA_TYPE_STRING) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a string"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ (void) nvpair_value_string(elem, &strval);
+ if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' can only be set to "
+ "'enabled'"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (nvlist_add_uint64(retprops, propname, 0) != 0) {
+ (void) no_memory(hdl);
+ goto error;
+ }
+ continue;
+ }
+
+ /*
+ * Make sure this property is valid and applies to this type.
+ */
+ if (prop == ZPROP_INVAL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid property '%s'"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (zpool_prop_readonly(prop)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
+ "is readonly"), propname);
+ (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
+ goto error;
+ }
+
+ if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
+ &strval, &intval, errbuf) != 0)
+ goto error;
+
+ /*
+ * Perform additional checking for specific properties.
+ */
+ switch (prop) {
+ case ZPOOL_PROP_VERSION:
+ if (intval < version ||
+ !SPA_VERSION_IS_SUPPORTED(intval)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' number %d is invalid."),
+ propname, intval);
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ goto error;
+ }
+ break;
+
+ case ZPOOL_PROP_BOOTFS:
+ if (flags.create || flags.import) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' cannot be set at creation "
+ "or import time"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (version < SPA_VERSION_BOOTFS) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded to support "
+ "'%s' property"), propname);
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ goto error;
+ }
+
+ /*
+ * bootfs property value has to be a dataset name and
+ * the dataset has to be in the same pool as it sets to.
+ */
+ if (strval[0] != '\0' && !bootfs_name_valid(poolname,
+ strval)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
+ "is an invalid name"), strval);
+ (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
+ goto error;
+ }
+
+ if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "could not open pool '%s'"), poolname);
+ (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
+ goto error;
+ }
+ verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+
+#ifdef sun
+ /*
+ * bootfs property cannot be set on a disk which has
+ * been EFI labeled.
+ */
+ if (pool_uses_efi(nvroot)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' not supported on "
+ "EFI labeled devices"), propname);
+ (void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf);
+ zpool_close(zhp);
+ goto error;
+ }
+#endif /* sun */
+ zpool_close(zhp);
+ break;
+
+ case ZPOOL_PROP_ALTROOT:
+ if (!flags.create && !flags.import) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' can only be set during pool "
+ "creation or import"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
+ if (strval[0] != '/') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "bad alternate root '%s'"), strval);
+ (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
+ goto error;
+ }
+ break;
+
+ case ZPOOL_PROP_CACHEFILE:
+ if (strval[0] == '\0')
+ break;
+
+ if (strcmp(strval, "none") == 0)
+ break;
+
+ if (strval[0] != '/') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' must be empty, an "
+ "absolute path, or 'none'"), propname);
+ (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
+ goto error;
+ }
+
+ slash = strrchr(strval, '/');
+
+ if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
+ strcmp(slash, "/..") == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is not a valid file"), strval);
+ (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
+ goto error;
+ }
+
+ *slash = '\0';
+
+ if (strval[0] != '\0' &&
+ (stat64(strval, &statbuf) != 0 ||
+ !S_ISDIR(statbuf.st_mode))) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is not a valid directory"),
+ strval);
+ (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
+ goto error;
+ }
+
+ *slash = '/';
+ break;
+
+ case ZPOOL_PROP_COMMENT:
+ for (check = strval; *check != '\0'; check++) {
+ if (!isprint(*check)) {
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN,
+ "comment may only have printable "
+ "characters"));
+ (void) zfs_error(hdl, EZFS_BADPROP,
+ errbuf);
+ goto error;
+ }
+ }
+ if (strlen(strval) > ZPROP_MAX_COMMENT) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "comment must not exceed %d characters"),
+ ZPROP_MAX_COMMENT);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ break;
+ case ZPOOL_PROP_READONLY:
+ if (!flags.import) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' can only be set at "
+ "import time"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+ break;
+ }
+ }
+
+ return (retprops);
+error:
+ nvlist_free(retprops);
+ return (NULL);
+}
+
+/*
+ * Set zpool property : propname=propval.
+ */
+int
+zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
+{
+ zfs_cmd_t zc = { 0 };
+ int ret = -1;
+ char errbuf[1024];
+ nvlist_t *nvl = NULL;
+ nvlist_t *realprops;
+ uint64_t version;
+ prop_flags_t flags = { 0 };
+
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
+ zhp->zpool_name);
+
+ if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
+ return (no_memory(zhp->zpool_hdl));
+
+ if (nvlist_add_string(nvl, propname, propval) != 0) {
+ nvlist_free(nvl);
+ return (no_memory(zhp->zpool_hdl));
+ }
+
+ version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
+ if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
+ zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
+ nvlist_free(nvl);
+ return (-1);
+ }
+
+ nvlist_free(nvl);
+ nvl = realprops;
+
+ /*
+ * Execute the corresponding ioctl() to set this property.
+ */
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+
+ if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
+ nvlist_free(nvl);
+ return (-1);
+ }
+
+ ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
+
+ zcmd_free_nvlists(&zc);
+ nvlist_free(nvl);
+
+ if (ret)
+ (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
+ else
+ (void) zpool_props_refresh(zhp);
+
+ return (ret);
+}
+
+int
+zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
+{
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ zprop_list_t *entry;
+ char buf[ZFS_MAXPROPLEN];
+ nvlist_t *features = NULL;
+ zprop_list_t **last;
+ boolean_t firstexpand = (NULL == *plp);
+
+ if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
+ return (-1);
+
+ last = plp;
+ while (*last != NULL)
+ last = &(*last)->pl_next;
+
+ if ((*plp)->pl_all)
+ features = zpool_get_features(zhp);
+
+ if ((*plp)->pl_all && firstexpand) {
+ for (int i = 0; i < SPA_FEATURES; i++) {
+ zprop_list_t *entry = zfs_alloc(hdl,
+ sizeof (zprop_list_t));
+ entry->pl_prop = ZPROP_INVAL;
+ entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
+ spa_feature_table[i].fi_uname);
+ entry->pl_width = strlen(entry->pl_user_prop);
+ entry->pl_all = B_TRUE;
+
+ *last = entry;
+ last = &entry->pl_next;
+ }
+ }
+
+ /* add any unsupported features */
+ for (nvpair_t *nvp = nvlist_next_nvpair(features, NULL);
+ nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
+ char *propname;
+ boolean_t found;
+ zprop_list_t *entry;
+
+ if (zfeature_is_supported(nvpair_name(nvp)))
+ continue;
+
+ propname = zfs_asprintf(hdl, "unsupported@%s",
+ nvpair_name(nvp));
+
+ /*
+ * Before adding the property to the list make sure that no
+ * other pool already added the same property.
+ */
+ found = B_FALSE;
+ entry = *plp;
+ while (entry != NULL) {
+ if (entry->pl_user_prop != NULL &&
+ strcmp(propname, entry->pl_user_prop) == 0) {
+ found = B_TRUE;
+ break;
+ }
+ entry = entry->pl_next;
+ }
+ if (found) {
+ free(propname);
+ continue;
+ }
+
+ entry = zfs_alloc(hdl, sizeof (zprop_list_t));
+ entry->pl_prop = ZPROP_INVAL;
+ entry->pl_user_prop = propname;
+ entry->pl_width = strlen(entry->pl_user_prop);
+ entry->pl_all = B_TRUE;
+
+ *last = entry;
+ last = &entry->pl_next;
+ }
+
+ for (entry = *plp; entry != NULL; entry = entry->pl_next) {
+
+ if (entry->pl_fixed)
+ continue;
+
+ if (entry->pl_prop != ZPROP_INVAL &&
+ zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
+ NULL) == 0) {
+ if (strlen(buf) > entry->pl_width)
+ entry->pl_width = strlen(buf);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Get the state for the given feature on the given ZFS pool.
+ */
+int
+zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
+ size_t len)
+{
+ uint64_t refcount;
+ boolean_t found = B_FALSE;
+ nvlist_t *features = zpool_get_features(zhp);
+ boolean_t supported;
+ const char *feature = strchr(propname, '@') + 1;
+
+ supported = zpool_prop_feature(propname);
+ ASSERT(supported || zpool_prop_unsupported(propname));
+
+ /*
+ * Convert from feature name to feature guid. This conversion is
+ * unecessary for unsupported@... properties because they already
+ * use guids.
+ */
+ if (supported) {
+ int ret;
+ zfeature_info_t *fi;
+
+ ret = zfeature_lookup_name(feature, &fi);
+ if (ret != 0) {
+ (void) strlcpy(buf, "-", len);
+ return (ENOTSUP);
+ }
+ feature = fi->fi_guid;
+ }
+
+ if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
+ found = B_TRUE;
+
+ if (supported) {
+ if (!found) {
+ (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
+ } else {
+ if (refcount == 0)
+ (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
+ else
+ (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
+ }
+ } else {
+ if (found) {
+ if (refcount == 0) {
+ (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
+ } else {
+ (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
+ }
+ } else {
+ (void) strlcpy(buf, "-", len);
+ return (ENOTSUP);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Don't start the slice at the default block of 34; many storage
+ * devices will use a stripe width of 128k, so start there instead.
+ */
+#define NEW_START_BLOCK 256
+
+/*
+ * Validate the given pool name, optionally putting an extended error message in
+ * 'buf'.
+ */
+boolean_t
+zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
+{
+ namecheck_err_t why;
+ char what;
+ int ret;
+
+ ret = pool_namecheck(pool, &why, &what);
+
+ /*
+ * The rules for reserved pool names were extended at a later point.
+ * But we need to support users with existing pools that may now be
+ * invalid. So we only check for this expanded set of names during a
+ * create (or import), and only in userland.
+ */
+ if (ret == 0 && !isopen &&
+ (strncmp(pool, "mirror", 6) == 0 ||
+ strncmp(pool, "raidz", 5) == 0 ||
+ strncmp(pool, "spare", 5) == 0 ||
+ strcmp(pool, "log") == 0)) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "name is reserved"));
+ return (B_FALSE);
+ }
+
+
+ if (ret != 0) {
+ if (hdl != NULL) {
+ switch (why) {
+ case NAME_ERR_TOOLONG:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "name is too long"));
+ break;
+
+ case NAME_ERR_INVALCHAR:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "invalid character "
+ "'%c' in pool name"), what);
+ break;
+
+ case NAME_ERR_NOLETTER:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "name must begin with a letter"));
+ break;
+
+ case NAME_ERR_RESERVED:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "name is reserved"));
+ break;
+
+ case NAME_ERR_DISKLIKE:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool name is reserved"));
+ break;
+
+ case NAME_ERR_LEADING_SLASH:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "leading slash in name"));
+ break;
+
+ case NAME_ERR_EMPTY_COMPONENT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "empty component in name"));
+ break;
+
+ case NAME_ERR_TRAILING_SLASH:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "trailing slash in name"));
+ break;
+
+ case NAME_ERR_MULTIPLE_AT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "multiple '@' delimiters in name"));
+ break;
+
+ }
+ }
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+/*
+ * Open a handle to the given pool, even if the pool is currently in the FAULTED
+ * state.
+ */
+zpool_handle_t *
+zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
+{
+ zpool_handle_t *zhp;
+ boolean_t missing;
+
+ /*
+ * Make sure the pool name is valid.
+ */
+ if (!zpool_name_valid(hdl, B_TRUE, pool)) {
+ (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"),
+ pool);
+ return (NULL);
+ }
+
+ if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
+ return (NULL);
+
+ zhp->zpool_hdl = hdl;
+ (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
+
+ if (zpool_refresh_stats(zhp, &missing) != 0) {
+ zpool_close(zhp);
+ return (NULL);
+ }
+
+ if (missing) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
+ (void) zfs_error_fmt(hdl, EZFS_NOENT,
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
+ zpool_close(zhp);
+ return (NULL);
+ }
+
+ return (zhp);
+}
+
+/*
+ * Like the above, but silent on error. Used when iterating over pools (because
+ * the configuration cache may be out of date).
+ */
+int
+zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
+{
+ zpool_handle_t *zhp;
+ boolean_t missing;
+
+ if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
+ return (-1);
+
+ zhp->zpool_hdl = hdl;
+ (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
+
+ if (zpool_refresh_stats(zhp, &missing) != 0) {
+ zpool_close(zhp);
+ return (-1);
+ }
+
+ if (missing) {
+ zpool_close(zhp);
+ *ret = NULL;
+ return (0);
+ }
+
+ *ret = zhp;
+ return (0);
+}
+
+/*
+ * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
+ * state.
+ */
+zpool_handle_t *
+zpool_open(libzfs_handle_t *hdl, const char *pool)
+{
+ zpool_handle_t *zhp;
+
+ if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
+ return (NULL);
+
+ if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
+ (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
+ dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
+ zpool_close(zhp);
+ return (NULL);
+ }
+
+ return (zhp);
+}
+
+/*
+ * Close the handle. Simply frees the memory associated with the handle.
+ */
+void
+zpool_close(zpool_handle_t *zhp)
+{
+ if (zhp->zpool_config)
+ nvlist_free(zhp->zpool_config);
+ if (zhp->zpool_old_config)
+ nvlist_free(zhp->zpool_old_config);
+ if (zhp->zpool_props)
+ nvlist_free(zhp->zpool_props);
+ free(zhp);
+}
+
+/*
+ * Return the name of the pool.
+ */
+const char *
+zpool_get_name(zpool_handle_t *zhp)
+{
+ return (zhp->zpool_name);
+}
+
+
+/*
+ * Return the state of the pool (ACTIVE or UNAVAILABLE)
+ */
+int
+zpool_get_state(zpool_handle_t *zhp)
+{
+ return (zhp->zpool_state);
+}
+
+/*
+ * Create the named pool, using the provided vdev list. It is assumed
+ * that the consumer has already validated the contents of the nvlist, so we
+ * don't have to worry about error semantics.
+ */
+int
+zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
+ nvlist_t *props, nvlist_t *fsprops)
+{
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *zc_fsprops = NULL;
+ nvlist_t *zc_props = NULL;
+ char msg[1024];
+ char *altroot;
+ int ret = -1;
+
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot create '%s'"), pool);
+
+ if (!zpool_name_valid(hdl, B_FALSE, pool))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
+
+ if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
+ return (-1);
+
+ if (props) {
+ prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
+
+ if ((zc_props = zpool_valid_proplist(hdl, pool, props,
+ SPA_VERSION_1, flags, msg)) == NULL) {
+ goto create_failed;
+ }
+ }
+
+ if (fsprops) {
+ uint64_t zoned;
+ char *zonestr;
+
+ zoned = ((nvlist_lookup_string(fsprops,
+ zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
+ strcmp(zonestr, "on") == 0);
+
+ if ((zc_fsprops = zfs_valid_proplist(hdl,
+ ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
+ goto create_failed;
+ }
+ if (!zc_props &&
+ (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
+ goto create_failed;
+ }
+ if (nvlist_add_nvlist(zc_props,
+ ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
+ goto create_failed;
+ }
+ }
+
+ if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
+ goto create_failed;
+
+ (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
+
+ if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
+
+ zcmd_free_nvlists(&zc);
+ nvlist_free(zc_props);
+ nvlist_free(zc_fsprops);
+
+ switch (errno) {
+ case EBUSY:
+ /*
+ * This can happen if the user has specified the same
+ * device multiple times. We can't reliably detect this
+ * until we try to add it and see we already have a
+ * label.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more vdevs refer to the same device"));
+ return (zfs_error(hdl, EZFS_BADDEV, msg));
+
+ case EOVERFLOW:
+ /*
+ * This occurs when one of the devices is below
+ * SPA_MINDEVSIZE. Unfortunately, we can't detect which
+ * device was the problem device since there's no
+ * reliable way to determine device size from userland.
+ */
+ {
+ char buf[64];
+
+ zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
+
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more devices is less than the "
+ "minimum size (%s)"), buf);
+ }
+ return (zfs_error(hdl, EZFS_BADDEV, msg));
+
+ case ENOSPC:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more devices is out of space"));
+ return (zfs_error(hdl, EZFS_BADDEV, msg));
+
+ case ENOTBLK:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cache device must be a disk or disk slice"));
+ return (zfs_error(hdl, EZFS_BADDEV, msg));
+
+ default:
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+ }
+
+ /*
+ * If this is an alternate root pool, then we automatically set the
+ * mountpoint of the root dataset to be '/'.
+ */
+ if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
+ &altroot) == 0) {
+ zfs_handle_t *zhp;
+
+ verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
+ verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
+ "/") == 0);
+
+ zfs_close(zhp);
+ }
+
+create_failed:
+ zcmd_free_nvlists(&zc);
+ nvlist_free(zc_props);
+ nvlist_free(zc_fsprops);
+ return (ret);
+}
+
+/*
+ * Destroy the given pool. It is up to the caller to ensure that there are no
+ * datasets left in the pool.
+ */
+int
+zpool_destroy(zpool_handle_t *zhp, const char *log_str)
+{
+ zfs_cmd_t zc = { 0 };
+ zfs_handle_t *zfp = NULL;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ char msg[1024];
+
+ if (zhp->zpool_state == POOL_STATE_ACTIVE &&
+ (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (-1);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_history = (uint64_t)(uintptr_t)log_str;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot destroy '%s'"), zhp->zpool_name);
+
+ if (errno == EROFS) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more devices is read only"));
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ } else {
+ (void) zpool_standard_error(hdl, errno, msg);
+ }
+
+ if (zfp)
+ zfs_close(zfp);
+ return (-1);
+ }
+
+ if (zfp) {
+ remove_mountpoint(zfp);
+ zfs_close(zfp);
+ }
+
+ return (0);
+}
+
+/*
+ * Add the given vdevs to the pool. The caller must have already performed the
+ * necessary verification to ensure that the vdev specification is well-formed.
+ */
+int
+zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
+{
+ zfs_cmd_t zc = { 0 };
+ int ret;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ char msg[1024];
+ nvlist_t **spares, **l2cache;
+ uint_t nspares, nl2cache;
+
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot add to '%s'"), zhp->zpool_name);
+
+ if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
+ SPA_VERSION_SPARES &&
+ nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ &spares, &nspares) == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
+ "upgraded to add hot spares"));
+ return (zfs_error(hdl, EZFS_BADVERSION, msg));
+ }
+
+ if (zpool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
+ ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
+ uint64_t s;
+
+ for (s = 0; s < nspares; s++) {
+ char *path;
+
+ if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
+ &path) == 0 && pool_uses_efi(spares[s])) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "device '%s' contains an EFI label and "
+ "cannot be used on root pools."),
+ zpool_vdev_name(hdl, NULL, spares[s],
+ B_FALSE));
+ return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
+ }
+ }
+ }
+
+ if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
+ SPA_VERSION_L2CACHE &&
+ nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
+ &l2cache, &nl2cache) == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
+ "upgraded to add cache devices"));
+ return (zfs_error(hdl, EZFS_BADVERSION, msg));
+ }
+
+ if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
+ return (-1);
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
+ switch (errno) {
+ case EBUSY:
+ /*
+ * This can happen if the user has specified the same
+ * device multiple times. We can't reliably detect this
+ * until we try to add it and see we already have a
+ * label.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more vdevs refer to the same device"));
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ case EOVERFLOW:
+ /*
+ * This occurrs when one of the devices is below
+ * SPA_MINDEVSIZE. Unfortunately, we can't detect which
+ * device was the problem device since there's no
+ * reliable way to determine device size from userland.
+ */
+ {
+ char buf[64];
+
+ zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
+
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "device is less than the minimum "
+ "size (%s)"), buf);
+ }
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded to add these vdevs"));
+ (void) zfs_error(hdl, EZFS_BADVERSION, msg);
+ break;
+
+ case EDOM:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "root pool can not have multiple vdevs"
+ " or separate logs"));
+ (void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
+ break;
+
+ case ENOTBLK:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cache device must be a disk or disk slice"));
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ default:
+ (void) zpool_standard_error(hdl, errno, msg);
+ }
+
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+
+ zcmd_free_nvlists(&zc);
+
+ return (ret);
+}
+
+/*
+ * Exports the pool from the system. The caller must ensure that there are no
+ * mounted datasets in the pool.
+ */
+static int
+zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
+ const char *log_str)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot export '%s'"), zhp->zpool_name);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_cookie = force;
+ zc.zc_guid = hardforce;
+ zc.zc_history = (uint64_t)(uintptr_t)log_str;
+
+ if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
+ switch (errno) {
+ case EXDEV:
+ zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
+ "use '-f' to override the following errors:\n"
+ "'%s' has an active shared spare which could be"
+ " used by other pools once '%s' is exported."),
+ zhp->zpool_name, zhp->zpool_name);
+ return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
+ msg));
+ default:
+ return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
+ msg));
+ }
+ }
+
+ return (0);
+}
+
+int
+zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
+{
+ return (zpool_export_common(zhp, force, B_FALSE, log_str));
+}
+
+int
+zpool_export_force(zpool_handle_t *zhp, const char *log_str)
+{
+ return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
+}
+
+static void
+zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
+ nvlist_t *config)
+{
+ nvlist_t *nv = NULL;
+ uint64_t rewindto;
+ int64_t loss = -1;
+ struct tm t;
+ char timestr[128];
+
+ if (!hdl->libzfs_printerr || config == NULL)
+ return;
+
+ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
+ nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
+ return;
+ }
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
+ return;
+ (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
+
+ if (localtime_r((time_t *)&rewindto, &t) != NULL &&
+ strftime(timestr, 128, 0, &t) != 0) {
+ if (dryrun) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Would be able to return %s "
+ "to its state as of %s.\n"),
+ name, timestr);
+ } else {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Pool %s returned to its state as of %s.\n"),
+ name, timestr);
+ }
+ if (loss > 120) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "%s approximately %lld "),
+ dryrun ? "Would discard" : "Discarded",
+ (loss + 30) / 60);
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "minutes of transactions.\n"));
+ } else if (loss > 0) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "%s approximately %lld "),
+ dryrun ? "Would discard" : "Discarded", loss);
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "seconds of transactions.\n"));
+ }
+ }
+}
+
+void
+zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
+ nvlist_t *config)
+{
+ nvlist_t *nv = NULL;
+ int64_t loss = -1;
+ uint64_t edata = UINT64_MAX;
+ uint64_t rewindto;
+ struct tm t;
+ char timestr[128];
+
+ if (!hdl->libzfs_printerr)
+ return;
+
+ if (reason >= 0)
+ (void) printf(dgettext(TEXT_DOMAIN, "action: "));
+ else
+ (void) printf(dgettext(TEXT_DOMAIN, "\t"));
+
+ /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
+ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
+ nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
+ nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
+ goto no_info;
+
+ (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
+ &edata);
+
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Recovery is possible, but will result in some data loss.\n"));
+
+ if (localtime_r((time_t *)&rewindto, &t) != NULL &&
+ strftime(timestr, 128, 0, &t) != 0) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "\tReturning the pool to its state as of %s\n"
+ "\tshould correct the problem. "),
+ timestr);
+ } else {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "\tReverting the pool to an earlier state "
+ "should correct the problem.\n\t"));
+ }
+
+ if (loss > 120) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Approximately %lld minutes of data\n"
+ "\tmust be discarded, irreversibly. "), (loss + 30) / 60);
+ } else if (loss > 0) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Approximately %lld seconds of data\n"
+ "\tmust be discarded, irreversibly. "), loss);
+ }
+ if (edata != 0 && edata != UINT64_MAX) {
+ if (edata == 1) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "After rewind, at least\n"
+ "\tone persistent user-data error will remain. "));
+ } else {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "After rewind, several\n"
+ "\tpersistent user-data errors will remain. "));
+ }
+ }
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
+ reason >= 0 ? "clear" : "import", name);
+
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "A scrub of the pool\n"
+ "\tis strongly recommended after recovery.\n"));
+ return;
+
+no_info:
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "Destroy and re-create the pool from\n\ta backup source.\n"));
+}
+
+/*
+ * zpool_import() is a contracted interface. Should be kept the same
+ * if possible.
+ *
+ * Applications should use zpool_import_props() to import a pool with
+ * new properties value to be set.
+ */
+int
+zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
+ char *altroot)
+{
+ nvlist_t *props = NULL;
+ int ret;
+
+ if (altroot != NULL) {
+ if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
+ return (zfs_error_fmt(hdl, EZFS_NOMEM,
+ dgettext(TEXT_DOMAIN, "cannot import '%s'"),
+ newname));
+ }
+
+ if (nvlist_add_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
+ nvlist_add_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
+ nvlist_free(props);
+ return (zfs_error_fmt(hdl, EZFS_NOMEM,
+ dgettext(TEXT_DOMAIN, "cannot import '%s'"),
+ newname));
+ }
+ }
+
+ ret = zpool_import_props(hdl, config, newname, props,
+ ZFS_IMPORT_NORMAL);
+ if (props)
+ nvlist_free(props);
+ return (ret);
+}
+
+static void
+print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
+ int indent)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ char *vname;
+ uint64_t is_log = 0;
+
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+
+ if (name != NULL)
+ (void) printf("\t%*s%s%s\n", indent, "", name,
+ is_log ? " [log]" : "");
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
+ print_vdev_tree(hdl, vname, child[c], indent + 2);
+ free(vname);
+ }
+}
+
+void
+zpool_print_unsup_feat(nvlist_t *config)
+{
+ nvlist_t *nvinfo, *unsup_feat;
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) ==
+ 0);
+ verify(nvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT,
+ &unsup_feat) == 0);
+
+ for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); nvp != NULL;
+ nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
+ char *desc;
+
+ verify(nvpair_type(nvp) == DATA_TYPE_STRING);
+ verify(nvpair_value_string(nvp, &desc) == 0);
+
+ if (strlen(desc) > 0)
+ (void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
+ else
+ (void) printf("\t%s\n", nvpair_name(nvp));
+ }
+}
+
+/*
+ * Import the given pool using the known configuration and a list of
+ * properties to be set. The configuration should have come from
+ * zpool_find_import(). The 'newname' parameters control whether the pool
+ * is imported with a different name.
+ */
+int
+zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
+ nvlist_t *props, int flags)
+{
+ zfs_cmd_t zc = { 0 };
+ zpool_rewind_policy_t policy;
+ nvlist_t *nv = NULL;
+ nvlist_t *nvinfo = NULL;
+ nvlist_t *missing = NULL;
+ char *thename;
+ char *origname;
+ int ret;
+ int error = 0;
+ char errbuf[1024];
+
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &origname) == 0);
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot import pool '%s'"), origname);
+
+ if (newname != NULL) {
+ if (!zpool_name_valid(hdl, B_FALSE, newname))
+ return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
+ dgettext(TEXT_DOMAIN, "cannot import '%s'"),
+ newname));
+ thename = (char *)newname;
+ } else {
+ thename = origname;
+ }
+
+ if (props) {
+ uint64_t version;
+ prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &version) == 0);
+
+ if ((props = zpool_valid_proplist(hdl, origname,
+ props, version, flags, errbuf)) == NULL) {
+ return (-1);
+ } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
+ nvlist_free(props);
+ return (-1);
+ }
+ }
+
+ (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
+ &zc.zc_guid) == 0);
+
+ if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
+ nvlist_free(props);
+ return (-1);
+ }
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2) != 0) {
+ nvlist_free(props);
+ return (-1);
+ }
+
+ zc.zc_cookie = flags;
+ while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
+ errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ }
+ if (ret != 0)
+ error = errno;
+
+ (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
+ zpool_get_rewind_policy(config, &policy);
+
+ if (error) {
+ char desc[1024];
+
+ /*
+ * Dry-run failed, but we print out what success
+ * looks like if we found a best txg
+ */
+ if (policy.zrp_request & ZPOOL_TRY_REWIND) {
+ zpool_rewind_exclaim(hdl, newname ? origname : thename,
+ B_TRUE, nv);
+ nvlist_free(nv);
+ return (-1);
+ }
+
+ if (newname == NULL)
+ (void) snprintf(desc, sizeof (desc),
+ dgettext(TEXT_DOMAIN, "cannot import '%s'"),
+ thename);
+ else
+ (void) snprintf(desc, sizeof (desc),
+ dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
+ origname, thename);
+
+ switch (error) {
+ case ENOTSUP:
+ if (nv != NULL && nvlist_lookup_nvlist(nv,
+ ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
+ nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
+ (void) printf(dgettext(TEXT_DOMAIN, "This "
+ "pool uses the following feature(s) not "
+ "supported by this system:\n"));
+ zpool_print_unsup_feat(nv);
+ if (nvlist_exists(nvinfo,
+ ZPOOL_CONFIG_CAN_RDONLY)) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "All unsupported features are only "
+ "required for writing to the pool."
+ "\nThe pool can be imported using "
+ "'-o readonly=on'.\n"));
+ }
+ }
+ /*
+ * Unsupported version.
+ */
+ (void) zfs_error(hdl, EZFS_BADVERSION, desc);
+ break;
+
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
+ break;
+
+ case EROFS:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more devices is read only"));
+ (void) zfs_error(hdl, EZFS_BADDEV, desc);
+ break;
+
+ case ENXIO:
+ if (nv && nvlist_lookup_nvlist(nv,
+ ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
+ nvlist_lookup_nvlist(nvinfo,
+ ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
+ (void) printf(dgettext(TEXT_DOMAIN,
+ "The devices below are missing, use "
+ "'-m' to import the pool anyway:\n"));
+ print_vdev_tree(hdl, NULL, missing, 2);
+ (void) printf("\n");
+ }
+ (void) zpool_standard_error(hdl, error, desc);
+ break;
+
+ case EEXIST:
+ (void) zpool_standard_error(hdl, error, desc);
+ break;
+
+ default:
+ (void) zpool_standard_error(hdl, error, desc);
+ zpool_explain_recover(hdl,
+ newname ? origname : thename, -error, nv);
+ break;
+ }
+
+ nvlist_free(nv);
+ ret = -1;
+ } else {
+ zpool_handle_t *zhp;
+
+ /*
+ * This should never fail, but play it safe anyway.
+ */
+ if (zpool_open_silent(hdl, thename, &zhp) != 0)
+ ret = -1;
+ else if (zhp != NULL)
+ zpool_close(zhp);
+ if (policy.zrp_request &
+ (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
+ zpool_rewind_exclaim(hdl, newname ? origname : thename,
+ ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0), nv);
+ }
+ nvlist_free(nv);
+ return (0);
+ }
+
+ zcmd_free_nvlists(&zc);
+ nvlist_free(props);
+
+ return (ret);
+}
+
+/*
+ * Scan the pool.
+ */
+int
+zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_cookie = func;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
+ (errno == ENOENT && func != POOL_SCAN_NONE))
+ return (0);
+
+ if (func == POOL_SCAN_SCRUB) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
+ } else if (func == POOL_SCAN_NONE) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
+ zc.zc_name);
+ } else {
+ assert(!"unexpected result");
+ }
+
+ if (errno == EBUSY) {
+ nvlist_t *nvroot;
+ pool_scan_stat_t *ps = NULL;
+ uint_t psc;
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config,
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+ (void) nvlist_lookup_uint64_array(nvroot,
+ ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
+ if (ps && ps->pss_func == POOL_SCAN_SCRUB)
+ return (zfs_error(hdl, EZFS_SCRUBBING, msg));
+ else
+ return (zfs_error(hdl, EZFS_RESILVERING, msg));
+ } else if (errno == ENOENT) {
+ return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
+ } else {
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+}
+
+/*
+ * This provides a very minimal check whether a given string is likely a
+ * c#t#d# style string. Users of this are expected to do their own
+ * verification of the s# part.
+ */
+#define CTD_CHECK(str) (str && str[0] == 'c' && isdigit(str[1]))
+
+/*
+ * More elaborate version for ones which may start with "/dev/dsk/"
+ * and the like.
+ */
+static int
+ctd_check_path(char *str) {
+ /*
+ * If it starts with a slash, check the last component.
+ */
+ if (str && str[0] == '/') {
+ char *tmp = strrchr(str, '/');
+
+ /*
+ * If it ends in "/old", check the second-to-last
+ * component of the string instead.
+ */
+ if (tmp != str && strcmp(tmp, "/old") == 0) {
+ for (tmp--; *tmp != '/'; tmp--)
+ ;
+ }
+ str = tmp + 1;
+ }
+ return (CTD_CHECK(str));
+}
+
+/*
+ * Find a vdev that matches the search criteria specified. We use the
+ * the nvpair name to determine how we should look for the device.
+ * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
+ * spare; but FALSE if its an INUSE spare.
+ */
+static nvlist_t *
+vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
+ boolean_t *l2cache, boolean_t *log)
+{
+ uint_t c, children;
+ nvlist_t **child;
+ nvlist_t *ret;
+ uint64_t is_log;
+ char *srchkey;
+ nvpair_t *pair = nvlist_next_nvpair(search, NULL);
+
+ /* Nothing to look for */
+ if (search == NULL || pair == NULL)
+ return (NULL);
+
+ /* Obtain the key we will use to search */
+ srchkey = nvpair_name(pair);
+
+ switch (nvpair_type(pair)) {
+ case DATA_TYPE_UINT64:
+ if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
+ uint64_t srchval, theguid;
+
+ verify(nvpair_value_uint64(pair, &srchval) == 0);
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
+ &theguid) == 0);
+ if (theguid == srchval)
+ return (nv);
+ }
+ break;
+
+ case DATA_TYPE_STRING: {
+ char *srchval, *val;
+
+ verify(nvpair_value_string(pair, &srchval) == 0);
+ if (nvlist_lookup_string(nv, srchkey, &val) != 0)
+ break;
+
+ /*
+ * Search for the requested value. Special cases:
+ *
+ * - ZPOOL_CONFIG_PATH for whole disk entries. These end in
+ * "s0" or "s0/old". The "s0" part is hidden from the user,
+ * but included in the string, so this matches around it.
+ * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
+ *
+ * Otherwise, all other searches are simple string compares.
+ */
+ if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 &&
+ ctd_check_path(val)) {
+ uint64_t wholedisk = 0;
+
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+ &wholedisk);
+ if (wholedisk) {
+ int slen = strlen(srchval);
+ int vlen = strlen(val);
+
+ if (slen != vlen - 2)
+ break;
+
+ /*
+ * make_leaf_vdev() should only set
+ * wholedisk for ZPOOL_CONFIG_PATHs which
+ * will include "/dev/dsk/", giving plenty of
+ * room for the indices used next.
+ */
+ ASSERT(vlen >= 6);
+
+ /*
+ * strings identical except trailing "s0"
+ */
+ if (strcmp(&val[vlen - 2], "s0") == 0 &&
+ strncmp(srchval, val, slen) == 0)
+ return (nv);
+
+ /*
+ * strings identical except trailing "s0/old"
+ */
+ if (strcmp(&val[vlen - 6], "s0/old") == 0 &&
+ strcmp(&srchval[slen - 4], "/old") == 0 &&
+ strncmp(srchval, val, slen - 4) == 0)
+ return (nv);
+
+ break;
+ }
+ } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
+ char *type, *idx, *end, *p;
+ uint64_t id, vdev_id;
+
+ /*
+ * Determine our vdev type, keeping in mind
+ * that the srchval is composed of a type and
+ * vdev id pair (i.e. mirror-4).
+ */
+ if ((type = strdup(srchval)) == NULL)
+ return (NULL);
+
+ if ((p = strrchr(type, '-')) == NULL) {
+ free(type);
+ break;
+ }
+ idx = p + 1;
+ *p = '\0';
+
+ /*
+ * If the types don't match then keep looking.
+ */
+ if (strncmp(val, type, strlen(val)) != 0) {
+ free(type);
+ break;
+ }
+
+ verify(strncmp(type, VDEV_TYPE_RAIDZ,
+ strlen(VDEV_TYPE_RAIDZ)) == 0 ||
+ strncmp(type, VDEV_TYPE_MIRROR,
+ strlen(VDEV_TYPE_MIRROR)) == 0);
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
+ &id) == 0);
+
+ errno = 0;
+ vdev_id = strtoull(idx, &end, 10);
+
+ free(type);
+ if (errno != 0)
+ return (NULL);
+
+ /*
+ * Now verify that we have the correct vdev id.
+ */
+ if (vdev_id == id)
+ return (nv);
+ }
+
+ /*
+ * Common case
+ */
+ if (strcmp(srchval, val) == 0)
+ return (nv);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0)
+ return (NULL);
+
+ for (c = 0; c < children; c++) {
+ if ((ret = vdev_to_nvlist_iter(child[c], search,
+ avail_spare, l2cache, NULL)) != NULL) {
+ /*
+ * The 'is_log' value is only set for the toplevel
+ * vdev, not the leaf vdevs. So we always lookup the
+ * log device from the root of the vdev tree (where
+ * 'log' is non-NULL).
+ */
+ if (log != NULL &&
+ nvlist_lookup_uint64(child[c],
+ ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
+ is_log) {
+ *log = B_TRUE;
+ }
+ return (ret);
+ }
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++) {
+ if ((ret = vdev_to_nvlist_iter(child[c], search,
+ avail_spare, l2cache, NULL)) != NULL) {
+ *avail_spare = B_TRUE;
+ return (ret);
+ }
+ }
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++) {
+ if ((ret = vdev_to_nvlist_iter(child[c], search,
+ avail_spare, l2cache, NULL)) != NULL) {
+ *l2cache = B_TRUE;
+ return (ret);
+ }
+ }
+ }
+
+ return (NULL);
+}
+
+/*
+ * Given a physical path (minus the "/devices" prefix), find the
+ * associated vdev.
+ */
+nvlist_t *
+zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
+ boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
+{
+ nvlist_t *search, *nvroot, *ret;
+
+ verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+
+ *avail_spare = B_FALSE;
+ *l2cache = B_FALSE;
+ if (log != NULL)
+ *log = B_FALSE;
+ ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
+ nvlist_free(search);
+
+ return (ret);
+}
+
+/*
+ * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
+ */
+boolean_t
+zpool_vdev_is_interior(const char *name)
+{
+ if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
+ strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
+ return (B_TRUE);
+ return (B_FALSE);
+}
+
+nvlist_t *
+zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
+ boolean_t *l2cache, boolean_t *log)
+{
+ char buf[MAXPATHLEN];
+ char *end;
+ nvlist_t *nvroot, *search, *ret;
+ uint64_t guid;
+
+ verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+
+ guid = strtoull(path, &end, 10);
+ if (guid != 0 && *end == '\0') {
+ verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
+ } else if (zpool_vdev_is_interior(path)) {
+ verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
+ } else if (path[0] != '/') {
+ (void) snprintf(buf, sizeof (buf), "%s%s", _PATH_DEV, path);
+ verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
+ } else {
+ verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
+ }
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+
+ *avail_spare = B_FALSE;
+ *l2cache = B_FALSE;
+ if (log != NULL)
+ *log = B_FALSE;
+ ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
+ nvlist_free(search);
+
+ return (ret);
+}
+
+static int
+vdev_online(nvlist_t *nv)
+{
+ uint64_t ival;
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
+ nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
+ nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Helper function for zpool_get_physpaths().
+ */
+static int
+vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
+ size_t *bytes_written)
+{
+ size_t bytes_left, pos, rsz;
+ char *tmppath;
+ const char *format;
+
+ if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
+ &tmppath) != 0)
+ return (EZFS_NODEVICE);
+
+ pos = *bytes_written;
+ bytes_left = physpath_size - pos;
+ format = (pos == 0) ? "%s" : " %s";
+
+ rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
+ *bytes_written += rsz;
+
+ if (rsz >= bytes_left) {
+ /* if physpath was not copied properly, clear it */
+ if (bytes_left != 0) {
+ physpath[pos] = 0;
+ }
+ return (EZFS_NOSPC);
+ }
+ return (0);
+}
+
+static int
+vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
+ size_t *rsz, boolean_t is_spare)
+{
+ char *type;
+ int ret;
+
+ if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
+ return (EZFS_INVALCONFIG);
+
+ if (strcmp(type, VDEV_TYPE_DISK) == 0) {
+ /*
+ * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
+ * For a spare vdev, we only want to boot from the active
+ * spare device.
+ */
+ if (is_spare) {
+ uint64_t spare = 0;
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
+ &spare);
+ if (!spare)
+ return (EZFS_INVALCONFIG);
+ }
+
+ if (vdev_online(nv)) {
+ if ((ret = vdev_get_one_physpath(nv, physpath,
+ phypath_size, rsz)) != 0)
+ return (ret);
+ }
+ } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
+ strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
+ (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
+ nvlist_t **child;
+ uint_t count;
+ int i, ret;
+
+ if (nvlist_lookup_nvlist_array(nv,
+ ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
+ return (EZFS_INVALCONFIG);
+
+ for (i = 0; i < count; i++) {
+ ret = vdev_get_physpaths(child[i], physpath,
+ phypath_size, rsz, is_spare);
+ if (ret == EZFS_NOSPC)
+ return (ret);
+ }
+ }
+
+ return (EZFS_POOL_INVALARG);
+}
+
+/*
+ * Get phys_path for a root pool config.
+ * Return 0 on success; non-zero on failure.
+ */
+static int
+zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
+{
+ size_t rsz;
+ nvlist_t *vdev_root;
+ nvlist_t **child;
+ uint_t count;
+ char *type;
+
+ rsz = 0;
+
+ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &vdev_root) != 0)
+ return (EZFS_INVALCONFIG);
+
+ if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
+ nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
+ &child, &count) != 0)
+ return (EZFS_INVALCONFIG);
+
+ /*
+ * root pool can not have EFI labeled disks and can only have
+ * a single top-level vdev.
+ */
+ if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
+ pool_uses_efi(vdev_root))
+ return (EZFS_POOL_INVALARG);
+
+ (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
+ B_FALSE);
+
+ /* No online devices */
+ if (rsz == 0)
+ return (EZFS_NODEVICE);
+
+ return (0);
+}
+
+/*
+ * Get phys_path for a root pool
+ * Return 0 on success; non-zero on failure.
+ */
+int
+zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
+{
+ return (zpool_get_config_physpath(zhp->zpool_config, physpath,
+ phypath_size));
+}
+
+/*
+ * If the device has being dynamically expanded then we need to relabel
+ * the disk to use the new unallocated space.
+ */
+static int
+zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
+{
+#ifdef sun
+ char path[MAXPATHLEN];
+ char errbuf[1024];
+ int fd, error;
+ int (*_efi_use_whole_disk)(int);
+
+ if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
+ "efi_use_whole_disk")) == NULL)
+ return (-1);
+
+ (void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
+
+ if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
+ "relabel '%s': unable to open device"), name);
+ return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
+ }
+
+ /*
+ * It's possible that we might encounter an error if the device
+ * does not have any unallocated space left. If so, we simply
+ * ignore that error and continue on.
+ */
+ error = _efi_use_whole_disk(fd);
+ (void) close(fd);
+ if (error && error != VT_ENOSPC) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
+ "relabel '%s': unable to read disk capacity"), name);
+ return (zfs_error(hdl, EZFS_NOCAP, errbuf));
+ }
+#endif /* sun */
+ return (0);
+}
+
+/*
+ * Bring the specified vdev online. The 'flags' parameter is a set of the
+ * ZFS_ONLINE_* flags.
+ */
+int
+zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
+ vdev_state_t *newstate)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tgt;
+ boolean_t avail_spare, l2cache, islog;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ if (flags & ZFS_ONLINE_EXPAND) {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
+ } else {
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot online %s"), path);
+ }
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
+ &islog)) == NULL)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
+
+ if (avail_spare)
+ return (zfs_error(hdl, EZFS_ISSPARE, msg));
+
+ if (flags & ZFS_ONLINE_EXPAND ||
+ zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
+ char *pathname = NULL;
+ uint64_t wholedisk = 0;
+
+ (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
+ &wholedisk);
+ verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
+ &pathname) == 0);
+
+ /*
+ * XXX - L2ARC 1.0 devices can't support expansion.
+ */
+ if (l2cache) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot expand cache devices"));
+ return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
+ }
+
+ if (wholedisk) {
+ pathname += strlen(DISK_ROOT) + 1;
+ (void) zpool_relabel_disk(hdl, pathname);
+ }
+ }
+
+ zc.zc_cookie = VDEV_STATE_ONLINE;
+ zc.zc_obj = flags;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
+ if (errno == EINVAL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
+ "from this pool into a new one. Use '%s' "
+ "instead"), "zpool detach");
+ return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, msg));
+ }
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+
+ *newstate = zc.zc_cookie;
+ return (0);
+}
+
+/*
+ * Take the specified vdev offline
+ */
+int
+zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tgt;
+ boolean_t avail_spare, l2cache;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
+ NULL)) == NULL)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
+
+ if (avail_spare)
+ return (zfs_error(hdl, EZFS_ISSPARE, msg));
+
+ zc.zc_cookie = VDEV_STATE_OFFLINE;
+ zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
+ return (0);
+
+ switch (errno) {
+ case EBUSY:
+
+ /*
+ * There are no other replicas of this device.
+ */
+ return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
+
+ case EEXIST:
+ /*
+ * The log device has unplayed logs
+ */
+ return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
+
+ default:
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+}
+
+/*
+ * Mark the given vdev faulted.
+ */
+int
+zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_guid = guid;
+ zc.zc_cookie = VDEV_STATE_FAULTED;
+ zc.zc_obj = aux;
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
+ return (0);
+
+ switch (errno) {
+ case EBUSY:
+
+ /*
+ * There are no other replicas of this device.
+ */
+ return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
+
+ default:
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+
+}
+
+/*
+ * Mark the given vdev degraded.
+ */
+int
+zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_guid = guid;
+ zc.zc_cookie = VDEV_STATE_DEGRADED;
+ zc.zc_obj = aux;
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
+ return (0);
+
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
+ * a hot spare.
+ */
+static boolean_t
+is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ char *type;
+
+ if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
+ &children) == 0) {
+ verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
+ &type) == 0);
+
+ if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
+ children == 2 && child[which] == tgt)
+ return (B_TRUE);
+
+ for (c = 0; c < children; c++)
+ if (is_replacing_spare(child[c], tgt, which))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * Attach new_disk (fully described by nvroot) to old_disk.
+ * If 'replacing' is specified, the new disk will replace the old one.
+ */
+int
+zpool_vdev_attach(zpool_handle_t *zhp,
+ const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ int ret;
+ nvlist_t *tgt;
+ boolean_t avail_spare, l2cache, islog;
+ uint64_t val;
+ char *newname;
+ nvlist_t **child;
+ uint_t children;
+ nvlist_t *config_root;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ boolean_t rootpool = zpool_is_bootable(zhp);
+
+ if (replacing)
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot replace %s with %s"), old_disk, new_disk);
+ else
+ (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+ "cannot attach %s to %s"), new_disk, old_disk);
+
+ /*
+ * If this is a root pool, make sure that we're not attaching an
+ * EFI labeled device.
+ */
+ if (rootpool && pool_uses_efi(nvroot)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "EFI labeled devices are not supported on root pools."));
+ return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
+ }
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
+ &islog)) == 0)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+
+ if (avail_spare)
+ return (zfs_error(hdl, EZFS_ISSPARE, msg));
+
+ if (l2cache)
+ return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
+ zc.zc_cookie = replacing;
+
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) != 0 || children != 1) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "new device must be a single disk"));
+ return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
+ }
+
+ verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
+ ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
+
+ if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
+ return (-1);
+
+ /*
+ * If the target is a hot spare that has been swapped in, we can only
+ * replace it with another hot spare.
+ */
+ if (replacing &&
+ nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
+ (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
+ NULL) == NULL || !avail_spare) &&
+ is_replacing_spare(config_root, tgt, 1)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "can only be replaced by another hot spare"));
+ free(newname);
+ return (zfs_error(hdl, EZFS_BADTARGET, msg));
+ }
+
+ free(newname);
+
+ if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
+ return (-1);
+
+ ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
+
+ zcmd_free_nvlists(&zc);
+
+ if (ret == 0) {
+ if (rootpool) {
+ /*
+ * XXX need a better way to prevent user from
+ * booting up a half-baked vdev.
+ */
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
+ "sure to wait until resilver is done "
+ "before rebooting.\n"));
+ (void) fprintf(stderr, "\n");
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "If "
+ "you boot from pool '%s', you may need to update\n"
+ "boot code on newly attached disk '%s'.\n\n"
+ "Assuming you use GPT partitioning and 'da0' is "
+ "your new boot disk\n"
+ "you may use the following command:\n\n"
+ "\tgpart bootcode -b /boot/pmbr -p "
+ "/boot/gptzfsboot -i 1 da0\n\n"),
+ zhp->zpool_name, new_disk);
+ }
+ return (0);
+ }
+
+ switch (errno) {
+ case ENOTSUP:
+ /*
+ * Can't attach to or replace this type of vdev.
+ */
+ if (replacing) {
+ uint64_t version = zpool_get_prop_int(zhp,
+ ZPOOL_PROP_VERSION, NULL);
+
+ if (islog)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot replace a log with a spare"));
+ else if (version >= SPA_VERSION_MULTI_REPLACE)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "already in replacing/spare config; wait "
+ "for completion or use 'zpool detach'"));
+ else
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot replace a replacing device"));
+ } else {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "can only attach to mirrors and top-level "
+ "disks"));
+ }
+ (void) zfs_error(hdl, EZFS_BADTARGET, msg);
+ break;
+
+ case EINVAL:
+ /*
+ * The new device must be a single disk.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "new device must be a single disk"));
+ (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
+ break;
+
+ case EBUSY:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
+ new_disk);
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ case EOVERFLOW:
+ /*
+ * The new device is too small.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "device is too small"));
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ case EDOM:
+ /*
+ * The new device has a different alignment requirement.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "devices have different sector alignment"));
+ (void) zfs_error(hdl, EZFS_BADDEV, msg);
+ break;
+
+ case ENAMETOOLONG:
+ /*
+ * The resulting top-level vdev spec won't fit in the label.
+ */
+ (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
+ break;
+
+ default:
+ (void) zpool_standard_error(hdl, errno, msg);
+ }
+
+ return (-1);
+}
+
+/*
+ * Detach the specified device.
+ */
+int
+zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tgt;
+ boolean_t avail_spare, l2cache;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
+ NULL)) == 0)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+
+ if (avail_spare)
+ return (zfs_error(hdl, EZFS_ISSPARE, msg));
+
+ if (l2cache)
+ return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
+ return (0);
+
+ switch (errno) {
+
+ case ENOTSUP:
+ /*
+ * Can't detach from this type of vdev.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
+ "applicable to mirror and replacing vdevs"));
+ (void) zfs_error(hdl, EZFS_BADTARGET, msg);
+ break;
+
+ case EBUSY:
+ /*
+ * There are no other replicas of this device.
+ */
+ (void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
+ break;
+
+ default:
+ (void) zpool_standard_error(hdl, errno, msg);
+ }
+
+ return (-1);
+}
+
+/*
+ * Find a mirror vdev in the source nvlist.
+ *
+ * The mchild array contains a list of disks in one of the top-level mirrors
+ * of the source pool. The schild array contains a list of disks that the
+ * user specified on the command line. We loop over the mchild array to
+ * see if any entry in the schild array matches.
+ *
+ * If a disk in the mchild array is found in the schild array, we return
+ * the index of that entry. Otherwise we return -1.
+ */
+static int
+find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
+ nvlist_t **schild, uint_t schildren)
+{
+ uint_t mc;
+
+ for (mc = 0; mc < mchildren; mc++) {
+ uint_t sc;
+ char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
+ mchild[mc], B_FALSE);
+
+ for (sc = 0; sc < schildren; sc++) {
+ char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
+ schild[sc], B_FALSE);
+ boolean_t result = (strcmp(mpath, spath) == 0);
+
+ free(spath);
+ if (result) {
+ free(mpath);
+ return (mc);
+ }
+ }
+
+ free(mpath);
+ }
+
+ return (-1);
+}
+
+/*
+ * Split a mirror pool. If newroot points to null, then a new nvlist
+ * is generated and it is the responsibility of the caller to free it.
+ */
+int
+zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
+ nvlist_t *props, splitflags_t flags)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
+ nvlist_t **varray = NULL, *zc_props = NULL;
+ uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ uint64_t vers;
+ boolean_t freelist = B_FALSE, memory_err = B_TRUE;
+ int retval = 0;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
+
+ if (!zpool_name_valid(hdl, B_FALSE, newname))
+ return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
+
+ if ((config = zpool_get_config(zhp, NULL)) == NULL) {
+ (void) fprintf(stderr, gettext("Internal error: unable to "
+ "retrieve pool configuration\n"));
+ return (-1);
+ }
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree)
+ == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &vers) == 0);
+
+ if (props) {
+ prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
+ if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
+ props, vers, flags, msg)) == NULL)
+ return (-1);
+ }
+
+ if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
+ &children) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "Source pool is missing vdev tree"));
+ if (zc_props)
+ nvlist_free(zc_props);
+ return (-1);
+ }
+
+ varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
+ vcount = 0;
+
+ if (*newroot == NULL ||
+ nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
+ &newchild, &newchildren) != 0)
+ newchildren = 0;
+
+ for (c = 0; c < children; c++) {
+ uint64_t is_log = B_FALSE, is_hole = B_FALSE;
+ char *type;
+ nvlist_t **mchild, *vdev;
+ uint_t mchildren;
+ int entry;
+
+ /*
+ * Unlike cache & spares, slogs are stored in the
+ * ZPOOL_CONFIG_CHILDREN array. We filter them out here.
+ */
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
+ &is_log);
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
+ &is_hole);
+ if (is_log || is_hole) {
+ /*
+ * Create a hole vdev and put it in the config.
+ */
+ if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
+ goto out;
+ if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_HOLE) != 0)
+ goto out;
+ if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
+ 1) != 0)
+ goto out;
+ if (lastlog == 0)
+ lastlog = vcount;
+ varray[vcount++] = vdev;
+ continue;
+ }
+ lastlog = 0;
+ verify(nvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE, &type)
+ == 0);
+ if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "Source pool must be composed only of mirrors\n"));
+ retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
+ goto out;
+ }
+
+ verify(nvlist_lookup_nvlist_array(child[c],
+ ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
+
+ /* find or add an entry for this top-level vdev */
+ if (newchildren > 0 &&
+ (entry = find_vdev_entry(zhp, mchild, mchildren,
+ newchild, newchildren)) >= 0) {
+ /* We found a disk that the user specified. */
+ vdev = mchild[entry];
+ ++found;
+ } else {
+ /* User didn't specify a disk for this vdev. */
+ vdev = mchild[mchildren - 1];
+ }
+
+ if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
+ goto out;
+ }
+
+ /* did we find every disk the user specified? */
+ if (found != newchildren) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
+ "include at most one disk from each mirror"));
+ retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
+ goto out;
+ }
+
+ /* Prepare the nvlist for populating. */
+ if (*newroot == NULL) {
+ if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
+ goto out;
+ freelist = B_TRUE;
+ if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
+ VDEV_TYPE_ROOT) != 0)
+ goto out;
+ } else {
+ verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
+ }
+
+ /* Add all the children we found */
+ if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, varray,
+ lastlog == 0 ? vcount : lastlog) != 0)
+ goto out;
+
+ /*
+ * If we're just doing a dry run, exit now with success.
+ */
+ if (flags.dryrun) {
+ memory_err = B_FALSE;
+ freelist = B_FALSE;
+ goto out;
+ }
+
+ /* now build up the config list & call the ioctl */
+ if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
+ goto out;
+
+ if (nvlist_add_nvlist(newconfig,
+ ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
+ nvlist_add_string(newconfig,
+ ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
+ nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
+ goto out;
+
+ /*
+ * The new pool is automatically part of the namespace unless we
+ * explicitly export it.
+ */
+ if (!flags.import)
+ zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
+ if (zcmd_write_conf_nvlist(hdl, &zc, newconfig) != 0)
+ goto out;
+ if (zc_props != NULL && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
+ goto out;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
+ retval = zpool_standard_error(hdl, errno, msg);
+ goto out;
+ }
+
+ freelist = B_FALSE;
+ memory_err = B_FALSE;
+
+out:
+ if (varray != NULL) {
+ int v;
+
+ for (v = 0; v < vcount; v++)
+ nvlist_free(varray[v]);
+ free(varray);
+ }
+ zcmd_free_nvlists(&zc);
+ if (zc_props)
+ nvlist_free(zc_props);
+ if (newconfig)
+ nvlist_free(newconfig);
+ if (freelist) {
+ nvlist_free(*newroot);
+ *newroot = NULL;
+ }
+
+ if (retval != 0)
+ return (retval);
+
+ if (memory_err)
+ return (no_memory(hdl));
+
+ return (0);
+}
+
+/*
+ * Remove the given device. Currently, this is supported only for hot spares
+ * and level 2 cache devices.
+ */
+int
+zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tgt;
+ boolean_t avail_spare, l2cache, islog;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ uint64_t version;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
+ &islog)) == 0)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+ /*
+ * XXX - this should just go away.
+ */
+ if (!avail_spare && !l2cache && !islog) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "only inactive hot spares, cache, top-level, "
+ "or log devices can be removed"));
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+ }
+
+ version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
+ if (islog && version < SPA_VERSION_HOLES) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgrade to support log removal"));
+ return (zfs_error(hdl, EZFS_BADVERSION, msg));
+ }
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
+
+ if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
+ return (0);
+
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Clear the errors for the pool, or the particular device if specified.
+ */
+int
+zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ nvlist_t *tgt;
+ zpool_rewind_policy_t policy;
+ boolean_t avail_spare, l2cache;
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ nvlist_t *nvi = NULL;
+ int error;
+
+ if (path)
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
+ path);
+ else
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
+ zhp->zpool_name);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if (path) {
+ if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
+ &l2cache, NULL)) == 0)
+ return (zfs_error(hdl, EZFS_NODEVICE, msg));
+
+ /*
+ * Don't allow error clearing for hot spares. Do allow
+ * error clearing for l2cache devices.
+ */
+ if (avail_spare)
+ return (zfs_error(hdl, EZFS_ISSPARE, msg));
+
+ verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
+ &zc.zc_guid) == 0);
+ }
+
+ zpool_get_rewind_policy(rewindnvl, &policy);
+ zc.zc_cookie = policy.zrp_request;
+
+ if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2) != 0)
+ return (-1);
+
+ if (zcmd_write_src_nvlist(hdl, &zc, rewindnvl) != 0)
+ return (-1);
+
+ while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
+ errno == ENOMEM) {
+ if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ }
+
+ if (!error || ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
+ errno != EPERM && errno != EACCES)) {
+ if (policy.zrp_request &
+ (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
+ (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
+ zpool_rewind_exclaim(hdl, zc.zc_name,
+ ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
+ nvi);
+ nvlist_free(nvi);
+ }
+ zcmd_free_nvlists(&zc);
+ return (0);
+ }
+
+ zcmd_free_nvlists(&zc);
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Similar to zpool_clear(), but takes a GUID (used by fmd).
+ */
+int
+zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
+ guid);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_guid = guid;
+ zc.zc_cookie = ZPOOL_NO_REWIND;
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
+ return (0);
+
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Change the GUID for a pool.
+ */
+int
+zpool_reguid(zpool_handle_t *zhp)
+{
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+ zfs_cmd_t zc = { 0 };
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
+ return (0);
+
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Reopen the pool.
+ */
+int
+zpool_reopen(zpool_handle_t *zhp)
+{
+ zfs_cmd_t zc = { 0 };
+ char msg[1024];
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) snprintf(msg, sizeof (msg),
+ dgettext(TEXT_DOMAIN, "cannot reopen '%s'"),
+ zhp->zpool_name);
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ if (zfs_ioctl(hdl, ZFS_IOC_POOL_REOPEN, &zc) == 0)
+ return (0);
+ return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
+ * Convert from a devid string to a path.
+ */
+static char *
+devid_to_path(char *devid_str)
+{
+ ddi_devid_t devid;
+ char *minor;
+ char *path;
+ devid_nmlist_t *list = NULL;
+ int ret;
+
+ if (devid_str_decode(devid_str, &devid, &minor) != 0)
+ return (NULL);
+
+ ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
+
+ devid_str_free(minor);
+ devid_free(devid);
+
+ if (ret != 0)
+ return (NULL);
+
+ if ((path = strdup(list[0].devname)) == NULL)
+ return (NULL);
+
+ devid_free_nmlist(list);
+
+ return (path);
+}
+
+/*
+ * Convert from a path to a devid string.
+ */
+static char *
+path_to_devid(const char *path)
+{
+ int fd;
+ ddi_devid_t devid;
+ char *minor, *ret;
+
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return (NULL);
+
+ minor = NULL;
+ ret = NULL;
+ if (devid_get(fd, &devid) == 0) {
+ if (devid_get_minor_name(fd, &minor) == 0)
+ ret = devid_str_encode(devid, minor);
+ if (minor != NULL)
+ devid_str_free(minor);
+ devid_free(devid);
+ }
+ (void) close(fd);
+
+ return (ret);
+}
+
+/*
+ * Issue the necessary ioctl() to update the stored path value for the vdev. We
+ * ignore any failure here, since a common case is for an unprivileged user to
+ * type 'zpool status', and we'll display the correct information anyway.
+ */
+static void
+set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
+{
+ zfs_cmd_t zc = { 0 };
+
+ (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
+ &zc.zc_guid) == 0);
+
+ (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
+}
+
+/*
+ * Given a vdev, return the name to display in iostat. If the vdev has a path,
+ * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
+ * We also check if this is a whole disk, in which case we strip off the
+ * trailing 's0' slice name.
+ *
+ * This routine is also responsible for identifying when disks have been
+ * reconfigured in a new location. The kernel will have opened the device by
+ * devid, but the path will still refer to the old location. To catch this, we
+ * first do a path -> devid translation (which is fast for the common case). If
+ * the devid matches, we're done. If not, we do a reverse devid -> path
+ * translation and issue the appropriate ioctl() to update the path of the vdev.
+ * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
+ * of these checks.
+ */
+char *
+zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
+ boolean_t verbose)
+{
+ char *path, *devid;
+ uint64_t value;
+ char buf[64];
+ vdev_stat_t *vs;
+ uint_t vsc;
+ int have_stats;
+ int have_path;
+
+ have_stats = nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &vsc) == 0;
+ have_path = nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0;
+
+ /*
+ * If the device is not currently present, assume it will not
+ * come back at the same device path. Display the device by GUID.
+ */
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
+ have_path && have_stats && vs->vs_state <= VDEV_STATE_CANT_OPEN) {
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
+ &value) == 0);
+ (void) snprintf(buf, sizeof (buf), "%llu",
+ (u_longlong_t)value);
+ path = buf;
+ } else if (have_path) {
+
+ /*
+ * If the device is dead (faulted, offline, etc) then don't
+ * bother opening it. Otherwise we may be forcing the user to
+ * open a misbehaving device, which can have undesirable
+ * effects.
+ */
+ if ((have_stats == 0 ||
+ vs->vs_state >= VDEV_STATE_DEGRADED) &&
+ zhp != NULL &&
+ nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
+ /*
+ * Determine if the current path is correct.
+ */
+ char *newdevid = path_to_devid(path);
+
+ if (newdevid == NULL ||
+ strcmp(devid, newdevid) != 0) {
+ char *newpath;
+
+ if ((newpath = devid_to_path(devid)) != NULL) {
+ /*
+ * Update the path appropriately.
+ */
+ set_path(zhp, nv, newpath);
+ if (nvlist_add_string(nv,
+ ZPOOL_CONFIG_PATH, newpath) == 0)
+ verify(nvlist_lookup_string(nv,
+ ZPOOL_CONFIG_PATH,
+ &path) == 0);
+ free(newpath);
+ }
+ }
+
+ if (newdevid)
+ devid_str_free(newdevid);
+ }
+
+#ifdef sun
+ if (strncmp(path, "/dev/dsk/", 9) == 0)
+ path += 9;
+
+ if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
+ &value) == 0 && value) {
+ int pathlen = strlen(path);
+ char *tmp = zfs_strdup(hdl, path);
+
+ /*
+ * If it starts with c#, and ends with "s0", chop
+ * the "s0" off, or if it ends with "s0/old", remove
+ * the "s0" from the middle.
+ */
+ if (CTD_CHECK(tmp)) {
+ if (strcmp(&tmp[pathlen - 2], "s0") == 0) {
+ tmp[pathlen - 2] = '\0';
+ } else if (pathlen > 6 &&
+ strcmp(&tmp[pathlen - 6], "s0/old") == 0) {
+ (void) strcpy(&tmp[pathlen - 6],
+ "/old");
+ }
+ }
+ return (tmp);
+ }
+#else /* !sun */
+ if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
+ path += sizeof(_PATH_DEV) - 1;
+#endif /* !sun */
+ } else {
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
+
+ /*
+ * If it's a raidz device, we need to stick in the parity level.
+ */
+ if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
+ &value) == 0);
+ (void) snprintf(buf, sizeof (buf), "%s%llu", path,
+ (u_longlong_t)value);
+ path = buf;
+ }
+
+ /*
+ * We identify each top-level vdev by using a <type-id>
+ * naming convention.
+ */
+ if (verbose) {
+ uint64_t id;
+
+ verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
+ &id) == 0);
+ (void) snprintf(buf, sizeof (buf), "%s-%llu", path,
+ (u_longlong_t)id);
+ path = buf;
+ }
+ }
+
+ return (zfs_strdup(hdl, path));
+}
+
+static int
+zbookmark_compare(const void *a, const void *b)
+{
+ return (memcmp(a, b, sizeof (zbookmark_t)));
+}
+
+/*
+ * Retrieve the persistent error log, uniquify the members, and return to the
+ * caller.
+ */
+int
+zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
+{
+ zfs_cmd_t zc = { 0 };
+ uint64_t count;
+ zbookmark_t *zb = NULL;
+ int i;
+
+ /*
+ * Retrieve the raw error list from the kernel. If the number of errors
+ * has increased, allocate more space and continue until we get the
+ * entire list.
+ */
+ verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
+ &count) == 0);
+ if (count == 0)
+ return (0);
+ if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
+ count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
+ return (-1);
+ zc.zc_nvlist_dst_size = count;
+ (void) strcpy(zc.zc_name, zhp->zpool_name);
+ for (;;) {
+ if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
+ &zc) != 0) {
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ if (errno == ENOMEM) {
+ count = zc.zc_nvlist_dst_size;
+ if ((zc.zc_nvlist_dst = (uintptr_t)
+ zfs_alloc(zhp->zpool_hdl, count *
+ sizeof (zbookmark_t))) == (uintptr_t)NULL)
+ return (-1);
+ } else {
+ return (-1);
+ }
+ } else {
+ break;
+ }
+ }
+
+ /*
+ * Sort the resulting bookmarks. This is a little confusing due to the
+ * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last
+ * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
+ * _not_ copied as part of the process. So we point the start of our
+ * array appropriate and decrement the total number of elements.
+ */
+ zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
+ zc.zc_nvlist_dst_size;
+ count -= zc.zc_nvlist_dst_size;
+
+ qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
+
+ verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
+
+ /*
+ * Fill in the nverrlistp with nvlist's of dataset and object numbers.
+ */
+ for (i = 0; i < count; i++) {
+ nvlist_t *nv;
+
+ /* ignoring zb_blkid and zb_level for now */
+ if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
+ zb[i-1].zb_object == zb[i].zb_object)
+ continue;
+
+ if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
+ goto nomem;
+ if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
+ zb[i].zb_objset) != 0) {
+ nvlist_free(nv);
+ goto nomem;
+ }
+ if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
+ zb[i].zb_object) != 0) {
+ nvlist_free(nv);
+ goto nomem;
+ }
+ if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
+ nvlist_free(nv);
+ goto nomem;
+ }
+ nvlist_free(nv);
+ }
+
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ return (0);
+
+nomem:
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ return (no_memory(zhp->zpool_hdl));
+}
+
+/*
+ * Upgrade a ZFS pool to the latest on-disk version.
+ */
+int
+zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) strcpy(zc.zc_name, zhp->zpool_name);
+ zc.zc_cookie = new_version;
+
+ if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
+ return (zpool_standard_error_fmt(hdl, errno,
+ dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
+ zhp->zpool_name));
+ return (0);
+}
+
+void
+zfs_save_arguments(int argc, char **argv, char *string, int len)
+{
+ (void) strlcpy(string, basename(argv[0]), len);
+ for (int i = 1; i < argc; i++) {
+ (void) strlcat(string, " ", len);
+ (void) strlcat(string, argv[i], len);
+ }
+}
+
+int
+zpool_log_history(libzfs_handle_t *hdl, const char *message)
+{
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *args;
+ int err;
+
+ args = fnvlist_alloc();
+ fnvlist_add_string(args, "message", message);
+ err = zcmd_write_src_nvlist(hdl, &zc, args);
+ if (err == 0)
+ err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
+ nvlist_free(args);
+ zcmd_free_nvlists(&zc);
+ return (err);
+}
+
+/*
+ * Perform ioctl to get some command history of a pool.
+ *
+ * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the
+ * logical offset of the history buffer to start reading from.
+ *
+ * Upon return, 'off' is the next logical offset to read from and
+ * 'len' is the actual amount of bytes read into 'buf'.
+ */
+static int
+get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+
+ zc.zc_history = (uint64_t)(uintptr_t)buf;
+ zc.zc_history_len = *len;
+ zc.zc_history_offset = *off;
+
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
+ switch (errno) {
+ case EPERM:
+ return (zfs_error_fmt(hdl, EZFS_PERM,
+ dgettext(TEXT_DOMAIN,
+ "cannot show history for pool '%s'"),
+ zhp->zpool_name));
+ case ENOENT:
+ return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
+ dgettext(TEXT_DOMAIN, "cannot get history for pool "
+ "'%s'"), zhp->zpool_name));
+ case ENOTSUP:
+ return (zfs_error_fmt(hdl, EZFS_BADVERSION,
+ dgettext(TEXT_DOMAIN, "cannot get history for pool "
+ "'%s', pool must be upgraded"), zhp->zpool_name));
+ default:
+ return (zpool_standard_error_fmt(hdl, errno,
+ dgettext(TEXT_DOMAIN,
+ "cannot get history for '%s'"), zhp->zpool_name));
+ }
+ }
+
+ *len = zc.zc_history_len;
+ *off = zc.zc_history_offset;
+
+ return (0);
+}
+
+/*
+ * Process the buffer of nvlists, unpacking and storing each nvlist record
+ * into 'records'. 'leftover' is set to the number of bytes that weren't
+ * processed as there wasn't a complete record.
+ */
+int
+zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
+ nvlist_t ***records, uint_t *numrecords)
+{
+ uint64_t reclen;
+ nvlist_t *nv;
+ int i;
+
+ while (bytes_read > sizeof (reclen)) {
+
+ /* get length of packed record (stored as little endian) */
+ for (i = 0, reclen = 0; i < sizeof (reclen); i++)
+ reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
+
+ if (bytes_read < sizeof (reclen) + reclen)
+ break;
+
+ /* unpack record */
+ if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
+ return (ENOMEM);
+ bytes_read -= sizeof (reclen) + reclen;
+ buf += sizeof (reclen) + reclen;
+
+ /* add record to nvlist array */
+ (*numrecords)++;
+ if (ISP2(*numrecords + 1)) {
+ *records = realloc(*records,
+ *numrecords * 2 * sizeof (nvlist_t *));
+ }
+ (*records)[*numrecords - 1] = nv;
+ }
+
+ *leftover = bytes_read;
+ return (0);
+}
+
+#define HIS_BUF_LEN (128*1024)
+
+/*
+ * Retrieve the command history of a pool.
+ */
+int
+zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
+{
+ char buf[HIS_BUF_LEN];
+ uint64_t off = 0;
+ nvlist_t **records = NULL;
+ uint_t numrecords = 0;
+ int err, i;
+
+ do {
+ uint64_t bytes_read = sizeof (buf);
+ uint64_t leftover;
+
+ if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
+ break;
+
+ /* if nothing else was read in, we're at EOF, just return */
+ if (!bytes_read)
+ break;
+
+ if ((err = zpool_history_unpack(buf, bytes_read,
+ &leftover, &records, &numrecords)) != 0)
+ break;
+ off -= leftover;
+
+ /* CONSTCOND */
+ } while (1);
+
+ if (!err) {
+ verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
+ verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
+ records, numrecords) == 0);
+ }
+ for (i = 0; i < numrecords; i++)
+ nvlist_free(records[i]);
+ free(records);
+
+ return (err);
+}
+
+void
+zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
+ char *pathname, size_t len)
+{
+ zfs_cmd_t zc = { 0 };
+ boolean_t mounted = B_FALSE;
+ char *mntpnt = NULL;
+ char dsname[MAXNAMELEN];
+
+ if (dsobj == 0) {
+ /* special case for the MOS */
+ (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
+ return;
+ }
+
+ /* get the dataset's name */
+ (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+ zc.zc_obj = dsobj;
+ if (ioctl(zhp->zpool_hdl->libzfs_fd,
+ ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
+ /* just write out a path of two object numbers */
+ (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
+ dsobj, obj);
+ return;
+ }
+ (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
+
+ /* find out if the dataset is mounted */
+ mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
+
+ /* get the corrupted object's path */
+ (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
+ zc.zc_obj = obj;
+ if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
+ &zc) == 0) {
+ if (mounted) {
+ (void) snprintf(pathname, len, "%s%s", mntpnt,
+ zc.zc_value);
+ } else {
+ (void) snprintf(pathname, len, "%s:%s",
+ dsname, zc.zc_value);
+ }
+ } else {
+ (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
+ }
+ free(mntpnt);
+}
+
+#ifdef sun
+/*
+ * Read the EFI label from the config, if a label does not exist then
+ * pass back the error to the caller. If the caller has passed a non-NULL
+ * diskaddr argument then we set it to the starting address of the EFI
+ * partition.
+ */
+static int
+read_efi_label(nvlist_t *config, diskaddr_t *sb)
+{
+ char *path;
+ int fd;
+ char diskname[MAXPATHLEN];
+ int err = -1;
+
+ if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
+ return (err);
+
+ (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
+ strrchr(path, '/'));
+ if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
+ struct dk_gpt *vtoc;
+
+ if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
+ if (sb != NULL)
+ *sb = vtoc->efi_parts[0].p_start;
+ efi_free(vtoc);
+ }
+ (void) close(fd);
+ }
+ return (err);
+}
+
+/*
+ * determine where a partition starts on a disk in the current
+ * configuration
+ */
+static diskaddr_t
+find_start_block(nvlist_t *config)
+{
+ nvlist_t **child;
+ uint_t c, children;
+ diskaddr_t sb = MAXOFFSET_T;
+ uint64_t wholedisk;
+
+ if (nvlist_lookup_nvlist_array(config,
+ ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
+ if (nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_WHOLE_DISK,
+ &wholedisk) != 0 || !wholedisk) {
+ return (MAXOFFSET_T);
+ }
+ if (read_efi_label(config, &sb) < 0)
+ sb = MAXOFFSET_T;
+ return (sb);
+ }
+
+ for (c = 0; c < children; c++) {
+ sb = find_start_block(child[c]);
+ if (sb != MAXOFFSET_T) {
+ return (sb);
+ }
+ }
+ return (MAXOFFSET_T);
+}
+#endif /* sun */
+
+/*
+ * Label an individual disk. The name provided is the short name,
+ * stripped of any leading /dev path.
+ */
+int
+zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
+{
+#ifdef sun
+ char path[MAXPATHLEN];
+ struct dk_gpt *vtoc;
+ int fd;
+ size_t resv = EFI_MIN_RESV_SIZE;
+ uint64_t slice_size;
+ diskaddr_t start_block;
+ char errbuf[1024];
+
+ /* prepare an error message just in case */
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
+
+ if (zhp) {
+ nvlist_t *nvroot;
+
+ if (zpool_is_bootable(zhp)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "EFI labeled devices are not supported on root "
+ "pools."));
+ return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
+ }
+
+ verify(nvlist_lookup_nvlist(zhp->zpool_config,
+ ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
+
+ if (zhp->zpool_start_block == 0)
+ start_block = find_start_block(nvroot);
+ else
+ start_block = zhp->zpool_start_block;
+ zhp->zpool_start_block = start_block;
+ } else {
+ /* new pool */
+ start_block = NEW_START_BLOCK;
+ }
+
+ (void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
+ BACKUP_SLICE);
+
+ if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
+ /*
+ * This shouldn't happen. We've long since verified that this
+ * is a valid device.
+ */
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "unable to open device"));
+ return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
+ }
+
+ if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
+ /*
+ * The only way this can fail is if we run out of memory, or we
+ * were unable to read the disk's capacity
+ */
+ if (errno == ENOMEM)
+ (void) no_memory(hdl);
+
+ (void) close(fd);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "unable to read disk capacity"), name);
+
+ return (zfs_error(hdl, EZFS_NOCAP, errbuf));
+ }
+
+ slice_size = vtoc->efi_last_u_lba + 1;
+ slice_size -= EFI_MIN_RESV_SIZE;
+ if (start_block == MAXOFFSET_T)
+ start_block = NEW_START_BLOCK;
+ slice_size -= start_block;
+
+ vtoc->efi_parts[0].p_start = start_block;
+ vtoc->efi_parts[0].p_size = slice_size;
+
+ /*
+ * Why we use V_USR: V_BACKUP confuses users, and is considered
+ * disposable by some EFI utilities (since EFI doesn't have a backup
+ * slice). V_UNASSIGNED is supposed to be used only for zero size
+ * partitions, and efi_write() will fail if we use it. V_ROOT, V_BOOT,
+ * etc. were all pretty specific. V_USR is as close to reality as we
+ * can get, in the absence of V_OTHER.
+ */
+ vtoc->efi_parts[0].p_tag = V_USR;
+ (void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
+
+ vtoc->efi_parts[8].p_start = slice_size + start_block;
+ vtoc->efi_parts[8].p_size = resv;
+ vtoc->efi_parts[8].p_tag = V_RESERVED;
+
+ if (efi_write(fd, vtoc) != 0) {
+ /*
+ * Some block drivers (like pcata) may not support EFI
+ * GPT labels. Print out a helpful error message dir-
+ * ecting the user to manually label the disk and give
+ * a specific slice.
+ */
+ (void) close(fd);
+ efi_free(vtoc);
+
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "try using fdisk(1M) and then provide a specific slice"));
+ return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
+ }
+
+ (void) close(fd);
+ efi_free(vtoc);
+#endif /* sun */
+ return (0);
+}
+
+static boolean_t
+supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
+{
+ char *type;
+ nvlist_t **child;
+ uint_t children, c;
+
+ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
+ if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
+ strcmp(type, VDEV_TYPE_FILE) == 0 ||
+ strcmp(type, VDEV_TYPE_LOG) == 0 ||
+ strcmp(type, VDEV_TYPE_HOLE) == 0 ||
+ strcmp(type, VDEV_TYPE_MISSING) == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "vdev type '%s' is not supported"), type);
+ (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf);
+ return (B_FALSE);
+ }
+ if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (c = 0; c < children; c++) {
+ if (!supported_dump_vdev_type(hdl, child[c], errbuf))
+ return (B_FALSE);
+ }
+ }
+ return (B_TRUE);
+}
+
+/*
+ * check if this zvol is allowable for use as a dump device; zero if
+ * it is, > 0 if it isn't, < 0 if it isn't a zvol
+ */
+int
+zvol_check_dump_config(char *arg)
+{
+ zpool_handle_t *zhp = NULL;
+ nvlist_t *config, *nvroot;
+ char *p, *volname;
+ nvlist_t **top;
+ uint_t toplevels;
+ libzfs_handle_t *hdl;
+ char errbuf[1024];
+ char poolname[ZPOOL_MAXNAMELEN];
+ int pathlen = strlen(ZVOL_FULL_DEV_DIR);
+ int ret = 1;
+
+ if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) {
+ return (-1);
+ }
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "dump is not supported on device '%s'"), arg);
+
+ if ((hdl = libzfs_init()) == NULL)
+ return (1);
+ libzfs_print_on_error(hdl, B_TRUE);
+
+ volname = arg + pathlen;
+
+ /* check the configuration of the pool */
+ if ((p = strchr(volname, '/')) == NULL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "malformed dataset name"));
+ (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
+ return (1);
+ } else if (p - volname >= ZFS_MAXNAMELEN) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset name is too long"));
+ (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf);
+ return (1);
+ } else {
+ (void) strncpy(poolname, volname, p - volname);
+ poolname[p - volname] = '\0';
+ }
+
+ if ((zhp = zpool_open(hdl, poolname)) == NULL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "could not open pool '%s'"), poolname);
+ (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
+ goto out;
+ }
+ config = zpool_get_config(zhp, NULL);
+ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "could not obtain vdev configuration for '%s'"), poolname);
+ (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
+ goto out;
+ }
+
+ verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ &top, &toplevels) == 0);
+ if (toplevels != 1) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' has multiple top level vdevs"), poolname);
+ (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf);
+ goto out;
+ }
+
+ if (!supported_dump_vdev_type(hdl, top[0], errbuf)) {
+ goto out;
+ }
+ ret = 0;
+
+out:
+ if (zhp)
+ zpool_close(zhp);
+ libzfs_fini(hdl);
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
new file mode 100644
index 0000000..34cb648
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
@@ -0,0 +1,3241 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
+ * All rights reserved.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <pthread.h>
+#include <umem.h>
+#include <time.h>
+
+#include <libzfs.h>
+
+#include "zfs_namecheck.h"
+#include "zfs_prop.h"
+#include "zfs_fletcher.h"
+#include "libzfs_impl.h"
+#include <sha2.h>
+#include <sys/zio_checksum.h>
+#include <sys/ddt.h>
+
+#ifdef __FreeBSD__
+extern int zfs_ioctl_version;
+#endif
+
+/* in libzfs_dataset.c */
+extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
+/* We need to use something for ENODATA. */
+#define ENODATA EIDRM
+
+static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t *,
+ int, const char *, nvlist_t *, avl_tree_t *, char **, int, uint64_t *);
+
+static const zio_cksum_t zero_cksum = { 0 };
+
+typedef struct dedup_arg {
+ int inputfd;
+ int outputfd;
+ libzfs_handle_t *dedup_hdl;
+} dedup_arg_t;
+
+typedef struct progress_arg {
+ zfs_handle_t *pa_zhp;
+ int pa_fd;
+ boolean_t pa_parsable;
+} progress_arg_t;
+
+typedef struct dataref {
+ uint64_t ref_guid;
+ uint64_t ref_object;
+ uint64_t ref_offset;
+} dataref_t;
+
+typedef struct dedup_entry {
+ struct dedup_entry *dde_next;
+ zio_cksum_t dde_chksum;
+ uint64_t dde_prop;
+ dataref_t dde_ref;
+} dedup_entry_t;
+
+#define MAX_DDT_PHYSMEM_PERCENT 20
+#define SMALLEST_POSSIBLE_MAX_DDT_MB 128
+
+typedef struct dedup_table {
+ dedup_entry_t **dedup_hash_array;
+ umem_cache_t *ddecache;
+ uint64_t max_ddt_size; /* max dedup table size in bytes */
+ uint64_t cur_ddt_size; /* current dedup table size in bytes */
+ uint64_t ddt_count;
+ int numhashbits;
+ boolean_t ddt_full;
+} dedup_table_t;
+
+static int
+high_order_bit(uint64_t n)
+{
+ int count;
+
+ for (count = 0; n != 0; count++)
+ n >>= 1;
+ return (count);
+}
+
+static size_t
+ssread(void *buf, size_t len, FILE *stream)
+{
+ size_t outlen;
+
+ if ((outlen = fread(buf, len, 1, stream)) == 0)
+ return (0);
+
+ return (outlen);
+}
+
+static void
+ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
+ zio_cksum_t *cs, uint64_t prop, dataref_t *dr)
+{
+ dedup_entry_t *dde;
+
+ if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
+ if (ddt->ddt_full == B_FALSE) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "Dedup table full. Deduplication will continue "
+ "with existing table entries"));
+ ddt->ddt_full = B_TRUE;
+ }
+ return;
+ }
+
+ if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
+ != NULL) {
+ assert(*ddepp == NULL);
+ dde->dde_next = NULL;
+ dde->dde_chksum = *cs;
+ dde->dde_prop = prop;
+ dde->dde_ref = *dr;
+ *ddepp = dde;
+ ddt->cur_ddt_size += sizeof (dedup_entry_t);
+ ddt->ddt_count++;
+ }
+}
+
+/*
+ * Using the specified dedup table, do a lookup for an entry with
+ * the checksum cs. If found, return the block's reference info
+ * in *dr. Otherwise, insert a new entry in the dedup table, using
+ * the reference information specified by *dr.
+ *
+ * return value: true - entry was found
+ * false - entry was not found
+ */
+static boolean_t
+ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
+ uint64_t prop, dataref_t *dr)
+{
+ uint32_t hashcode;
+ dedup_entry_t **ddepp;
+
+ hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);
+
+ for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
+ ddepp = &((*ddepp)->dde_next)) {
+ if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) &&
+ (*ddepp)->dde_prop == prop) {
+ *dr = (*ddepp)->dde_ref;
+ return (B_TRUE);
+ }
+ }
+ ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr);
+ return (B_FALSE);
+}
+
+static int
+cksum_and_write(const void *buf, uint64_t len, zio_cksum_t *zc, int outfd)
+{
+ fletcher_4_incremental_native(buf, len, zc);
+ return (write(outfd, buf, len));
+}
+
+/*
+ * This function is started in a separate thread when the dedup option
+ * has been requested. The main send thread determines the list of
+ * snapshots to be included in the send stream and makes the ioctl calls
+ * for each one. But instead of having the ioctl send the output to the
+ * the output fd specified by the caller of zfs_send()), the
+ * ioctl is told to direct the output to a pipe, which is read by the
+ * alternate thread running THIS function. This function does the
+ * dedup'ing by:
+ * 1. building a dedup table (the DDT)
+ * 2. doing checksums on each data block and inserting a record in the DDT
+ * 3. looking for matching checksums, and
+ * 4. sending a DRR_WRITE_BYREF record instead of a write record whenever
+ * a duplicate block is found.
+ * The output of this function then goes to the output fd requested
+ * by the caller of zfs_send().
+ */
+static void *
+cksummer(void *arg)
+{
+ dedup_arg_t *dda = arg;
+ char *buf = malloc(1<<20);
+ dmu_replay_record_t thedrr;
+ dmu_replay_record_t *drr = &thedrr;
+ struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
+ struct drr_end *drre = &thedrr.drr_u.drr_end;
+ struct drr_object *drro = &thedrr.drr_u.drr_object;
+ struct drr_write *drrw = &thedrr.drr_u.drr_write;
+ struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
+ FILE *ofp;
+ int outfd;
+ dmu_replay_record_t wbr_drr = {0};
+ struct drr_write_byref *wbr_drrr = &wbr_drr.drr_u.drr_write_byref;
+ dedup_table_t ddt;
+ zio_cksum_t stream_cksum;
+ uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
+ uint64_t numbuckets;
+
+ ddt.max_ddt_size =
+ MAX((physmem * MAX_DDT_PHYSMEM_PERCENT)/100,
+ SMALLEST_POSSIBLE_MAX_DDT_MB<<20);
+
+ numbuckets = ddt.max_ddt_size/(sizeof (dedup_entry_t));
+
+ /*
+ * numbuckets must be a power of 2. Increase number to
+ * a power of 2 if necessary.
+ */
+ if (!ISP2(numbuckets))
+ numbuckets = 1 << high_order_bit(numbuckets);
+
+ ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
+ ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
+ NULL, NULL, NULL, NULL, NULL, 0);
+ ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
+ ddt.numhashbits = high_order_bit(numbuckets) - 1;
+ ddt.ddt_full = B_FALSE;
+
+ /* Initialize the write-by-reference block. */
+ wbr_drr.drr_type = DRR_WRITE_BYREF;
+ wbr_drr.drr_payloadlen = 0;
+
+ outfd = dda->outputfd;
+ ofp = fdopen(dda->inputfd, "r");
+ while (ssread(drr, sizeof (dmu_replay_record_t), ofp) != 0) {
+
+ switch (drr->drr_type) {
+ case DRR_BEGIN:
+ {
+ int fflags;
+ ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
+
+ /* set the DEDUP feature flag for this stream */
+ fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
+ fflags |= (DMU_BACKUP_FEATURE_DEDUP |
+ DMU_BACKUP_FEATURE_DEDUPPROPS);
+ DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
+
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
+ DMU_COMPOUNDSTREAM && drr->drr_payloadlen != 0) {
+ int sz = drr->drr_payloadlen;
+
+ if (sz > 1<<20) {
+ free(buf);
+ buf = malloc(sz);
+ }
+ (void) ssread(buf, sz, ofp);
+ if (ferror(stdin))
+ perror("fread");
+ if (cksum_and_write(buf, sz, &stream_cksum,
+ outfd) == -1)
+ goto out;
+ }
+ break;
+ }
+
+ case DRR_END:
+ {
+ /* use the recalculated checksum */
+ ZIO_SET_CHECKSUM(&drre->drr_checksum,
+ stream_cksum.zc_word[0], stream_cksum.zc_word[1],
+ stream_cksum.zc_word[2], stream_cksum.zc_word[3]);
+ if ((write(outfd, drr,
+ sizeof (dmu_replay_record_t))) == -1)
+ goto out;
+ break;
+ }
+
+ case DRR_OBJECT:
+ {
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ if (drro->drr_bonuslen > 0) {
+ (void) ssread(buf,
+ P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
+ ofp);
+ if (cksum_and_write(buf,
+ P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ }
+ break;
+ }
+
+ case DRR_SPILL:
+ {
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ (void) ssread(buf, drrs->drr_length, ofp);
+ if (cksum_and_write(buf, drrs->drr_length,
+ &stream_cksum, outfd) == -1)
+ goto out;
+ break;
+ }
+
+ case DRR_FREEOBJECTS:
+ {
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ break;
+ }
+
+ case DRR_WRITE:
+ {
+ dataref_t dataref;
+
+ (void) ssread(buf, drrw->drr_length, ofp);
+
+ /*
+ * Use the existing checksum if it's dedup-capable,
+ * else calculate a SHA256 checksum for it.
+ */
+
+ if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
+ zero_cksum) ||
+ !DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
+ SHA256_CTX ctx;
+ zio_cksum_t tmpsha256;
+
+ SHA256Init(&ctx);
+ SHA256Update(&ctx, buf, drrw->drr_length);
+ SHA256Final(&tmpsha256, &ctx);
+ drrw->drr_key.ddk_cksum.zc_word[0] =
+ BE_64(tmpsha256.zc_word[0]);
+ drrw->drr_key.ddk_cksum.zc_word[1] =
+ BE_64(tmpsha256.zc_word[1]);
+ drrw->drr_key.ddk_cksum.zc_word[2] =
+ BE_64(tmpsha256.zc_word[2]);
+ drrw->drr_key.ddk_cksum.zc_word[3] =
+ BE_64(tmpsha256.zc_word[3]);
+ drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256;
+ drrw->drr_checksumflags = DRR_CHECKSUM_DEDUP;
+ }
+
+ dataref.ref_guid = drrw->drr_toguid;
+ dataref.ref_object = drrw->drr_object;
+ dataref.ref_offset = drrw->drr_offset;
+
+ if (ddt_update(dda->dedup_hdl, &ddt,
+ &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
+ &dataref)) {
+ /* block already present in stream */
+ wbr_drrr->drr_object = drrw->drr_object;
+ wbr_drrr->drr_offset = drrw->drr_offset;
+ wbr_drrr->drr_length = drrw->drr_length;
+ wbr_drrr->drr_toguid = drrw->drr_toguid;
+ wbr_drrr->drr_refguid = dataref.ref_guid;
+ wbr_drrr->drr_refobject =
+ dataref.ref_object;
+ wbr_drrr->drr_refoffset =
+ dataref.ref_offset;
+
+ wbr_drrr->drr_checksumtype =
+ drrw->drr_checksumtype;
+ wbr_drrr->drr_checksumflags =
+ drrw->drr_checksumtype;
+ wbr_drrr->drr_key.ddk_cksum =
+ drrw->drr_key.ddk_cksum;
+ wbr_drrr->drr_key.ddk_prop =
+ drrw->drr_key.ddk_prop;
+
+ if (cksum_and_write(&wbr_drr,
+ sizeof (dmu_replay_record_t), &stream_cksum,
+ outfd) == -1)
+ goto out;
+ } else {
+ /* block not previously seen */
+ if (cksum_and_write(drr,
+ sizeof (dmu_replay_record_t), &stream_cksum,
+ outfd) == -1)
+ goto out;
+ if (cksum_and_write(buf,
+ drrw->drr_length,
+ &stream_cksum, outfd) == -1)
+ goto out;
+ }
+ break;
+ }
+
+ case DRR_FREE:
+ {
+ if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
+ &stream_cksum, outfd) == -1)
+ goto out;
+ break;
+ }
+
+ default:
+ (void) printf("INVALID record type 0x%x\n",
+ drr->drr_type);
+ /* should never happen, so assert */
+ assert(B_FALSE);
+ }
+ }
+out:
+ umem_cache_destroy(ddt.ddecache);
+ free(ddt.dedup_hash_array);
+ free(buf);
+ (void) fclose(ofp);
+
+ return (NULL);
+}
+
+/*
+ * Routines for dealing with the AVL tree of fs-nvlists
+ */
+typedef struct fsavl_node {
+ avl_node_t fn_node;
+ nvlist_t *fn_nvfs;
+ char *fn_snapname;
+ uint64_t fn_guid;
+} fsavl_node_t;
+
+static int
+fsavl_compare(const void *arg1, const void *arg2)
+{
+ const fsavl_node_t *fn1 = arg1;
+ const fsavl_node_t *fn2 = arg2;
+
+ if (fn1->fn_guid > fn2->fn_guid)
+ return (+1);
+ else if (fn1->fn_guid < fn2->fn_guid)
+ return (-1);
+ else
+ return (0);
+}
+
+/*
+ * Given the GUID of a snapshot, find its containing filesystem and
+ * (optionally) name.
+ */
+static nvlist_t *
+fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
+{
+ fsavl_node_t fn_find;
+ fsavl_node_t *fn;
+
+ fn_find.fn_guid = snapguid;
+
+ fn = avl_find(avl, &fn_find, NULL);
+ if (fn) {
+ if (snapname)
+ *snapname = fn->fn_snapname;
+ return (fn->fn_nvfs);
+ }
+ return (NULL);
+}
+
+static void
+fsavl_destroy(avl_tree_t *avl)
+{
+ fsavl_node_t *fn;
+ void *cookie;
+
+ if (avl == NULL)
+ return;
+
+ cookie = NULL;
+ while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
+ free(fn);
+ avl_destroy(avl);
+ free(avl);
+}
+
+/*
+ * Given an nvlist, produce an avl tree of snapshots, ordered by guid
+ */
+static avl_tree_t *
+fsavl_create(nvlist_t *fss)
+{
+ avl_tree_t *fsavl;
+ nvpair_t *fselem = NULL;
+
+ if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
+ return (NULL);
+
+ avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
+ offsetof(fsavl_node_t, fn_node));
+
+ while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
+ nvlist_t *nvfs, *snaps;
+ nvpair_t *snapelem = NULL;
+
+ VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
+ VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
+
+ while ((snapelem =
+ nvlist_next_nvpair(snaps, snapelem)) != NULL) {
+ fsavl_node_t *fn;
+ uint64_t guid;
+
+ VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
+ if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
+ fsavl_destroy(fsavl);
+ return (NULL);
+ }
+ fn->fn_nvfs = nvfs;
+ fn->fn_snapname = nvpair_name(snapelem);
+ fn->fn_guid = guid;
+
+ /*
+ * Note: if there are multiple snaps with the
+ * same GUID, we ignore all but one.
+ */
+ if (avl_find(fsavl, fn, NULL) == NULL)
+ avl_add(fsavl, fn);
+ else
+ free(fn);
+ }
+ }
+
+ return (fsavl);
+}
+
+/*
+ * Routines for dealing with the giant nvlist of fs-nvlists, etc.
+ */
+typedef struct send_data {
+ uint64_t parent_fromsnap_guid;
+ nvlist_t *parent_snaps;
+ nvlist_t *fss;
+ nvlist_t *snapprops;
+ const char *fromsnap;
+ const char *tosnap;
+ boolean_t recursive;
+
+ /*
+ * The header nvlist is of the following format:
+ * {
+ * "tosnap" -> string
+ * "fromsnap" -> string (if incremental)
+ * "fss" -> {
+ * id -> {
+ *
+ * "name" -> string (full name; for debugging)
+ * "parentfromsnap" -> number (guid of fromsnap in parent)
+ *
+ * "props" -> { name -> value (only if set here) }
+ * "snaps" -> { name (lastname) -> number (guid) }
+ * "snapprops" -> { name (lastname) -> { name -> value } }
+ *
+ * "origin" -> number (guid) (if clone)
+ * "sent" -> boolean (not on-disk)
+ * }
+ * }
+ * }
+ *
+ */
+} send_data_t;
+
+static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv);
+
+static int
+send_iterate_snap(zfs_handle_t *zhp, void *arg)
+{
+ send_data_t *sd = arg;
+ uint64_t guid = zhp->zfs_dmustats.dds_guid;
+ char *snapname;
+ nvlist_t *nv;
+
+ snapname = strrchr(zhp->zfs_name, '@')+1;
+
+ VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
+ /*
+ * NB: if there is no fromsnap here (it's a newly created fs in
+ * an incremental replication), we will substitute the tosnap.
+ */
+ if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
+ (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
+ strcmp(snapname, sd->tosnap) == 0)) {
+ sd->parent_fromsnap_guid = guid;
+ }
+
+ VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
+ send_iterate_prop(zhp, nv);
+ VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
+ nvlist_free(nv);
+
+ zfs_close(zhp);
+ return (0);
+}
+
+static void
+send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv)
+{
+ nvpair_t *elem = NULL;
+
+ while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
+ char *propname = nvpair_name(elem);
+ zfs_prop_t prop = zfs_name_to_prop(propname);
+ nvlist_t *propnv;
+
+ if (!zfs_prop_user(propname)) {
+ /*
+ * Realistically, this should never happen. However,
+ * we want the ability to add DSL properties without
+ * needing to make incompatible version changes. We
+ * need to ignore unknown properties to allow older
+ * software to still send datasets containing these
+ * properties, with the unknown properties elided.
+ */
+ if (prop == ZPROP_INVAL)
+ continue;
+
+ if (zfs_prop_readonly(prop))
+ continue;
+ }
+
+ verify(nvpair_value_nvlist(elem, &propnv) == 0);
+ if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION ||
+ prop == ZFS_PROP_REFQUOTA ||
+ prop == ZFS_PROP_REFRESERVATION) {
+ char *source;
+ uint64_t value;
+ verify(nvlist_lookup_uint64(propnv,
+ ZPROP_VALUE, &value) == 0);
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
+ continue;
+ /*
+ * May have no source before SPA_VERSION_RECVD_PROPS,
+ * but is still modifiable.
+ */
+ if (nvlist_lookup_string(propnv,
+ ZPROP_SOURCE, &source) == 0) {
+ if ((strcmp(source, zhp->zfs_name) != 0) &&
+ (strcmp(source,
+ ZPROP_SOURCE_VAL_RECVD) != 0))
+ continue;
+ }
+ } else {
+ char *source;
+ if (nvlist_lookup_string(propnv,
+ ZPROP_SOURCE, &source) != 0)
+ continue;
+ if ((strcmp(source, zhp->zfs_name) != 0) &&
+ (strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0))
+ continue;
+ }
+
+ if (zfs_prop_user(propname) ||
+ zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
+ char *value;
+ verify(nvlist_lookup_string(propnv,
+ ZPROP_VALUE, &value) == 0);
+ VERIFY(0 == nvlist_add_string(nv, propname, value));
+ } else {
+ uint64_t value;
+ verify(nvlist_lookup_uint64(propnv,
+ ZPROP_VALUE, &value) == 0);
+ VERIFY(0 == nvlist_add_uint64(nv, propname, value));
+ }
+ }
+}
+
+/*
+ * recursively generate nvlists describing datasets. See comment
+ * for the data structure send_data_t above for description of contents
+ * of the nvlist.
+ */
+static int
+send_iterate_fs(zfs_handle_t *zhp, void *arg)
+{
+ send_data_t *sd = arg;
+ nvlist_t *nvfs, *nv;
+ int rv = 0;
+ uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
+ uint64_t guid = zhp->zfs_dmustats.dds_guid;
+ char guidstring[64];
+
+ VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
+ VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
+ VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
+ sd->parent_fromsnap_guid));
+
+ if (zhp->zfs_dmustats.dds_origin[0]) {
+ zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
+ zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
+ if (origin == NULL)
+ return (-1);
+ VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
+ origin->zfs_dmustats.dds_guid));
+ }
+
+ /* iterate over props */
+ VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
+ send_iterate_prop(zhp, nv);
+ VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
+ nvlist_free(nv);
+
+ /* iterate over snaps, and set sd->parent_fromsnap_guid */
+ sd->parent_fromsnap_guid = 0;
+ VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
+ VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
+ (void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd);
+ VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
+ VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
+ nvlist_free(sd->parent_snaps);
+ nvlist_free(sd->snapprops);
+
+ /* add this fs to nvlist */
+ (void) snprintf(guidstring, sizeof (guidstring),
+ "0x%llx", (longlong_t)guid);
+ VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
+ nvlist_free(nvfs);
+
+ /* iterate over children */
+ if (sd->recursive)
+ rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
+
+ sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
+
+ zfs_close(zhp);
+ return (rv);
+}
+
+static int
+gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
+ const char *tosnap, boolean_t recursive, nvlist_t **nvlp, avl_tree_t **avlp)
+{
+ zfs_handle_t *zhp;
+ send_data_t sd = { 0 };
+ int error;
+
+ zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+ return (EZFS_BADTYPE);
+
+ VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
+ sd.fromsnap = fromsnap;
+ sd.tosnap = tosnap;
+ sd.recursive = recursive;
+
+ if ((error = send_iterate_fs(zhp, &sd)) != 0) {
+ nvlist_free(sd.fss);
+ if (avlp != NULL)
+ *avlp = NULL;
+ *nvlp = NULL;
+ return (error);
+ }
+
+ if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
+ nvlist_free(sd.fss);
+ *nvlp = NULL;
+ return (EZFS_NOMEM);
+ }
+
+ *nvlp = sd.fss;
+ return (0);
+}
+
+/*
+ * Routines specific to "zfs send"
+ */
+typedef struct send_dump_data {
+ /* these are all just the short snapname (the part after the @) */
+ const char *fromsnap;
+ const char *tosnap;
+ char prevsnap[ZFS_MAXNAMELEN];
+ uint64_t prevsnap_obj;
+ boolean_t seenfrom, seento, replicate, doall, fromorigin;
+ boolean_t verbose, dryrun, parsable, progress;
+ int outfd;
+ boolean_t err;
+ nvlist_t *fss;
+ avl_tree_t *fsavl;
+ snapfilter_cb_t *filter_cb;
+ void *filter_cb_arg;
+ nvlist_t *debugnv;
+ char holdtag[ZFS_MAXNAMELEN];
+ int cleanup_fd;
+ uint64_t size;
+} send_dump_data_t;
+
+static int
+estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
+ boolean_t fromorigin, uint64_t *sizep)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+
+ assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
+ assert(fromsnap_obj == 0 || !fromorigin);
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ zc.zc_obj = fromorigin;
+ zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
+ zc.zc_fromobj = fromsnap_obj;
+ zc.zc_guid = 1; /* estimate flag */
+
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
+ char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "warning: cannot estimate space for '%s'"), zhp->zfs_name);
+
+ switch (errno) {
+ case EXDEV:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "not an earlier snapshot from the same fs"));
+ return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
+
+ case ENOENT:
+ if (zfs_dataset_exists(hdl, zc.zc_name,
+ ZFS_TYPE_SNAPSHOT)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "incremental source (@%s) does not exist"),
+ zc.zc_value);
+ }
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+
+ case EDQUOT:
+ case EFBIG:
+ case EIO:
+ case ENOLINK:
+ case ENOSPC:
+ case ENXIO:
+ case EPIPE:
+ case ERANGE:
+ case EFAULT:
+ case EROFS:
+ zfs_error_aux(hdl, strerror(errno));
+ return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
+
+ default:
+ return (zfs_standard_error(hdl, errno, errbuf));
+ }
+ }
+
+ *sizep = zc.zc_objset_type;
+
+ return (0);
+}
+
+/*
+ * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
+ * NULL) to the file descriptor specified by outfd.
+ */
+static int
+dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
+ boolean_t fromorigin, int outfd, nvlist_t *debugnv)
+{
+ zfs_cmd_t zc = { 0 };
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ nvlist_t *thisdbg;
+
+ assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
+ assert(fromsnap_obj == 0 || !fromorigin);
+
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+ zc.zc_cookie = outfd;
+ zc.zc_obj = fromorigin;
+ zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
+ zc.zc_fromobj = fromsnap_obj;
+
+ VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
+ if (fromsnap && fromsnap[0] != '\0') {
+ VERIFY(0 == nvlist_add_string(thisdbg,
+ "fromsnap", fromsnap));
+ }
+
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
+ char errbuf[1024];
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "warning: cannot send '%s'"), zhp->zfs_name);
+
+ VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
+ if (debugnv) {
+ VERIFY(0 == nvlist_add_nvlist(debugnv,
+ zhp->zfs_name, thisdbg));
+ }
+ nvlist_free(thisdbg);
+
+ switch (errno) {
+ case EXDEV:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "not an earlier snapshot from the same fs"));
+ return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
+
+ case ENOENT:
+ if (zfs_dataset_exists(hdl, zc.zc_name,
+ ZFS_TYPE_SNAPSHOT)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "incremental source (@%s) does not exist"),
+ zc.zc_value);
+ }
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+
+ case EDQUOT:
+ case EFBIG:
+ case EIO:
+ case ENOLINK:
+ case ENOSPC:
+#ifdef sun
+ case ENOSTR:
+#endif
+ case ENXIO:
+ case EPIPE:
+ case ERANGE:
+ case EFAULT:
+ case EROFS:
+ zfs_error_aux(hdl, strerror(errno));
+ return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
+
+ default:
+ return (zfs_standard_error(hdl, errno, errbuf));
+ }
+ }
+
+ if (debugnv)
+ VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
+ nvlist_free(thisdbg);
+
+ return (0);
+}
+
+static int
+hold_for_send(zfs_handle_t *zhp, send_dump_data_t *sdd)
+{
+ zfs_handle_t *pzhp;
+ int error = 0;
+ char *thissnap;
+
+ assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
+
+ if (sdd->dryrun)
+ return (0);
+
+ /*
+ * zfs_send() only opens a cleanup_fd for sends that need it,
+ * e.g. replication and doall.
+ */
+ if (sdd->cleanup_fd == -1)
+ return (0);
+
+ thissnap = strchr(zhp->zfs_name, '@') + 1;
+ *(thissnap - 1) = '\0';
+ pzhp = zfs_open(zhp->zfs_hdl, zhp->zfs_name, ZFS_TYPE_DATASET);
+ *(thissnap - 1) = '@';
+
+ /*
+ * It's OK if the parent no longer exists. The send code will
+ * handle that error.
+ */
+ if (pzhp) {
+ error = zfs_hold(pzhp, thissnap, sdd->holdtag,
+ B_FALSE, B_TRUE, sdd->cleanup_fd);
+ zfs_close(pzhp);
+ }
+
+ return (error);
+}
+
+static void *
+send_progress_thread(void *arg)
+{
+ progress_arg_t *pa = arg;
+
+ zfs_cmd_t zc = { 0 };
+ zfs_handle_t *zhp = pa->pa_zhp;
+ libzfs_handle_t *hdl = zhp->zfs_hdl;
+ unsigned long long bytes;
+ char buf[16];
+
+ time_t t;
+ struct tm *tm;
+
+ assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
+ (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
+
+ if (!pa->pa_parsable)
+ (void) fprintf(stderr, "TIME SENT SNAPSHOT\n");
+
+ /*
+ * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
+ */
+ for (;;) {
+ (void) sleep(1);
+
+ zc.zc_cookie = pa->pa_fd;
+ if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
+ return ((void *)-1);
+
+ (void) time(&t);
+ tm = localtime(&t);
+ bytes = zc.zc_cookie;
+
+ if (pa->pa_parsable) {
+ (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ bytes, zhp->zfs_name);
+ } else {
+ zfs_nicenum(bytes, buf, sizeof (buf));
+ (void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ buf, zhp->zfs_name);
+ }
+ }
+}
+
+static int
+dump_snapshot(zfs_handle_t *zhp, void *arg)
+{
+ send_dump_data_t *sdd = arg;
+ progress_arg_t pa = { 0 };
+ pthread_t tid;
+
+ char *thissnap;
+ int err;
+ boolean_t isfromsnap, istosnap, fromorigin;
+ boolean_t exclude = B_FALSE;
+
+ thissnap = strchr(zhp->zfs_name, '@') + 1;
+ isfromsnap = (sdd->fromsnap != NULL &&
+ strcmp(sdd->fromsnap, thissnap) == 0);
+
+ if (!sdd->seenfrom && isfromsnap) {
+ err = hold_for_send(zhp, sdd);
+ if (err == 0) {
+ sdd->seenfrom = B_TRUE;
+ (void) strcpy(sdd->prevsnap, thissnap);
+ sdd->prevsnap_obj = zfs_prop_get_int(zhp,
+ ZFS_PROP_OBJSETID);
+ } else if (err == ENOENT) {
+ err = 0;
+ }
+ zfs_close(zhp);
+ return (err);
+ }
+
+ if (sdd->seento || !sdd->seenfrom) {
+ zfs_close(zhp);
+ return (0);
+ }
+
+ istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
+ if (istosnap)
+ sdd->seento = B_TRUE;
+
+ if (!sdd->doall && !isfromsnap && !istosnap) {
+ if (sdd->replicate) {
+ char *snapname;
+ nvlist_t *snapprops;
+ /*
+ * Filter out all intermediate snapshots except origin
+ * snapshots needed to replicate clones.
+ */
+ nvlist_t *nvfs = fsavl_find(sdd->fsavl,
+ zhp->zfs_dmustats.dds_guid, &snapname);
+
+ VERIFY(0 == nvlist_lookup_nvlist(nvfs,
+ "snapprops", &snapprops));
+ VERIFY(0 == nvlist_lookup_nvlist(snapprops,
+ thissnap, &snapprops));
+ exclude = !nvlist_exists(snapprops, "is_clone_origin");
+ } else {
+ exclude = B_TRUE;
+ }
+ }
+
+ /*
+ * If a filter function exists, call it to determine whether
+ * this snapshot will be sent.
+ */
+ if (exclude || (sdd->filter_cb != NULL &&
+ sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
+ /*
+ * This snapshot is filtered out. Don't send it, and don't
+ * set prevsnap_obj, so it will be as if this snapshot didn't
+ * exist, and the next accepted snapshot will be sent as
+ * an incremental from the last accepted one, or as the
+ * first (and full) snapshot in the case of a replication,
+ * non-incremental send.
+ */
+ zfs_close(zhp);
+ return (0);
+ }
+
+ err = hold_for_send(zhp, sdd);
+ if (err) {
+ if (err == ENOENT)
+ err = 0;
+ zfs_close(zhp);
+ return (err);
+ }
+
+ fromorigin = sdd->prevsnap[0] == '\0' &&
+ (sdd->fromorigin || sdd->replicate);
+
+ if (sdd->verbose) {
+ uint64_t size;
+ err = estimate_ioctl(zhp, sdd->prevsnap_obj,
+ fromorigin, &size);
+
+ if (sdd->parsable) {
+ if (sdd->prevsnap[0] != '\0') {
+ (void) fprintf(stderr, "incremental\t%s\t%s",
+ sdd->prevsnap, zhp->zfs_name);
+ } else {
+ (void) fprintf(stderr, "full\t%s",
+ zhp->zfs_name);
+ }
+ } else {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "send from @%s to %s"),
+ sdd->prevsnap, zhp->zfs_name);
+ }
+ if (err == 0) {
+ if (sdd->parsable) {
+ (void) fprintf(stderr, "\t%llu\n",
+ (longlong_t)size);
+ } else {
+ char buf[16];
+ zfs_nicenum(size, buf, sizeof (buf));
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ " estimated size is %s\n"), buf);
+ }
+ sdd->size += size;
+ } else {
+ (void) fprintf(stderr, "\n");
+ }
+ }
+
+ if (!sdd->dryrun) {
+ /*
+ * If progress reporting is requested, spawn a new thread to
+ * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
+ */
+ if (sdd->progress) {
+ pa.pa_zhp = zhp;
+ pa.pa_fd = sdd->outfd;
+ pa.pa_parsable = sdd->parsable;
+
+ if (err = pthread_create(&tid, NULL,
+ send_progress_thread, &pa)) {
+ zfs_close(zhp);
+ return (err);
+ }
+ }
+
+ err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
+ fromorigin, sdd->outfd, sdd->debugnv);
+
+ if (sdd->progress) {
+ (void) pthread_cancel(tid);
+ (void) pthread_join(tid, NULL);
+ }
+ }
+
+ (void) strcpy(sdd->prevsnap, thissnap);
+ sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
+ zfs_close(zhp);
+ return (err);
+}
+
+static int
+dump_filesystem(zfs_handle_t *zhp, void *arg)
+{
+ int rv = 0;
+ send_dump_data_t *sdd = arg;
+ boolean_t missingfrom = B_FALSE;
+ zfs_cmd_t zc = { 0 };
+
+ (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
+ zhp->zfs_name, sdd->tosnap);
+ if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "WARNING: could not send %s@%s: does not exist\n"),
+ zhp->zfs_name, sdd->tosnap);
+ sdd->err = B_TRUE;
+ return (0);
+ }
+
+ if (sdd->replicate && sdd->fromsnap) {
+ /*
+ * If this fs does not have fromsnap, and we're doing
+ * recursive, we need to send a full stream from the
+ * beginning (or an incremental from the origin if this
+ * is a clone). If we're doing non-recursive, then let
+ * them get the error.
+ */
+ (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
+ zhp->zfs_name, sdd->fromsnap);
+ if (ioctl(zhp->zfs_hdl->libzfs_fd,
+ ZFS_IOC_OBJSET_STATS, &zc) != 0) {
+ missingfrom = B_TRUE;
+ }
+ }
+
+ sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0;
+ sdd->prevsnap_obj = 0;
+ if (sdd->fromsnap == NULL || missingfrom)
+ sdd->seenfrom = B_TRUE;
+
+ rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
+ if (!sdd->seenfrom) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "WARNING: could not send %s@%s:\n"
+ "incremental source (%s@%s) does not exist\n"),
+ zhp->zfs_name, sdd->tosnap,
+ zhp->zfs_name, sdd->fromsnap);
+ sdd->err = B_TRUE;
+ } else if (!sdd->seento) {
+ if (sdd->fromsnap) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "WARNING: could not send %s@%s:\n"
+ "incremental source (%s@%s) "
+ "is not earlier than it\n"),
+ zhp->zfs_name, sdd->tosnap,
+ zhp->zfs_name, sdd->fromsnap);
+ } else {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "WARNING: "
+ "could not send %s@%s: does not exist\n"),
+ zhp->zfs_name, sdd->tosnap);
+ }
+ sdd->err = B_TRUE;
+ }
+
+ return (rv);
+}
+
+static int
+dump_filesystems(zfs_handle_t *rzhp, void *arg)
+{
+ send_dump_data_t *sdd = arg;
+ nvpair_t *fspair;
+ boolean_t needagain, progress;
+
+ if (!sdd->replicate)
+ return (dump_filesystem(rzhp, sdd));
+
+ /* Mark the clone origin snapshots. */
+ for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
+ fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
+ nvlist_t *nvfs;
+ uint64_t origin_guid = 0;
+
+ VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs));
+ (void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
+ if (origin_guid != 0) {
+ char *snapname;
+ nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
+ origin_guid, &snapname);
+ if (origin_nv != NULL) {
+ nvlist_t *snapprops;
+ VERIFY(0 == nvlist_lookup_nvlist(origin_nv,
+ "snapprops", &snapprops));
+ VERIFY(0 == nvlist_lookup_nvlist(snapprops,
+ snapname, &snapprops));
+ VERIFY(0 == nvlist_add_boolean(
+ snapprops, "is_clone_origin"));
+ }
+ }
+ }
+again:
+ needagain = progress = B_FALSE;
+ for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
+ fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
+ nvlist_t *fslist, *parent_nv;
+ char *fsname;
+ zfs_handle_t *zhp;
+ int err;
+ uint64_t origin_guid = 0;
+ uint64_t parent_guid = 0;
+
+ VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
+ if (nvlist_lookup_boolean(fslist, "sent") == 0)
+ continue;
+
+ VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
+ (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
+ (void) nvlist_lookup_uint64(fslist, "parentfromsnap",
+ &parent_guid);
+
+ if (parent_guid != 0) {
+ parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
+ if (!nvlist_exists(parent_nv, "sent")) {
+ /* parent has not been sent; skip this one */
+ needagain = B_TRUE;
+ continue;
+ }
+ }
+
+ if (origin_guid != 0) {
+ nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
+ origin_guid, NULL);
+ if (origin_nv != NULL &&
+ !nvlist_exists(origin_nv, "sent")) {
+ /*
+ * origin has not been sent yet;
+ * skip this clone.
+ */
+ needagain = B_TRUE;
+ continue;
+ }
+ }
+
+ zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
+ if (zhp == NULL)
+ return (-1);
+ err = dump_filesystem(zhp, sdd);
+ VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
+ progress = B_TRUE;
+ zfs_close(zhp);
+ if (err)
+ return (err);
+ }
+ if (needagain) {
+ assert(progress);
+ goto again;
+ }
+
+ /* clean out the sent flags in case we reuse this fss */
+ for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
+ fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
+ nvlist_t *fslist;
+
+ VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
+ (void) nvlist_remove_all(fslist, "sent");
+ }
+
+ return (0);
+}
+
+/*
+ * Generate a send stream for the dataset identified by the argument zhp.
+ *
+ * The content of the send stream is the snapshot identified by
+ * 'tosnap'. Incremental streams are requested in two ways:
+ * - from the snapshot identified by "fromsnap" (if non-null) or
+ * - from the origin of the dataset identified by zhp, which must
+ * be a clone. In this case, "fromsnap" is null and "fromorigin"
+ * is TRUE.
+ *
+ * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
+ * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
+ * if "replicate" is set. If "doall" is set, dump all the intermediate
+ * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
+ * case too. If "props" is set, send properties.
+ */
+int
+zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
+ sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
+ void *cb_arg, nvlist_t **debugnvp)
+{
+ char errbuf[1024];
+ send_dump_data_t sdd = { 0 };
+ int err = 0;
+ nvlist_t *fss = NULL;
+ avl_tree_t *fsavl = NULL;
+ static uint64_t holdseq;
+ int spa_version;
+ pthread_t tid;
+ int pipefd[2];
+ dedup_arg_t dda = { 0 };
+ int featureflags = 0;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot send '%s'"), zhp->zfs_name);
+
+ if (fromsnap && fromsnap[0] == '\0') {
+ zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
+ "zero-length incremental source"));
+ return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
+ }
+
+ if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) {
+ uint64_t version;
+ version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ if (version >= ZPL_VERSION_SA) {
+ featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
+ }
+ }
+
+ if (flags->dedup && !flags->dryrun) {
+ featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
+ DMU_BACKUP_FEATURE_DEDUPPROPS);
+ if (err = pipe(pipefd)) {
+ zfs_error_aux(zhp->zfs_hdl, strerror(errno));
+ return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
+ errbuf));
+ }
+ dda.outputfd = outfd;
+ dda.inputfd = pipefd[1];
+ dda.dedup_hdl = zhp->zfs_hdl;
+ if (err = pthread_create(&tid, NULL, cksummer, &dda)) {
+ (void) close(pipefd[0]);
+ (void) close(pipefd[1]);
+ zfs_error_aux(zhp->zfs_hdl, strerror(errno));
+ return (zfs_error(zhp->zfs_hdl,
+ EZFS_THREADCREATEFAILED, errbuf));
+ }
+ }
+
+ if (flags->replicate || flags->doall || flags->props) {
+ dmu_replay_record_t drr = { 0 };
+ char *packbuf = NULL;
+ size_t buflen = 0;
+ zio_cksum_t zc = { 0 };
+
+ if (flags->replicate || flags->props) {
+ nvlist_t *hdrnv;
+
+ VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
+ if (fromsnap) {
+ VERIFY(0 == nvlist_add_string(hdrnv,
+ "fromsnap", fromsnap));
+ }
+ VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
+ if (!flags->replicate) {
+ VERIFY(0 == nvlist_add_boolean(hdrnv,
+ "not_recursive"));
+ }
+
+ err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
+ fromsnap, tosnap, flags->replicate, &fss, &fsavl);
+ if (err)
+ goto err_out;
+ VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
+ err = nvlist_pack(hdrnv, &packbuf, &buflen,
+ NV_ENCODE_XDR, 0);
+ if (debugnvp)
+ *debugnvp = hdrnv;
+ else
+ nvlist_free(hdrnv);
+ if (err) {
+ fsavl_destroy(fsavl);
+ nvlist_free(fss);
+ goto stderr_out;
+ }
+ }
+
+ if (!flags->dryrun) {
+ /* write first begin record */
+ drr.drr_type = DRR_BEGIN;
+ drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
+ DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
+ drr_versioninfo, DMU_COMPOUNDSTREAM);
+ DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
+ drr_versioninfo, featureflags);
+ (void) snprintf(drr.drr_u.drr_begin.drr_toname,
+ sizeof (drr.drr_u.drr_begin.drr_toname),
+ "%s@%s", zhp->zfs_name, tosnap);
+ drr.drr_payloadlen = buflen;
+ err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
+
+ /* write header nvlist */
+ if (err != -1 && packbuf != NULL) {
+ err = cksum_and_write(packbuf, buflen, &zc,
+ outfd);
+ }
+ free(packbuf);
+ if (err == -1) {
+ fsavl_destroy(fsavl);
+ nvlist_free(fss);
+ err = errno;
+ goto stderr_out;
+ }
+
+ /* write end record */
+ bzero(&drr, sizeof (drr));
+ drr.drr_type = DRR_END;
+ drr.drr_u.drr_end.drr_checksum = zc;
+ err = write(outfd, &drr, sizeof (drr));
+ if (err == -1) {
+ fsavl_destroy(fsavl);
+ nvlist_free(fss);
+ err = errno;
+ goto stderr_out;
+ }
+
+ err = 0;
+ }
+ }
+
+ /* dump each stream */
+ sdd.fromsnap = fromsnap;
+ sdd.tosnap = tosnap;
+ if (flags->dedup)
+ sdd.outfd = pipefd[0];
+ else
+ sdd.outfd = outfd;
+ sdd.replicate = flags->replicate;
+ sdd.doall = flags->doall;
+ sdd.fromorigin = flags->fromorigin;
+ sdd.fss = fss;
+ sdd.fsavl = fsavl;
+ sdd.verbose = flags->verbose;
+ sdd.parsable = flags->parsable;
+ sdd.progress = flags->progress;
+ sdd.dryrun = flags->dryrun;
+ sdd.filter_cb = filter_func;
+ sdd.filter_cb_arg = cb_arg;
+ if (debugnvp)
+ sdd.debugnv = *debugnvp;
+
+ /*
+ * Some flags require that we place user holds on the datasets that are
+ * being sent so they don't get destroyed during the send. We can skip
+ * this step if the pool is imported read-only since the datasets cannot
+ * be destroyed.
+ */
+ if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
+ ZPOOL_PROP_READONLY, NULL) &&
+ zfs_spa_version(zhp, &spa_version) == 0 &&
+ spa_version >= SPA_VERSION_USERREFS &&
+ (flags->doall || flags->replicate)) {
+ ++holdseq;
+ (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
+ ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
+ sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
+ if (sdd.cleanup_fd < 0) {
+ err = errno;
+ goto stderr_out;
+ }
+ } else {
+ sdd.cleanup_fd = -1;
+ }
+ if (flags->verbose) {
+ /*
+ * Do a verbose no-op dry run to get all the verbose output
+ * before generating any data. Then do a non-verbose real
+ * run to generate the streams.
+ */
+ sdd.dryrun = B_TRUE;
+ err = dump_filesystems(zhp, &sdd);
+ sdd.dryrun = flags->dryrun;
+ sdd.verbose = B_FALSE;
+ if (flags->parsable) {
+ (void) fprintf(stderr, "size\t%llu\n",
+ (longlong_t)sdd.size);
+ } else {
+ char buf[16];
+ zfs_nicenum(sdd.size, buf, sizeof (buf));
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "total estimated size is %s\n"), buf);
+ }
+ }
+ err = dump_filesystems(zhp, &sdd);
+ fsavl_destroy(fsavl);
+ nvlist_free(fss);
+
+ if (flags->dedup) {
+ (void) close(pipefd[0]);
+ (void) pthread_join(tid, NULL);
+ }
+
+ if (sdd.cleanup_fd != -1) {
+ VERIFY(0 == close(sdd.cleanup_fd));
+ sdd.cleanup_fd = -1;
+ }
+
+ if (!flags->dryrun && (flags->replicate || flags->doall ||
+ flags->props)) {
+ /*
+ * write final end record. NB: want to do this even if
+ * there was some error, because it might not be totally
+ * failed.
+ */
+ dmu_replay_record_t drr = { 0 };
+ drr.drr_type = DRR_END;
+ if (write(outfd, &drr, sizeof (drr)) == -1) {
+ return (zfs_standard_error(zhp->zfs_hdl,
+ errno, errbuf));
+ }
+ }
+
+ return (err || sdd.err);
+
+stderr_out:
+ err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
+err_out:
+ if (sdd.cleanup_fd != -1)
+ VERIFY(0 == close(sdd.cleanup_fd));
+ if (flags->dedup) {
+ (void) pthread_cancel(tid);
+ (void) pthread_join(tid, NULL);
+ (void) close(pipefd[0]);
+ }
+ return (err);
+}
+
+/*
+ * Routines specific to "zfs recv"
+ */
+
+static int
+recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
+ boolean_t byteswap, zio_cksum_t *zc)
+{
+ char *cp = buf;
+ int rv;
+ int len = ilen;
+
+ do {
+ rv = read(fd, cp, len);
+ cp += rv;
+ len -= rv;
+ } while (rv > 0);
+
+ if (rv < 0 || len != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "failed to read from stream"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
+ "cannot receive")));
+ }
+
+ if (zc) {
+ if (byteswap)
+ fletcher_4_incremental_byteswap(buf, ilen, zc);
+ else
+ fletcher_4_incremental_native(buf, ilen, zc);
+ }
+ return (0);
+}
+
+static int
+recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
+ boolean_t byteswap, zio_cksum_t *zc)
+{
+ char *buf;
+ int err;
+
+ buf = zfs_alloc(hdl, len);
+ if (buf == NULL)
+ return (ENOMEM);
+
+ err = recv_read(hdl, fd, buf, len, byteswap, zc);
+ if (err != 0) {
+ free(buf);
+ return (err);
+ }
+
+ err = nvlist_unpack(buf, len, nvp, 0);
+ free(buf);
+ if (err != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
+ "stream (malformed nvlist)"));
+ return (EINVAL);
+ }
+ return (0);
+}
+
+static int
+recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
+ int baselen, char *newname, recvflags_t *flags)
+{
+ static int seq;
+ zfs_cmd_t zc = { 0 };
+ int err;
+ prop_changelist_t *clp;
+ zfs_handle_t *zhp;
+
+ zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
+ if (zhp == NULL)
+ return (-1);
+ clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
+ flags->force ? MS_FORCE : 0);
+ zfs_close(zhp);
+ if (clp == NULL)
+ return (-1);
+ err = changelist_prefix(clp);
+ if (err)
+ return (err);
+
+ zc.zc_objset_type = DMU_OST_ZFS;
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+ if (tryname) {
+ (void) strcpy(newname, tryname);
+
+ (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
+
+ if (flags->verbose) {
+ (void) printf("attempting rename %s to %s\n",
+ zc.zc_name, zc.zc_value);
+ }
+ err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
+ if (err == 0)
+ changelist_rename(clp, name, tryname);
+ } else {
+ err = ENOENT;
+ }
+
+ if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
+ seq++;
+
+ (void) snprintf(newname, ZFS_MAXNAMELEN, "%.*srecv-%u-%u",
+ baselen, name, getpid(), seq);
+ (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
+
+ if (flags->verbose) {
+ (void) printf("failed - trying rename %s to %s\n",
+ zc.zc_name, zc.zc_value);
+ }
+ err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
+ if (err == 0)
+ changelist_rename(clp, name, newname);
+ if (err && flags->verbose) {
+ (void) printf("failed (%u) - "
+ "will try again on next pass\n", errno);
+ }
+ err = EAGAIN;
+ } else if (flags->verbose) {
+ if (err == 0)
+ (void) printf("success\n");
+ else
+ (void) printf("failed (%u)\n", errno);
+ }
+
+ (void) changelist_postfix(clp);
+ changelist_free(clp);
+
+ return (err);
+}
+
+static int
+recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
+ char *newname, recvflags_t *flags)
+{
+ zfs_cmd_t zc = { 0 };
+ int err = 0;
+ prop_changelist_t *clp;
+ zfs_handle_t *zhp;
+ boolean_t defer = B_FALSE;
+ int spa_version;
+
+ zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
+ if (zhp == NULL)
+ return (-1);
+ clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
+ flags->force ? MS_FORCE : 0);
+ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
+ zfs_spa_version(zhp, &spa_version) == 0 &&
+ spa_version >= SPA_VERSION_USERREFS)
+ defer = B_TRUE;
+ zfs_close(zhp);
+ if (clp == NULL)
+ return (-1);
+ err = changelist_prefix(clp);
+ if (err)
+ return (err);
+
+ zc.zc_objset_type = DMU_OST_ZFS;
+ zc.zc_defer_destroy = defer;
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+ if (flags->verbose)
+ (void) printf("attempting destroy %s\n", zc.zc_name);
+ err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
+ if (err == 0) {
+ if (flags->verbose)
+ (void) printf("success\n");
+ changelist_remove(clp, zc.zc_name);
+ }
+
+ (void) changelist_postfix(clp);
+ changelist_free(clp);
+
+ /*
+ * Deferred destroy might destroy the snapshot or only mark it to be
+ * destroyed later, and it returns success in either case.
+ */
+ if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
+ ZFS_TYPE_SNAPSHOT))) {
+ err = recv_rename(hdl, name, NULL, baselen, newname, flags);
+ }
+
+ return (err);
+}
+
+typedef struct guid_to_name_data {
+ uint64_t guid;
+ char *name;
+ char *skip;
+} guid_to_name_data_t;
+
+static int
+guid_to_name_cb(zfs_handle_t *zhp, void *arg)
+{
+ guid_to_name_data_t *gtnd = arg;
+ int err;
+
+ if (gtnd->skip != NULL &&
+ strcmp(zhp->zfs_name, gtnd->skip) == 0) {
+ return (0);
+ }
+
+ if (zhp->zfs_dmustats.dds_guid == gtnd->guid) {
+ (void) strcpy(gtnd->name, zhp->zfs_name);
+ zfs_close(zhp);
+ return (EEXIST);
+ }
+
+ err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
+ zfs_close(zhp);
+ return (err);
+}
+
+/*
+ * Attempt to find the local dataset associated with this guid. In the case of
+ * multiple matches, we attempt to find the "best" match by searching
+ * progressively larger portions of the hierarchy. This allows one to send a
+ * tree of datasets individually and guarantee that we will find the source
+ * guid within that hierarchy, even if there are multiple matches elsewhere.
+ */
+static int
+guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
+ char *name)
+{
+ /* exhaustive search all local snapshots */
+ char pname[ZFS_MAXNAMELEN];
+ guid_to_name_data_t gtnd;
+ int err = 0;
+ zfs_handle_t *zhp;
+ char *cp;
+
+ gtnd.guid = guid;
+ gtnd.name = name;
+ gtnd.skip = NULL;
+
+ (void) strlcpy(pname, parent, sizeof (pname));
+
+ /*
+ * Search progressively larger portions of the hierarchy. This will
+ * select the "most local" version of the origin snapshot in the case
+ * that there are multiple matching snapshots in the system.
+ */
+ while ((cp = strrchr(pname, '/')) != NULL) {
+
+ /* Chop off the last component and open the parent */
+ *cp = '\0';
+ zhp = make_dataset_handle(hdl, pname);
+
+ if (zhp == NULL)
+ continue;
+
+ err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
+ zfs_close(zhp);
+ if (err == EEXIST)
+ return (0);
+
+ /*
+ * Remember the dataset that we already searched, so we
+ * skip it next time through.
+ */
+ gtnd.skip = pname;
+ }
+
+ return (ENOENT);
+}
+
+/*
+ * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
+ * guid1 is after guid2.
+ */
+static int
+created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
+ uint64_t guid1, uint64_t guid2)
+{
+ nvlist_t *nvfs;
+ char *fsname, *snapname;
+ char buf[ZFS_MAXNAMELEN];
+ int rv;
+ zfs_handle_t *guid1hdl, *guid2hdl;
+ uint64_t create1, create2;
+
+ if (guid2 == 0)
+ return (0);
+ if (guid1 == 0)
+ return (1);
+
+ nvfs = fsavl_find(avl, guid1, &snapname);
+ VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
+ (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
+ guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
+ if (guid1hdl == NULL)
+ return (-1);
+
+ nvfs = fsavl_find(avl, guid2, &snapname);
+ VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
+ (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
+ guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
+ if (guid2hdl == NULL) {
+ zfs_close(guid1hdl);
+ return (-1);
+ }
+
+ create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
+ create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
+
+ if (create1 < create2)
+ rv = -1;
+ else if (create1 > create2)
+ rv = +1;
+ else
+ rv = 0;
+
+ zfs_close(guid1hdl);
+ zfs_close(guid2hdl);
+
+ return (rv);
+}
+
+static int
+recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
+ recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
+ nvlist_t *renamed)
+{
+ nvlist_t *local_nv, *deleted = NULL;
+ avl_tree_t *local_avl;
+ nvpair_t *fselem, *nextfselem;
+ char *fromsnap;
+ char newname[ZFS_MAXNAMELEN];
+ char guidname[32];
+ int error;
+ boolean_t needagain, progress, recursive;
+ char *s1, *s2;
+
+ VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
+
+ recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
+ ENOENT);
+
+ if (flags->dryrun)
+ return (0);
+
+again:
+ needagain = progress = B_FALSE;
+
+ VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
+
+ if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
+ recursive, &local_nv, &local_avl)) != 0)
+ return (error);
+
+ /*
+ * Process deletes and renames
+ */
+ for (fselem = nvlist_next_nvpair(local_nv, NULL);
+ fselem; fselem = nextfselem) {
+ nvlist_t *nvfs, *snaps;
+ nvlist_t *stream_nvfs = NULL;
+ nvpair_t *snapelem, *nextsnapelem;
+ uint64_t fromguid = 0;
+ uint64_t originguid = 0;
+ uint64_t stream_originguid = 0;
+ uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
+ char *fsname, *stream_fsname;
+
+ nextfselem = nvlist_next_nvpair(local_nv, fselem);
+
+ VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
+ VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
+ VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
+ VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
+ &parent_fromsnap_guid));
+ (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
+
+ /*
+ * First find the stream's fs, so we can check for
+ * a different origin (due to "zfs promote")
+ */
+ for (snapelem = nvlist_next_nvpair(snaps, NULL);
+ snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
+ uint64_t thisguid;
+
+ VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
+ stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
+
+ if (stream_nvfs != NULL)
+ break;
+ }
+
+ /* check for promote */
+ (void) nvlist_lookup_uint64(stream_nvfs, "origin",
+ &stream_originguid);
+ if (stream_nvfs && originguid != stream_originguid) {
+ switch (created_before(hdl, local_avl,
+ stream_originguid, originguid)) {
+ case 1: {
+ /* promote it! */
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *origin_nvfs;
+ char *origin_fsname;
+
+ if (flags->verbose)
+ (void) printf("promoting %s\n", fsname);
+
+ origin_nvfs = fsavl_find(local_avl, originguid,
+ NULL);
+ VERIFY(0 == nvlist_lookup_string(origin_nvfs,
+ "name", &origin_fsname));
+ (void) strlcpy(zc.zc_value, origin_fsname,
+ sizeof (zc.zc_value));
+ (void) strlcpy(zc.zc_name, fsname,
+ sizeof (zc.zc_name));
+ error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
+ if (error == 0)
+ progress = B_TRUE;
+ break;
+ }
+ default:
+ break;
+ case -1:
+ fsavl_destroy(local_avl);
+ nvlist_free(local_nv);
+ return (-1);
+ }
+ /*
+ * We had/have the wrong origin, therefore our
+ * list of snapshots is wrong. Need to handle
+ * them on the next pass.
+ */
+ needagain = B_TRUE;
+ continue;
+ }
+
+ for (snapelem = nvlist_next_nvpair(snaps, NULL);
+ snapelem; snapelem = nextsnapelem) {
+ uint64_t thisguid;
+ char *stream_snapname;
+ nvlist_t *found, *props;
+
+ nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
+
+ VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
+ found = fsavl_find(stream_avl, thisguid,
+ &stream_snapname);
+
+ /* check for delete */
+ if (found == NULL) {
+ char name[ZFS_MAXNAMELEN];
+
+ if (!flags->force)
+ continue;
+
+ (void) snprintf(name, sizeof (name), "%s@%s",
+ fsname, nvpair_name(snapelem));
+
+ error = recv_destroy(hdl, name,
+ strlen(fsname)+1, newname, flags);
+ if (error)
+ needagain = B_TRUE;
+ else
+ progress = B_TRUE;
+ sprintf(guidname, "%lu", thisguid);
+ nvlist_add_boolean(deleted, guidname);
+ continue;
+ }
+
+ stream_nvfs = found;
+
+ if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
+ &props) && 0 == nvlist_lookup_nvlist(props,
+ stream_snapname, &props)) {
+ zfs_cmd_t zc = { 0 };
+
+ zc.zc_cookie = B_TRUE; /* received */
+ (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
+ "%s@%s", fsname, nvpair_name(snapelem));
+ if (zcmd_write_src_nvlist(hdl, &zc,
+ props) == 0) {
+ (void) zfs_ioctl(hdl,
+ ZFS_IOC_SET_PROP, &zc);
+ zcmd_free_nvlists(&zc);
+ }
+ }
+
+ /* check for different snapname */
+ if (strcmp(nvpair_name(snapelem),
+ stream_snapname) != 0) {
+ char name[ZFS_MAXNAMELEN];
+ char tryname[ZFS_MAXNAMELEN];
+
+ (void) snprintf(name, sizeof (name), "%s@%s",
+ fsname, nvpair_name(snapelem));
+ (void) snprintf(tryname, sizeof (name), "%s@%s",
+ fsname, stream_snapname);
+
+ error = recv_rename(hdl, name, tryname,
+ strlen(fsname)+1, newname, flags);
+ if (error)
+ needagain = B_TRUE;
+ else
+ progress = B_TRUE;
+ }
+
+ if (strcmp(stream_snapname, fromsnap) == 0)
+ fromguid = thisguid;
+ }
+
+ /* check for delete */
+ if (stream_nvfs == NULL) {
+ if (!flags->force)
+ continue;
+
+ error = recv_destroy(hdl, fsname, strlen(tofs)+1,
+ newname, flags);
+ if (error)
+ needagain = B_TRUE;
+ else
+ progress = B_TRUE;
+ sprintf(guidname, "%lu", parent_fromsnap_guid);
+ nvlist_add_boolean(deleted, guidname);
+ continue;
+ }
+
+ if (fromguid == 0) {
+ if (flags->verbose) {
+ (void) printf("local fs %s does not have "
+ "fromsnap (%s in stream); must have "
+ "been deleted locally; ignoring\n",
+ fsname, fromsnap);
+ }
+ continue;
+ }
+
+ VERIFY(0 == nvlist_lookup_string(stream_nvfs,
+ "name", &stream_fsname));
+ VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
+ "parentfromsnap", &stream_parent_fromsnap_guid));
+
+ s1 = strrchr(fsname, '/');
+ s2 = strrchr(stream_fsname, '/');
+
+ /*
+ * Check if we're going to rename based on parent guid change
+ * and the current parent guid was also deleted. If it was then
+ * rename will fail and is likely unneeded, so avoid this and
+ * force an early retry to determine the new
+ * parent_fromsnap_guid.
+ */
+ if (stream_parent_fromsnap_guid != 0 &&
+ parent_fromsnap_guid != 0 &&
+ stream_parent_fromsnap_guid != parent_fromsnap_guid) {
+ sprintf(guidname, "%lu", parent_fromsnap_guid);
+ if (nvlist_exists(deleted, guidname)) {
+ progress = B_TRUE;
+ needagain = B_TRUE;
+ goto doagain;
+ }
+ }
+
+ /*
+ * Check for rename. If the exact receive path is specified, it
+ * does not count as a rename, but we still need to check the
+ * datasets beneath it.
+ */
+ if ((stream_parent_fromsnap_guid != 0 &&
+ parent_fromsnap_guid != 0 &&
+ stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
+ ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
+ (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
+ nvlist_t *parent;
+ char tryname[ZFS_MAXNAMELEN];
+
+ parent = fsavl_find(local_avl,
+ stream_parent_fromsnap_guid, NULL);
+ /*
+ * NB: parent might not be found if we used the
+ * tosnap for stream_parent_fromsnap_guid,
+ * because the parent is a newly-created fs;
+ * we'll be able to rename it after we recv the
+ * new fs.
+ */
+ if (parent != NULL) {
+ char *pname;
+
+ VERIFY(0 == nvlist_lookup_string(parent, "name",
+ &pname));
+ (void) snprintf(tryname, sizeof (tryname),
+ "%s%s", pname, strrchr(stream_fsname, '/'));
+ } else {
+ tryname[0] = '\0';
+ if (flags->verbose) {
+ (void) printf("local fs %s new parent "
+ "not found\n", fsname);
+ }
+ }
+
+ newname[0] = '\0';
+
+ error = recv_rename(hdl, fsname, tryname,
+ strlen(tofs)+1, newname, flags);
+
+ if (renamed != NULL && newname[0] != '\0') {
+ VERIFY(0 == nvlist_add_boolean(renamed,
+ newname));
+ }
+
+ if (error)
+ needagain = B_TRUE;
+ else
+ progress = B_TRUE;
+ }
+ }
+
+doagain:
+ fsavl_destroy(local_avl);
+ nvlist_free(local_nv);
+ nvlist_free(deleted);
+
+ if (needagain && progress) {
+ /* do another pass to fix up temporary names */
+ if (flags->verbose)
+ (void) printf("another pass:\n");
+ goto again;
+ }
+
+ return (needagain);
+}
+
+static int
+zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
+ recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
+ char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
+{
+ nvlist_t *stream_nv = NULL;
+ avl_tree_t *stream_avl = NULL;
+ char *fromsnap = NULL;
+ char *cp;
+ char tofs[ZFS_MAXNAMELEN];
+ char sendfs[ZFS_MAXNAMELEN];
+ char errbuf[1024];
+ dmu_replay_record_t drre;
+ int error;
+ boolean_t anyerr = B_FALSE;
+ boolean_t softerr = B_FALSE;
+ boolean_t recursive;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive"));
+
+ assert(drr->drr_type == DRR_BEGIN);
+ assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
+ assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
+ DMU_COMPOUNDSTREAM);
+
+ /*
+ * Read in the nvlist from the stream.
+ */
+ if (drr->drr_payloadlen != 0) {
+ error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
+ &stream_nv, flags->byteswap, zc);
+ if (error) {
+ error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ goto out;
+ }
+ }
+
+ recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
+ ENOENT);
+
+ if (recursive && strchr(destname, '@')) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot specify snapshot name for multi-snapshot stream"));
+ error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ goto out;
+ }
+
+ /*
+ * Read in the end record and verify checksum.
+ */
+ if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
+ flags->byteswap, NULL)))
+ goto out;
+ if (flags->byteswap) {
+ drre.drr_type = BSWAP_32(drre.drr_type);
+ drre.drr_u.drr_end.drr_checksum.zc_word[0] =
+ BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
+ drre.drr_u.drr_end.drr_checksum.zc_word[1] =
+ BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
+ drre.drr_u.drr_end.drr_checksum.zc_word[2] =
+ BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
+ drre.drr_u.drr_end.drr_checksum.zc_word[3] =
+ BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
+ }
+ if (drre.drr_type != DRR_END) {
+ error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ goto out;
+ }
+ if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "incorrect header checksum"));
+ error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ goto out;
+ }
+
+ (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
+
+ if (drr->drr_payloadlen != 0) {
+ nvlist_t *stream_fss;
+
+ VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
+ &stream_fss));
+ if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "couldn't allocate avl tree"));
+ error = zfs_error(hdl, EZFS_NOMEM, errbuf);
+ goto out;
+ }
+
+ if (fromsnap != NULL) {
+ nvlist_t *renamed = NULL;
+ nvpair_t *pair = NULL;
+
+ (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
+ if (flags->isprefix) {
+ struct drr_begin *drrb = &drr->drr_u.drr_begin;
+ int i;
+
+ if (flags->istail) {
+ cp = strrchr(drrb->drr_toname, '/');
+ if (cp == NULL) {
+ (void) strlcat(tofs, "/",
+ ZFS_MAXNAMELEN);
+ i = 0;
+ } else {
+ i = (cp - drrb->drr_toname);
+ }
+ } else {
+ i = strcspn(drrb->drr_toname, "/@");
+ }
+ /* zfs_receive_one() will create_parents() */
+ (void) strlcat(tofs, &drrb->drr_toname[i],
+ ZFS_MAXNAMELEN);
+ *strchr(tofs, '@') = '\0';
+ }
+
+ if (recursive && !flags->dryrun && !flags->nomount) {
+ VERIFY(0 == nvlist_alloc(&renamed,
+ NV_UNIQUE_NAME, 0));
+ }
+
+ softerr = recv_incremental_replication(hdl, tofs, flags,
+ stream_nv, stream_avl, renamed);
+
+ /* Unmount renamed filesystems before receiving. */
+ while ((pair = nvlist_next_nvpair(renamed,
+ pair)) != NULL) {
+ zfs_handle_t *zhp;
+ prop_changelist_t *clp = NULL;
+
+ zhp = zfs_open(hdl, nvpair_name(pair),
+ ZFS_TYPE_FILESYSTEM);
+ if (zhp != NULL) {
+ clp = changelist_gather(zhp,
+ ZFS_PROP_MOUNTPOINT, 0, 0);
+ zfs_close(zhp);
+ if (clp != NULL) {
+ softerr |=
+ changelist_prefix(clp);
+ changelist_free(clp);
+ }
+ }
+ }
+
+ nvlist_free(renamed);
+ }
+ }
+
+ /*
+ * Get the fs specified by the first path in the stream (the top level
+ * specified by 'zfs send') and pass it to each invocation of
+ * zfs_receive_one().
+ */
+ (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
+ ZFS_MAXNAMELEN);
+ if ((cp = strchr(sendfs, '@')) != NULL)
+ *cp = '\0';
+
+ /* Finally, receive each contained stream */
+ do {
+ /*
+ * we should figure out if it has a recoverable
+ * error, in which case do a recv_skip() and drive on.
+ * Note, if we fail due to already having this guid,
+ * zfs_receive_one() will take care of it (ie,
+ * recv_skip() and return 0).
+ */
+ error = zfs_receive_impl(hdl, destname, flags, fd,
+ sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
+ action_handlep);
+ if (error == ENODATA) {
+ error = 0;
+ break;
+ }
+ anyerr |= error;
+ } while (error == 0);
+
+ if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
+ /*
+ * Now that we have the fs's they sent us, try the
+ * renames again.
+ */
+ softerr = recv_incremental_replication(hdl, tofs, flags,
+ stream_nv, stream_avl, NULL);
+ }
+
+out:
+ fsavl_destroy(stream_avl);
+ if (stream_nv)
+ nvlist_free(stream_nv);
+ if (softerr)
+ error = -2;
+ if (anyerr)
+ error = -1;
+ return (error);
+}
+
+static void
+trunc_prop_errs(int truncated)
+{
+ ASSERT(truncated != 0);
+
+ if (truncated == 1)
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "1 more property could not be set\n"));
+ else
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "%d more properties could not be set\n"), truncated);
+}
+
+static int
+recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
+{
+ dmu_replay_record_t *drr;
+ void *buf = malloc(1<<20);
+ char errbuf[1024];
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive:"));
+
+ /* XXX would be great to use lseek if possible... */
+ drr = buf;
+
+ while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
+ byteswap, NULL) == 0) {
+ if (byteswap)
+ drr->drr_type = BSWAP_32(drr->drr_type);
+
+ switch (drr->drr_type) {
+ case DRR_BEGIN:
+ /* NB: not to be used on v2 stream packages */
+ if (drr->drr_payloadlen != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid substream header"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+ break;
+
+ case DRR_END:
+ free(buf);
+ return (0);
+
+ case DRR_OBJECT:
+ if (byteswap) {
+ drr->drr_u.drr_object.drr_bonuslen =
+ BSWAP_32(drr->drr_u.drr_object.
+ drr_bonuslen);
+ }
+ (void) recv_read(hdl, fd, buf,
+ P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
+ B_FALSE, NULL);
+ break;
+
+ case DRR_WRITE:
+ if (byteswap) {
+ drr->drr_u.drr_write.drr_length =
+ BSWAP_64(drr->drr_u.drr_write.drr_length);
+ }
+ (void) recv_read(hdl, fd, buf,
+ drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
+ break;
+ case DRR_SPILL:
+ if (byteswap) {
+ drr->drr_u.drr_write.drr_length =
+ BSWAP_64(drr->drr_u.drr_spill.drr_length);
+ }
+ (void) recv_read(hdl, fd, buf,
+ drr->drr_u.drr_spill.drr_length, B_FALSE, NULL);
+ break;
+ case DRR_WRITE_BYREF:
+ case DRR_FREEOBJECTS:
+ case DRR_FREE:
+ break;
+
+ default:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid record type"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+ }
+
+ free(buf);
+ return (-1);
+}
+
+/*
+ * Restores a backup of tosnap from the file descriptor specified by infd.
+ */
+static int
+zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
+ recvflags_t *flags, dmu_replay_record_t *drr,
+ dmu_replay_record_t *drr_noswap, const char *sendfs,
+ nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
+ uint64_t *action_handlep)
+{
+ zfs_cmd_t zc = { 0 };
+ time_t begin_time;
+ int ioctl_err, ioctl_errno, err;
+ char *cp;
+ struct drr_begin *drrb = &drr->drr_u.drr_begin;
+ char errbuf[1024];
+ char prop_errbuf[1024];
+ const char *chopprefix;
+ boolean_t newfs = B_FALSE;
+ boolean_t stream_wantsnewfs;
+ uint64_t parent_snapguid = 0;
+ prop_changelist_t *clp = NULL;
+ nvlist_t *snapprops_nvlist = NULL;
+ zprop_errflags_t prop_errflags;
+ boolean_t recursive;
+
+ begin_time = time(NULL);
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive"));
+
+ recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
+ ENOENT);
+
+ if (stream_avl != NULL) {
+ char *snapname;
+ nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
+ &snapname);
+ nvlist_t *props;
+ int ret;
+
+ (void) nvlist_lookup_uint64(fs, "parentfromsnap",
+ &parent_snapguid);
+ err = nvlist_lookup_nvlist(fs, "props", &props);
+ if (err)
+ VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
+
+ if (flags->canmountoff) {
+ VERIFY(0 == nvlist_add_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
+ }
+ ret = zcmd_write_src_nvlist(hdl, &zc, props);
+ if (err)
+ nvlist_free(props);
+
+ if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
+ VERIFY(0 == nvlist_lookup_nvlist(props,
+ snapname, &snapprops_nvlist));
+ }
+
+ if (ret != 0)
+ return (-1);
+ }
+
+ cp = NULL;
+
+ /*
+ * Determine how much of the snapshot name stored in the stream
+ * we are going to tack on to the name they specified on the
+ * command line, and how much we are going to chop off.
+ *
+ * If they specified a snapshot, chop the entire name stored in
+ * the stream.
+ */
+ if (flags->istail) {
+ /*
+ * A filesystem was specified with -e. We want to tack on only
+ * the tail of the sent snapshot path.
+ */
+ if (strchr(tosnap, '@')) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
+ "argument - snapshot not allowed with -e"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
+ chopprefix = strrchr(sendfs, '/');
+
+ if (chopprefix == NULL) {
+ /*
+ * The tail is the poolname, so we need to
+ * prepend a path separator.
+ */
+ int len = strlen(drrb->drr_toname);
+ cp = malloc(len + 2);
+ cp[0] = '/';
+ (void) strcpy(&cp[1], drrb->drr_toname);
+ chopprefix = cp;
+ } else {
+ chopprefix = drrb->drr_toname + (chopprefix - sendfs);
+ }
+ } else if (flags->isprefix) {
+ /*
+ * A filesystem was specified with -d. We want to tack on
+ * everything but the first element of the sent snapshot path
+ * (all but the pool name).
+ */
+ if (strchr(tosnap, '@')) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
+ "argument - snapshot not allowed with -d"));
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
+ chopprefix = strchr(drrb->drr_toname, '/');
+ if (chopprefix == NULL)
+ chopprefix = strchr(drrb->drr_toname, '@');
+ } else if (strchr(tosnap, '@') == NULL) {
+ /*
+ * If a filesystem was specified without -d or -e, we want to
+ * tack on everything after the fs specified by 'zfs send'.
+ */
+ chopprefix = drrb->drr_toname + strlen(sendfs);
+ } else {
+ /* A snapshot was specified as an exact path (no -d or -e). */
+ if (recursive) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot specify snapshot name for multi-snapshot "
+ "stream"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+ chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
+ }
+
+ ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
+ ASSERT(chopprefix > drrb->drr_toname);
+ ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname));
+ ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
+ chopprefix[0] == '\0');
+
+ /*
+ * Determine name of destination snapshot, store in zc_value.
+ */
+ (void) strcpy(zc.zc_value, tosnap);
+ (void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+ /*
+ * For forward compatibility hide tosnap in zc_value
+ */
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ (void) strcpy(zc.zc_value + strlen(zc.zc_value) + 1, tosnap);
+#endif
+ free(cp);
+ if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
+ zcmd_free_nvlists(&zc);
+ return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+ }
+
+ /*
+ * Determine the name of the origin snapshot, store in zc_string.
+ */
+ if (drrb->drr_flags & DRR_FLAG_CLONE) {
+ if (guid_to_name(hdl, zc.zc_value,
+ drrb->drr_fromguid, zc.zc_string) != 0) {
+ zcmd_free_nvlists(&zc);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "local origin for clone %s does not exist"),
+ zc.zc_value);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ }
+ if (flags->verbose)
+ (void) printf("found clone origin %s\n", zc.zc_string);
+ }
+
+ stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
+ (drrb->drr_flags & DRR_FLAG_CLONE));
+
+ if (stream_wantsnewfs) {
+ /*
+ * if the parent fs does not exist, look for it based on
+ * the parent snap GUID
+ */
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive new filesystem stream"));
+
+ (void) strcpy(zc.zc_name, zc.zc_value);
+ cp = strrchr(zc.zc_name, '/');
+ if (cp)
+ *cp = '\0';
+ if (cp &&
+ !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
+ char suffix[ZFS_MAXNAMELEN];
+ (void) strcpy(suffix, strrchr(zc.zc_value, '/'));
+ if (guid_to_name(hdl, zc.zc_name, parent_snapguid,
+ zc.zc_value) == 0) {
+ *strchr(zc.zc_value, '@') = '\0';
+ (void) strcat(zc.zc_value, suffix);
+ }
+ }
+ } else {
+ /*
+ * if the fs does not exist, look for it based on the
+ * fromsnap GUID
+ */
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive incremental stream"));
+
+ (void) strcpy(zc.zc_name, zc.zc_value);
+ *strchr(zc.zc_name, '@') = '\0';
+
+ /*
+ * If the exact receive path was specified and this is the
+ * topmost path in the stream, then if the fs does not exist we
+ * should look no further.
+ */
+ if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
+ strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
+ !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
+ char snap[ZFS_MAXNAMELEN];
+ (void) strcpy(snap, strchr(zc.zc_value, '@'));
+ if (guid_to_name(hdl, zc.zc_name, drrb->drr_fromguid,
+ zc.zc_value) == 0) {
+ *strchr(zc.zc_value, '@') = '\0';
+ (void) strcat(zc.zc_value, snap);
+ }
+ }
+ }
+
+ (void) strcpy(zc.zc_name, zc.zc_value);
+ *strchr(zc.zc_name, '@') = '\0';
+
+ if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
+ zfs_handle_t *zhp;
+
+ /*
+ * Destination fs exists. Therefore this should either
+ * be an incremental, or the stream specifies a new fs
+ * (full stream or clone) and they want us to blow it
+ * away (and have therefore specified -F and removed any
+ * snapshots).
+ */
+ if (stream_wantsnewfs) {
+ if (!flags->force) {
+ zcmd_free_nvlists(&zc);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination '%s' exists\n"
+ "must specify -F to overwrite it"),
+ zc.zc_name);
+ return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+ }
+ if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
+ &zc) == 0) {
+ zcmd_free_nvlists(&zc);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination has snapshots (eg. %s)\n"
+ "must destroy them to overwrite it"),
+ zc.zc_name);
+ return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+ }
+ }
+
+ if ((zhp = zfs_open(hdl, zc.zc_name,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+
+ if (stream_wantsnewfs &&
+ zhp->zfs_dmustats.dds_origin[0]) {
+ zcmd_free_nvlists(&zc);
+ zfs_close(zhp);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination '%s' is a clone\n"
+ "must destroy it to overwrite it"),
+ zc.zc_name);
+ return (zfs_error(hdl, EZFS_EXISTS, errbuf));
+ }
+
+ if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
+ stream_wantsnewfs) {
+ /* We can't do online recv in this case */
+ clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
+ if (clp == NULL) {
+ zfs_close(zhp);
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ if (changelist_prefix(clp) != 0) {
+ changelist_free(clp);
+ zfs_close(zhp);
+ zcmd_free_nvlists(&zc);
+ return (-1);
+ }
+ }
+ zfs_close(zhp);
+ } else {
+ /*
+ * Destination filesystem does not exist. Therefore we better
+ * be creating a new filesystem (either from a full backup, or
+ * a clone). It would therefore be invalid if the user
+ * specified only the pool name (i.e. if the destination name
+ * contained no slash character).
+ */
+ if (!stream_wantsnewfs ||
+ (cp = strrchr(zc.zc_name, '/')) == NULL) {
+ zcmd_free_nvlists(&zc);
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination '%s' does not exist"), zc.zc_name);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ }
+
+ /*
+ * Trim off the final dataset component so we perform the
+ * recvbackup ioctl to the filesystems's parent.
+ */
+ *cp = '\0';
+
+ if (flags->isprefix && !flags->istail && !flags->dryrun &&
+ create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
+ zcmd_free_nvlists(&zc);
+ return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
+ }
+
+ newfs = B_TRUE;
+ }
+
+ zc.zc_begin_record = drr_noswap->drr_u.drr_begin;
+ zc.zc_cookie = infd;
+ zc.zc_guid = flags->force;
+ if (flags->verbose) {
+ (void) printf("%s %s stream of %s into %s\n",
+ flags->dryrun ? "would receive" : "receiving",
+ drrb->drr_fromguid ? "incremental" : "full",
+ drrb->drr_toname, zc.zc_value);
+ (void) fflush(stdout);
+ }
+
+ if (flags->dryrun) {
+ zcmd_free_nvlists(&zc);
+ return (recv_skip(hdl, infd, flags->byteswap));
+ }
+
+ zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf;
+ zc.zc_nvlist_dst_size = sizeof (prop_errbuf);
+ zc.zc_cleanup_fd = cleanup_fd;
+ zc.zc_action_handle = *action_handlep;
+
+ err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
+ ioctl_errno = errno;
+ prop_errflags = (zprop_errflags_t)zc.zc_obj;
+
+ if (err == 0) {
+ nvlist_t *prop_errors;
+ VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
+ zc.zc_nvlist_dst_size, &prop_errors, 0));
+
+ nvpair_t *prop_err = NULL;
+
+ while ((prop_err = nvlist_next_nvpair(prop_errors,
+ prop_err)) != NULL) {
+ char tbuf[1024];
+ zfs_prop_t prop;
+ int intval;
+
+ prop = zfs_name_to_prop(nvpair_name(prop_err));
+ (void) nvpair_value_int32(prop_err, &intval);
+ if (strcmp(nvpair_name(prop_err),
+ ZPROP_N_MORE_ERRORS) == 0) {
+ trunc_prop_errs(intval);
+ break;
+ } else {
+ (void) snprintf(tbuf, sizeof (tbuf),
+ dgettext(TEXT_DOMAIN,
+ "cannot receive %s property on %s"),
+ nvpair_name(prop_err), zc.zc_name);
+ zfs_setprop_error(hdl, prop, intval, tbuf);
+ }
+ }
+ nvlist_free(prop_errors);
+ }
+
+ zc.zc_nvlist_dst = 0;
+ zc.zc_nvlist_dst_size = 0;
+ zcmd_free_nvlists(&zc);
+
+ if (err == 0 && snapprops_nvlist) {
+ zfs_cmd_t zc2 = { 0 };
+
+ (void) strcpy(zc2.zc_name, zc.zc_value);
+ zc2.zc_cookie = B_TRUE; /* received */
+ if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
+ (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
+ zcmd_free_nvlists(&zc2);
+ }
+ }
+
+ if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
+ /*
+ * It may be that this snapshot already exists,
+ * in which case we want to consume & ignore it
+ * rather than failing.
+ */
+ avl_tree_t *local_avl;
+ nvlist_t *local_nv, *fs;
+ cp = strchr(zc.zc_value, '@');
+
+ /*
+ * XXX Do this faster by just iterating over snaps in
+ * this fs. Also if zc_value does not exist, we will
+ * get a strange "does not exist" error message.
+ */
+ *cp = '\0';
+ if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE,
+ &local_nv, &local_avl) == 0) {
+ *cp = '@';
+ fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
+ fsavl_destroy(local_avl);
+ nvlist_free(local_nv);
+
+ if (fs != NULL) {
+ if (flags->verbose) {
+ (void) printf("snap %s already exists; "
+ "ignoring\n", zc.zc_value);
+ }
+ err = ioctl_err = recv_skip(hdl, infd,
+ flags->byteswap);
+ }
+ }
+ *cp = '@';
+ }
+
+ if (ioctl_err != 0) {
+ switch (ioctl_errno) {
+ case ENODEV:
+ cp = strchr(zc.zc_value, '@');
+ *cp = '\0';
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "most recent snapshot of %s does not\n"
+ "match incremental source"), zc.zc_value);
+ (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
+ *cp = '@';
+ break;
+ case ETXTBSY:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination %s has been modified\n"
+ "since most recent snapshot"), zc.zc_name);
+ (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
+ break;
+ case EEXIST:
+ cp = strchr(zc.zc_value, '@');
+ if (newfs) {
+ /* it's the containing fs that exists */
+ *cp = '\0';
+ }
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination already exists"));
+ (void) zfs_error_fmt(hdl, EZFS_EXISTS,
+ dgettext(TEXT_DOMAIN, "cannot restore to %s"),
+ zc.zc_value);
+ *cp = '@';
+ break;
+ case EINVAL:
+ (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ break;
+ case ECKSUM:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid stream (checksum mismatch)"));
+ (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
+ break;
+ case ENOTSUP:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool must be upgraded to receive this stream."));
+ (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
+ break;
+ case EDQUOT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "destination %s space quota exceeded"), zc.zc_name);
+ (void) zfs_error(hdl, EZFS_NOSPC, errbuf);
+ break;
+ default:
+ (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
+ }
+ }
+
+ /*
+ * Mount the target filesystem (if created). Also mount any
+ * children of the target filesystem if we did a replication
+ * receive (indicated by stream_avl being non-NULL).
+ */
+ cp = strchr(zc.zc_value, '@');
+ if (cp && (ioctl_err == 0 || !newfs)) {
+ zfs_handle_t *h;
+
+ *cp = '\0';
+ h = zfs_open(hdl, zc.zc_value,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (h != NULL) {
+ if (h->zfs_type == ZFS_TYPE_VOLUME) {
+ *cp = '@';
+ } else if (newfs || stream_avl) {
+ /*
+ * Track the first/top of hierarchy fs,
+ * for mounting and sharing later.
+ */
+ if (top_zfs && *top_zfs == NULL)
+ *top_zfs = zfs_strdup(hdl, zc.zc_value);
+ }
+ zfs_close(h);
+ }
+ *cp = '@';
+ }
+
+ if (clp) {
+ err |= changelist_postfix(clp);
+ changelist_free(clp);
+ }
+
+ if (prop_errflags & ZPROP_ERR_NOCLEAR) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
+ "failed to clear unreceived properties on %s"),
+ zc.zc_name);
+ (void) fprintf(stderr, "\n");
+ }
+ if (prop_errflags & ZPROP_ERR_NORESTORE) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
+ "failed to restore original properties on %s"),
+ zc.zc_name);
+ (void) fprintf(stderr, "\n");
+ }
+
+ if (err || ioctl_err)
+ return (-1);
+
+ *action_handlep = zc.zc_action_handle;
+
+ if (flags->verbose) {
+ char buf1[64];
+ char buf2[64];
+ uint64_t bytes = zc.zc_cookie;
+ time_t delta = time(NULL) - begin_time;
+ if (delta == 0)
+ delta = 1;
+ zfs_nicenum(bytes, buf1, sizeof (buf1));
+ zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
+
+ (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
+ buf1, delta, buf2);
+ }
+
+ return (0);
+}
+
+static int
+zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
+ int infd, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl,
+ char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
+{
+ int err;
+ dmu_replay_record_t drr, drr_noswap;
+ struct drr_begin *drrb = &drr.drr_u.drr_begin;
+ char errbuf[1024];
+ zio_cksum_t zcksum = { 0 };
+ uint64_t featureflags;
+ int hdrtype;
+
+ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+ "cannot receive"));
+
+ if (flags->isprefix &&
+ !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
+ "(%s) does not exist"), tosnap);
+ return (zfs_error(hdl, EZFS_NOENT, errbuf));
+ }
+
+ /* read in the BEGIN record */
+ if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
+ &zcksum)))
+ return (err);
+
+ if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
+ /* It's the double end record at the end of a package */
+ return (ENODATA);
+ }
+
+ /* the kernel needs the non-byteswapped begin record */
+ drr_noswap = drr;
+
+ flags->byteswap = B_FALSE;
+ if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
+ /*
+ * We computed the checksum in the wrong byteorder in
+ * recv_read() above; do it again correctly.
+ */
+ bzero(&zcksum, sizeof (zio_cksum_t));
+ fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
+ flags->byteswap = B_TRUE;
+
+ drr.drr_type = BSWAP_32(drr.drr_type);
+ drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
+ drrb->drr_magic = BSWAP_64(drrb->drr_magic);
+ drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
+ drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
+ drrb->drr_type = BSWAP_32(drrb->drr_type);
+ drrb->drr_flags = BSWAP_32(drrb->drr_flags);
+ drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
+ drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
+ }
+
+ if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
+ "stream (bad magic number)"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+
+ featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
+ hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
+
+ if (!DMU_STREAM_SUPPORTED(featureflags) ||
+ (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "stream has unsupported feature, feature flags = %lx"),
+ featureflags);
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+
+ if (strchr(drrb->drr_toname, '@') == NULL) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
+ "stream (bad snapshot name)"));
+ return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
+ }
+
+ if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
+ char nonpackage_sendfs[ZFS_MAXNAMELEN];
+ if (sendfs == NULL) {
+ /*
+ * We were not called from zfs_receive_package(). Get
+ * the fs specified by 'zfs send'.
+ */
+ char *cp;
+ (void) strlcpy(nonpackage_sendfs,
+ drr.drr_u.drr_begin.drr_toname, ZFS_MAXNAMELEN);
+ if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
+ *cp = '\0';
+ sendfs = nonpackage_sendfs;
+ }
+ return (zfs_receive_one(hdl, infd, tosnap, flags,
+ &drr, &drr_noswap, sendfs, stream_nv, stream_avl,
+ top_zfs, cleanup_fd, action_handlep));
+ } else {
+ assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
+ DMU_COMPOUNDSTREAM);
+ return (zfs_receive_package(hdl, infd, tosnap, flags,
+ &drr, &zcksum, top_zfs, cleanup_fd, action_handlep));
+ }
+}
+
+/*
+ * Restores a backup of tosnap from the file descriptor specified by infd.
+ * Return 0 on total success, -2 if some things couldn't be
+ * destroyed/renamed/promoted, -1 if some things couldn't be received.
+ * (-1 will override -2).
+ */
+int
+zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
+ int infd, avl_tree_t *stream_avl)
+{
+ char *top_zfs = NULL;
+ int err;
+ int cleanup_fd;
+ uint64_t action_handle = 0;
+
+ cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
+ VERIFY(cleanup_fd >= 0);
+
+ err = zfs_receive_impl(hdl, tosnap, flags, infd, NULL, NULL,
+ stream_avl, &top_zfs, cleanup_fd, &action_handle);
+
+ VERIFY(0 == close(cleanup_fd));
+
+ if (err == 0 && !flags->nomount && top_zfs) {
+ zfs_handle_t *zhp;
+ prop_changelist_t *clp;
+
+ zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
+ if (zhp != NULL) {
+ clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
+ CL_GATHER_MOUNT_ALWAYS, 0);
+ zfs_close(zhp);
+ if (clp != NULL) {
+ /* mount and share received datasets */
+ err = changelist_postfix(clp);
+ changelist_free(clp);
+ }
+ }
+ if (zhp == NULL || clp == NULL || err)
+ err = -1;
+ }
+ if (top_zfs)
+ free(top_zfs);
+
+ return (err);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c
new file mode 100644
index 0000000..6af5f77
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_status.c
@@ -0,0 +1,449 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * This file contains the functions which analyze the status of a pool. This
+ * include both the status of an active pool, as well as the status exported
+ * pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
+ * the pool. This status is independent (to a certain degree) from the state of
+ * the pool. A pool's state describes only whether or not it is capable of
+ * providing the necessary fault tolerance for data. The status describes the
+ * overall status of devices. A pool that is online can still have a device
+ * that is experiencing errors.
+ *
+ * Only a subset of the possible faults can be detected using 'zpool status',
+ * and not all possible errors correspond to a FMA message ID. The explanation
+ * is left up to the caller, depending on whether it is a live pool or an
+ * import.
+ */
+
+#include <libzfs.h>
+#include <string.h>
+#include <unistd.h>
+#include "libzfs_impl.h"
+#include "zfeature_common.h"
+
+/*
+ * Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
+ * in libzfs.h. Note that there are some status results which go past the end
+ * of this table, and hence have no associated message ID.
+ */
+static char *zfs_msgid_table[] = {
+ "ZFS-8000-14",
+ "ZFS-8000-2Q",
+ "ZFS-8000-3C",
+ "ZFS-8000-4J",
+ "ZFS-8000-5E",
+ "ZFS-8000-6X",
+ "ZFS-8000-72",
+ "ZFS-8000-8A",
+ "ZFS-8000-9P",
+ "ZFS-8000-A5",
+ "ZFS-8000-EY",
+ "ZFS-8000-HC",
+ "ZFS-8000-JQ",
+ "ZFS-8000-K4",
+};
+
+#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
+
+/* ARGSUSED */
+static int
+vdev_missing(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_CANT_OPEN &&
+ aux == VDEV_AUX_OPEN_FAILED);
+}
+
+/* ARGSUSED */
+static int
+vdev_faulted(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_FAULTED);
+}
+
+/* ARGSUSED */
+static int
+vdev_errors(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_DEGRADED || errs != 0);
+}
+
+/* ARGSUSED */
+static int
+vdev_broken(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_CANT_OPEN);
+}
+
+/* ARGSUSED */
+static int
+vdev_offlined(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_OFFLINE);
+}
+
+/* ARGSUSED */
+static int
+vdev_removed(uint64_t state, uint64_t aux, uint64_t errs)
+{
+ return (state == VDEV_STATE_REMOVED);
+}
+
+/*
+ * Detect if any leaf devices that have seen errors or could not be opened.
+ */
+static boolean_t
+find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
+{
+ nvlist_t **child;
+ vdev_stat_t *vs;
+ uint_t c, children;
+ char *type;
+
+ /*
+ * Ignore problems within a 'replacing' vdev, since we're presumably in
+ * the process of repairing any such errors, and don't want to call them
+ * out again. We'll pick up the fact that a resilver is happening
+ * later.
+ */
+ verify(nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE, &type) == 0);
+ if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
+ return (B_FALSE);
+
+ if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
+ &children) == 0) {
+ for (c = 0; c < children; c++)
+ if (find_vdev_problem(child[c], func))
+ return (B_TRUE);
+ } else {
+ verify(nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) == 0);
+
+ if (func(vs->vs_state, vs->vs_aux,
+ vs->vs_read_errors +
+ vs->vs_write_errors +
+ vs->vs_checksum_errors))
+ return (B_TRUE);
+ }
+
+ /*
+ * Check any L2 cache devs
+ */
+ if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
+ &children) == 0) {
+ for (c = 0; c < children; c++)
+ if (find_vdev_problem(child[c], func))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * Active pool health status.
+ *
+ * To determine the status for a pool, we make several passes over the config,
+ * picking the most egregious error we find. In order of importance, we do the
+ * following:
+ *
+ * - Check for a complete and valid configuration
+ * - Look for any faulted or missing devices in a non-replicated config
+ * - Check for any data errors
+ * - Check for any faulted or missing devices in a replicated config
+ * - Look for any devices showing errors
+ * - Check for any resilvering devices
+ *
+ * There can obviously be multiple errors within a single pool, so this routine
+ * only picks the most damaging of all the current errors to report.
+ */
+static zpool_status_t
+check_status(nvlist_t *config, boolean_t isimport)
+{
+ nvlist_t *nvroot;
+ vdev_stat_t *vs;
+ pool_scan_stat_t *ps = NULL;
+ uint_t vsc, psc;
+ uint64_t nerr;
+ uint64_t version;
+ uint64_t stateval;
+ uint64_t suspended;
+ uint64_t hostid = 0;
+
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
+ &version) == 0);
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &vsc) == 0);
+ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &stateval) == 0);
+
+ /*
+ * Currently resilvering a vdev
+ */
+ (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
+ (uint64_t **)&ps, &psc);
+ if (ps && ps->pss_func == POOL_SCAN_RESILVER &&
+ ps->pss_state == DSS_SCANNING)
+ return (ZPOOL_STATUS_RESILVERING);
+
+ /*
+ * Pool last accessed by another system.
+ */
+ (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
+ if (hostid != 0 && (unsigned long)hostid != gethostid() &&
+ stateval == POOL_STATE_ACTIVE)
+ return (ZPOOL_STATUS_HOSTID_MISMATCH);
+
+ /*
+ * Newer on-disk version.
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_VERSION_NEWER)
+ return (ZPOOL_STATUS_VERSION_NEWER);
+
+ /*
+ * Unsupported feature(s).
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_UNSUP_FEAT) {
+ nvlist_t *nvinfo;
+
+ verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
+ &nvinfo) == 0);
+ if (nvlist_exists(nvinfo, ZPOOL_CONFIG_CAN_RDONLY))
+ return (ZPOOL_STATUS_UNSUP_FEAT_WRITE);
+ return (ZPOOL_STATUS_UNSUP_FEAT_READ);
+ }
+
+ /*
+ * Check that the config is complete.
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_BAD_GUID_SUM)
+ return (ZPOOL_STATUS_BAD_GUID_SUM);
+
+ /*
+ * Check whether the pool has suspended due to failed I/O.
+ */
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
+ &suspended) == 0) {
+ if (suspended == ZIO_FAILURE_MODE_CONTINUE)
+ return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
+ return (ZPOOL_STATUS_IO_FAILURE_WAIT);
+ }
+
+ /*
+ * Could not read a log.
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_BAD_LOG) {
+ return (ZPOOL_STATUS_BAD_LOG);
+ }
+
+ /*
+ * Bad devices in non-replicated config.
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ find_vdev_problem(nvroot, vdev_faulted))
+ return (ZPOOL_STATUS_FAULTED_DEV_NR);
+
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ find_vdev_problem(nvroot, vdev_missing))
+ return (ZPOOL_STATUS_MISSING_DEV_NR);
+
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ find_vdev_problem(nvroot, vdev_broken))
+ return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
+
+ /*
+ * Corrupted pool metadata
+ */
+ if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
+ vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
+ return (ZPOOL_STATUS_CORRUPT_POOL);
+
+ /*
+ * Persistent data errors.
+ */
+ if (!isimport) {
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
+ &nerr) == 0 && nerr != 0)
+ return (ZPOOL_STATUS_CORRUPT_DATA);
+ }
+
+ /*
+ * Missing devices in a replicated config.
+ */
+ if (find_vdev_problem(nvroot, vdev_faulted))
+ return (ZPOOL_STATUS_FAULTED_DEV_R);
+ if (find_vdev_problem(nvroot, vdev_missing))
+ return (ZPOOL_STATUS_MISSING_DEV_R);
+ if (find_vdev_problem(nvroot, vdev_broken))
+ return (ZPOOL_STATUS_CORRUPT_LABEL_R);
+
+ /*
+ * Devices with errors
+ */
+ if (!isimport && find_vdev_problem(nvroot, vdev_errors))
+ return (ZPOOL_STATUS_FAILING_DEV);
+
+ /*
+ * Offlined devices
+ */
+ if (find_vdev_problem(nvroot, vdev_offlined))
+ return (ZPOOL_STATUS_OFFLINE_DEV);
+
+ /*
+ * Removed device
+ */
+ if (find_vdev_problem(nvroot, vdev_removed))
+ return (ZPOOL_STATUS_REMOVED_DEV);
+
+ /*
+ * Outdated, but usable, version
+ */
+ if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION)
+ return (ZPOOL_STATUS_VERSION_OLDER);
+
+ /*
+ * Usable pool with disabled features
+ */
+ if (version >= SPA_VERSION_FEATURES) {
+ int i;
+ nvlist_t *feat;
+
+ if (isimport) {
+ feat = fnvlist_lookup_nvlist(config,
+ ZPOOL_CONFIG_LOAD_INFO);
+ feat = fnvlist_lookup_nvlist(feat,
+ ZPOOL_CONFIG_ENABLED_FEAT);
+ } else {
+ feat = fnvlist_lookup_nvlist(config,
+ ZPOOL_CONFIG_FEATURE_STATS);
+ }
+
+ for (i = 0; i < SPA_FEATURES; i++) {
+ zfeature_info_t *fi = &spa_feature_table[i];
+ if (!nvlist_exists(feat, fi->fi_guid))
+ return (ZPOOL_STATUS_FEAT_DISABLED);
+ }
+ }
+
+ return (ZPOOL_STATUS_OK);
+}
+
+zpool_status_t
+zpool_get_status(zpool_handle_t *zhp, char **msgid)
+{
+ zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE);
+
+ if (ret >= NMSGID)
+ *msgid = NULL;
+ else
+ *msgid = zfs_msgid_table[ret];
+
+ return (ret);
+}
+
+zpool_status_t
+zpool_import_status(nvlist_t *config, char **msgid)
+{
+ zpool_status_t ret = check_status(config, B_TRUE);
+
+ if (ret >= NMSGID)
+ *msgid = NULL;
+ else
+ *msgid = zfs_msgid_table[ret];
+
+ return (ret);
+}
+
+static void
+dump_ddt_stat(const ddt_stat_t *dds, int h)
+{
+ char refcnt[6];
+ char blocks[6], lsize[6], psize[6], dsize[6];
+ char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6];
+
+ if (dds == NULL || dds->dds_blocks == 0)
+ return;
+
+ if (h == -1)
+ (void) strcpy(refcnt, "Total");
+ else
+ zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt));
+
+ zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks));
+ zfs_nicenum(dds->dds_lsize, lsize, sizeof (lsize));
+ zfs_nicenum(dds->dds_psize, psize, sizeof (psize));
+ zfs_nicenum(dds->dds_dsize, dsize, sizeof (dsize));
+ zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks));
+ zfs_nicenum(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize));
+ zfs_nicenum(dds->dds_ref_psize, ref_psize, sizeof (ref_psize));
+ zfs_nicenum(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize));
+
+ (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
+ refcnt,
+ blocks, lsize, psize, dsize,
+ ref_blocks, ref_lsize, ref_psize, ref_dsize);
+}
+
+/*
+ * Print the DDT histogram and the column totals.
+ */
+void
+zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)
+{
+ int h;
+
+ (void) printf("\n");
+
+ (void) printf("bucket "
+ " allocated "
+ " referenced \n");
+ (void) printf("______ "
+ "______________________________ "
+ "______________________________\n");
+
+ (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
+ "refcnt",
+ "blocks", "LSIZE", "PSIZE", "DSIZE",
+ "blocks", "LSIZE", "PSIZE", "DSIZE");
+
+ (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
+ "------",
+ "------", "-----", "-----", "-----",
+ "------", "-----", "-----", "-----");
+
+ for (h = 0; h < 64; h++)
+ dump_ddt_stat(&ddh->ddh_stat[h], h);
+
+ dump_ddt_stat(dds_total, -1);
+
+ (void) printf("\n");
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
new file mode 100644
index 0000000..6823c07
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
@@ -0,0 +1,1535 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Internal utility routines for the ZFS library.
+ */
+
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/mnttab.h>
+#include <sys/mntent.h>
+#include <sys/types.h>
+
+#include <libzfs.h>
+#include <libzfs_core.h>
+
+#include "libzfs_impl.h"
+#include "zfs_prop.h"
+#include "zfeature_common.h"
+
+int aok;
+
+int
+libzfs_errno(libzfs_handle_t *hdl)
+{
+ return (hdl->libzfs_error);
+}
+
+const char *
+libzfs_error_action(libzfs_handle_t *hdl)
+{
+ return (hdl->libzfs_action);
+}
+
+const char *
+libzfs_error_description(libzfs_handle_t *hdl)
+{
+ if (hdl->libzfs_desc[0] != '\0')
+ return (hdl->libzfs_desc);
+
+ switch (hdl->libzfs_error) {
+ case EZFS_NOMEM:
+ return (dgettext(TEXT_DOMAIN, "out of memory"));
+ case EZFS_BADPROP:
+ return (dgettext(TEXT_DOMAIN, "invalid property value"));
+ case EZFS_PROPREADONLY:
+ return (dgettext(TEXT_DOMAIN, "read-only property"));
+ case EZFS_PROPTYPE:
+ return (dgettext(TEXT_DOMAIN, "property doesn't apply to "
+ "datasets of this type"));
+ case EZFS_PROPNONINHERIT:
+ return (dgettext(TEXT_DOMAIN, "property cannot be inherited"));
+ case EZFS_PROPSPACE:
+ return (dgettext(TEXT_DOMAIN, "invalid quota or reservation"));
+ case EZFS_BADTYPE:
+ return (dgettext(TEXT_DOMAIN, "operation not applicable to "
+ "datasets of this type"));
+ case EZFS_BUSY:
+ return (dgettext(TEXT_DOMAIN, "pool or dataset is busy"));
+ case EZFS_EXISTS:
+ return (dgettext(TEXT_DOMAIN, "pool or dataset exists"));
+ case EZFS_NOENT:
+ return (dgettext(TEXT_DOMAIN, "no such pool or dataset"));
+ case EZFS_BADSTREAM:
+ return (dgettext(TEXT_DOMAIN, "invalid backup stream"));
+ case EZFS_DSREADONLY:
+ return (dgettext(TEXT_DOMAIN, "dataset is read-only"));
+ case EZFS_VOLTOOBIG:
+ return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
+ "this system"));
+ case EZFS_INVALIDNAME:
+ return (dgettext(TEXT_DOMAIN, "invalid name"));
+ case EZFS_BADRESTORE:
+ return (dgettext(TEXT_DOMAIN, "unable to restore to "
+ "destination"));
+ case EZFS_BADBACKUP:
+ return (dgettext(TEXT_DOMAIN, "backup failed"));
+ case EZFS_BADTARGET:
+ return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
+ case EZFS_NODEVICE:
+ return (dgettext(TEXT_DOMAIN, "no such device in pool"));
+ case EZFS_BADDEV:
+ return (dgettext(TEXT_DOMAIN, "invalid device"));
+ case EZFS_NOREPLICAS:
+ return (dgettext(TEXT_DOMAIN, "no valid replicas"));
+ case EZFS_RESILVERING:
+ return (dgettext(TEXT_DOMAIN, "currently resilvering"));
+ case EZFS_BADVERSION:
+ return (dgettext(TEXT_DOMAIN, "unsupported version or "
+ "feature"));
+ case EZFS_POOLUNAVAIL:
+ return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
+ case EZFS_DEVOVERFLOW:
+ return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
+ case EZFS_BADPATH:
+ return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
+ case EZFS_CROSSTARGET:
+ return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
+ "pools"));
+ case EZFS_ZONED:
+ return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
+ case EZFS_MOUNTFAILED:
+ return (dgettext(TEXT_DOMAIN, "mount failed"));
+ case EZFS_UMOUNTFAILED:
+ return (dgettext(TEXT_DOMAIN, "umount failed"));
+ case EZFS_UNSHARENFSFAILED:
+ return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
+ case EZFS_SHARENFSFAILED:
+ return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
+ case EZFS_UNSHARESMBFAILED:
+ return (dgettext(TEXT_DOMAIN, "smb remove share failed"));
+ case EZFS_SHARESMBFAILED:
+ return (dgettext(TEXT_DOMAIN, "smb add share failed"));
+ case EZFS_PERM:
+ return (dgettext(TEXT_DOMAIN, "permission denied"));
+ case EZFS_NOSPC:
+ return (dgettext(TEXT_DOMAIN, "out of space"));
+ case EZFS_FAULT:
+ return (dgettext(TEXT_DOMAIN, "bad address"));
+ case EZFS_IO:
+ return (dgettext(TEXT_DOMAIN, "I/O error"));
+ case EZFS_INTR:
+ return (dgettext(TEXT_DOMAIN, "signal received"));
+ case EZFS_ISSPARE:
+ return (dgettext(TEXT_DOMAIN, "device is reserved as a hot "
+ "spare"));
+ case EZFS_INVALCONFIG:
+ return (dgettext(TEXT_DOMAIN, "invalid vdev configuration"));
+ case EZFS_RECURSIVE:
+ return (dgettext(TEXT_DOMAIN, "recursive dataset dependency"));
+ case EZFS_NOHISTORY:
+ return (dgettext(TEXT_DOMAIN, "no history available"));
+ case EZFS_POOLPROPS:
+ return (dgettext(TEXT_DOMAIN, "failed to retrieve "
+ "pool properties"));
+ case EZFS_POOL_NOTSUP:
+ return (dgettext(TEXT_DOMAIN, "operation not supported "
+ "on this type of pool"));
+ case EZFS_POOL_INVALARG:
+ return (dgettext(TEXT_DOMAIN, "invalid argument for "
+ "this pool operation"));
+ case EZFS_NAMETOOLONG:
+ return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
+ case EZFS_OPENFAILED:
+ return (dgettext(TEXT_DOMAIN, "open failed"));
+ case EZFS_NOCAP:
+ return (dgettext(TEXT_DOMAIN,
+ "disk capacity information could not be retrieved"));
+ case EZFS_LABELFAILED:
+ return (dgettext(TEXT_DOMAIN, "write of label failed"));
+ case EZFS_BADWHO:
+ return (dgettext(TEXT_DOMAIN, "invalid user/group"));
+ case EZFS_BADPERM:
+ return (dgettext(TEXT_DOMAIN, "invalid permission"));
+ case EZFS_BADPERMSET:
+ return (dgettext(TEXT_DOMAIN, "invalid permission set name"));
+ case EZFS_NODELEGATION:
+ return (dgettext(TEXT_DOMAIN, "delegated administration is "
+ "disabled on pool"));
+ case EZFS_BADCACHE:
+ return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
+ case EZFS_ISL2CACHE:
+ return (dgettext(TEXT_DOMAIN, "device is in use as a cache"));
+ case EZFS_VDEVNOTSUP:
+ return (dgettext(TEXT_DOMAIN, "vdev specification is not "
+ "supported"));
+ case EZFS_NOTSUP:
+ return (dgettext(TEXT_DOMAIN, "operation not supported "
+ "on this dataset"));
+ case EZFS_ACTIVE_SPARE:
+ return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
+ "device"));
+ case EZFS_UNPLAYED_LOGS:
+ return (dgettext(TEXT_DOMAIN, "log device has unplayed intent "
+ "logs"));
+ case EZFS_REFTAG_RELE:
+ return (dgettext(TEXT_DOMAIN, "no such tag on this dataset"));
+ case EZFS_REFTAG_HOLD:
+ return (dgettext(TEXT_DOMAIN, "tag already exists on this "
+ "dataset"));
+ case EZFS_TAGTOOLONG:
+ return (dgettext(TEXT_DOMAIN, "tag too long"));
+ case EZFS_PIPEFAILED:
+ return (dgettext(TEXT_DOMAIN, "pipe create failed"));
+ case EZFS_THREADCREATEFAILED:
+ return (dgettext(TEXT_DOMAIN, "thread create failed"));
+ case EZFS_POSTSPLIT_ONLINE:
+ return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
+ "into a new one"));
+ case EZFS_SCRUBBING:
+ return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
+ "use 'zpool scrub -s' to cancel current scrub"));
+ case EZFS_NO_SCRUB:
+ return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
+ case EZFS_DIFF:
+ return (dgettext(TEXT_DOMAIN, "unable to generate diffs"));
+ case EZFS_DIFFDATA:
+ return (dgettext(TEXT_DOMAIN, "invalid diff data"));
+ case EZFS_POOLREADONLY:
+ return (dgettext(TEXT_DOMAIN, "pool is read-only"));
+ case EZFS_UNKNOWN:
+ return (dgettext(TEXT_DOMAIN, "unknown error"));
+ default:
+ assert(hdl->libzfs_error == 0);
+ return (dgettext(TEXT_DOMAIN, "no error"));
+ }
+}
+
+/*PRINTFLIKE2*/
+void
+zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
+ fmt, ap);
+ hdl->libzfs_desc_active = 1;
+
+ va_end(ap);
+}
+
+static void
+zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap)
+{
+ (void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action),
+ fmt, ap);
+ hdl->libzfs_error = error;
+
+ if (hdl->libzfs_desc_active)
+ hdl->libzfs_desc_active = 0;
+ else
+ hdl->libzfs_desc[0] = '\0';
+
+ if (hdl->libzfs_printerr) {
+ if (error == EZFS_UNKNOWN) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal "
+ "error: %s\n"), libzfs_error_description(hdl));
+ abort();
+ }
+
+ (void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action,
+ libzfs_error_description(hdl));
+ if (error == EZFS_NOMEM)
+ exit(1);
+ }
+}
+
+int
+zfs_error(libzfs_handle_t *hdl, int error, const char *msg)
+{
+ return (zfs_error_fmt(hdl, error, "%s", msg));
+}
+
+/*PRINTFLIKE3*/
+int
+zfs_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ zfs_verror(hdl, error, fmt, ap);
+
+ va_end(ap);
+
+ return (-1);
+}
+
+static int
+zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
+ va_list ap)
+{
+ switch (error) {
+ case EPERM:
+ case EACCES:
+ zfs_verror(hdl, EZFS_PERM, fmt, ap);
+ return (-1);
+
+ case ECANCELED:
+ zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap);
+ return (-1);
+
+ case EIO:
+ zfs_verror(hdl, EZFS_IO, fmt, ap);
+ return (-1);
+
+ case EFAULT:
+ zfs_verror(hdl, EZFS_FAULT, fmt, ap);
+ return (-1);
+
+ case EINTR:
+ zfs_verror(hdl, EZFS_INTR, fmt, ap);
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+zfs_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
+{
+ return (zfs_standard_error_fmt(hdl, error, "%s", msg));
+}
+
+/*PRINTFLIKE3*/
+int
+zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ if (zfs_common_error(hdl, error, fmt, ap) != 0) {
+ va_end(ap);
+ return (-1);
+ }
+
+ switch (error) {
+ case ENXIO:
+ case ENODEV:
+ case EPIPE:
+ zfs_verror(hdl, EZFS_IO, fmt, ap);
+ break;
+
+ case ENOENT:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset does not exist"));
+ zfs_verror(hdl, EZFS_NOENT, fmt, ap);
+ break;
+
+ case ENOSPC:
+ case EDQUOT:
+ zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
+ va_end(ap);
+ return (-1);
+
+ case EEXIST:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset already exists"));
+ zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
+ break;
+
+ case EBUSY:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dataset is busy"));
+ zfs_verror(hdl, EZFS_BUSY, fmt, ap);
+ break;
+ case EROFS:
+ zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
+ break;
+ case ENAMETOOLONG:
+ zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
+ break;
+ case ENOTSUP:
+ zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
+ break;
+ case EAGAIN:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool I/O is currently suspended"));
+ zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
+ break;
+ default:
+ zfs_error_aux(hdl, strerror(error));
+ zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
+ break;
+ }
+
+ va_end(ap);
+ return (-1);
+}
+
+int
+zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
+{
+ return (zpool_standard_error_fmt(hdl, error, "%s", msg));
+}
+
+/*PRINTFLIKE3*/
+int
+zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ if (zfs_common_error(hdl, error, fmt, ap) != 0) {
+ va_end(ap);
+ return (-1);
+ }
+
+ switch (error) {
+ case ENODEV:
+ zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
+ break;
+
+ case ENOENT:
+ zfs_error_aux(hdl,
+ dgettext(TEXT_DOMAIN, "no such pool or dataset"));
+ zfs_verror(hdl, EZFS_NOENT, fmt, ap);
+ break;
+
+ case EEXIST:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool already exists"));
+ zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
+ break;
+
+ case EBUSY:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
+ zfs_verror(hdl, EZFS_BUSY, fmt, ap);
+ break;
+
+ case ENXIO:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "one or more devices is currently unavailable"));
+ zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
+ break;
+
+ case ENAMETOOLONG:
+ zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
+ break;
+
+ case ENOTSUP:
+ zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap);
+ break;
+
+ case EINVAL:
+ zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
+ break;
+
+ case ENOSPC:
+ case EDQUOT:
+ zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
+ va_end(ap);
+ return (-1);
+
+ case EAGAIN:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "pool I/O is currently suspended"));
+ zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
+ break;
+
+ case EROFS:
+ zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
+ break;
+
+ default:
+ zfs_error_aux(hdl, strerror(error));
+ zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
+ }
+
+ va_end(ap);
+ return (-1);
+}
+
+/*
+ * Display an out of memory error message and abort the current program.
+ */
+int
+no_memory(libzfs_handle_t *hdl)
+{
+ return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
+}
+
+/*
+ * A safe form of malloc() which will die if the allocation fails.
+ */
+void *
+zfs_alloc(libzfs_handle_t *hdl, size_t size)
+{
+ void *data;
+
+ if ((data = calloc(1, size)) == NULL)
+ (void) no_memory(hdl);
+
+ return (data);
+}
+
+/*
+ * A safe form of asprintf() which will die if the allocation fails.
+ */
+/*PRINTFLIKE2*/
+char *
+zfs_asprintf(libzfs_handle_t *hdl, const char *fmt, ...)
+{
+ va_list ap;
+ char *ret;
+ int err;
+
+ va_start(ap, fmt);
+
+ err = vasprintf(&ret, fmt, ap);
+
+ va_end(ap);
+
+ if (err < 0)
+ (void) no_memory(hdl);
+
+ return (ret);
+}
+
+/*
+ * A safe form of realloc(), which also zeroes newly allocated space.
+ */
+void *
+zfs_realloc(libzfs_handle_t *hdl, void *ptr, size_t oldsize, size_t newsize)
+{
+ void *ret;
+
+ if ((ret = realloc(ptr, newsize)) == NULL) {
+ (void) no_memory(hdl);
+ return (NULL);
+ }
+
+ bzero((char *)ret + oldsize, (newsize - oldsize));
+ return (ret);
+}
+
+/*
+ * A safe form of strdup() which will die if the allocation fails.
+ */
+char *
+zfs_strdup(libzfs_handle_t *hdl, const char *str)
+{
+ char *ret;
+
+ if ((ret = strdup(str)) == NULL)
+ (void) no_memory(hdl);
+
+ return (ret);
+}
+
+/*
+ * Convert a number to an appropriately human-readable output.
+ */
+void
+zfs_nicenum(uint64_t num, char *buf, size_t buflen)
+{
+ uint64_t n = num;
+ int index = 0;
+ char u;
+
+ while (n >= 1024) {
+ n /= 1024;
+ index++;
+ }
+
+ u = " KMGTPE"[index];
+
+ if (index == 0) {
+ (void) snprintf(buf, buflen, "%llu", n);
+ } else if ((num & ((1ULL << 10 * index) - 1)) == 0) {
+ /*
+ * If this is an even multiple of the base, always display
+ * without any decimal precision.
+ */
+ (void) snprintf(buf, buflen, "%llu%c", n, u);
+ } else {
+ /*
+ * We want to choose a precision that reflects the best choice
+ * for fitting in 5 characters. This can get rather tricky when
+ * we have numbers that are very close to an order of magnitude.
+ * For example, when displaying 10239 (which is really 9.999K),
+ * we want only a single place of precision for 10.0K. We could
+ * develop some complex heuristics for this, but it's much
+ * easier just to try each combination in turn.
+ */
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (snprintf(buf, buflen, "%.*f%c", i,
+ (double)num / (1ULL << 10 * index), u) <= 5)
+ break;
+ }
+ }
+}
+
+void
+libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr)
+{
+ hdl->libzfs_printerr = printerr;
+}
+
+static int
+libzfs_load(void)
+{
+ int error;
+
+ if (modfind("zfs") < 0) {
+ /* Not present in kernel, try loading it. */
+ if (kldload("zfs") < 0 || modfind("zfs") < 0) {
+ if (errno != EEXIST)
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+libzfs_handle_t *
+libzfs_init(void)
+{
+ libzfs_handle_t *hdl;
+
+ if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
+ return (NULL);
+ }
+
+ if (libzfs_load() < 0) {
+ free(hdl);
+ return (NULL);
+ }
+
+ if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
+ free(hdl);
+ return (NULL);
+ }
+
+ if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
+ (void) close(hdl->libzfs_fd);
+ free(hdl);
+ return (NULL);
+ }
+
+ hdl->libzfs_sharetab = fopen(ZFS_EXPORTS_PATH, "r");
+
+ if (libzfs_core_init() != 0) {
+ (void) close(hdl->libzfs_fd);
+ (void) fclose(hdl->libzfs_mnttab);
+ (void) fclose(hdl->libzfs_sharetab);
+ free(hdl);
+ return (NULL);
+ }
+
+ zfs_prop_init();
+ zpool_prop_init();
+ zpool_feature_init();
+ libzfs_mnttab_init(hdl);
+
+ return (hdl);
+}
+
+void
+libzfs_fini(libzfs_handle_t *hdl)
+{
+ (void) close(hdl->libzfs_fd);
+ if (hdl->libzfs_mnttab)
+ (void) fclose(hdl->libzfs_mnttab);
+ if (hdl->libzfs_sharetab)
+ (void) fclose(hdl->libzfs_sharetab);
+ zfs_uninit_libshare(hdl);
+ zpool_free_handles(hdl);
+#ifdef sun
+ libzfs_fru_clear(hdl, B_TRUE);
+#endif
+ namespace_clear(hdl);
+ libzfs_mnttab_fini(hdl);
+ libzfs_core_fini();
+ free(hdl);
+}
+
+libzfs_handle_t *
+zpool_get_handle(zpool_handle_t *zhp)
+{
+ return (zhp->zpool_hdl);
+}
+
+libzfs_handle_t *
+zfs_get_handle(zfs_handle_t *zhp)
+{
+ return (zhp->zfs_hdl);
+}
+
+zpool_handle_t *
+zfs_get_pool_handle(const zfs_handle_t *zhp)
+{
+ return (zhp->zpool_hdl);
+}
+
+/*
+ * Given a name, determine whether or not it's a valid path
+ * (starts with '/' or "./"). If so, walk the mnttab trying
+ * to match the device number. If not, treat the path as an
+ * fs/vol/snap name.
+ */
+zfs_handle_t *
+zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
+{
+ struct stat64 statbuf;
+ struct extmnttab entry;
+ int ret;
+
+ if (path[0] != '/' && strncmp(path, "./", strlen("./")) != 0) {
+ /*
+ * It's not a valid path, assume it's a name of type 'argtype'.
+ */
+ return (zfs_open(hdl, path, argtype));
+ }
+
+ if (stat64(path, &statbuf) != 0) {
+ (void) fprintf(stderr, "%s: %s\n", path, strerror(errno));
+ return (NULL);
+ }
+
+#ifdef sun
+ rewind(hdl->libzfs_mnttab);
+ while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) {
+ if (makedevice(entry.mnt_major, entry.mnt_minor) ==
+ statbuf.st_dev) {
+ break;
+ }
+ }
+#else
+ {
+ struct statfs sfs;
+
+ ret = statfs(path, &sfs);
+ if (ret == 0)
+ statfs2mnttab(&sfs, &entry);
+ else {
+ (void) fprintf(stderr, "%s: %s\n", path,
+ strerror(errno));
+ }
+ }
+#endif /* sun */
+ if (ret != 0) {
+ return (NULL);
+ }
+
+ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) {
+ (void) fprintf(stderr, gettext("'%s': not a ZFS filesystem\n"),
+ path);
+ return (NULL);
+ }
+
+ return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM));
+}
+
+/*
+ * Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from
+ * an ioctl().
+ */
+int
+zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
+{
+ if (len == 0)
+ len = 16 * 1024;
+ zc->zc_nvlist_dst_size = len;
+ if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
+ zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == 0)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Called when an ioctl() which returns an nvlist fails with ENOMEM. This will
+ * expand the nvlist to the size specified in 'zc_nvlist_dst_size', which was
+ * filled in by the kernel to indicate the actual required size.
+ */
+int
+zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
+{
+ free((void *)(uintptr_t)zc->zc_nvlist_dst);
+ if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
+ zfs_alloc(hdl, zc->zc_nvlist_dst_size))
+ == 0)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Called to free the src and dst nvlists stored in the command structure.
+ */
+void
+zcmd_free_nvlists(zfs_cmd_t *zc)
+{
+ free((void *)(uintptr_t)zc->zc_nvlist_conf);
+ free((void *)(uintptr_t)zc->zc_nvlist_src);
+ free((void *)(uintptr_t)zc->zc_nvlist_dst);
+}
+
+static int
+zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
+ nvlist_t *nvl)
+{
+ char *packed;
+ size_t len;
+
+ verify(nvlist_size(nvl, &len, NV_ENCODE_NATIVE) == 0);
+
+ if ((packed = zfs_alloc(hdl, len)) == NULL)
+ return (-1);
+
+ verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
+
+ *outnv = (uint64_t)(uintptr_t)packed;
+ *outlen = len;
+
+ return (0);
+}
+
+int
+zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
+{
+ return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf,
+ &zc->zc_nvlist_conf_size, nvl));
+}
+
+int
+zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
+{
+ return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
+ &zc->zc_nvlist_src_size, nvl));
+}
+
+/*
+ * Unpacks an nvlist from the ZFS ioctl command structure.
+ */
+int
+zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
+{
+ if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
+ zc->zc_nvlist_dst_size, nvlp, 0) != 0)
+ return (no_memory(hdl));
+
+ return (0);
+}
+
+int
+zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
+{
+ return (ioctl(hdl->libzfs_fd, request, zc));
+}
+
+/*
+ * ================================================================
+ * API shared by zfs and zpool property management
+ * ================================================================
+ */
+
+static void
+zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
+{
+ zprop_list_t *pl = cbp->cb_proplist;
+ int i;
+ char *title;
+ size_t len;
+
+ cbp->cb_first = B_FALSE;
+ if (cbp->cb_scripted)
+ return;
+
+ /*
+ * Start with the length of the column headers.
+ */
+ cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN, "NAME"));
+ cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN,
+ "PROPERTY"));
+ cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN,
+ "VALUE"));
+ cbp->cb_colwidths[GET_COL_RECVD] = strlen(dgettext(TEXT_DOMAIN,
+ "RECEIVED"));
+ cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN,
+ "SOURCE"));
+
+ /* first property is always NAME */
+ assert(cbp->cb_proplist->pl_prop ==
+ ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME : ZFS_PROP_NAME));
+
+ /*
+ * Go through and calculate the widths for each column. For the
+ * 'source' column, we kludge it up by taking the worst-case scenario of
+ * inheriting from the longest name. This is acceptable because in the
+ * majority of cases 'SOURCE' is the last column displayed, and we don't
+ * use the width anyway. Note that the 'VALUE' column can be oversized,
+ * if the name of the property is much longer than any values we find.
+ */
+ for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
+ /*
+ * 'PROPERTY' column
+ */
+ if (pl->pl_prop != ZPROP_INVAL) {
+ const char *propname = (type == ZFS_TYPE_POOL) ?
+ zpool_prop_to_name(pl->pl_prop) :
+ zfs_prop_to_name(pl->pl_prop);
+
+ len = strlen(propname);
+ if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
+ cbp->cb_colwidths[GET_COL_PROPERTY] = len;
+ } else {
+ len = strlen(pl->pl_user_prop);
+ if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
+ cbp->cb_colwidths[GET_COL_PROPERTY] = len;
+ }
+
+ /*
+ * 'VALUE' column. The first property is always the 'name'
+ * property that was tacked on either by /sbin/zfs's
+ * zfs_do_get() or when calling zprop_expand_list(), so we
+ * ignore its width. If the user specified the name property
+ * to display, then it will be later in the list in any case.
+ */
+ if (pl != cbp->cb_proplist &&
+ pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE])
+ cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width;
+
+ /* 'RECEIVED' column. */
+ if (pl != cbp->cb_proplist &&
+ pl->pl_recvd_width > cbp->cb_colwidths[GET_COL_RECVD])
+ cbp->cb_colwidths[GET_COL_RECVD] = pl->pl_recvd_width;
+
+ /*
+ * 'NAME' and 'SOURCE' columns
+ */
+ if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME :
+ ZFS_PROP_NAME) &&
+ pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
+ cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
+ cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
+ strlen(dgettext(TEXT_DOMAIN, "inherited from"));
+ }
+ }
+
+ /*
+ * Now go through and print the headers.
+ */
+ for (i = 0; i < ZFS_GET_NCOLS; i++) {
+ switch (cbp->cb_columns[i]) {
+ case GET_COL_NAME:
+ title = dgettext(TEXT_DOMAIN, "NAME");
+ break;
+ case GET_COL_PROPERTY:
+ title = dgettext(TEXT_DOMAIN, "PROPERTY");
+ break;
+ case GET_COL_VALUE:
+ title = dgettext(TEXT_DOMAIN, "VALUE");
+ break;
+ case GET_COL_RECVD:
+ title = dgettext(TEXT_DOMAIN, "RECEIVED");
+ break;
+ case GET_COL_SOURCE:
+ title = dgettext(TEXT_DOMAIN, "SOURCE");
+ break;
+ default:
+ title = NULL;
+ }
+
+ if (title != NULL) {
+ if (i == (ZFS_GET_NCOLS - 1) ||
+ cbp->cb_columns[i + 1] == GET_COL_NONE)
+ (void) printf("%s", title);
+ else
+ (void) printf("%-*s ",
+ cbp->cb_colwidths[cbp->cb_columns[i]],
+ title);
+ }
+ }
+ (void) printf("\n");
+}
+
+/*
+ * Display a single line of output, according to the settings in the callback
+ * structure.
+ */
+void
+zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
+ const char *propname, const char *value, zprop_source_t sourcetype,
+ const char *source, const char *recvd_value)
+{
+ int i;
+ const char *str;
+ char buf[128];
+
+ /*
+ * Ignore those source types that the user has chosen to ignore.
+ */
+ if ((sourcetype & cbp->cb_sources) == 0)
+ return;
+
+ if (cbp->cb_first)
+ zprop_print_headers(cbp, cbp->cb_type);
+
+ for (i = 0; i < ZFS_GET_NCOLS; i++) {
+ switch (cbp->cb_columns[i]) {
+ case GET_COL_NAME:
+ str = name;
+ break;
+
+ case GET_COL_PROPERTY:
+ str = propname;
+ break;
+
+ case GET_COL_VALUE:
+ str = value;
+ break;
+
+ case GET_COL_SOURCE:
+ switch (sourcetype) {
+ case ZPROP_SRC_NONE:
+ str = "-";
+ break;
+
+ case ZPROP_SRC_DEFAULT:
+ str = "default";
+ break;
+
+ case ZPROP_SRC_LOCAL:
+ str = "local";
+ break;
+
+ case ZPROP_SRC_TEMPORARY:
+ str = "temporary";
+ break;
+
+ case ZPROP_SRC_INHERITED:
+ (void) snprintf(buf, sizeof (buf),
+ "inherited from %s", source);
+ str = buf;
+ break;
+ case ZPROP_SRC_RECEIVED:
+ str = "received";
+ break;
+ }
+ break;
+
+ case GET_COL_RECVD:
+ str = (recvd_value == NULL ? "-" : recvd_value);
+ break;
+
+ default:
+ continue;
+ }
+
+ if (cbp->cb_columns[i + 1] == GET_COL_NONE)
+ (void) printf("%s", str);
+ else if (cbp->cb_scripted)
+ (void) printf("%s\t", str);
+ else
+ (void) printf("%-*s ",
+ cbp->cb_colwidths[cbp->cb_columns[i]],
+ str);
+ }
+
+ (void) printf("\n");
+}
+
+/*
+ * Given a numeric suffix, convert the value into a number of bits that the
+ * resulting value must be shifted.
+ */
+static int
+str2shift(libzfs_handle_t *hdl, const char *buf)
+{
+ const char *ends = "BKMGTPEZ";
+ int i;
+
+ if (buf[0] == '\0')
+ return (0);
+ for (i = 0; i < strlen(ends); i++) {
+ if (toupper(buf[0]) == ends[i])
+ break;
+ }
+ if (i == strlen(ends)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid numeric suffix '%s'"), buf);
+ return (-1);
+ }
+
+ /*
+ * We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't
+ * allow 'BB' - that's just weird.
+ */
+ if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
+ toupper(buf[0]) != 'B'))
+ return (10*i);
+
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid numeric suffix '%s'"), buf);
+ return (-1);
+}
+
+/*
+ * Convert a string of the form '100G' into a real number. Used when setting
+ * properties or creating a volume. 'buf' is used to place an extended error
+ * message for the caller to use.
+ */
+int
+zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
+{
+ char *end;
+ int shift;
+
+ *num = 0;
+
+ /* Check to see if this looks like a number. */
+ if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
+ if (hdl)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "bad numeric value '%s'"), value);
+ return (-1);
+ }
+
+ /* Rely on strtoull() to process the numeric portion. */
+ errno = 0;
+ *num = strtoull(value, &end, 10);
+
+ /*
+ * Check for ERANGE, which indicates that the value is too large to fit
+ * in a 64-bit value.
+ */
+ if (errno == ERANGE) {
+ if (hdl)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "numeric value is too large"));
+ return (-1);
+ }
+
+ /*
+ * If we have a decimal value, then do the computation with floating
+ * point arithmetic. Otherwise, use standard arithmetic.
+ */
+ if (*end == '.') {
+ double fval = strtod(value, &end);
+
+ if ((shift = str2shift(hdl, end)) == -1)
+ return (-1);
+
+ fval *= pow(2, shift);
+
+ if (fval > UINT64_MAX) {
+ if (hdl)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "numeric value is too large"));
+ return (-1);
+ }
+
+ *num = (uint64_t)fval;
+ } else {
+ if ((shift = str2shift(hdl, end)) == -1)
+ return (-1);
+
+ /* Check for overflow */
+ if (shift >= 64 || (*num << shift) >> shift != *num) {
+ if (hdl)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "numeric value is too large"));
+ return (-1);
+ }
+
+ *num <<= shift;
+ }
+
+ return (0);
+}
+
+/*
+ * Given a propname=value nvpair to set, parse any numeric properties
+ * (index, boolean, etc) if they are specified as strings and add the
+ * resulting nvpair to the returned nvlist.
+ *
+ * At the DSL layer, all properties are either 64-bit numbers or strings.
+ * We want the user to be able to ignore this fact and specify properties
+ * as native values (numbers, for example) or as strings (to simplify
+ * command line utilities). This also handles converting index types
+ * (compression, checksum, etc) from strings to their on-disk index.
+ */
+int
+zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
+ zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
+ const char *errbuf)
+{
+ data_type_t datatype = nvpair_type(elem);
+ zprop_type_t proptype;
+ const char *propname;
+ char *value;
+ boolean_t isnone = B_FALSE;
+
+ if (type == ZFS_TYPE_POOL) {
+ proptype = zpool_prop_get_type(prop);
+ propname = zpool_prop_to_name(prop);
+ } else {
+ proptype = zfs_prop_get_type(prop);
+ propname = zfs_prop_to_name(prop);
+ }
+
+ /*
+ * Convert any properties to the internal DSL value types.
+ */
+ *svalp = NULL;
+ *ivalp = 0;
+
+ switch (proptype) {
+ case PROP_TYPE_STRING:
+ if (datatype != DATA_TYPE_STRING) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a string"), nvpair_name(elem));
+ goto error;
+ }
+ (void) nvpair_value_string(elem, svalp);
+ if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' is too long"), nvpair_name(elem));
+ goto error;
+ }
+ break;
+
+ case PROP_TYPE_NUMBER:
+ if (datatype == DATA_TYPE_STRING) {
+ (void) nvpair_value_string(elem, &value);
+ if (strcmp(value, "none") == 0) {
+ isnone = B_TRUE;
+ } else if (zfs_nicestrtonum(hdl, value, ivalp)
+ != 0) {
+ goto error;
+ }
+ } else if (datatype == DATA_TYPE_UINT64) {
+ (void) nvpair_value_uint64(elem, ivalp);
+ } else {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a number"), nvpair_name(elem));
+ goto error;
+ }
+
+ /*
+ * Quota special: force 'none' and don't allow 0.
+ */
+ if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
+ (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "use 'none' to disable quota/refquota"));
+ goto error;
+ }
+ break;
+
+ case PROP_TYPE_INDEX:
+ if (datatype != DATA_TYPE_STRING) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be a string"), nvpair_name(elem));
+ goto error;
+ }
+
+ (void) nvpair_value_string(elem, &value);
+
+ if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "'%s' must be one of '%s'"), propname,
+ zprop_values(prop, type));
+ goto error;
+ }
+ break;
+
+ default:
+ abort();
+ }
+
+ /*
+ * Add the result to our return set of properties.
+ */
+ if (*svalp != NULL) {
+ if (nvlist_add_string(ret, propname, *svalp) != 0) {
+ (void) no_memory(hdl);
+ return (-1);
+ }
+ } else {
+ if (nvlist_add_uint64(ret, propname, *ivalp) != 0) {
+ (void) no_memory(hdl);
+ return (-1);
+ }
+ }
+
+ return (0);
+error:
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ return (-1);
+}
+
+static int
+addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
+ zfs_type_t type)
+{
+ int prop;
+ zprop_list_t *entry;
+
+ prop = zprop_name_to_prop(propname, type);
+
+ if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
+ prop = ZPROP_INVAL;
+
+ /*
+ * When no property table entry can be found, return failure if
+ * this is a pool property or if this isn't a user-defined
+ * dataset property,
+ */
+ if (prop == ZPROP_INVAL && ((type == ZFS_TYPE_POOL &&
+ !zpool_prop_feature(propname) &&
+ !zpool_prop_unsupported(propname)) ||
+ (type == ZFS_TYPE_DATASET && !zfs_prop_user(propname) &&
+ !zfs_prop_userquota(propname) && !zfs_prop_written(propname)))) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid property '%s'"), propname);
+ return (zfs_error(hdl, EZFS_BADPROP,
+ dgettext(TEXT_DOMAIN, "bad property list")));
+ }
+
+ if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
+ return (-1);
+
+ entry->pl_prop = prop;
+ if (prop == ZPROP_INVAL) {
+ if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) ==
+ NULL) {
+ free(entry);
+ return (-1);
+ }
+ entry->pl_width = strlen(propname);
+ } else {
+ entry->pl_width = zprop_width(prop, &entry->pl_fixed,
+ type);
+ }
+
+ *listp = entry;
+
+ return (0);
+}
+
+/*
+ * Given a comma-separated list of properties, construct a property list
+ * containing both user-defined and native properties. This function will
+ * return a NULL list if 'all' is specified, which can later be expanded
+ * by zprop_expand_list().
+ */
+int
+zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp,
+ zfs_type_t type)
+{
+ *listp = NULL;
+
+ /*
+ * If 'all' is specified, return a NULL list.
+ */
+ if (strcmp(props, "all") == 0)
+ return (0);
+
+ /*
+ * If no props were specified, return an error.
+ */
+ if (props[0] == '\0') {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "no properties specified"));
+ return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
+ "bad property list")));
+ }
+
+ /*
+ * It would be nice to use getsubopt() here, but the inclusion of column
+ * aliases makes this more effort than it's worth.
+ */
+ while (*props != '\0') {
+ size_t len;
+ char *p;
+ char c;
+
+ if ((p = strchr(props, ',')) == NULL) {
+ len = strlen(props);
+ p = props + len;
+ } else {
+ len = p - props;
+ }
+
+ /*
+ * Check for empty options.
+ */
+ if (len == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "empty property name"));
+ return (zfs_error(hdl, EZFS_BADPROP,
+ dgettext(TEXT_DOMAIN, "bad property list")));
+ }
+
+ /*
+ * Check all regular property names.
+ */
+ c = props[len];
+ props[len] = '\0';
+
+ if (strcmp(props, "space") == 0) {
+ static char *spaceprops[] = {
+ "name", "avail", "used", "usedbysnapshots",
+ "usedbydataset", "usedbyrefreservation",
+ "usedbychildren", NULL
+ };
+ int i;
+
+ for (i = 0; spaceprops[i]; i++) {
+ if (addlist(hdl, spaceprops[i], listp, type))
+ return (-1);
+ listp = &(*listp)->pl_next;
+ }
+ } else {
+ if (addlist(hdl, props, listp, type))
+ return (-1);
+ listp = &(*listp)->pl_next;
+ }
+
+ props = p;
+ if (c == ',')
+ props++;
+ }
+
+ return (0);
+}
+
+void
+zprop_free_list(zprop_list_t *pl)
+{
+ zprop_list_t *next;
+
+ while (pl != NULL) {
+ next = pl->pl_next;
+ free(pl->pl_user_prop);
+ free(pl);
+ pl = next;
+ }
+}
+
+typedef struct expand_data {
+ zprop_list_t **last;
+ libzfs_handle_t *hdl;
+ zfs_type_t type;
+} expand_data_t;
+
+int
+zprop_expand_list_cb(int prop, void *cb)
+{
+ zprop_list_t *entry;
+ expand_data_t *edp = cb;
+
+ if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL)
+ return (ZPROP_INVAL);
+
+ entry->pl_prop = prop;
+ entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type);
+ entry->pl_all = B_TRUE;
+
+ *(edp->last) = entry;
+ edp->last = &entry->pl_next;
+
+ return (ZPROP_CONT);
+}
+
+int
+zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type)
+{
+ zprop_list_t *entry;
+ zprop_list_t **last;
+ expand_data_t exp;
+
+ if (*plp == NULL) {
+ /*
+ * If this is the very first time we've been called for an 'all'
+ * specification, expand the list to include all native
+ * properties.
+ */
+ last = plp;
+
+ exp.last = last;
+ exp.hdl = hdl;
+ exp.type = type;
+
+ if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE,
+ B_FALSE, type) == ZPROP_INVAL)
+ return (-1);
+
+ /*
+ * Add 'name' to the beginning of the list, which is handled
+ * specially.
+ */
+ if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
+ return (-1);
+
+ entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
+ ZFS_PROP_NAME;
+ entry->pl_width = zprop_width(entry->pl_prop,
+ &entry->pl_fixed, type);
+ entry->pl_all = B_TRUE;
+ entry->pl_next = *plp;
+ *plp = entry;
+ }
+ return (0);
+}
+
+int
+zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
+ zfs_type_t type)
+{
+ return (zprop_iter_common(func, cb, show_all, ordered, type));
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
new file mode 100644
index 0000000..ab23aa1
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -0,0 +1,618 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
+ * It has the following characteristics:
+ *
+ * - Thread Safe. libzfs_core is accessible concurrently from multiple
+ * threads. This is accomplished primarily by avoiding global data
+ * (e.g. caching). Since it's thread-safe, there is no reason for a
+ * process to have multiple libzfs "instances". Therefore, we store
+ * our few pieces of data (e.g. the file descriptor) in global
+ * variables. The fd is reference-counted so that the libzfs_core
+ * library can be "initialized" multiple times (e.g. by different
+ * consumers within the same process).
+ *
+ * - Committed Interface. The libzfs_core interface will be committed,
+ * therefore consumers can compile against it and be confident that
+ * their code will continue to work on future releases of this code.
+ * Currently, the interface is Evolving (not Committed), but we intend
+ * to commit to it once it is more complete and we determine that it
+ * meets the needs of all consumers.
+ *
+ * - Programatic Error Handling. libzfs_core communicates errors with
+ * defined error numbers, and doesn't print anything to stdout/stderr.
+ *
+ * - Thin Layer. libzfs_core is a thin layer, marshaling arguments
+ * to/from the kernel ioctls. There is generally a 1:1 correspondence
+ * between libzfs_core functions and ioctls to /dev/zfs.
+ *
+ * - Clear Atomicity. Because libzfs_core functions are generally 1:1
+ * with kernel ioctls, and kernel ioctls are general atomic, each
+ * libzfs_core function is atomic. For example, creating multiple
+ * snapshots with a single call to lzc_snapshot() is atomic -- it
+ * can't fail with only some of the requested snapshots created, even
+ * in the event of power loss or system crash.
+ *
+ * - Continued libzfs Support. Some higher-level operations (e.g.
+ * support for "zfs send -R") are too complicated to fit the scope of
+ * libzfs_core. This functionality will continue to live in libzfs.
+ * Where appropriate, libzfs will use the underlying atomic operations
+ * of libzfs_core. For example, libzfs may implement "zfs send -R |
+ * zfs receive" by using individual "send one snapshot", rename,
+ * destroy, and "receive one snapshot" operations in libzfs_core.
+ * /sbin/zfs and /zbin/zpool will link with both libzfs and
+ * libzfs_core. Other consumers should aim to use only libzfs_core,
+ * since that will be the supported, stable interface going forwards.
+ */
+
+#define _IN_LIBZFS_CORE_
+
+#include <libzfs_core.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/nvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/zfs_ioctl.h>
+#include "libzfs_core_compat.h"
+#include "libzfs_compat.h"
+
+#ifdef __FreeBSD__
+extern int zfs_ioctl_version;
+#endif
+
+static int g_fd;
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+static int g_refcount;
+
+int
+libzfs_core_init(void)
+{
+ (void) pthread_mutex_lock(&g_lock);
+ if (g_refcount == 0) {
+ g_fd = open("/dev/zfs", O_RDWR);
+ if (g_fd < 0) {
+ (void) pthread_mutex_unlock(&g_lock);
+ return (errno);
+ }
+ }
+ g_refcount++;
+ (void) pthread_mutex_unlock(&g_lock);
+
+ return (0);
+}
+
+void
+libzfs_core_fini(void)
+{
+ (void) pthread_mutex_lock(&g_lock);
+ ASSERT3S(g_refcount, >, 0);
+ g_refcount--;
+ if (g_refcount == 0)
+ (void) close(g_fd);
+ (void) pthread_mutex_unlock(&g_lock);
+}
+
+static int
+lzc_ioctl(zfs_ioc_t ioc, const char *name,
+ nvlist_t *source, nvlist_t **resultp)
+{
+ zfs_cmd_t zc = { 0 };
+ int error = 0;
+ char *packed;
+#ifdef __FreeBSD__
+ nvlist_t *oldsource;
+#endif
+ size_t size;
+
+ ASSERT3S(g_refcount, >, 0);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
+
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
+ oldsource = source;
+ error = lzc_compat_pre(&zc, &ioc, &source);
+ if (error)
+ return (error);
+ }
+#endif
+
+ packed = fnvlist_pack(source, &size);
+ zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
+ zc.zc_nvlist_src_size = size;
+
+ if (resultp != NULL) {
+ *resultp = NULL;
+ zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
+ zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
+ malloc(zc.zc_nvlist_dst_size);
+#ifdef illumos
+ if (zc.zc_nvlist_dst == NULL) {
+#else
+ if (zc.zc_nvlist_dst == 0) {
+#endif
+ error = ENOMEM;
+ goto out;
+ }
+ }
+
+ while (ioctl(g_fd, ioc, &zc) != 0) {
+ if (errno == ENOMEM && resultp != NULL) {
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ zc.zc_nvlist_dst_size *= 2;
+ zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
+ malloc(zc.zc_nvlist_dst_size);
+#ifdef illumos
+ if (zc.zc_nvlist_dst == NULL) {
+#else
+ if (zc.zc_nvlist_dst == 0) {
+#endif
+ error = ENOMEM;
+ goto out;
+ }
+ } else {
+ error = errno;
+ break;
+ }
+ }
+
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ lzc_compat_post(&zc, ioc);
+#endif
+ if (zc.zc_nvlist_dst_filled) {
+ *resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
+ zc.zc_nvlist_dst_size);
+ }
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
+ lzc_compat_outnvl(&zc, ioc, resultp);
+#endif
+out:
+#ifdef __FreeBSD__
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
+ if (source != oldsource)
+ nvlist_free(source);
+ source = oldsource;
+ }
+#endif
+ fnvlist_pack_free(packed, size);
+ free((void *)(uintptr_t)zc.zc_nvlist_dst);
+ return (error);
+}
+
+int
+lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props)
+{
+ int error;
+ nvlist_t *args = fnvlist_alloc();
+ fnvlist_add_int32(args, "type", type);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+ error = lzc_ioctl(ZFS_IOC_CREATE, fsname, args, NULL);
+ nvlist_free(args);
+ return (error);
+}
+
+int
+lzc_clone(const char *fsname, const char *origin,
+ nvlist_t *props)
+{
+ int error;
+ nvlist_t *args = fnvlist_alloc();
+ fnvlist_add_string(args, "origin", origin);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+ error = lzc_ioctl(ZFS_IOC_CLONE, fsname, args, NULL);
+ nvlist_free(args);
+ return (error);
+}
+
+/*
+ * Creates snapshots.
+ *
+ * The keys in the snaps nvlist are the snapshots to be created.
+ * They must all be in the same pool.
+ *
+ * The props nvlist is properties to set. Currently only user properties
+ * are supported. { user:prop_name -> string value }
+ *
+ * The returned results nvlist will have an entry for each snapshot that failed.
+ * The value will be the (int32) error code.
+ *
+ * The return value will be 0 if all snapshots were created, otherwise it will
+ * be the errno of a (unspecified) snapshot that failed.
+ */
+int
+lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist)
+{
+ nvpair_t *elem;
+ nvlist_t *args;
+ int error;
+ char pool[MAXNAMELEN];
+
+ *errlist = NULL;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(snaps, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "snaps", snaps);
+ if (props != NULL)
+ fnvlist_add_nvlist(args, "props", props);
+
+ error = lzc_ioctl(ZFS_IOC_SNAPSHOT, pool, args, errlist);
+ nvlist_free(args);
+
+ return (error);
+}
+
+/*
+ * Destroys snapshots.
+ *
+ * The keys in the snaps nvlist are the snapshots to be destroyed.
+ * They must all be in the same pool.
+ *
+ * Snapshots that do not exist will be silently ignored.
+ *
+ * If 'defer' is not set, and a snapshot has user holds or clones, the
+ * destroy operation will fail and none of the snapshots will be
+ * destroyed.
+ *
+ * If 'defer' is set, and a snapshot has user holds or clones, it will be
+ * marked for deferred destruction, and will be destroyed when the last hold
+ * or clone is removed/destroyed.
+ *
+ * The return value will be 0 if all snapshots were destroyed (or marked for
+ * later destruction if 'defer' is set) or didn't exist to begin with.
+ *
+ * Otherwise the return value will be the errno of a (unspecified) snapshot
+ * that failed, no snapshots will be destroyed, and the errlist will have an
+ * entry for each snapshot that failed. The value in the errlist will be
+ * the (int32) error code.
+ */
+int
+lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist)
+{
+ nvpair_t *elem;
+ nvlist_t *args;
+ int error;
+ char pool[MAXNAMELEN];
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(snaps, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "snaps", snaps);
+ if (defer)
+ fnvlist_add_boolean(args, "defer");
+
+ error = lzc_ioctl(ZFS_IOC_DESTROY_SNAPS, pool, args, errlist);
+ nvlist_free(args);
+
+ return (error);
+
+}
+
+int
+lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
+ uint64_t *usedp)
+{
+ nvlist_t *args;
+ nvlist_t *result;
+ int err;
+ char fs[MAXNAMELEN];
+ char *atp;
+
+ /* determine the fs name */
+ (void) strlcpy(fs, firstsnap, sizeof (fs));
+ atp = strchr(fs, '@');
+ if (atp == NULL)
+ return (EINVAL);
+ *atp = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_string(args, "firstsnap", firstsnap);
+
+ err = lzc_ioctl(ZFS_IOC_SPACE_SNAPS, lastsnap, args, &result);
+ nvlist_free(args);
+ if (err == 0)
+ *usedp = fnvlist_lookup_uint64(result, "used");
+ fnvlist_free(result);
+
+ return (err);
+}
+
+boolean_t
+lzc_exists(const char *dataset)
+{
+ /*
+ * The objset_stats ioctl is still legacy, so we need to construct our
+ * own zfs_cmd_t rather than using zfsc_ioctl().
+ */
+ zfs_cmd_t zc = { 0 };
+
+ (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
+ return (ioctl(g_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0);
+}
+
+/*
+ * Create "user holds" on snapshots. If there is a hold on a snapshot,
+ * the snapshot can not be destroyed. (However, it can be marked for deletion
+ * by lzc_destroy_snaps(defer=B_TRUE).)
+ *
+ * The keys in the nvlist are snapshot names.
+ * The snapshots must all be in the same pool.
+ * The value is the name of the hold (string type).
+ *
+ * If cleanup_fd is not -1, it must be the result of open("/dev/zfs", O_EXCL).
+ * In this case, when the cleanup_fd is closed (including on process
+ * termination), the holds will be released. If the system is shut down
+ * uncleanly, the holds will be released when the pool is next opened
+ * or imported.
+ *
+ * The return value will be 0 if all holds were created. Otherwise the return
+ * value will be the errno of a (unspecified) hold that failed, no holds will
+ * be created, and the errlist will have an entry for each hold that
+ * failed (name = snapshot). The value in the errlist will be the error
+ * code (int32).
+ */
+int
+lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
+{
+ char pool[MAXNAMELEN];
+ nvlist_t *args;
+ nvpair_t *elem;
+ int error;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(holds, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ args = fnvlist_alloc();
+ fnvlist_add_nvlist(args, "holds", holds);
+ if (cleanup_fd != -1)
+ fnvlist_add_int32(args, "cleanup_fd", cleanup_fd);
+
+ error = lzc_ioctl(ZFS_IOC_HOLD, pool, args, errlist);
+ nvlist_free(args);
+ return (error);
+}
+
+/*
+ * Release "user holds" on snapshots. If the snapshot has been marked for
+ * deferred destroy (by lzc_destroy_snaps(defer=B_TRUE)), it does not have
+ * any clones, and all the user holds are removed, then the snapshot will be
+ * destroyed.
+ *
+ * The keys in the nvlist are snapshot names.
+ * The snapshots must all be in the same pool.
+ * The value is a nvlist whose keys are the holds to remove.
+ *
+ * The return value will be 0 if all holds were removed.
+ * Otherwise the return value will be the errno of a (unspecified) release
+ * that failed, no holds will be released, and the errlist will have an
+ * entry for each snapshot that has failed releases (name = snapshot).
+ * The value in the errlist will be the error code (int32) of a failed release.
+ */
+int
+lzc_release(nvlist_t *holds, nvlist_t **errlist)
+{
+ char pool[MAXNAMELEN];
+ nvpair_t *elem;
+
+ /* determine the pool name */
+ elem = nvlist_next_nvpair(holds, NULL);
+ if (elem == NULL)
+ return (0);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+
+ return (lzc_ioctl(ZFS_IOC_RELEASE, pool, holds, errlist));
+}
+
+/*
+ * Retrieve list of user holds on the specified snapshot.
+ *
+ * On success, *holdsp will be set to a nvlist which the caller must free.
+ * The keys are the names of the holds, and the value is the creation time
+ * of the hold (uint64) in seconds since the epoch.
+ */
+int
+lzc_get_holds(const char *snapname, nvlist_t **holdsp)
+{
+ int error;
+ nvlist_t *innvl = fnvlist_alloc();
+ error = lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, innvl, holdsp);
+ fnvlist_free(innvl);
+ return (error);
+}
+
+/*
+ * If fromsnap is NULL, a full (non-incremental) stream will be sent.
+ */
+int
+lzc_send(const char *snapname, const char *fromsnap, int fd)
+{
+ nvlist_t *args;
+ int err;
+
+ args = fnvlist_alloc();
+ fnvlist_add_int32(args, "fd", fd);
+ if (fromsnap != NULL)
+ fnvlist_add_string(args, "fromsnap", fromsnap);
+ err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
+ nvlist_free(args);
+ return (err);
+}
+
+/*
+ * If fromsnap is NULL, a full (non-incremental) stream will be estimated.
+ */
+int
+lzc_send_space(const char *snapname, const char *fromsnap, uint64_t *spacep)
+{
+ nvlist_t *args;
+ nvlist_t *result;
+ int err;
+
+ args = fnvlist_alloc();
+ if (fromsnap != NULL)
+ fnvlist_add_string(args, "fromsnap", fromsnap);
+ err = lzc_ioctl(ZFS_IOC_SEND_SPACE, snapname, args, &result);
+ nvlist_free(args);
+ if (err == 0)
+ *spacep = fnvlist_lookup_uint64(result, "space");
+ nvlist_free(result);
+ return (err);
+}
+
+static int
+recv_read(int fd, void *buf, int ilen)
+{
+ char *cp = buf;
+ int rv;
+ int len = ilen;
+
+ do {
+ rv = read(fd, cp, len);
+ cp += rv;
+ len -= rv;
+ } while (rv > 0);
+
+ if (rv < 0 || len != 0)
+ return (EIO);
+
+ return (0);
+}
+
+/*
+ * The simplest receive case: receive from the specified fd, creating the
+ * specified snapshot. Apply the specified properties a "received" properties
+ * (which can be overridden by locally-set properties). If the stream is a
+ * clone, its origin snapshot must be specified by 'origin'. The 'force'
+ * flag will cause the target filesystem to be rolled back or destroyed if
+ * necessary to receive.
+ *
+ * Return 0 on success or an errno on failure.
+ *
+ * Note: this interface does not work on dedup'd streams
+ * (those with DMU_BACKUP_FEATURE_DEDUP).
+ */
+int
+lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
+ boolean_t force, int fd)
+{
+ /*
+ * The receive ioctl is still legacy, so we need to construct our own
+ * zfs_cmd_t rather than using zfsc_ioctl().
+ */
+ zfs_cmd_t zc = { 0 };
+ char *atp;
+ char *packed = NULL;
+ size_t size;
+ dmu_replay_record_t drr;
+ int error;
+
+ ASSERT3S(g_refcount, >, 0);
+
+ /* zc_name is name of containing filesystem */
+ (void) strlcpy(zc.zc_name, snapname, sizeof (zc.zc_name));
+ atp = strchr(zc.zc_name, '@');
+ if (atp == NULL)
+ return (EINVAL);
+ *atp = '\0';
+
+ /* if the fs does not exist, try its parent. */
+ if (!lzc_exists(zc.zc_name)) {
+ char *slashp = strrchr(zc.zc_name, '/');
+ if (slashp == NULL)
+ return (ENOENT);
+ *slashp = '\0';
+
+ }
+
+ /* zc_value is full name of the snapshot to create */
+ (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
+
+ if (props != NULL) {
+ /* zc_nvlist_src is props to set */
+ packed = fnvlist_pack(props, &size);
+ zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
+ zc.zc_nvlist_src_size = size;
+ }
+
+ /* zc_string is name of clone origin (if DRR_FLAG_CLONE) */
+ if (origin != NULL)
+ (void) strlcpy(zc.zc_string, origin, sizeof (zc.zc_string));
+
+ /* zc_begin_record is non-byteswapped BEGIN record */
+ error = recv_read(fd, &drr, sizeof (drr));
+ if (error != 0)
+ goto out;
+ zc.zc_begin_record = drr.drr_u.drr_begin;
+
+ /* zc_cookie is fd to read from */
+ zc.zc_cookie = fd;
+
+ /* zc guid is force flag */
+ zc.zc_guid = force;
+
+ /* zc_cleanup_fd is unused */
+ zc.zc_cleanup_fd = -1;
+
+ error = ioctl(g_fd, ZFS_IOC_RECV, &zc);
+ if (error != 0)
+ error = errno;
+
+out:
+ if (packed != NULL)
+ fnvlist_pack_free(packed, size);
+ free((void*)(uintptr_t)zc.zc_nvlist_dst);
+ return (error);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
new file mode 100644
index 0000000..b10098b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_CORE_H
+#define _LIBZFS_CORE_H
+
+#include <libnvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int libzfs_core_init(void);
+void libzfs_core_fini(void);
+
+int lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist);
+int lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props);
+int lzc_clone(const char *fsname, const char *origin, nvlist_t *props);
+int lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist);
+
+int lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
+ uint64_t *usedp);
+
+int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist);
+int lzc_release(nvlist_t *holds, nvlist_t **errlist);
+int lzc_get_holds(const char *snapname, nvlist_t **holdsp);
+
+int lzc_send(const char *snapname, const char *fromsnap, int fd);
+int lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
+ boolean_t force, int fd);
+int lzc_send_space(const char *snapname, const char *fromsnap,
+ uint64_t *result);
+
+boolean_t lzc_exists(const char *dataset);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_CORE_H */
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
new file mode 100644
index 0000000..a3b872e
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
@@ -0,0 +1,189 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include <sys/zfs_ioctl.h>
+#include <zfs_ioctl_compat.h>
+#include "libzfs_core_compat.h"
+
+extern int zfs_ioctl_version;
+
+int
+lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
+{
+ nvlist_t *nvl = NULL;
+ nvpair_t *pair, *hpair;
+ char *buf, *val;
+ zfs_ioc_t vecnum;
+ uint32_t type32;
+ int32_t cleanup_fd;
+ int error = 0;
+ int pos;
+
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return (0);
+
+ vecnum = *ioc;
+
+ switch (vecnum) {
+ case ZFS_IOC_CREATE:
+ type32 = fnvlist_lookup_int32(*source, "type");
+ zc->zc_objset_type = (uint64_t)type32;
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *source = nvl;
+ break;
+ case ZFS_IOC_CLONE:
+ buf = fnvlist_lookup_string(*source, "origin");
+ strlcpy(zc->zc_value, buf, MAXPATHLEN);
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *ioc = ZFS_IOC_CREATE;
+ *source = nvl;
+ break;
+ case ZFS_IOC_SNAPSHOT:
+ nvl = fnvlist_lookup_nvlist(*source, "snaps");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ } else
+ error = EINVAL;
+ /* old kernel cannot create multiple snapshots */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ nvlist_free(nvl);
+ nvl = NULL;
+ nvlist_lookup_nvlist(*source, "props", &nvl);
+ *source = nvl;
+ break;
+ case ZFS_IOC_SPACE_SNAPS:
+ buf = fnvlist_lookup_string(*source, "firstsnap");
+ strlcpy(zc->zc_value, buf, MAXPATHLEN);
+ break;
+ case ZFS_IOC_DESTROY_SNAPS:
+ nvl = fnvlist_lookup_nvlist(*source, "snaps");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically destroy multiple snaps */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ *source = nvl;
+ break;
+ case ZFS_IOC_HOLD:
+ nvl = fnvlist_lookup_nvlist(*source, "holds");
+ pair = nvlist_next_nvpair(nvl, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ if (nvpair_value_string(pair, &val) == 0)
+ strlcpy(zc->zc_string, val, MAXNAMELEN);
+ else
+ error = EINVAL;
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically create multiple holds */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ nvlist_free(nvl);
+ if (nvlist_lookup_int32(*source, "cleanup_fd",
+ &cleanup_fd) == 0)
+ zc->zc_cleanup_fd = cleanup_fd;
+ else
+ zc->zc_cleanup_fd = -1;
+ break;
+ case ZFS_IOC_RELEASE:
+ pair = nvlist_next_nvpair(*source, NULL);
+ if (pair != NULL) {
+ buf = nvpair_name(pair);
+ pos = strcspn(buf, "@");
+ strlcpy(zc->zc_name, buf, pos + 1);
+ strlcpy(zc->zc_value, buf + pos + 1, MAXPATHLEN);
+ if (nvpair_value_nvlist(pair, &nvl) == 0) {
+ hpair = nvlist_next_nvpair(nvl, NULL);
+ if (hpair != NULL)
+ strlcpy(zc->zc_string,
+ nvpair_name(hpair), MAXNAMELEN);
+ else
+ error = EINVAL;
+ if (!error && nvlist_next_nvpair(nvl,
+ hpair) != NULL)
+ error = EOPNOTSUPP;
+ } else
+ error = EINVAL;
+ } else
+ error = EINVAL;
+ /* old kernel cannot atomically release multiple holds */
+ if (!error && nvlist_next_nvpair(nvl, pair) != NULL)
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ return (error);
+}
+
+void
+lzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
+{
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return;
+
+ switch (ioc) {
+ case ZFS_IOC_CREATE:
+ case ZFS_IOC_CLONE:
+ case ZFS_IOC_SNAPSHOT:
+ case ZFS_IOC_SPACE_SNAPS:
+ case ZFS_IOC_DESTROY_SNAPS:
+ zc->zc_nvlist_dst_filled = B_FALSE;
+ break;
+ }
+}
+
+int
+lzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
+{
+ nvlist_t *nvl;
+
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
+ return (0);
+
+ switch (ioc) {
+ case ZFS_IOC_SPACE_SNAPS:
+ nvl = fnvlist_alloc();
+ fnvlist_add_uint64(nvl, "used", zc->zc_cookie);
+ fnvlist_add_uint64(nvl, "compressed", zc->zc_objset_type);
+ fnvlist_add_uint64(nvl, "uncompressed", zc->zc_perm_action);
+ *outnvl = nvl;
+ break;
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h
new file mode 100644
index 0000000..6527c4b
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.h
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#ifndef _LIBZFS_CORE_COMPAT_H
+#define _LIBZFS_CORE_COMPAT_H
+
+#include <libnvpair.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int lzc_compat_pre(zfs_cmd_t *, zfs_ioc_t *, nvlist_t **);
+void lzc_compat_post(zfs_cmd_t *, const zfs_ioc_t);
+int lzc_compat_outnvl(zfs_cmd_t *, const zfs_ioc_t, nvlist_t **);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBZFS_CORE_COMPAT_H */
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
new file mode 100644
index 0000000..c5c7b66
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
@@ -0,0 +1,1086 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <zlib.h>
+#include <sys/spa.h>
+#include <sys/stat.h>
+#include <sys/processor.h>
+#include <sys/zfs_context.h>
+#include <sys/rrwlock.h>
+#include <sys/zmod.h>
+#include <sys/utsname.h>
+#include <sys/systeminfo.h>
+
+/*
+ * Emulation of kernel services in userland.
+ */
+
+int aok;
+uint64_t physmem;
+vnode_t *rootdir = (vnode_t *)0xabcd1234;
+char hw_serial[HW_HOSTID_LEN];
+#ifdef illumos
+kmutex_t cpu_lock;
+#endif
+
+struct utsname utsname = {
+ "userland", "libzpool", "1", "1", "na"
+};
+
+/* this only exists to have its address taken */
+struct proc p0;
+
+/*
+ * =========================================================================
+ * threads
+ * =========================================================================
+ */
+/*ARGSUSED*/
+kthread_t *
+zk_thread_create(void (*func)(), void *arg)
+{
+ thread_t tid;
+
+ VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
+ &tid) == 0);
+
+ return ((void *)(uintptr_t)tid);
+}
+
+/*
+ * =========================================================================
+ * kstats
+ * =========================================================================
+ */
+/*ARGSUSED*/
+kstat_t *
+kstat_create(char *module, int instance, char *name, char *class,
+ uchar_t type, ulong_t ndata, uchar_t ks_flag)
+{
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+kstat_install(kstat_t *ksp)
+{}
+
+/*ARGSUSED*/
+void
+kstat_delete(kstat_t *ksp)
+{}
+
+/*
+ * =========================================================================
+ * mutexes
+ * =========================================================================
+ */
+void
+zmutex_init(kmutex_t *mp)
+{
+ mp->m_owner = NULL;
+ mp->initialized = B_TRUE;
+ (void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
+}
+
+void
+zmutex_destroy(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+ ASSERT(mp->m_owner == NULL);
+ (void) _mutex_destroy(&(mp)->m_lock);
+ mp->m_owner = (void *)-1UL;
+ mp->initialized = B_FALSE;
+}
+
+int
+zmutex_owned(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+
+ return (mp->m_owner == curthread);
+}
+
+void
+mutex_enter(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+ ASSERT(mp->m_owner != (void *)-1UL);
+ ASSERT(mp->m_owner != curthread);
+ VERIFY(mutex_lock(&mp->m_lock) == 0);
+ ASSERT(mp->m_owner == NULL);
+ mp->m_owner = curthread;
+}
+
+int
+mutex_tryenter(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+ ASSERT(mp->m_owner != (void *)-1UL);
+ if (0 == mutex_trylock(&mp->m_lock)) {
+ ASSERT(mp->m_owner == NULL);
+ mp->m_owner = curthread;
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+void
+mutex_exit(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+ ASSERT(mutex_owner(mp) == curthread);
+ mp->m_owner = NULL;
+ VERIFY(mutex_unlock(&mp->m_lock) == 0);
+}
+
+void *
+mutex_owner(kmutex_t *mp)
+{
+ ASSERT(mp->initialized == B_TRUE);
+ return (mp->m_owner);
+}
+
+/*
+ * =========================================================================
+ * rwlocks
+ * =========================================================================
+ */
+/*ARGSUSED*/
+void
+rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
+{
+ rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
+ rwlp->rw_owner = NULL;
+ rwlp->initialized = B_TRUE;
+ rwlp->rw_count = 0;
+}
+
+void
+rw_destroy(krwlock_t *rwlp)
+{
+ ASSERT(rwlp->rw_count == 0);
+ rwlock_destroy(&rwlp->rw_lock);
+ rwlp->rw_owner = (void *)-1UL;
+ rwlp->initialized = B_FALSE;
+}
+
+void
+rw_enter(krwlock_t *rwlp, krw_t rw)
+{
+ //ASSERT(!RW_LOCK_HELD(rwlp));
+ ASSERT(rwlp->initialized == B_TRUE);
+ ASSERT(rwlp->rw_owner != (void *)-1UL);
+ ASSERT(rwlp->rw_owner != curthread);
+
+ if (rw == RW_READER) {
+ VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
+ ASSERT(rwlp->rw_count >= 0);
+ atomic_add_int(&rwlp->rw_count, 1);
+ } else {
+ VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
+ ASSERT(rwlp->rw_count == 0);
+ rwlp->rw_count = -1;
+ rwlp->rw_owner = curthread;
+ }
+}
+
+void
+rw_exit(krwlock_t *rwlp)
+{
+ ASSERT(rwlp->initialized == B_TRUE);
+ ASSERT(rwlp->rw_owner != (void *)-1UL);
+
+ if (rwlp->rw_owner == curthread) {
+ /* Write locked. */
+ ASSERT(rwlp->rw_count == -1);
+ rwlp->rw_count = 0;
+ rwlp->rw_owner = NULL;
+ } else {
+ /* Read locked. */
+ ASSERT(rwlp->rw_count > 0);
+ atomic_add_int(&rwlp->rw_count, -1);
+ }
+ VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
+}
+
+int
+rw_tryenter(krwlock_t *rwlp, krw_t rw)
+{
+ int rv;
+
+ ASSERT(rwlp->initialized == B_TRUE);
+ ASSERT(rwlp->rw_owner != (void *)-1UL);
+ ASSERT(rwlp->rw_owner != curthread);
+
+ if (rw == RW_READER)
+ rv = rw_tryrdlock(&rwlp->rw_lock);
+ else
+ rv = rw_trywrlock(&rwlp->rw_lock);
+
+ if (rv == 0) {
+ ASSERT(rwlp->rw_owner == NULL);
+ if (rw == RW_READER) {
+ ASSERT(rwlp->rw_count >= 0);
+ atomic_add_int(&rwlp->rw_count, 1);
+ } else {
+ ASSERT(rwlp->rw_count == 0);
+ rwlp->rw_count = -1;
+ rwlp->rw_owner = curthread;
+ }
+ return (1);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+rw_tryupgrade(krwlock_t *rwlp)
+{
+ ASSERT(rwlp->initialized == B_TRUE);
+ ASSERT(rwlp->rw_owner != (void *)-1UL);
+
+ return (0);
+}
+
+int
+rw_lock_held(krwlock_t *rwlp)
+{
+
+ return (rwlp->rw_count != 0);
+}
+
+/*
+ * =========================================================================
+ * condition variables
+ * =========================================================================
+ */
+/*ARGSUSED*/
+void
+cv_init(kcondvar_t *cv, char *name, int type, void *arg)
+{
+ VERIFY(cond_init(cv, name, NULL) == 0);
+}
+
+void
+cv_destroy(kcondvar_t *cv)
+{
+ VERIFY(cond_destroy(cv) == 0);
+}
+
+void
+cv_wait(kcondvar_t *cv, kmutex_t *mp)
+{
+ ASSERT(mutex_owner(mp) == curthread);
+ mp->m_owner = NULL;
+ int ret = cond_wait(cv, &mp->m_lock);
+ VERIFY(ret == 0 || ret == EINTR);
+ mp->m_owner = curthread;
+}
+
+clock_t
+cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
+{
+ int error;
+ struct timespec ts;
+ struct timeval tv;
+ clock_t delta;
+
+ abstime += ddi_get_lbolt();
+top:
+ delta = abstime - ddi_get_lbolt();
+ if (delta <= 0)
+ return (-1);
+
+ if (gettimeofday(&tv, NULL) != 0)
+ assert(!"gettimeofday() failed");
+
+ ts.tv_sec = tv.tv_sec + delta / hz;
+ ts.tv_nsec = tv.tv_usec * 1000 + (delta % hz) * (NANOSEC / hz);
+ ASSERT(ts.tv_nsec >= 0);
+
+ if (ts.tv_nsec >= NANOSEC) {
+ ts.tv_sec++;
+ ts.tv_nsec -= NANOSEC;
+ }
+
+ ASSERT(mutex_owner(mp) == curthread);
+ mp->m_owner = NULL;
+ error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
+ mp->m_owner = curthread;
+
+ if (error == EINTR)
+ goto top;
+
+ if (error == ETIMEDOUT)
+ return (-1);
+
+ ASSERT(error == 0);
+
+ return (1);
+}
+
+void
+cv_signal(kcondvar_t *cv)
+{
+ VERIFY(cond_signal(cv) == 0);
+}
+
+void
+cv_broadcast(kcondvar_t *cv)
+{
+ VERIFY(cond_broadcast(cv) == 0);
+}
+
+/*
+ * =========================================================================
+ * vnode operations
+ * =========================================================================
+ */
+/*
+ * Note: for the xxxat() versions of these functions, we assume that the
+ * starting vp is always rootdir (which is true for spa_directory.c, the only
+ * ZFS consumer of these interfaces). We assert this is true, and then emulate
+ * them by adding '/' in front of the path.
+ */
+
+/*ARGSUSED*/
+int
+vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
+{
+ int fd;
+ vnode_t *vp;
+ int old_umask;
+ char realpath[MAXPATHLEN];
+ struct stat64 st;
+
+ /*
+ * If we're accessing a real disk from userland, we need to use
+ * the character interface to avoid caching. This is particularly
+ * important if we're trying to look at a real in-kernel storage
+ * pool from userland, e.g. via zdb, because otherwise we won't
+ * see the changes occurring under the segmap cache.
+ * On the other hand, the stupid character device returns zero
+ * for its size. So -- gag -- we open the block device to get
+ * its size, and remember it for subsequent VOP_GETATTR().
+ */
+ if (strncmp(path, "/dev/", 5) == 0) {
+ char *dsk;
+ fd = open64(path, O_RDONLY);
+ if (fd == -1)
+ return (errno);
+ if (fstat64(fd, &st) == -1) {
+ close(fd);
+ return (errno);
+ }
+ close(fd);
+ (void) sprintf(realpath, "%s", path);
+ dsk = strstr(path, "/dsk/");
+ if (dsk != NULL)
+ (void) sprintf(realpath + (dsk - path) + 1, "r%s",
+ dsk + 1);
+ } else {
+ (void) sprintf(realpath, "%s", path);
+ if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
+ return (errno);
+ }
+
+ if (flags & FCREAT)
+ old_umask = umask(0);
+
+ /*
+ * The construct 'flags - FREAD' conveniently maps combinations of
+ * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
+ */
+ fd = open64(realpath, flags - FREAD, mode);
+
+ if (flags & FCREAT)
+ (void) umask(old_umask);
+
+ if (fd == -1)
+ return (errno);
+
+ if (fstat64(fd, &st) == -1) {
+ close(fd);
+ return (errno);
+ }
+
+ (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
+
+ vp->v_fd = fd;
+ vp->v_size = st.st_size;
+ vp->v_path = spa_strdup(path);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
+ int x3, vnode_t *startvp, int fd)
+{
+ char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
+ int ret;
+
+ ASSERT(startvp == rootdir);
+ (void) sprintf(realpath, "/%s", path);
+
+ /* fd ignored for now, need if want to simulate nbmand support */
+ ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
+
+ umem_free(realpath, strlen(path) + 2);
+
+ return (ret);
+}
+
+/*ARGSUSED*/
+int
+vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
+ int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
+{
+ ssize_t iolen, split;
+
+ if (uio == UIO_READ) {
+ iolen = pread64(vp->v_fd, addr, len, offset);
+ } else {
+ /*
+ * To simulate partial disk writes, we split writes into two
+ * system calls so that the process can be killed in between.
+ */
+ int sectors = len >> SPA_MINBLOCKSHIFT;
+ split = (sectors > 0 ? rand() % sectors : 0) <<
+ SPA_MINBLOCKSHIFT;
+ iolen = pwrite64(vp->v_fd, addr, split, offset);
+ iolen += pwrite64(vp->v_fd, (char *)addr + split,
+ len - split, offset + split);
+ }
+
+ if (iolen == -1)
+ return (errno);
+ if (residp)
+ *residp = len - iolen;
+ else if (iolen != len)
+ return (EIO);
+ return (0);
+}
+
+void
+vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
+{
+ close(vp->v_fd);
+ spa_strfree(vp->v_path);
+ umem_free(vp, sizeof (vnode_t));
+}
+
+/*
+ * At a minimum we need to update the size since vdev_reopen()
+ * will no longer call vn_openat().
+ */
+int
+fop_getattr(vnode_t *vp, vattr_t *vap)
+{
+ struct stat64 st;
+
+ if (fstat64(vp->v_fd, &st) == -1) {
+ close(vp->v_fd);
+ return (errno);
+ }
+
+ vap->va_size = st.st_size;
+ return (0);
+}
+
+#ifdef ZFS_DEBUG
+
+/*
+ * =========================================================================
+ * Figure out which debugging statements to print
+ * =========================================================================
+ */
+
+static char *dprintf_string;
+static int dprintf_print_all;
+
+int
+dprintf_find_string(const char *string)
+{
+ char *tmp_str = dprintf_string;
+ int len = strlen(string);
+
+ /*
+ * Find out if this is a string we want to print.
+ * String format: file1.c,function_name1,file2.c,file3.c
+ */
+
+ while (tmp_str != NULL) {
+ if (strncmp(tmp_str, string, len) == 0 &&
+ (tmp_str[len] == ',' || tmp_str[len] == '\0'))
+ return (1);
+ tmp_str = strchr(tmp_str, ',');
+ if (tmp_str != NULL)
+ tmp_str++; /* Get rid of , */
+ }
+ return (0);
+}
+
+void
+dprintf_setup(int *argc, char **argv)
+{
+ int i, j;
+
+ /*
+ * Debugging can be specified two ways: by setting the
+ * environment variable ZFS_DEBUG, or by including a
+ * "debug=..." argument on the command line. The command
+ * line setting overrides the environment variable.
+ */
+
+ for (i = 1; i < *argc; i++) {
+ int len = strlen("debug=");
+ /* First look for a command line argument */
+ if (strncmp("debug=", argv[i], len) == 0) {
+ dprintf_string = argv[i] + len;
+ /* Remove from args */
+ for (j = i; j < *argc; j++)
+ argv[j] = argv[j+1];
+ argv[j] = NULL;
+ (*argc)--;
+ }
+ }
+
+ if (dprintf_string == NULL) {
+ /* Look for ZFS_DEBUG environment variable */
+ dprintf_string = getenv("ZFS_DEBUG");
+ }
+
+ /*
+ * Are we just turning on all debugging?
+ */
+ if (dprintf_find_string("on"))
+ dprintf_print_all = 1;
+}
+
+/*
+ * =========================================================================
+ * debug printfs
+ * =========================================================================
+ */
+void
+__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
+{
+ const char *newfile;
+ va_list adx;
+
+ /*
+ * Get rid of annoying "../common/" prefix to filename.
+ */
+ newfile = strrchr(file, '/');
+ if (newfile != NULL) {
+ newfile = newfile + 1; /* Get rid of leading / */
+ } else {
+ newfile = file;
+ }
+
+ if (dprintf_print_all ||
+ dprintf_find_string(newfile) ||
+ dprintf_find_string(func)) {
+ /* Print out just the function name if requested */
+ flockfile(stdout);
+ if (dprintf_find_string("pid"))
+ (void) printf("%d ", getpid());
+ if (dprintf_find_string("tid"))
+ (void) printf("%u ", thr_self());
+#if 0
+ if (dprintf_find_string("cpu"))
+ (void) printf("%u ", getcpuid());
+#endif
+ if (dprintf_find_string("time"))
+ (void) printf("%llu ", gethrtime());
+ if (dprintf_find_string("long"))
+ (void) printf("%s, line %d: ", newfile, line);
+ (void) printf("%s: ", func);
+ va_start(adx, fmt);
+ (void) vprintf(fmt, adx);
+ va_end(adx);
+ funlockfile(stdout);
+ }
+}
+
+#endif /* ZFS_DEBUG */
+
+/*
+ * =========================================================================
+ * cmn_err() and panic()
+ * =========================================================================
+ */
+static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
+static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
+
+void
+vpanic(const char *fmt, va_list adx)
+{
+ (void) fprintf(stderr, "error: ");
+ (void) vfprintf(stderr, fmt, adx);
+ (void) fprintf(stderr, "\n");
+
+ abort(); /* think of it as a "user-level crash dump" */
+}
+
+void
+panic(const char *fmt, ...)
+{
+ va_list adx;
+
+ va_start(adx, fmt);
+ vpanic(fmt, adx);
+ va_end(adx);
+}
+
+void
+vcmn_err(int ce, const char *fmt, va_list adx)
+{
+ if (ce == CE_PANIC)
+ vpanic(fmt, adx);
+ if (ce != CE_NOTE) { /* suppress noise in userland stress testing */
+ (void) fprintf(stderr, "%s", ce_prefix[ce]);
+ (void) vfprintf(stderr, fmt, adx);
+ (void) fprintf(stderr, "%s", ce_suffix[ce]);
+ }
+}
+
+/*PRINTFLIKE2*/
+void
+cmn_err(int ce, const char *fmt, ...)
+{
+ va_list adx;
+
+ va_start(adx, fmt);
+ vcmn_err(ce, fmt, adx);
+ va_end(adx);
+}
+
+/*
+ * =========================================================================
+ * kobj interfaces
+ * =========================================================================
+ */
+struct _buf *
+kobj_open_file(char *name)
+{
+ struct _buf *file;
+ vnode_t *vp;
+
+ /* set vp as the _fd field of the file */
+ if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
+ -1) != 0)
+ return ((void *)-1UL);
+
+ file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
+ file->_fd = (intptr_t)vp;
+ return (file);
+}
+
+int
+kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
+{
+ ssize_t resid;
+
+ vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
+ UIO_SYSSPACE, 0, 0, 0, &resid);
+
+ return (size - resid);
+}
+
+void
+kobj_close_file(struct _buf *file)
+{
+ vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
+ umem_free(file, sizeof (struct _buf));
+}
+
+int
+kobj_get_filesize(struct _buf *file, uint64_t *size)
+{
+ struct stat64 st;
+ vnode_t *vp = (vnode_t *)file->_fd;
+
+ if (fstat64(vp->v_fd, &st) == -1) {
+ vn_close(vp, 0, NULL, NULL);
+ return (errno);
+ }
+ *size = st.st_size;
+ return (0);
+}
+
+/*
+ * =========================================================================
+ * misc routines
+ * =========================================================================
+ */
+
+void
+delay(clock_t ticks)
+{
+ poll(0, 0, ticks * (1000 / hz));
+}
+
+#if 0
+/*
+ * Find highest one bit set.
+ * Returns bit number + 1 of highest bit that is set, otherwise returns 0.
+ * High order bit is 31 (or 63 in _LP64 kernel).
+ */
+int
+highbit(ulong_t i)
+{
+ register int h = 1;
+
+ if (i == 0)
+ return (0);
+#ifdef _LP64
+ if (i & 0xffffffff00000000ul) {
+ h += 32; i >>= 32;
+ }
+#endif
+ if (i & 0xffff0000) {
+ h += 16; i >>= 16;
+ }
+ if (i & 0xff00) {
+ h += 8; i >>= 8;
+ }
+ if (i & 0xf0) {
+ h += 4; i >>= 4;
+ }
+ if (i & 0xc) {
+ h += 2; i >>= 2;
+ }
+ if (i & 0x2) {
+ h += 1;
+ }
+ return (h);
+}
+#endif
+
+static int random_fd = -1, urandom_fd = -1;
+
+static int
+random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
+{
+ size_t resid = len;
+ ssize_t bytes;
+
+ ASSERT(fd != -1);
+
+ while (resid != 0) {
+ bytes = read(fd, ptr, resid);
+ ASSERT3S(bytes, >=, 0);
+ ptr += bytes;
+ resid -= bytes;
+ }
+
+ return (0);
+}
+
+int
+random_get_bytes(uint8_t *ptr, size_t len)
+{
+ return (random_get_bytes_common(ptr, len, random_fd));
+}
+
+int
+random_get_pseudo_bytes(uint8_t *ptr, size_t len)
+{
+ return (random_get_bytes_common(ptr, len, urandom_fd));
+}
+
+int
+ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
+{
+ char *end;
+
+ *result = strtoul(hw_serial, &end, base);
+ if (*result == 0)
+ return (errno);
+ return (0);
+}
+
+int
+ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
+{
+ char *end;
+
+ *result = strtoull(str, &end, base);
+ if (*result == 0)
+ return (errno);
+ return (0);
+}
+
+#ifdef illumos
+/* ARGSUSED */
+cyclic_id_t
+cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
+{
+ return (1);
+}
+
+/* ARGSUSED */
+void
+cyclic_remove(cyclic_id_t id)
+{
+}
+
+/* ARGSUSED */
+int
+cyclic_reprogram(cyclic_id_t id, hrtime_t expiration)
+{
+ return (1);
+}
+#endif
+
+/*
+ * =========================================================================
+ * kernel emulation setup & teardown
+ * =========================================================================
+ */
+static int
+umem_out_of_memory(void)
+{
+ char errmsg[] = "out of memory -- generating core dump\n";
+
+ write(fileno(stderr), errmsg, sizeof (errmsg));
+ abort();
+ return (0);
+}
+
+void
+kernel_init(int mode)
+{
+ extern uint_t rrw_tsd_key;
+
+ umem_nofail_callback(umem_out_of_memory);
+
+ physmem = sysconf(_SC_PHYS_PAGES);
+
+ dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
+ (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
+
+ (void) snprintf(hw_serial, sizeof (hw_serial), "%lu",
+ (mode & FWRITE) ? (unsigned long)gethostid() : 0);
+
+ VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
+ VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
+
+ system_taskq_init();
+
+#ifdef illumos
+ mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
+#endif
+
+ spa_init(mode);
+
+ tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
+}
+
+void
+kernel_fini(void)
+{
+ spa_fini();
+
+ system_taskq_fini();
+
+ close(random_fd);
+ close(urandom_fd);
+
+ random_fd = -1;
+ urandom_fd = -1;
+}
+
+int
+z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
+{
+ int ret;
+ uLongf len = *dstlen;
+
+ if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
+ *dstlen = (size_t)len;
+
+ return (ret);
+}
+
+int
+z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
+ int level)
+{
+ int ret;
+ uLongf len = *dstlen;
+
+ if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
+ *dstlen = (size_t)len;
+
+ return (ret);
+}
+
+uid_t
+crgetuid(cred_t *cr)
+{
+ return (0);
+}
+
+uid_t
+crgetruid(cred_t *cr)
+{
+ return (0);
+}
+
+gid_t
+crgetgid(cred_t *cr)
+{
+ return (0);
+}
+
+int
+crgetngroups(cred_t *cr)
+{
+ return (0);
+}
+
+gid_t *
+crgetgroups(cred_t *cr)
+{
+ return (NULL);
+}
+
+int
+zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
+{
+ return (0);
+}
+
+int
+zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
+{
+ return (0);
+}
+
+int
+zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
+{
+ return (0);
+}
+
+ksiddomain_t *
+ksid_lookupdomain(const char *dom)
+{
+ ksiddomain_t *kd;
+
+ kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
+ kd->kd_name = spa_strdup(dom);
+ return (kd);
+}
+
+void
+ksiddomain_rele(ksiddomain_t *ksid)
+{
+ spa_strfree(ksid->kd_name);
+ umem_free(ksid, sizeof (ksiddomain_t));
+}
+
+/*
+ * Do not change the length of the returned string; it must be freed
+ * with strfree().
+ */
+char *
+kmem_asprintf(const char *fmt, ...)
+{
+ int size;
+ va_list adx;
+ char *buf;
+
+ va_start(adx, fmt);
+ size = vsnprintf(NULL, 0, fmt, adx) + 1;
+ va_end(adx);
+
+ buf = kmem_alloc(size, KM_SLEEP);
+
+ va_start(adx, fmt);
+ size = vsnprintf(buf, size, fmt, adx);
+ va_end(adx);
+
+ return (buf);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_fd_hold(int fd, minor_t *minorp)
+{
+ *minorp = 0;
+ return (0);
+}
+
+/* ARGSUSED */
+void
+zfs_onexit_fd_rele(int fd)
+{
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
+ uint64_t *action_handle)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
+{
+ return (0);
+}
+
+#ifdef __FreeBSD__
+/* ARGSUSED */
+int
+zvol_create_minors(const char *name)
+{
+ return (0);
+}
+#endif
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
new file mode 100644
index 0000000..f026fb3
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
@@ -0,0 +1,678 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_ZFS_CONTEXT_H
+#define _SYS_ZFS_CONTEXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _SYS_MUTEX_H
+#define _SYS_RWLOCK_H
+#define _SYS_CONDVAR_H
+#define _SYS_SYSTM_H
+#define _SYS_T_LOCK_H
+#define _SYS_VNODE_H
+#define _SYS_VFS_H
+#define _SYS_SUNDDI_H
+#define _SYS_CALLB_H
+#define _SYS_SCHED_H_
+
+#include <solaris.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <thread.h>
+#include <assert.h>
+#include <limits.h>
+#include <dirent.h>
+#include <time.h>
+#include <math.h>
+#include <umem.h>
+#include <inttypes.h>
+#include <fsshare.h>
+#include <pthread.h>
+#include <sys/debug.h>
+#include <sys/note.h>
+#include <sys/types.h>
+#include <sys/cred.h>
+#include <sys/atomic.h>
+#include <sys/sysmacros.h>
+#include <sys/bitmap.h>
+#include <sys/resource.h>
+#include <sys/byteorder.h>
+#include <sys/list.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/zfs_debug.h>
+#include <sys/sdt.h>
+#include <sys/kstat.h>
+#include <sys/u8_textprep.h>
+#include <sys/kernel.h>
+#include <sys/disk.h>
+#include <sys/sysevent.h>
+#include <sys/sysevent/eventdefs.h>
+#include <sys/sysevent/dev.h>
+#include <machine/atomic.h>
+#include <sys/debug.h>
+
+#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
+
+/*
+ * Debugging
+ */
+
+/*
+ * Note that we are not using the debugging levels.
+ */
+
+#define CE_CONT 0 /* continuation */
+#define CE_NOTE 1 /* notice */
+#define CE_WARN 2 /* warning */
+#define CE_PANIC 3 /* panic */
+#define CE_IGNORE 4 /* print nothing */
+
+/*
+ * ZFS debugging
+ */
+
+#define ZFS_LOG(...) do { } while (0)
+
+typedef u_longlong_t rlim64_t;
+#define RLIM64_INFINITY ((rlim64_t)-3)
+
+#ifdef ZFS_DEBUG
+extern void dprintf_setup(int *argc, char **argv);
+#endif /* ZFS_DEBUG */
+
+extern void cmn_err(int, const char *, ...);
+extern void vcmn_err(int, const char *, __va_list);
+extern void panic(const char *, ...);
+extern void vpanic(const char *, __va_list);
+
+#define fm_panic panic
+
+extern int aok;
+
+/*
+ * DTrace SDT probes have different signatures in userland than they do in
+ * kernel. If they're being used in kernel code, re-define them out of
+ * existence for their counterparts in libzpool.
+ */
+
+#ifdef DTRACE_PROBE
+#undef DTRACE_PROBE
+#define DTRACE_PROBE(a) ((void)0)
+#endif /* DTRACE_PROBE */
+
+#ifdef DTRACE_PROBE1
+#undef DTRACE_PROBE1
+#define DTRACE_PROBE1(a, b, c) ((void)0)
+#endif /* DTRACE_PROBE1 */
+
+#ifdef DTRACE_PROBE2
+#undef DTRACE_PROBE2
+#define DTRACE_PROBE2(a, b, c, d, e) ((void)0)
+#endif /* DTRACE_PROBE2 */
+
+#ifdef DTRACE_PROBE3
+#undef DTRACE_PROBE3
+#define DTRACE_PROBE3(a, b, c, d, e, f, g) ((void)0)
+#endif /* DTRACE_PROBE3 */
+
+#ifdef DTRACE_PROBE4
+#undef DTRACE_PROBE4
+#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) ((void)0)
+#endif /* DTRACE_PROBE4 */
+
+/*
+ * Threads
+ */
+#define curthread ((void *)(uintptr_t)thr_self())
+
+typedef struct kthread kthread_t;
+
+#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
+ zk_thread_create(func, arg)
+#define thread_exit() thr_exit(NULL)
+#define thread_join(t) panic("libzpool cannot join threads")
+
+#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
+
+/* in libzpool, p0 exists only to have its address taken */
+struct proc {
+ uintptr_t this_is_never_used_dont_dereference_it;
+};
+
+extern struct proc p0;
+#define curproc (&p0)
+
+#define PS_NONE -1
+
+extern kthread_t *zk_thread_create(void (*func)(), void *arg);
+
+#define issig(why) (FALSE)
+#define ISSIG(thr, why) (FALSE)
+
+/*
+ * Mutexes
+ */
+typedef struct kmutex {
+ void *m_owner;
+ boolean_t initialized;
+ mutex_t m_lock;
+} kmutex_t;
+
+#define MUTEX_DEFAULT USYNC_THREAD
+#undef MUTEX_HELD
+#undef MUTEX_NOT_HELD
+#define MUTEX_HELD(m) ((m)->m_owner == curthread)
+#define MUTEX_NOT_HELD(m) (!MUTEX_HELD(m))
+#define _mutex_held(m) pthread_mutex_isowned_np(m)
+
+/*
+ * Argh -- we have to get cheesy here because the kernel and userland
+ * have different signatures for the same routine.
+ */
+//extern int _mutex_init(mutex_t *mp, int type, void *arg);
+//extern int _mutex_destroy(mutex_t *mp);
+//extern int _mutex_owned(mutex_t *mp);
+
+#define mutex_init(mp, b, c, d) zmutex_init((kmutex_t *)(mp))
+#define mutex_destroy(mp) zmutex_destroy((kmutex_t *)(mp))
+#define mutex_owned(mp) zmutex_owned((kmutex_t *)(mp))
+
+extern void zmutex_init(kmutex_t *mp);
+extern void zmutex_destroy(kmutex_t *mp);
+extern int zmutex_owned(kmutex_t *mp);
+extern void mutex_enter(kmutex_t *mp);
+extern void mutex_exit(kmutex_t *mp);
+extern int mutex_tryenter(kmutex_t *mp);
+extern void *mutex_owner(kmutex_t *mp);
+
+/*
+ * RW locks
+ */
+typedef struct krwlock {
+ int rw_count;
+ void *rw_owner;
+ boolean_t initialized;
+ rwlock_t rw_lock;
+} krwlock_t;
+
+typedef int krw_t;
+
+#define RW_READER 0
+#define RW_WRITER 1
+#define RW_DEFAULT USYNC_THREAD
+
+#undef RW_READ_HELD
+#define RW_READ_HELD(x) ((x)->rw_owner == NULL && (x)->rw_count > 0)
+
+#undef RW_WRITE_HELD
+#define RW_WRITE_HELD(x) ((x)->rw_owner == curthread)
+#define RW_LOCK_HELD(x) rw_lock_held(x)
+
+#undef RW_LOCK_HELD
+#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x))
+
+extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
+extern void rw_destroy(krwlock_t *rwlp);
+extern void rw_enter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
+extern int rw_tryupgrade(krwlock_t *rwlp);
+extern void rw_exit(krwlock_t *rwlp);
+extern int rw_lock_held(krwlock_t *rwlp);
+#define rw_downgrade(rwlp) do { } while (0)
+
+extern uid_t crgetuid(cred_t *cr);
+extern uid_t crgetruid(cred_t *cr);
+extern gid_t crgetgid(cred_t *cr);
+extern int crgetngroups(cred_t *cr);
+extern gid_t *crgetgroups(cred_t *cr);
+
+/*
+ * Condition variables
+ */
+typedef cond_t kcondvar_t;
+
+#define CV_DEFAULT USYNC_THREAD
+
+extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
+extern void cv_destroy(kcondvar_t *cv);
+extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
+extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
+extern void cv_signal(kcondvar_t *cv);
+extern void cv_broadcast(kcondvar_t *cv);
+
+/*
+ * Thread-specific data
+ */
+#define tsd_get(k) pthread_getspecific(k)
+#define tsd_set(k, v) pthread_setspecific(k, v)
+#define tsd_create(kp, d) pthread_key_create(kp, d)
+#define tsd_destroy(kp) /* nothing */
+
+/*
+ * Kernel memory
+ */
+#define KM_SLEEP UMEM_NOFAIL
+#define KM_PUSHPAGE KM_SLEEP
+#define KM_NOSLEEP UMEM_DEFAULT
+#define KMC_NODEBUG UMC_NODEBUG
+#define KMC_NOTOUCH 0 /* not needed for userland caches */
+#define KM_NODEBUG 0
+#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
+#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
+#define kmem_free(_b, _s) umem_free(_b, _s)
+#define kmem_size() (physmem * PAGESIZE)
+#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
+ umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
+#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
+#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
+#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
+#define kmem_debugging() 0
+#define kmem_cache_reap_now(_c) /* nothing */
+#define kmem_cache_set_move(_c, _cb) /* nothing */
+#define POINTER_INVALIDATE(_pp) /* nothing */
+#define POINTER_IS_VALID(_p) 0
+
+typedef umem_cache_t kmem_cache_t;
+
+typedef enum kmem_cbrc {
+ KMEM_CBRC_YES,
+ KMEM_CBRC_NO,
+ KMEM_CBRC_LATER,
+ KMEM_CBRC_DONT_NEED,
+ KMEM_CBRC_DONT_KNOW
+} kmem_cbrc_t;
+
+/*
+ * Task queues
+ */
+typedef struct taskq taskq_t;
+typedef uintptr_t taskqid_t;
+typedef void (task_func_t)(void *);
+
+#define TASKQ_PREPOPULATE 0x0001
+#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
+#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
+#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
+#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
+
+#define TQ_SLEEP KM_SLEEP /* Can block for memory */
+#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
+#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
+#define TQ_FRONT 0x08 /* Queue in front */
+
+extern taskq_t *system_taskq;
+
+extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
+#define taskq_create_proc(a, b, c, d, e, p, f) \
+ (taskq_create(a, b, c, d, e, f))
+#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
+ (taskq_create(a, b, maxclsyspri, d, e, f))
+extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
+extern void taskq_destroy(taskq_t *);
+extern void taskq_wait(taskq_t *);
+extern int taskq_member(taskq_t *, void *);
+extern void system_taskq_init(void);
+extern void system_taskq_fini(void);
+
+#define taskq_dispatch_safe(tq, func, arg, flags, task) \
+ taskq_dispatch((tq), (func), (arg), (flags))
+
+#define XVA_MAPSIZE 3
+#define XVA_MAGIC 0x78766174
+
+/*
+ * vnodes
+ */
+typedef struct vnode {
+ uint64_t v_size;
+ int v_fd;
+ char *v_path;
+} vnode_t;
+
+#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */
+
+typedef struct xoptattr {
+ timestruc_t xoa_createtime; /* Create time of file */
+ uint8_t xoa_archive;
+ uint8_t xoa_system;
+ uint8_t xoa_readonly;
+ uint8_t xoa_hidden;
+ uint8_t xoa_nounlink;
+ uint8_t xoa_immutable;
+ uint8_t xoa_appendonly;
+ uint8_t xoa_nodump;
+ uint8_t xoa_settable;
+ uint8_t xoa_opaque;
+ uint8_t xoa_av_quarantined;
+ uint8_t xoa_av_modified;
+ uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ];
+ uint8_t xoa_reparse;
+ uint8_t xoa_offline;
+ uint8_t xoa_sparse;
+} xoptattr_t;
+
+typedef struct vattr {
+ uint_t va_mask; /* bit-mask of attributes */
+ u_offset_t va_size; /* file size in bytes */
+} vattr_t;
+
+
+typedef struct xvattr {
+ vattr_t xva_vattr; /* Embedded vattr structure */
+ uint32_t xva_magic; /* Magic Number */
+ uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
+ uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
+ uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
+ uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
+ xoptattr_t xva_xoptattrs; /* Optional attributes */
+} xvattr_t;
+
+typedef struct vsecattr {
+ uint_t vsa_mask; /* See below */
+ int vsa_aclcnt; /* ACL entry count */
+ void *vsa_aclentp; /* pointer to ACL entries */
+ int vsa_dfaclcnt; /* default ACL entry count */
+ void *vsa_dfaclentp; /* pointer to default ACL entries */
+ size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
+} vsecattr_t;
+
+#define AT_TYPE 0x00001
+#define AT_MODE 0x00002
+#define AT_UID 0x00004
+#define AT_GID 0x00008
+#define AT_FSID 0x00010
+#define AT_NODEID 0x00020
+#define AT_NLINK 0x00040
+#define AT_SIZE 0x00080
+#define AT_ATIME 0x00100
+#define AT_MTIME 0x00200
+#define AT_CTIME 0x00400
+#define AT_RDEV 0x00800
+#define AT_BLKSIZE 0x01000
+#define AT_NBLOCKS 0x02000
+#define AT_SEQ 0x08000
+#define AT_XVATTR 0x10000
+
+#define CRCREAT 0
+
+extern int fop_getattr(vnode_t *vp, vattr_t *vap);
+
+#define VOP_CLOSE(vp, f, c, o, cr, ct) 0
+#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0
+#define VOP_GETATTR(vp, vap, cr) fop_getattr((vp), (vap));
+
+#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd)
+
+#define VN_RELE(vp) vn_close(vp, 0, NULL, NULL)
+#define VN_RELE_ASYNC(vp, taskq) vn_close(vp, 0, NULL, NULL)
+
+#define vn_lock(vp, type)
+#define VOP_UNLOCK(vp, type)
+
+extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
+ int x2, int x3);
+extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
+ int x2, int x3, vnode_t *vp, int fd);
+extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
+ offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
+extern void vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td);
+
+#define vn_remove(path, x1, x2) remove(path)
+#define vn_rename(from, to, seg) rename((from), (to))
+#define vn_is_readonly(vp) B_FALSE
+
+extern vnode_t *rootdir;
+
+#include <sys/file.h> /* for FREAD, FWRITE, etc */
+#define FTRUNC O_TRUNC
+
+/*
+ * Random stuff
+ */
+#define ddi_get_lbolt() (gethrtime() >> 23)
+#define ddi_get_lbolt64() (gethrtime() >> 23)
+#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
+
+extern void delay(clock_t ticks);
+
+#define SEC_TO_TICK(sec) ((sec) * hz)
+#define NSEC_TO_TICK(usec) ((usec) / (NANOSEC / hz))
+
+#define gethrestime_sec() time(NULL)
+#define gethrestime(t) \
+ do {\
+ (t)->tv_sec = gethrestime_sec();\
+ (t)->tv_nsec = 0;\
+ } while (0);
+
+#define max_ncpus 64
+
+#define minclsyspri 60
+#define maxclsyspri 99
+
+#define CPU_SEQID (thr_self() & (max_ncpus - 1))
+
+#define kcred NULL
+#define CRED() NULL
+
+#ifndef ptob
+#define ptob(x) ((x) * PAGESIZE)
+#endif
+
+extern uint64_t physmem;
+
+extern int highbit(ulong_t i);
+extern int random_get_bytes(uint8_t *ptr, size_t len);
+extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
+
+extern void kernel_init(int);
+extern void kernel_fini(void);
+
+struct spa;
+extern void nicenum(uint64_t num, char *buf);
+extern void show_pool_stats(struct spa *);
+
+typedef struct callb_cpr {
+ kmutex_t *cc_lockp;
+} callb_cpr_t;
+
+#define CALLB_CPR_INIT(cp, lockp, func, name) { \
+ (cp)->cc_lockp = lockp; \
+}
+
+#define CALLB_CPR_SAFE_BEGIN(cp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+}
+
+#define CALLB_CPR_SAFE_END(cp, lockp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+}
+
+#define CALLB_CPR_EXIT(cp) { \
+ ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
+ mutex_exit((cp)->cc_lockp); \
+}
+
+#define zone_dataset_visible(x, y) (1)
+#define INGLOBALZONE(z) (1)
+
+extern char *kmem_asprintf(const char *fmt, ...);
+#define strfree(str) kmem_free((str), strlen(str) + 1)
+
+/*
+ * Hostname information
+ */
+extern struct utsname utsname;
+extern char hw_serial[]; /* for userland-emulated hostid access */
+extern int ddi_strtoul(const char *str, char **nptr, int base,
+ unsigned long *result);
+
+extern int ddi_strtoull(const char *str, char **nptr, int base,
+ u_longlong_t *result);
+
+/* ZFS Boot Related stuff. */
+
+struct _buf {
+ intptr_t _fd;
+};
+
+struct bootstat {
+ uint64_t st_size;
+};
+
+typedef struct ace_object {
+ uid_t a_who;
+ uint32_t a_access_mask;
+ uint16_t a_flags;
+ uint16_t a_type;
+ uint8_t a_obj_type[16];
+ uint8_t a_inherit_obj_type[16];
+} ace_object_t;
+
+
+#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
+#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
+#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
+#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
+
+extern struct _buf *kobj_open_file(char *name);
+extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
+ unsigned off);
+extern void kobj_close_file(struct _buf *file);
+extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
+extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
+extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
+ cred_t *cr);
+extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
+extern zoneid_t getzoneid(void);
+/* Random compatibility stuff. */
+#define lbolt (gethrtime() >> 23)
+#define lbolt64 (gethrtime() >> 23)
+
+extern uint64_t physmem;
+
+#define gethrestime_sec() time(NULL)
+
+#define pwrite64(d, p, n, o) pwrite(d, p, n, o)
+#define readdir64(d) readdir(d)
+#define SIGPENDING(td) (0)
+#define root_mount_wait() do { } while (0)
+#define root_mounted() (1)
+
+struct file {
+ void *dummy;
+};
+
+#define FCREAT O_CREAT
+#define FOFFMAX 0x0
+
+/* SID stuff */
+typedef struct ksiddomain {
+ uint_t kd_ref;
+ uint_t kd_len;
+ char *kd_name;
+} ksiddomain_t;
+
+ksiddomain_t *ksid_lookupdomain(const char *);
+void ksiddomain_rele(ksiddomain_t *);
+
+typedef uint32_t idmap_rid_t;
+
+#define DDI_SLEEP KM_SLEEP
+#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) (0)
+
+#define SX_SYSINIT(name, lock, desc)
+
+#define SYSCTL_DECL(...)
+#define SYSCTL_NODE(...)
+#define SYSCTL_INT(...)
+#define SYSCTL_UINT(...)
+#define SYSCTL_ULONG(...)
+#define SYSCTL_QUAD(...)
+#define SYSCTL_UQUAD(...)
+#ifdef TUNABLE_INT
+#undef TUNABLE_INT
+#undef TUNABLE_ULONG
+#undef TUNABLE_QUAD
+#endif
+#define TUNABLE_INT(...)
+#define TUNABLE_ULONG(...)
+#define TUNABLE_QUAD(...)
+
+/* Errors */
+
+#ifndef ERESTART
+#define ERESTART (-1)
+#endif
+
+#ifdef illumos
+/*
+ * Cyclic information
+ */
+extern kmutex_t cpu_lock;
+
+typedef uintptr_t cyclic_id_t;
+typedef uint16_t cyc_level_t;
+typedef void (*cyc_func_t)(void *);
+
+#define CY_LOW_LEVEL 0
+#define CY_INFINITY INT64_MAX
+#define CYCLIC_NONE ((cyclic_id_t)0)
+
+typedef struct cyc_time {
+ hrtime_t cyt_when;
+ hrtime_t cyt_interval;
+} cyc_time_t;
+
+typedef struct cyc_handler {
+ cyc_func_t cyh_func;
+ void *cyh_arg;
+ cyc_level_t cyh_level;
+} cyc_handler_t;
+
+extern cyclic_id_t cyclic_add(cyc_handler_t *, cyc_time_t *);
+extern void cyclic_remove(cyclic_id_t);
+extern int cyclic_reprogram(cyclic_id_t, hrtime_t);
+#endif /* illumos */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_ZFS_CONTEXT_H */
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c
new file mode 100644
index 0000000..c407bba
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c
@@ -0,0 +1,303 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/zfs_context.h>
+
+int taskq_now;
+taskq_t *system_taskq;
+
+typedef struct task {
+ struct task *task_next;
+ struct task *task_prev;
+ task_func_t *task_func;
+ void *task_arg;
+} task_t;
+
+#define TASKQ_ACTIVE 0x00010000
+
+struct taskq {
+ kmutex_t tq_lock;
+ krwlock_t tq_threadlock;
+ kcondvar_t tq_dispatch_cv;
+ kcondvar_t tq_wait_cv;
+ thread_t *tq_threadlist;
+ int tq_flags;
+ int tq_active;
+ int tq_nthreads;
+ int tq_nalloc;
+ int tq_minalloc;
+ int tq_maxalloc;
+ kcondvar_t tq_maxalloc_cv;
+ int tq_maxalloc_wait;
+ task_t *tq_freelist;
+ task_t tq_task;
+};
+
+static task_t *
+task_alloc(taskq_t *tq, int tqflags)
+{
+ task_t *t;
+ int rv;
+
+again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
+ tq->tq_freelist = t->task_next;
+ } else {
+ if (tq->tq_nalloc >= tq->tq_maxalloc) {
+ if (!(tqflags & KM_SLEEP))
+ return (NULL);
+
+ /*
+ * We don't want to exceed tq_maxalloc, but we can't
+ * wait for other tasks to complete (and thus free up
+ * task structures) without risking deadlock with
+ * the caller. So, we just delay for one second
+ * to throttle the allocation rate. If we have tasks
+ * complete before one second timeout expires then
+ * taskq_ent_free will signal us and we will
+ * immediately retry the allocation.
+ */
+ tq->tq_maxalloc_wait++;
+ rv = cv_timedwait(&tq->tq_maxalloc_cv,
+ &tq->tq_lock, ddi_get_lbolt() + hz);
+ tq->tq_maxalloc_wait--;
+ if (rv > 0)
+ goto again; /* signaled */
+ }
+ mutex_exit(&tq->tq_lock);
+
+ t = kmem_alloc(sizeof (task_t), tqflags & KM_SLEEP);
+
+ mutex_enter(&tq->tq_lock);
+ if (t != NULL)
+ tq->tq_nalloc++;
+ }
+ return (t);
+}
+
+static void
+task_free(taskq_t *tq, task_t *t)
+{
+ if (tq->tq_nalloc <= tq->tq_minalloc) {
+ t->task_next = tq->tq_freelist;
+ tq->tq_freelist = t;
+ } else {
+ tq->tq_nalloc--;
+ mutex_exit(&tq->tq_lock);
+ kmem_free(t, sizeof (task_t));
+ mutex_enter(&tq->tq_lock);
+ }
+
+ if (tq->tq_maxalloc_wait)
+ cv_signal(&tq->tq_maxalloc_cv);
+}
+
+taskqid_t
+taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
+{
+ task_t *t;
+
+ if (taskq_now) {
+ func(arg);
+ return (1);
+ }
+
+ mutex_enter(&tq->tq_lock);
+ ASSERT(tq->tq_flags & TASKQ_ACTIVE);
+ if ((t = task_alloc(tq, tqflags)) == NULL) {
+ mutex_exit(&tq->tq_lock);
+ return (0);
+ }
+ if (tqflags & TQ_FRONT) {
+ t->task_next = tq->tq_task.task_next;
+ t->task_prev = &tq->tq_task;
+ } else {
+ t->task_next = &tq->tq_task;
+ t->task_prev = tq->tq_task.task_prev;
+ }
+ t->task_next->task_prev = t;
+ t->task_prev->task_next = t;
+ t->task_func = func;
+ t->task_arg = arg;
+ cv_signal(&tq->tq_dispatch_cv);
+ mutex_exit(&tq->tq_lock);
+ return (1);
+}
+
+void
+taskq_wait(taskq_t *tq)
+{
+ mutex_enter(&tq->tq_lock);
+ while (tq->tq_task.task_next != &tq->tq_task || tq->tq_active != 0)
+ cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
+ mutex_exit(&tq->tq_lock);
+}
+
+static void *
+taskq_thread(void *arg)
+{
+ taskq_t *tq = arg;
+ task_t *t;
+
+ mutex_enter(&tq->tq_lock);
+ while (tq->tq_flags & TASKQ_ACTIVE) {
+ if ((t = tq->tq_task.task_next) == &tq->tq_task) {
+ if (--tq->tq_active == 0)
+ cv_broadcast(&tq->tq_wait_cv);
+ cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
+ tq->tq_active++;
+ continue;
+ }
+ t->task_prev->task_next = t->task_next;
+ t->task_next->task_prev = t->task_prev;
+ mutex_exit(&tq->tq_lock);
+
+ rw_enter(&tq->tq_threadlock, RW_READER);
+ t->task_func(t->task_arg);
+ rw_exit(&tq->tq_threadlock);
+
+ mutex_enter(&tq->tq_lock);
+ task_free(tq, t);
+ }
+ tq->tq_nthreads--;
+ cv_broadcast(&tq->tq_wait_cv);
+ mutex_exit(&tq->tq_lock);
+ return (NULL);
+}
+
+/*ARGSUSED*/
+taskq_t *
+taskq_create(const char *name, int nthreads, pri_t pri,
+ int minalloc, int maxalloc, uint_t flags)
+{
+ taskq_t *tq = kmem_zalloc(sizeof (taskq_t), KM_SLEEP);
+ int t;
+
+ if (flags & TASKQ_THREADS_CPU_PCT) {
+ int pct;
+ ASSERT3S(nthreads, >=, 0);
+ ASSERT3S(nthreads, <=, 100);
+ pct = MIN(nthreads, 100);
+ pct = MAX(pct, 0);
+
+ nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100;
+ nthreads = MAX(nthreads, 1); /* need at least 1 thread */
+ } else {
+ ASSERT3S(nthreads, >=, 1);
+ }
+
+ rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
+ mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
+ cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
+ cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL);
+ tq->tq_flags = flags | TASKQ_ACTIVE;
+ tq->tq_active = nthreads;
+ tq->tq_nthreads = nthreads;
+ tq->tq_minalloc = minalloc;
+ tq->tq_maxalloc = maxalloc;
+ tq->tq_task.task_next = &tq->tq_task;
+ tq->tq_task.task_prev = &tq->tq_task;
+ tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP);
+
+ if (flags & TASKQ_PREPOPULATE) {
+ mutex_enter(&tq->tq_lock);
+ while (minalloc-- > 0)
+ task_free(tq, task_alloc(tq, KM_SLEEP));
+ mutex_exit(&tq->tq_lock);
+ }
+
+ for (t = 0; t < nthreads; t++)
+ (void) thr_create(0, 0, taskq_thread,
+ tq, THR_BOUND, &tq->tq_threadlist[t]);
+
+ return (tq);
+}
+
+void
+taskq_destroy(taskq_t *tq)
+{
+ int t;
+ int nthreads = tq->tq_nthreads;
+
+ taskq_wait(tq);
+
+ mutex_enter(&tq->tq_lock);
+
+ tq->tq_flags &= ~TASKQ_ACTIVE;
+ cv_broadcast(&tq->tq_dispatch_cv);
+
+ while (tq->tq_nthreads != 0)
+ cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
+
+ tq->tq_minalloc = 0;
+ while (tq->tq_nalloc != 0) {
+ ASSERT(tq->tq_freelist != NULL);
+ task_free(tq, task_alloc(tq, KM_SLEEP));
+ }
+
+ mutex_exit(&tq->tq_lock);
+
+ for (t = 0; t < nthreads; t++)
+ (void) thr_join(tq->tq_threadlist[t], NULL, NULL);
+
+ kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
+
+ rw_destroy(&tq->tq_threadlock);
+ mutex_destroy(&tq->tq_lock);
+ cv_destroy(&tq->tq_dispatch_cv);
+ cv_destroy(&tq->tq_wait_cv);
+ cv_destroy(&tq->tq_maxalloc_cv);
+
+ kmem_free(tq, sizeof (taskq_t));
+}
+
+int
+taskq_member(taskq_t *tq, void *t)
+{
+ int i;
+
+ if (taskq_now)
+ return (1);
+
+ for (i = 0; i < tq->tq_nthreads; i++)
+ if (tq->tq_threadlist[i] == (thread_t)(uintptr_t)t)
+ return (1);
+
+ return (0);
+}
+
+void
+system_taskq_init(void)
+{
+ system_taskq = taskq_create("system_taskq", 64, minclsyspri, 4, 512,
+ TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
+}
+
+void
+system_taskq_fini(void)
+{
+ taskq_destroy(system_taskq);
+ system_taskq = NULL; /* defensive */
+}
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/util.c b/cddl/contrib/opensolaris/lib/libzpool/common/util.c
new file mode 100644
index 0000000..9b99531
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/util.c
@@ -0,0 +1,155 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <assert.h>
+#include <sys/zfs_context.h>
+#include <sys/avl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/spa.h>
+#include <sys/fs/zfs.h>
+#include <sys/refcount.h>
+
+/*
+ * Routines needed by more than one client of libzpool.
+ */
+
+void
+nicenum(uint64_t num, char *buf)
+{
+ uint64_t n = num;
+ int index = 0;
+ char u;
+
+ while (n >= 1024) {
+ n = (n + (1024 / 2)) / 1024; /* Round up or down */
+ index++;
+ }
+
+ u = " KMGTPE"[index];
+
+ if (index == 0) {
+ (void) sprintf(buf, "%llu", (u_longlong_t)n);
+ } else if (n < 10 && (num & (num - 1)) != 0) {
+ (void) sprintf(buf, "%.2f%c",
+ (double)num / (1ULL << 10 * index), u);
+ } else if (n < 100 && (num & (num - 1)) != 0) {
+ (void) sprintf(buf, "%.1f%c",
+ (double)num / (1ULL << 10 * index), u);
+ } else {
+ (void) sprintf(buf, "%llu%c", (u_longlong_t)n, u);
+ }
+}
+
+static void
+show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
+{
+ vdev_stat_t *vs;
+ vdev_stat_t v0 = { 0 };
+ uint64_t sec;
+ uint64_t is_log = 0;
+ nvlist_t **child;
+ uint_t c, children;
+ char used[6], avail[6];
+ char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
+ char *prefix = "";
+
+ if (indent == 0 && desc != NULL) {
+ (void) printf(" "
+ " capacity operations bandwidth ---- errors ----\n");
+ (void) printf("description "
+ "used avail read write read write read write cksum\n");
+ }
+
+ if (desc != NULL) {
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
+
+ if (is_log)
+ prefix = "log ";
+
+ if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+ (uint64_t **)&vs, &c) != 0)
+ vs = &v0;
+
+ sec = MAX(1, vs->vs_timestamp / NANOSEC);
+
+ nicenum(vs->vs_alloc, used);
+ nicenum(vs->vs_space - vs->vs_alloc, avail);
+ nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
+ nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
+ nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
+ nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
+ nicenum(vs->vs_read_errors, rerr);
+ nicenum(vs->vs_write_errors, werr);
+ nicenum(vs->vs_checksum_errors, cerr);
+
+ (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
+ indent, "",
+ prefix,
+ indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12),
+ desc,
+ vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
+ vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
+ rops, wops, rbytes, wbytes, rerr, werr, cerr);
+ }
+
+ if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
+ return;
+
+ for (c = 0; c < children; c++) {
+ nvlist_t *cnv = child[c];
+ char *cname, *tname;
+ uint64_t np;
+ if (nvlist_lookup_string(cnv, ZPOOL_CONFIG_PATH, &cname) &&
+ nvlist_lookup_string(cnv, ZPOOL_CONFIG_TYPE, &cname))
+ cname = "<unknown>";
+ tname = calloc(1, strlen(cname) + 2);
+ (void) strcpy(tname, cname);
+ if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
+ tname[strlen(tname)] = '0' + np;
+ show_vdev_stats(tname, ctype, cnv, indent + 2);
+ free(tname);
+ }
+}
+
+void
+show_pool_stats(spa_t *spa)
+{
+ nvlist_t *config, *nvroot;
+ char *name;
+
+ VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
+
+ VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+ &nvroot) == 0);
+ VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &name) == 0);
+
+ show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
+ show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
+ show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
+
+ nvlist_free(config);
+}
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/__init__.py b/cddl/contrib/opensolaris/lib/pyzfs/common/__init__.py
new file mode 100644
index 0000000..76b0998
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/__init__.py
@@ -0,0 +1,27 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""
+package which provides an administrative interface to ZFS
+"""
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py b/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py
new file mode 100644
index 0000000..fa8209f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/allow.py
@@ -0,0 +1,396 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""This module implements the "zfs allow" and "zfs unallow" subcommands.
+The only public interface is the zfs.allow.do_allow() function."""
+
+import zfs.util
+import zfs.dataset
+import optparse
+import sys
+import pwd
+import grp
+import errno
+
+_ = zfs.util._
+
+class FSPerms(object):
+ """This class represents all the permissions that are set on a
+ particular filesystem (not including those inherited)."""
+
+ __slots__ = "create", "sets", "local", "descend", "ld"
+ __repr__ = zfs.util.default_repr
+
+ def __init__(self, raw):
+ """Create a FSPerms based on the dict of raw permissions
+ from zfs.ioctl.get_fsacl()."""
+ # set of perms
+ self.create = set()
+
+ # below are { "Ntype name": set(perms) }
+ # where N is a number that we just use for sorting,
+ # type is "user", "group", "everyone", or "" (for sets)
+ # name is a user, group, or set name, or "" (for everyone)
+ self.sets = dict()
+ self.local = dict()
+ self.descend = dict()
+ self.ld = dict()
+
+ # see the comment in dsl_deleg.c for the definition of whokey
+ for whokey in raw.keys():
+ perms = raw[whokey].keys()
+ whotypechr = whokey[0].lower()
+ ws = whokey[3:]
+ if whotypechr == "c":
+ self.create.update(perms)
+ elif whotypechr == "s":
+ nwho = "1" + ws
+ self.sets.setdefault(nwho, set()).update(perms)
+ else:
+ if whotypechr == "u":
+ try:
+ name = pwd.getpwuid(int(ws)).pw_name
+ except KeyError:
+ name = ws
+ nwho = "1user " + name
+ elif whotypechr == "g":
+ try:
+ name = grp.getgrgid(int(ws)).gr_name
+ except KeyError:
+ name = ws
+ nwho = "2group " + name
+ elif whotypechr == "e":
+ nwho = "3everyone"
+ else:
+ raise ValueError(whotypechr)
+
+ if whokey[1] == "l":
+ d = self.local
+ elif whokey[1] == "d":
+ d = self.descend
+ else:
+ raise ValueError(whokey[1])
+
+ d.setdefault(nwho, set()).update(perms)
+
+ # Find perms that are in both local and descend, and
+ # move them to ld.
+ for nwho in self.local:
+ if nwho not in self.descend:
+ continue
+ # note: these are set operations
+ self.ld[nwho] = self.local[nwho] & self.descend[nwho]
+ self.local[nwho] -= self.ld[nwho]
+ self.descend[nwho] -= self.ld[nwho]
+
+ @staticmethod
+ def __ldstr(d, header):
+ s = ""
+ for (nwho, perms) in sorted(d.items()):
+ # local and descend may have entries where perms
+ # is an empty set, due to consolidating all
+ # permissions into ld
+ if perms:
+ s += "\t%s %s\n" % \
+ (nwho[1:], ",".join(sorted(perms)))
+ if s:
+ s = header + s
+ return s
+
+ def __str__(self):
+ s = self.__ldstr(self.sets, _("Permission sets:\n"))
+
+ if self.create:
+ s += _("Create time permissions:\n")
+ s += "\t%s\n" % ",".join(sorted(self.create))
+
+ s += self.__ldstr(self.local, _("Local permissions:\n"))
+ s += self.__ldstr(self.descend, _("Descendent permissions:\n"))
+ s += self.__ldstr(self.ld, _("Local+Descendent permissions:\n"))
+ return s.rstrip()
+
+def args_to_perms(parser, options, who, perms):
+ """Return a dict of raw perms {"whostr" -> {"perm" -> None}}
+ based on the command-line input."""
+
+ # perms is not set if we are doing a "zfs unallow <who> <fs>" to
+ # remove all of someone's permissions
+ if perms:
+ setperms = dict(((p, None) for p in perms if p[0] == "@"))
+ baseperms = dict(((canonicalized_perm(p), None)
+ for p in perms if p[0] != "@"))
+ else:
+ setperms = None
+ baseperms = None
+
+ d = dict()
+
+ def storeperm(typechr, inheritchr, arg):
+ assert typechr in "ugecs"
+ assert inheritchr in "ld-"
+
+ def mkwhokey(t):
+ return "%c%c$%s" % (t, inheritchr, arg)
+
+ if baseperms or not perms:
+ d[mkwhokey(typechr)] = baseperms
+ if setperms or not perms:
+ d[mkwhokey(typechr.upper())] = setperms
+
+ def decodeid(w, toidfunc, fmt):
+ try:
+ return int(w)
+ except ValueError:
+ try:
+ return toidfunc(w)[2]
+ except KeyError:
+ parser.error(fmt % w)
+
+ if options.set:
+ storeperm("s", "-", who)
+ elif options.create:
+ storeperm("c", "-", "")
+ else:
+ for w in who:
+ if options.user:
+ id = decodeid(w, pwd.getpwnam,
+ _("invalid user %s"))
+ typechr = "u"
+ elif options.group:
+ id = decodeid(w, grp.getgrnam,
+ _("invalid group %s"))
+ typechr = "g"
+ elif w == "everyone":
+ id = ""
+ typechr = "e"
+ else:
+ try:
+ id = pwd.getpwnam(w)[2]
+ typechr = "u"
+ except KeyError:
+ try:
+ id = grp.getgrnam(w)[2]
+ typechr = "g"
+ except KeyError:
+ parser.error(_("invalid user/group %s") % w)
+ if options.local:
+ storeperm(typechr, "l", id)
+ if options.descend:
+ storeperm(typechr, "d", id)
+ return d
+
+perms_subcmd = dict(
+ create=_("Must also have the 'mount' ability"),
+ destroy=_("Must also have the 'mount' ability"),
+ snapshot="",
+ rollback="",
+ clone=_("""Must also have the 'create' ability and 'mount'
+\t\t\t\tability in the origin file system"""),
+ promote=_("""Must also have the 'mount'
+\t\t\t\tand 'promote' ability in the origin file system"""),
+ rename=_("""Must also have the 'mount' and 'create'
+\t\t\t\tability in the new parent"""),
+ receive=_("Must also have the 'mount' and 'create' ability"),
+ allow=_("Must also have the permission that is being\n\t\t\t\tallowed"),
+ mount=_("Allows mount/umount of ZFS datasets"),
+ share=_("Allows sharing file systems over NFS or SMB\n\t\t\t\tprotocols"),
+ send="",
+ hold=_("Allows adding a user hold to a snapshot"),
+ release=_("Allows releasing a user hold which\n\t\t\t\tmight destroy the snapshot"),
+ diff=_("Allows lookup of paths within a dataset,\n\t\t\t\tgiven an object number. Ordinary users need this\n\t\t\t\tin order to use zfs diff"),
+)
+
+perms_other = dict(
+ userprop=_("Allows changing any user property"),
+ userquota=_("Allows accessing any userquota@... property"),
+ groupquota=_("Allows accessing any groupquota@... property"),
+ userused=_("Allows reading any userused@... property"),
+ groupused=_("Allows reading any groupused@... property"),
+)
+
+def hasset(ds, setname):
+ """Return True if the given setname (string) is defined for this
+ ds (Dataset)."""
+ # It would be nice to cache the result of get_fsacl().
+ for raw in ds.get_fsacl().values():
+ for whokey in raw.keys():
+ if whokey[0].lower() == "s" and whokey[3:] == setname:
+ return True
+ return False
+
+def canonicalized_perm(permname):
+ """Return the canonical name (string) for this permission (string).
+ Raises ZFSError if it is not a valid permission."""
+ if permname in perms_subcmd.keys() or permname in perms_other.keys():
+ return permname
+ try:
+ return zfs.dataset.getpropobj(permname).name
+ except KeyError:
+ raise zfs.util.ZFSError(errno.EINVAL, permname,
+ _("invalid permission"))
+
+def print_perms():
+ """Print the set of supported permissions."""
+ print(_("\nThe following permissions are supported:\n"))
+ fmt = "%-16s %-14s\t%s"
+ print(fmt % (_("NAME"), _("TYPE"), _("NOTES")))
+
+ for (name, note) in sorted(perms_subcmd.iteritems()):
+ print(fmt % (name, _("subcommand"), note))
+
+ for (name, note) in sorted(perms_other.iteritems()):
+ print(fmt % (name, _("other"), note))
+
+ for (name, prop) in sorted(zfs.dataset.proptable.iteritems()):
+ if prop.visible and prop.delegatable():
+ print(fmt % (name, _("property"), ""))
+
+def do_allow():
+ """Implements the "zfs allow" and "zfs unallow" subcommands."""
+ un = (sys.argv[1] == "unallow")
+
+ def usage(msg=None):
+ parser.print_help()
+ print_perms()
+ if msg:
+ print
+ parser.exit("zfs: error: " + msg)
+ else:
+ parser.exit()
+
+ if un:
+ u = _("""unallow [-rldug] <"everyone"|user|group>[,...]
+ [<perm|@setname>[,...]] <filesystem|volume>
+ unallow [-rld] -e [<perm|@setname>[,...]] <filesystem|volume>
+ unallow [-r] -c [<perm|@setname>[,...]] <filesystem|volume>
+ unallow [-r] -s @setname [<perm|@setname>[,...]] <filesystem|volume>""")
+ verb = _("remove")
+ sstr = _("undefine permission set")
+ else:
+ u = _("""allow <filesystem|volume>
+ allow [-ldug] <"everyone"|user|group>[,...] <perm|@setname>[,...]
+ <filesystem|volume>
+ allow [-ld] -e <perm|@setname>[,...] <filesystem|volume>
+ allow -c <perm|@setname>[,...] <filesystem|volume>
+ allow -s @setname <perm|@setname>[,...] <filesystem|volume>""")
+ verb = _("set")
+ sstr = _("define permission set")
+
+ parser = optparse.OptionParser(usage=u, prog="zfs")
+
+ parser.add_option("-l", action="store_true", dest="local",
+ help=_("%s permission locally") % verb)
+ parser.add_option("-d", action="store_true", dest="descend",
+ help=_("%s permission for descendents") % verb)
+ parser.add_option("-u", action="store_true", dest="user",
+ help=_("%s permission for user") % verb)
+ parser.add_option("-g", action="store_true", dest="group",
+ help=_("%s permission for group") % verb)
+ parser.add_option("-e", action="store_true", dest="everyone",
+ help=_("%s permission for everyone") % verb)
+ parser.add_option("-c", action="store_true", dest="create",
+ help=_("%s create time permissions") % verb)
+ parser.add_option("-s", action="store_true", dest="set", help=sstr)
+ if un:
+ parser.add_option("-r", action="store_true", dest="recursive",
+ help=_("remove permissions recursively"))
+
+ if len(sys.argv) == 3 and not un:
+ # just print the permissions on this fs
+
+ if sys.argv[2] == "-h":
+ # hack to make "zfs allow -h" work
+ usage()
+ ds = zfs.dataset.Dataset(sys.argv[2], snaps=False)
+
+ p = dict()
+ for (fs, raw) in ds.get_fsacl().items():
+ p[fs] = FSPerms(raw)
+
+ for fs in sorted(p.keys(), reverse=True):
+ s = _("---- Permissions on %s ") % fs
+ print(s + "-" * (70-len(s)))
+ print(p[fs])
+ return
+
+
+ (options, args) = parser.parse_args(sys.argv[2:])
+
+ if sum((bool(options.everyone), bool(options.user),
+ bool(options.group))) > 1:
+ parser.error(_("-u, -g, and -e are mutually exclusive"))
+
+ def mungeargs(expected_len):
+ if un and len(args) == expected_len-1:
+ return (None, args[expected_len-2])
+ elif len(args) == expected_len:
+ return (args[expected_len-2].split(","),
+ args[expected_len-1])
+ else:
+ usage(_("wrong number of parameters"))
+
+ if options.set:
+ if options.local or options.descend or options.user or \
+ options.group or options.everyone or options.create:
+ parser.error(_("invalid option combined with -s"))
+ if args[0][0] != "@":
+ parser.error(_("invalid set name: missing '@' prefix"))
+
+ (perms, fsname) = mungeargs(3)
+ who = args[0]
+ elif options.create:
+ if options.local or options.descend or options.user or \
+ options.group or options.everyone or options.set:
+ parser.error(_("invalid option combined with -c"))
+
+ (perms, fsname) = mungeargs(2)
+ who = None
+ elif options.everyone:
+ if options.user or options.group or \
+ options.create or options.set:
+ parser.error(_("invalid option combined with -e"))
+
+ (perms, fsname) = mungeargs(2)
+ who = ["everyone"]
+ else:
+ (perms, fsname) = mungeargs(3)
+ who = args[0].split(",")
+
+ if not options.local and not options.descend:
+ options.local = True
+ options.descend = True
+
+ d = args_to_perms(parser, options, who, perms)
+
+ ds = zfs.dataset.Dataset(fsname, snaps=False)
+
+ if not un and perms:
+ for p in perms:
+ if p[0] == "@" and not hasset(ds, p):
+ parser.error(_("set %s is not defined") % p)
+
+ ds.set_fsacl(un, d)
+ if un and options.recursive:
+ for child in ds.descendents():
+ child.set_fsacl(un, d)
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/dataset.py b/cddl/contrib/opensolaris/lib/pyzfs/common/dataset.py
new file mode 100644
index 0000000..26192e4
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/dataset.py
@@ -0,0 +1,234 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""Implements the Dataset class, providing methods for manipulating ZFS
+datasets. Also implements the Property class, which describes ZFS
+properties."""
+
+import zfs.ioctl
+import zfs.util
+import errno
+
+_ = zfs.util._
+
+class Property(object):
+ """This class represents a ZFS property. It contains
+ information about the property -- if it's readonly, a number vs
+ string vs index, etc. Only native properties are represented by
+ this class -- not user properties (eg "user:prop") or userspace
+ properties (eg "userquota@joe")."""
+
+ __slots__ = "name", "number", "type", "default", "attr", "validtypes", \
+ "values", "colname", "rightalign", "visible", "indextable"
+ __repr__ = zfs.util.default_repr
+
+ def __init__(self, t):
+ """t is the tuple of information about this property
+ from zfs.ioctl.get_proptable, which should match the
+ members of zprop_desc_t (see zfs_prop.h)."""
+
+ self.name = t[0]
+ self.number = t[1]
+ self.type = t[2]
+ if self.type == "string":
+ self.default = t[3]
+ else:
+ self.default = t[4]
+ self.attr = t[5]
+ self.validtypes = t[6]
+ self.values = t[7]
+ self.colname = t[8]
+ self.rightalign = t[9]
+ self.visible = t[10]
+ self.indextable = t[11]
+
+ def delegatable(self):
+ """Return True if this property can be delegated with
+ "zfs allow"."""
+ return self.attr != "readonly"
+
+proptable = dict()
+for name, t in zfs.ioctl.get_proptable().iteritems():
+ proptable[name] = Property(t)
+del name, t
+
+def getpropobj(name):
+ """Return the Property object that is identified by the given
+ name string. It can be the full name, or the column name."""
+ try:
+ return proptable[name]
+ except KeyError:
+ for p in proptable.itervalues():
+ if p.colname and p.colname.lower() == name:
+ return p
+ raise
+
+class Dataset(object):
+ """Represents a ZFS dataset (filesystem, snapshot, zvol, clone, etc).
+
+ Generally, this class provides interfaces to the C functions in
+ zfs.ioctl which actually interface with the kernel to manipulate
+ datasets.
+
+ Unless otherwise noted, any method can raise a ZFSError to
+ indicate failure."""
+
+ __slots__ = "name", "__props"
+ __repr__ = zfs.util.default_repr
+
+ def __init__(self, name, props=None,
+ types=("filesystem", "volume"), snaps=True):
+ """Open the named dataset, checking that it exists and
+ is of the specified type.
+
+ name is the string name of this dataset.
+
+ props is the property settings dict from zfs.ioctl.next_dataset.
+
+ types is an iterable of strings specifying which types
+ of datasets are permitted. Accepted strings are
+ "filesystem" and "volume". Defaults to accepting all
+ types.
+
+ snaps is a boolean specifying if snapshots are acceptable.
+
+ Raises a ZFSError if the dataset can't be accessed (eg
+ doesn't exist) or is not of the specified type.
+ """
+
+ self.name = name
+
+ e = zfs.util.ZFSError(errno.EINVAL,
+ _("cannot open %s") % name,
+ _("operation not applicable to datasets of this type"))
+ if "@" in name and not snaps:
+ raise e
+ if not props:
+ props = zfs.ioctl.dataset_props(name)
+ self.__props = props
+ if "volume" not in types and self.getprop("type") == 3:
+ raise e
+ if "filesystem" not in types and self.getprop("type") == 2:
+ raise e
+
+ def getprop(self, propname):
+ """Return the value of the given property for this dataset.
+
+ Currently only works for native properties (those with a
+ Property object.)
+
+ Raises KeyError if propname does not specify a native property.
+ Does not raise ZFSError.
+ """
+
+ p = getpropobj(propname)
+ try:
+ return self.__props[p.name]["value"]
+ except KeyError:
+ return p.default
+
+ def parent(self):
+ """Return a Dataset representing the parent of this one."""
+ return Dataset(self.name[:self.name.rindex("/")])
+
+ def descendents(self):
+ """A generator function which iterates over all
+ descendent Datasets (not including snapshots."""
+
+ cookie = 0
+ while True:
+ # next_dataset raises StopIteration when done
+ (name, cookie, props) = \
+ zfs.ioctl.next_dataset(self.name, False, cookie)
+ ds = Dataset(name, props)
+ yield ds
+ for child in ds.descendents():
+ yield child
+
+ def userspace(self, prop):
+ """A generator function which iterates over a
+ userspace-type property.
+
+ prop specifies which property ("userused@",
+ "userquota@", "groupused@", or "groupquota@").
+
+ returns 3-tuple of domain (string), rid (int), and space (int).
+ """
+
+ d = zfs.ioctl.userspace_many(self.name, prop)
+ for ((domain, rid), space) in d.iteritems():
+ yield (domain, rid, space)
+
+ def userspace_upgrade(self):
+ """Initialize the accounting information for
+ userused@... and groupused@... properties."""
+ return zfs.ioctl.userspace_upgrade(self.name)
+
+ def set_fsacl(self, un, d):
+ """Add to the "zfs allow"-ed permissions on this Dataset.
+
+ un is True if the specified permissions should be removed.
+
+ d is a dict specifying which permissions to add/remove:
+ { "whostr" -> None # remove all perms for this entity
+ "whostr" -> { "perm" -> None} # add/remove these perms
+ } """
+ return zfs.ioctl.set_fsacl(self.name, un, d)
+
+ def get_fsacl(self):
+ """Get the "zfs allow"-ed permissions on the Dataset.
+
+ Return a dict("whostr": { "perm" -> None })."""
+
+ return zfs.ioctl.get_fsacl(self.name)
+
+ def get_holds(self):
+ """Get the user holds on this Dataset.
+
+ Return a dict("tag": timestamp)."""
+
+ return zfs.ioctl.get_holds(self.name)
+
+def snapshots_fromcmdline(dsnames, recursive):
+ for dsname in dsnames:
+ if not "@" in dsname:
+ raise zfs.util.ZFSError(errno.EINVAL,
+ _("cannot open %s") % dsname,
+ _("operation only applies to snapshots"))
+ try:
+ ds = Dataset(dsname)
+ yield ds
+ except zfs.util.ZFSError, e:
+ if not recursive or e.errno != errno.ENOENT:
+ raise
+ if recursive:
+ (base, snapname) = dsname.split('@')
+ parent = Dataset(base)
+ for child in parent.descendents():
+ try:
+ yield Dataset(child.name + "@" +
+ snapname)
+ except zfs.util.ZFSError, e:
+ if e.errno != errno.ENOENT:
+ raise
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/groupspace.py b/cddl/contrib/opensolaris/lib/pyzfs/common/groupspace.py
new file mode 100644
index 0000000..9f380fd
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/groupspace.py
@@ -0,0 +1,28 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import zfs.userspace
+
+do_groupspace = zfs.userspace.do_userspace
+
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/holds.py b/cddl/contrib/opensolaris/lib/pyzfs/common/holds.py
new file mode 100644
index 0000000..800e28f
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/holds.py
@@ -0,0 +1,75 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""This module implements the "zfs holds" subcommand.
+The only public interface is the zfs.holds.do_holds() function."""
+
+import optparse
+import sys
+import errno
+import time
+import zfs.util
+import zfs.dataset
+import zfs.table
+
+_ = zfs.util._
+
+def do_holds():
+ """Implements the "zfs holds" subcommand."""
+ def usage(msg=None):
+ parser.print_help()
+ if msg:
+ print
+ parser.exit("zfs: error: " + msg)
+ else:
+ parser.exit()
+
+ u = _("""holds [-r] <snapshot> ...""")
+
+ parser = optparse.OptionParser(usage=u, prog="zfs")
+
+ parser.add_option("-r", action="store_true", dest="recursive",
+ help=_("list holds recursively"))
+
+ (options, args) = parser.parse_args(sys.argv[2:])
+
+ if len(args) < 1:
+ usage(_("missing snapshot argument"))
+
+ fields = ("name", "tag", "timestamp")
+ rjustfields = ()
+ printing = False
+ gotone = False
+ t = zfs.table.Table(fields, rjustfields)
+ for ds in zfs.dataset.snapshots_fromcmdline(args, options.recursive):
+ gotone = True
+ for tag, tm in ds.get_holds().iteritems():
+ val = {"name": ds.name, "tag": tag,
+ "timestamp": time.ctime(tm)}
+ t.addline(ds.name, val)
+ printing = True
+ if printing:
+ t.printme()
+ elif not gotone:
+ raise zfs.util.ZFSError(errno.ENOENT, _("no matching datasets"))
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/ioctl.c b/cddl/contrib/opensolaris/lib/pyzfs/common/ioctl.c
new file mode 100644
index 0000000..d1f82a7
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/ioctl.c
@@ -0,0 +1,544 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <Python.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/fs/zfs.h>
+#include <strings.h>
+#include <unistd.h>
+#include <libnvpair.h>
+#include <libintl.h>
+#include <libzfs.h>
+#include <libzfs_impl.h>
+#include "zfs_prop.h"
+
+static PyObject *ZFSError;
+static int zfsdevfd;
+
+#ifdef __lint
+#define dgettext(x, y) y
+#endif
+
+#define _(s) dgettext(TEXT_DOMAIN, s)
+
+/*PRINTFLIKE1*/
+static void
+seterr(char *fmt, ...)
+{
+ char errstr[1024];
+ va_list v;
+
+ va_start(v, fmt);
+ (void) vsnprintf(errstr, sizeof (errstr), fmt, v);
+ va_end(v);
+
+ PyErr_SetObject(ZFSError, Py_BuildValue("is", errno, errstr));
+}
+
+static char cmdstr[HIS_MAX_RECORD_LEN];
+
+static int
+ioctl_with_cmdstr(int ioc, zfs_cmd_t *zc)
+{
+ int err;
+
+ if (cmdstr[0])
+ zc->zc_history = (uint64_t)(uintptr_t)cmdstr;
+ err = ioctl(zfsdevfd, ioc, zc);
+ cmdstr[0] = '\0';
+ return (err);
+}
+
+static PyObject *
+nvl2py(nvlist_t *nvl)
+{
+ PyObject *pyo;
+ nvpair_t *nvp;
+
+ pyo = PyDict_New();
+
+ for (nvp = nvlist_next_nvpair(nvl, NULL); nvp;
+ nvp = nvlist_next_nvpair(nvl, nvp)) {
+ PyObject *pyval;
+ char *sval;
+ uint64_t ival;
+ boolean_t bval;
+ nvlist_t *nval;
+
+ switch (nvpair_type(nvp)) {
+ case DATA_TYPE_STRING:
+ (void) nvpair_value_string(nvp, &sval);
+ pyval = Py_BuildValue("s", sval);
+ break;
+
+ case DATA_TYPE_UINT64:
+ (void) nvpair_value_uint64(nvp, &ival);
+ pyval = Py_BuildValue("K", ival);
+ break;
+
+ case DATA_TYPE_NVLIST:
+ (void) nvpair_value_nvlist(nvp, &nval);
+ pyval = nvl2py(nval);
+ break;
+
+ case DATA_TYPE_BOOLEAN:
+ Py_INCREF(Py_None);
+ pyval = Py_None;
+ break;
+
+ case DATA_TYPE_BOOLEAN_VALUE:
+ (void) nvpair_value_boolean_value(nvp, &bval);
+ pyval = Py_BuildValue("i", bval);
+ break;
+
+ default:
+ PyErr_SetNone(PyExc_ValueError);
+ Py_DECREF(pyo);
+ return (NULL);
+ }
+
+ PyDict_SetItemString(pyo, nvpair_name(nvp), pyval);
+ Py_DECREF(pyval);
+ }
+
+ return (pyo);
+}
+
+static nvlist_t *
+dict2nvl(PyObject *d)
+{
+ nvlist_t *nvl;
+ int err;
+ PyObject *key, *value;
+ int pos = 0;
+
+ if (!PyDict_Check(d)) {
+ PyErr_SetObject(PyExc_ValueError, d);
+ return (NULL);
+ }
+
+ err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
+ assert(err == 0);
+
+ while (PyDict_Next(d, &pos, &key, &value)) {
+ char *keystr = PyString_AsString(key);
+ if (keystr == NULL) {
+ PyErr_SetObject(PyExc_KeyError, key);
+ nvlist_free(nvl);
+ return (NULL);
+ }
+
+ if (PyDict_Check(value)) {
+ nvlist_t *valnvl = dict2nvl(value);
+ err = nvlist_add_nvlist(nvl, keystr, valnvl);
+ nvlist_free(valnvl);
+ } else if (value == Py_None) {
+ err = nvlist_add_boolean(nvl, keystr);
+ } else if (PyString_Check(value)) {
+ char *valstr = PyString_AsString(value);
+ err = nvlist_add_string(nvl, keystr, valstr);
+ } else if (PyInt_Check(value)) {
+ uint64_t valint = PyInt_AsUnsignedLongLongMask(value);
+ err = nvlist_add_uint64(nvl, keystr, valint);
+ } else if (PyBool_Check(value)) {
+ boolean_t valbool = value == Py_True ? B_TRUE : B_FALSE;
+ err = nvlist_add_boolean_value(nvl, keystr, valbool);
+ } else {
+ PyErr_SetObject(PyExc_ValueError, value);
+ nvlist_free(nvl);
+ return (NULL);
+ }
+ assert(err == 0);
+ }
+
+ return (nvl);
+}
+
+static PyObject *
+fakepropval(uint64_t value)
+{
+ PyObject *d = PyDict_New();
+ PyDict_SetItemString(d, "value", Py_BuildValue("K", value));
+ return (d);
+}
+
+static void
+add_ds_props(zfs_cmd_t *zc, PyObject *nvl)
+{
+ dmu_objset_stats_t *s = &zc->zc_objset_stats;
+ PyDict_SetItemString(nvl, "numclones",
+ fakepropval(s->dds_num_clones));
+ PyDict_SetItemString(nvl, "issnap",
+ fakepropval(s->dds_is_snapshot));
+ PyDict_SetItemString(nvl, "inconsistent",
+ fakepropval(s->dds_inconsistent));
+}
+
+/* On error, returns NULL but does not set python exception. */
+static PyObject *
+ioctl_with_dstnv(int ioc, zfs_cmd_t *zc)
+{
+ int nvsz = 2048;
+ void *nvbuf;
+ PyObject *pynv = NULL;
+
+again:
+ nvbuf = malloc(nvsz);
+ zc->zc_nvlist_dst_size = nvsz;
+ zc->zc_nvlist_dst = (uintptr_t)nvbuf;
+
+ if (ioctl(zfsdevfd, ioc, zc) == 0) {
+ nvlist_t *nvl;
+
+ errno = nvlist_unpack(nvbuf, zc->zc_nvlist_dst_size, &nvl, 0);
+ if (errno == 0) {
+ pynv = nvl2py(nvl);
+ nvlist_free(nvl);
+ }
+ } else if (errno == ENOMEM) {
+ free(nvbuf);
+ nvsz = zc->zc_nvlist_dst_size;
+ goto again;
+ }
+ free(nvbuf);
+ return (pynv);
+}
+
+static PyObject *
+py_next_dataset(PyObject *self, PyObject *args)
+{
+ int ioc;
+ uint64_t cookie;
+ zfs_cmd_t zc = { 0 };
+ int snaps;
+ char *name;
+ PyObject *nvl;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTuple(args, "siK", &name, &snaps, &cookie))
+ return (NULL);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+ zc.zc_cookie = cookie;
+
+ if (snaps)
+ ioc = ZFS_IOC_SNAPSHOT_LIST_NEXT;
+ else
+ ioc = ZFS_IOC_DATASET_LIST_NEXT;
+
+ nvl = ioctl_with_dstnv(ioc, &zc);
+ if (nvl) {
+ add_ds_props(&zc, nvl);
+ ret = Py_BuildValue("sKO", zc.zc_name, zc.zc_cookie, nvl);
+ Py_DECREF(nvl);
+ } else if (errno == ESRCH) {
+ PyErr_SetNone(PyExc_StopIteration);
+ } else {
+ if (snaps)
+ seterr(_("cannot get snapshots of %s"), name);
+ else
+ seterr(_("cannot get child datasets of %s"), name);
+ }
+ return (ret);
+}
+
+static PyObject *
+py_dataset_props(PyObject *self, PyObject *args)
+{
+ zfs_cmd_t zc = { 0 };
+ int snaps;
+ char *name;
+ PyObject *nvl;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return (NULL);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+ nvl = ioctl_with_dstnv(ZFS_IOC_OBJSET_STATS, &zc);
+ if (nvl) {
+ add_ds_props(&zc, nvl);
+ } else {
+ seterr(_("cannot access dataset %s"), name);
+ }
+ return (nvl);
+}
+
+static PyObject *
+py_get_fsacl(PyObject *self, PyObject *args)
+{
+ zfs_cmd_t zc = { 0 };
+ char *name;
+ PyObject *nvl;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return (NULL);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+ nvl = ioctl_with_dstnv(ZFS_IOC_GET_FSACL, &zc);
+ if (nvl == NULL)
+ seterr(_("cannot get permissions on %s"), name);
+
+ return (nvl);
+}
+
+static PyObject *
+py_set_fsacl(PyObject *self, PyObject *args)
+{
+ int un;
+ size_t nvsz;
+ zfs_cmd_t zc = { 0 };
+ char *name, *nvbuf;
+ PyObject *dict, *file;
+ nvlist_t *nvl;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "siO!", &name, &un,
+ &PyDict_Type, &dict))
+ return (NULL);
+
+ nvl = dict2nvl(dict);
+ if (nvl == NULL)
+ return (NULL);
+
+ err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
+ assert(err == 0);
+ nvbuf = malloc(nvsz);
+ err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
+ assert(err == 0);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+ zc.zc_nvlist_src_size = nvsz;
+ zc.zc_nvlist_src = (uintptr_t)nvbuf;
+ zc.zc_perm_action = un;
+
+ err = ioctl_with_cmdstr(ZFS_IOC_SET_FSACL, &zc);
+ free(nvbuf);
+ if (err) {
+ seterr(_("cannot set permissions on %s"), name);
+ return (NULL);
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+py_get_holds(PyObject *self, PyObject *args)
+{
+ zfs_cmd_t zc = { 0 };
+ char *name;
+ PyObject *nvl;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return (NULL);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+
+ nvl = ioctl_with_dstnv(ZFS_IOC_GET_HOLDS, &zc);
+ if (nvl == NULL)
+ seterr(_("cannot get holds for %s"), name);
+
+ return (nvl);
+}
+
+static PyObject *
+py_userspace_many(PyObject *self, PyObject *args)
+{
+ zfs_cmd_t zc = { 0 };
+ zfs_userquota_prop_t type;
+ char *name, *propname;
+ int bufsz = 1<<20;
+ void *buf;
+ PyObject *dict, *file;
+ int error;
+
+ if (!PyArg_ParseTuple(args, "ss", &name, &propname))
+ return (NULL);
+
+ for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++)
+ if (strcmp(propname, zfs_userquota_prop_prefixes[type]) == 0)
+ break;
+ if (type == ZFS_NUM_USERQUOTA_PROPS) {
+ PyErr_SetString(PyExc_KeyError, propname);
+ return (NULL);
+ }
+
+ dict = PyDict_New();
+ buf = malloc(bufsz);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+ zc.zc_objset_type = type;
+ zc.zc_cookie = 0;
+
+ while (1) {
+ zfs_useracct_t *zua = buf;
+
+ zc.zc_nvlist_dst = (uintptr_t)buf;
+ zc.zc_nvlist_dst_size = bufsz;
+
+ error = ioctl(zfsdevfd, ZFS_IOC_USERSPACE_MANY, &zc);
+ if (error || zc.zc_nvlist_dst_size == 0)
+ break;
+
+ while (zc.zc_nvlist_dst_size > 0) {
+ PyObject *pykey, *pyval;
+
+ pykey = Py_BuildValue("sI",
+ zua->zu_domain, zua->zu_rid);
+ pyval = Py_BuildValue("K", zua->zu_space);
+ PyDict_SetItem(dict, pykey, pyval);
+ Py_DECREF(pykey);
+ Py_DECREF(pyval);
+
+ zua++;
+ zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
+ }
+ }
+
+ free(buf);
+
+ if (error != 0) {
+ Py_DECREF(dict);
+ seterr(_("cannot get %s property on %s"), propname, name);
+ return (NULL);
+ }
+
+ return (dict);
+}
+
+static PyObject *
+py_userspace_upgrade(PyObject *self, PyObject *args)
+{
+ zfs_cmd_t zc = { 0 };
+ char *name;
+ int error;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return (NULL);
+
+ (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+ error = ioctl(zfsdevfd, ZFS_IOC_USERSPACE_UPGRADE, &zc);
+
+ if (error != 0) {
+ seterr(_("cannot initialize user accounting information on %s"),
+ name);
+ return (NULL);
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+py_set_cmdstr(PyObject *self, PyObject *args)
+{
+ char *str;
+
+ if (!PyArg_ParseTuple(args, "s", &str))
+ return (NULL);
+
+ (void) strlcpy(cmdstr, str, sizeof (cmdstr));
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+py_get_proptable(PyObject *self, PyObject *args)
+{
+ zprop_desc_t *t = zfs_prop_get_table();
+ PyObject *d = PyDict_New();
+ zfs_prop_t i;
+
+ for (i = 0; i < ZFS_NUM_PROPS; i++) {
+ zprop_desc_t *p = &t[i];
+ PyObject *tuple;
+ static const char *typetable[] =
+ {"number", "string", "index"};
+ static const char *attrtable[] =
+ {"default", "readonly", "inherit", "onetime"};
+ PyObject *indextable;
+
+ if (p->pd_proptype == PROP_TYPE_INDEX) {
+ const zprop_index_t *it = p->pd_table;
+ indextable = PyDict_New();
+ int j;
+ for (j = 0; it[j].pi_name; j++) {
+ PyDict_SetItemString(indextable,
+ it[j].pi_name,
+ Py_BuildValue("K", it[j].pi_value));
+ }
+ } else {
+ Py_INCREF(Py_None);
+ indextable = Py_None;
+ }
+
+ tuple = Py_BuildValue("sissKsissiiO",
+ p->pd_name, p->pd_propnum, typetable[p->pd_proptype],
+ p->pd_strdefault, p->pd_numdefault,
+ attrtable[p->pd_attr], p->pd_types,
+ p->pd_values, p->pd_colname,
+ p->pd_rightalign, p->pd_visible, indextable);
+ PyDict_SetItemString(d, p->pd_name, tuple);
+ Py_DECREF(tuple);
+ }
+
+ return (d);
+}
+
+static PyMethodDef zfsmethods[] = {
+ {"next_dataset", py_next_dataset, METH_VARARGS,
+ "Get next child dataset or snapshot."},
+ {"get_fsacl", py_get_fsacl, METH_VARARGS, "Get allowed permissions."},
+ {"set_fsacl", py_set_fsacl, METH_VARARGS, "Set allowed permissions."},
+ {"userspace_many", py_userspace_many, METH_VARARGS,
+ "Get user space accounting."},
+ {"userspace_upgrade", py_userspace_upgrade, METH_VARARGS,
+ "Upgrade fs to enable user space accounting."},
+ {"set_cmdstr", py_set_cmdstr, METH_VARARGS,
+ "Set command string for history logging."},
+ {"dataset_props", py_dataset_props, METH_VARARGS,
+ "Get dataset properties."},
+ {"get_proptable", py_get_proptable, METH_NOARGS,
+ "Get property table."},
+ {"get_holds", py_get_holds, METH_VARARGS, "Get user holds."},
+ {NULL, NULL, 0, NULL}
+};
+
+void
+initioctl(void)
+{
+ PyObject *zfs_ioctl = Py_InitModule("zfs.ioctl", zfsmethods);
+ PyObject *zfs_util = PyImport_ImportModule("zfs.util");
+ PyObject *devfile;
+
+ if (zfs_util == NULL)
+ return;
+
+ ZFSError = PyObject_GetAttrString(zfs_util, "ZFSError");
+ devfile = PyObject_GetAttrString(zfs_util, "dev");
+ zfsdevfd = PyObject_AsFileDescriptor(devfile);
+
+ zfs_prop_init();
+}
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/table.py b/cddl/contrib/opensolaris/lib/pyzfs/common/table.py
new file mode 100644
index 0000000..d2a45a1
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/table.py
@@ -0,0 +1,70 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import zfs.util
+
+class Table:
+ __slots__ = "fields", "rjustfields", "maxfieldlen", "lines"
+ __repr__ = zfs.util.default_repr
+
+ def __init__(self, fields, rjustfields=()):
+ # XXX maybe have a defaults, too?
+ self.fields = fields
+ self.rjustfields = rjustfields
+ self.maxfieldlen = dict.fromkeys(fields, 0)
+ self.lines = list()
+
+ def __updatemax(self, k, v):
+ self.maxfieldlen[k] = max(self.maxfieldlen.get(k, None), v)
+
+ def addline(self, sortkey, values):
+ """values is a dict from field name to value"""
+
+ va = list()
+ for f in self.fields:
+ v = str(values[f])
+ va.append(v)
+ self.__updatemax(f, len(v))
+ self.lines.append((sortkey, va))
+
+ def printme(self, headers=True):
+ if headers:
+ d = dict([(f, f.upper()) for f in self.fields])
+ self.addline(None, d)
+
+ self.lines.sort()
+ for (k, va) in self.lines:
+ line = str()
+ for i in range(len(self.fields)):
+ if not headers:
+ line += va[i]
+ line += "\t"
+ else:
+ if self.fields[i] in self.rjustfields:
+ fmt = "%*s "
+ else:
+ fmt = "%-*s "
+ mfl = self.maxfieldlen[self.fields[i]]
+ line += fmt % (mfl, va[i])
+ print(line)
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/unallow.py b/cddl/contrib/opensolaris/lib/pyzfs/common/unallow.py
new file mode 100644
index 0000000..cbdd4dd
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/unallow.py
@@ -0,0 +1,27 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import zfs.allow
+
+do_unallow = zfs.allow.do_allow
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/userspace.py b/cddl/contrib/opensolaris/lib/pyzfs/common/userspace.py
new file mode 100644
index 0000000..33646bc
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/userspace.py
@@ -0,0 +1,246 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""This module implements the "zfs userspace" and "zfs groupspace" subcommands.
+The only public interface is the zfs.userspace.do_userspace() function."""
+
+import optparse
+import sys
+import pwd
+import grp
+import errno
+import solaris.misc
+import zfs.util
+import zfs.ioctl
+import zfs.dataset
+import zfs.table
+
+_ = zfs.util._
+
+# map from property name prefix -> (field name, isgroup)
+props = {
+ "userused@": ("used", False),
+ "userquota@": ("quota", False),
+ "groupused@": ("used", True),
+ "groupquota@": ("quota", True),
+}
+
+def skiptype(options, prop):
+ """Return True if this property (eg "userquota@") should be skipped."""
+ (field, isgroup) = props[prop]
+ if field not in options.fields:
+ return True
+ if isgroup and "posixgroup" not in options.types and \
+ "smbgroup" not in options.types:
+ return True
+ if not isgroup and "posixuser" not in options.types and \
+ "smbuser" not in options.types:
+ return True
+ return False
+
+def new_entry(options, isgroup, domain, rid):
+ """Return a dict("field": value) for this domain (string) + rid (int)"""
+
+ if domain:
+ idstr = "%s-%u" % (domain, rid)
+ else:
+ idstr = "%u" % rid
+
+ (typename, mapfunc) = {
+ (1, 1): ("SMB Group", lambda id: solaris.misc.sid_to_name(id, 0)),
+ (1, 0): ("POSIX Group", lambda id: grp.getgrgid(int(id)).gr_name),
+ (0, 1): ("SMB User", lambda id: solaris.misc.sid_to_name(id, 1)),
+ (0, 0): ("POSIX User", lambda id: pwd.getpwuid(int(id)).pw_name)
+ }[isgroup, bool(domain)]
+
+ if typename.lower().replace(" ", "") not in options.types:
+ return None
+
+ v = dict()
+ v["type"] = typename
+
+ # python's getpwuid/getgrgid is confused by ephemeral uids
+ if not options.noname and rid < 1<<31:
+ try:
+ v["name"] = mapfunc(idstr)
+ except KeyError:
+ pass
+
+ if "name" not in v:
+ v["name"] = idstr
+ if not domain:
+ # it's just a number, so pad it with spaces so
+ # that it will sort numerically
+ v["name.sort"] = "%20d" % rid
+ # fill in default values
+ v["used"] = "0"
+ v["used.sort"] = 0
+ v["quota"] = "none"
+ v["quota.sort"] = 0
+ return v
+
+def process_one_raw(acct, options, prop, elem):
+ """Update the acct dict to incorporate the
+ information from this elem from Dataset.userspace(prop)."""
+
+ (domain, rid, value) = elem
+ (field, isgroup) = props[prop]
+
+ if options.translate and domain:
+ try:
+ rid = solaris.misc.sid_to_id("%s-%u" % (domain, rid),
+ not isgroup)
+ domain = None
+ except KeyError:
+ pass;
+ key = (isgroup, domain, rid)
+
+ try:
+ v = acct[key]
+ except KeyError:
+ v = new_entry(options, isgroup, domain, rid)
+ if not v:
+ return
+ acct[key] = v
+
+ # Add our value to an existing value, which may be present if
+ # options.translate is set.
+ value = v[field + ".sort"] = value + v[field + ".sort"]
+
+ if options.parsable:
+ v[field] = str(value)
+ else:
+ v[field] = zfs.util.nicenum(value)
+
+def do_userspace():
+ """Implements the "zfs userspace" and "zfs groupspace" subcommands."""
+
+ def usage(msg=None):
+ parser.print_help()
+ if msg:
+ print
+ parser.exit("zfs: error: " + msg)
+ else:
+ parser.exit()
+
+ if sys.argv[1] == "userspace":
+ defaulttypes = "posixuser,smbuser"
+ else:
+ defaulttypes = "posixgroup,smbgroup"
+
+ fields = ("type", "name", "used", "quota")
+ rjustfields = ("used", "quota")
+ types = ("all", "posixuser", "smbuser", "posixgroup", "smbgroup")
+
+ u = _("%s [-niHp] [-o field[,...]] [-sS field] ... \n") % sys.argv[1]
+ u += _(" [-t type[,...]] <filesystem|snapshot>")
+ parser = optparse.OptionParser(usage=u, prog="zfs")
+
+ parser.add_option("-n", action="store_true", dest="noname",
+ help=_("Print numeric ID instead of user/group name"))
+ parser.add_option("-i", action="store_true", dest="translate",
+ help=_("translate SID to posix (possibly ephemeral) ID"))
+ parser.add_option("-H", action="store_true", dest="noheaders",
+ help=_("no headers, tab delimited output"))
+ parser.add_option("-p", action="store_true", dest="parsable",
+ help=_("exact (parsable) numeric output"))
+ parser.add_option("-o", dest="fields", metavar="field[,...]",
+ default="type,name,used,quota",
+ help=_("print only these fields (eg type,name,used,quota)"))
+ parser.add_option("-s", dest="sortfields", metavar="field",
+ type="choice", choices=fields, default=list(),
+ action="callback", callback=zfs.util.append_with_opt,
+ help=_("sort field"))
+ parser.add_option("-S", dest="sortfields", metavar="field",
+ type="choice", choices=fields, #-s sets the default
+ action="callback", callback=zfs.util.append_with_opt,
+ help=_("reverse sort field"))
+ parser.add_option("-t", dest="types", metavar="type[,...]",
+ default=defaulttypes,
+ help=_("print only these types (eg posixuser,smbuser,posixgroup,smbgroup,all)"))
+
+ (options, args) = parser.parse_args(sys.argv[2:])
+ if len(args) != 1:
+ usage(_("wrong number of arguments"))
+ dsname = args[0]
+
+ options.fields = options.fields.split(",")
+ for f in options.fields:
+ if f not in fields:
+ usage(_("invalid field %s") % f)
+
+ options.types = options.types.split(",")
+ for t in options.types:
+ if t not in types:
+ usage(_("invalid type %s") % t)
+
+ if not options.sortfields:
+ options.sortfields = [("-s", "type"), ("-s", "name")]
+
+ if "all" in options.types:
+ options.types = types[1:]
+
+ ds = zfs.dataset.Dataset(dsname, types=("filesystem"))
+
+ if ds.getprop("jailed") and solaris.misc.isglobalzone():
+ options.noname = True
+
+ if not ds.getprop("useraccounting"):
+ print(_("Initializing accounting information on old filesystem, please wait..."))
+ ds.userspace_upgrade()
+
+ # gather and process accounting information
+ # Due to -i, we need to keep a dict, so we can potentially add
+ # together the posix ID and SID's usage. Grr.
+ acct = dict()
+ for prop in props.keys():
+ if skiptype(options, prop):
+ continue;
+ for elem in ds.userspace(prop):
+ process_one_raw(acct, options, prop, elem)
+
+ def cmpkey(val):
+ l = list()
+ for (opt, field) in options.sortfields:
+ try:
+ n = val[field + ".sort"]
+ except KeyError:
+ n = val[field]
+ if opt == "-S":
+ # reverse sorting
+ try:
+ n = -n
+ except TypeError:
+ # it's a string; decompose it
+ # into an array of integers,
+ # each one the negative of that
+ # character
+ n = [-ord(c) for c in n]
+ l.append(n)
+ return l
+
+ t = zfs.table.Table(options.fields, rjustfields)
+ for val in acct.itervalues():
+ t.addline(cmpkey(val), val)
+ t.printme(not options.noheaders)
diff --git a/cddl/contrib/opensolaris/lib/pyzfs/common/util.py b/cddl/contrib/opensolaris/lib/pyzfs/common/util.py
new file mode 100644
index 0000000..a33c669
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/pyzfs/common/util.py
@@ -0,0 +1,141 @@
+#! /usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""This module provides utility functions for ZFS.
+zfs.util.dev -- a file object of /dev/zfs """
+
+import gettext
+import errno
+import os
+import solaris.misc
+# Note: this module (zfs.util) should not import zfs.ioctl, because that
+# would introduce a circular dependency
+
+errno.ECANCELED = 47
+errno.ENOTSUP = 48
+
+dev = open("/dev/zfs", "w")
+
+try:
+ _ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale",
+ fallback=True).gettext
+except:
+ _ = solaris.misc.gettext
+
+def default_repr(self):
+ """A simple __repr__ function."""
+ if self.__slots__:
+ str = "<" + self.__class__.__name__
+ for v in self.__slots__:
+ str += " %s: %r" % (v, getattr(self, v))
+ return str + ">"
+ else:
+ return "<%s %s>" % \
+ (self.__class__.__name__, repr(self.__dict__))
+
+class ZFSError(StandardError):
+ """This exception class represents a potentially user-visible
+ ZFS error. If uncaught, it will be printed and the process will
+ exit with exit code 1.
+
+ errno -- the error number (eg, from ioctl(2))."""
+
+ __slots__ = "why", "task", "errno"
+ __repr__ = default_repr
+
+ def __init__(self, eno, task=None, why=None):
+ """Create a ZFS exception.
+ eno -- the error number (errno)
+ task -- a string describing the task that failed
+ why -- a string describing why it failed (defaults to
+ strerror(eno))"""
+
+ self.errno = eno
+ self.task = task
+ self.why = why
+
+ def __str__(self):
+ s = ""
+ if self.task:
+ s += self.task + ": "
+ if self.why:
+ s += self.why
+ else:
+ s += self.strerror
+ return s
+
+ __strs = {
+ errno.EPERM: _("permission denied"),
+ errno.ECANCELED:
+ _("delegated administration is disabled on pool"),
+ errno.EINTR: _("signal received"),
+ errno.EIO: _("I/O error"),
+ errno.ENOENT: _("dataset does not exist"),
+ errno.ENOSPC: _("out of space"),
+ errno.EEXIST: _("dataset already exists"),
+ errno.EBUSY: _("dataset is busy"),
+ errno.EROFS:
+ _("snapshot permissions cannot be modified"),
+ errno.ENAMETOOLONG: _("dataset name is too long"),
+ errno.ENOTSUP: _("unsupported version"),
+ errno.EAGAIN: _("pool I/O is currently suspended"),
+ }
+
+ __strs[errno.EACCES] = __strs[errno.EPERM]
+ __strs[errno.ENXIO] = __strs[errno.EIO]
+ __strs[errno.ENODEV] = __strs[errno.EIO]
+ __strs[errno.EDQUOT] = __strs[errno.ENOSPC]
+
+ @property
+ def strerror(self):
+ return ZFSError.__strs.get(self.errno, os.strerror(self.errno))
+
+def nicenum(num):
+ """Return a nice string (eg "1.23M") for this integer."""
+ index = 0;
+ n = num;
+
+ while n >= 1024:
+ n /= 1024
+ index += 1
+
+ u = " KMGTPE"[index]
+ if index == 0:
+ return "%u" % n;
+ elif n >= 100 or num & ((1024*index)-1) == 0:
+ # it's an exact multiple of its index, or it wouldn't
+ # fit as floating point, so print as an integer
+ return "%u%c" % (n, u)
+ else:
+ # due to rounding, it's tricky to tell what precision to
+ # use; try each precision and see which one fits
+ for i in (2, 1, 0):
+ s = "%.*f%c" % (i, float(num) / (1<<(10*index)), u)
+ if len(s) <= 5:
+ return s
+
+def append_with_opt(option, opt, value, parser):
+ """A function for OptionParser which appends a tuple (opt, value)."""
+ getattr(parser.values, option.dest).append((opt, value))
+
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/ctf_headers.h b/cddl/contrib/opensolaris/tools/ctf/common/ctf_headers.h
new file mode 100644
index 0000000..b00b8fd
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/ctf_headers.h
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CTF_HEADERS_H
+#define _CTF_HEADERS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Because the ON tools are executed on the system where they are built,
+ * the tools need to include the headers installed on the build system,
+ * rather than those in the ON source tree. However, some of the headers
+ * required by the tools are part of the ON source tree, but not delivered
+ * as part of Solaris. These include the following:
+ *
+ * $(SRC)/lib/libctf/common/libctf.h
+ * $(SRC)/uts/common/sys/ctf_api.h
+ * $(SRC)/uts/common/sys/ctf.h
+ *
+ * These headers get installed in the proto area in the build environment
+ * under $(ROOT)/usr/include and $(ROOT)/usr/include/sys. Though these
+ * headers are not part of the release, in releases including and prior to
+ * Solaris 9, they did get installed on the build system via bfu. Therefore,
+ * we can not simply force the order of inclusion with -I/usr/include first
+ * in Makefile.ctf because we might actually get downlevel versions of the
+ * ctf headers. Depending on the order of the -I includes, we can also have
+ * a problem with mismatched headers when building the ctf tools with some
+ * headers getting pulled in from /usr/include and others from
+ * $(SRC)/uts/common/sys.
+ *
+ * To address the problem, we have done two things:
+ * 1) Created this header with a specific order of inclusion for the
+ * ctf headers. Because the <libctf.h> header includes <sys/ctf_api.h>
+ * which in turn includes <sys/ctf.h> we need to include these in
+ * reverse order to guarantee that we get the correct versions of
+ * the headers.
+ * 2) In $(SRC)/tools/ctf/Makefile.ctf, we order the -I includes such
+ * that we first search the directories where the ctf headers
+ * live, followed by /usr/include, followed by $(SRC)/uts/common.
+ * This last -I include is needed in order to prevent a build failure
+ * when <sys/ctf_api.h> is included via a nested #include rather than
+ * an explicit path #include.
+ */
+
+#include <uts/common/sys/ctf.h>
+#include <uts/common/sys/ctf_api.h>
+#include <lib/libctf/common/libctf.h>
+
+#endif /* _CTF_HEADERS_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/list.c b/cddl/contrib/opensolaris/tools/ctf/common/list.c
new file mode 100644
index 0000000..4958f27
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/list.c
@@ -0,0 +1,228 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating linked lists
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "list.h"
+#include "memory.h"
+
+struct list {
+ void *l_data;
+ struct list *l_next;
+};
+
+/* Add an element to a list */
+void
+list_add(list_t **list, void *data)
+{
+ list_t *le;
+
+ le = xmalloc(sizeof (list_t));
+ le->l_data = data;
+ le->l_next = *list;
+ *list = le;
+}
+
+/* Add an element to a sorted list */
+void
+slist_add(list_t **list, void *data, int (*cmp)(void *, void *))
+{
+ list_t **nextp;
+
+ for (nextp = list; *nextp; nextp = &((*nextp)->l_next)) {
+ if (cmp((*nextp)->l_data, data) > 0)
+ break;
+ }
+
+ list_add(nextp, data);
+}
+
+/*ARGSUSED2*/
+static int
+list_defcmp(void *d1, void *d2, void *private __unused)
+{
+ return (d1 != d2);
+}
+
+void *
+list_remove(list_t **list, void *data, int (*cmp)(void *, void *, void *),
+ void *private)
+{
+ list_t *le, **le2;
+ void *led;
+
+ if (!cmp)
+ cmp = list_defcmp;
+
+ for (le = *list, le2 = list; le; le2 = &le->l_next, le = le->l_next) {
+ if (cmp(le->l_data, data, private) == 0) {
+ *le2 = le->l_next;
+ led = le->l_data;
+ free(le);
+ return (led);
+ }
+ }
+
+ return (NULL);
+}
+
+void
+list_free(list_t *list, void (*datafree)(void *, void *), void *private)
+{
+ list_t *le;
+
+ while (list) {
+ le = list;
+ list = list->l_next;
+ if (le->l_data && datafree)
+ datafree(le->l_data, private);
+ free(le);
+ }
+}
+
+/*
+ * This iterator is specifically designed to tolerate the deletion of the
+ * node being iterated over.
+ */
+int
+list_iter(list_t *list, int (*func)(void *, void *), void *private)
+{
+ list_t *lnext;
+ int cumrc = 0;
+ int cbrc;
+
+ while (list) {
+ lnext = list->l_next;
+ if ((cbrc = func(list->l_data, private)) < 0)
+ return (cbrc);
+ cumrc += cbrc;
+ list = lnext;
+ }
+
+ return (cumrc);
+}
+
+/*ARGSUSED*/
+static int
+list_count_cb(void *data __unused, void *private __unused)
+{
+ return (1);
+}
+
+int
+list_count(list_t *list)
+{
+ return (list_iter(list, list_count_cb, NULL));
+}
+
+int
+list_empty(list_t *list)
+{
+ return (list == NULL);
+}
+
+void *
+list_find(list_t *list, void *tmpl, int (*cmp)(void *, void *))
+{
+ for (; list; list = list->l_next) {
+ if (cmp(list->l_data, tmpl) == 0)
+ return (list->l_data);
+ }
+
+ return (NULL);
+}
+
+void *
+list_first(list_t *list)
+{
+ return (list ? list->l_data : NULL);
+}
+
+void
+list_concat(list_t **list1, list_t *list2)
+{
+ list_t *l, *last;
+
+ for (l = *list1, last = NULL; l; last = l, l = l->l_next)
+ continue;
+
+ if (last == NULL)
+ *list1 = list2;
+ else
+ last->l_next = list2;
+}
+
+/*
+ * Merges two sorted lists. Equal nodes (as determined by cmp) are retained.
+ */
+void
+slist_merge(list_t **list1p, list_t *list2, int (*cmp)(void *, void *))
+{
+ list_t *list1, *next2;
+ list_t *last1 = NULL;
+
+ if (*list1p == NULL) {
+ *list1p = list2;
+ return;
+ }
+
+ list1 = *list1p;
+ while (list2 != NULL) {
+ if (cmp(list1->l_data, list2->l_data) > 0) {
+ next2 = list2->l_next;
+
+ if (last1 == NULL) {
+ /* Insert at beginning */
+ *list1p = last1 = list2;
+ list2->l_next = list1;
+ } else {
+ list2->l_next = list1;
+ last1->l_next = list2;
+ last1 = list2;
+ }
+
+ list2 = next2;
+ } else {
+
+ last1 = list1;
+ list1 = list1->l_next;
+
+ if (list1 == NULL) {
+ /* Add the rest to the end of list1 */
+ last1->l_next = list2;
+ list2 = NULL;
+ }
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/list.h b/cddl/contrib/opensolaris/tools/ctf/common/list.h
new file mode 100644
index 0000000..2e41271d
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/list.h
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIST_H
+#define _LIST_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating linked lists
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct list list_t;
+
+void list_add(list_t **, void *);
+void slist_add(list_t **, void *, int (*)(void *, void *));
+void *list_remove(list_t **, void *, int (*)(void *, void *, void *), void *);
+void list_free(list_t *, void (*)(void *, void *), void *);
+void *list_find(list_t *, void *, int (*)(void *, void *));
+void *list_first(list_t *);
+int list_iter(list_t *, int (*)(void *, void *), void *);
+int list_count(list_t *);
+int list_empty(list_t *);
+void list_concat(list_t **, list_t *);
+void slist_merge(list_t **, list_t *, int (*)(void *, void *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIST_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/memory.c b/cddl/contrib/opensolaris/tools/ctf/common/memory.c
new file mode 100644
index 0000000..e16044a
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/memory.c
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for memory management
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "memory.h"
+
+static void
+memory_bailout(void)
+{
+ (void) fprintf(stderr, "Out of memory\n");
+ exit(1);
+}
+
+void *
+xmalloc(size_t size)
+{
+ void *mem;
+
+ if ((mem = malloc(size)) == NULL)
+ memory_bailout();
+
+ return (mem);
+}
+
+void *
+xcalloc(size_t size)
+{
+ void *mem;
+
+ mem = xmalloc(size);
+ bzero(mem, size);
+
+ return (mem);
+}
+
+char *
+xstrdup(const char *str)
+{
+ char *newstr;
+
+ if ((newstr = strdup(str)) == NULL)
+ memory_bailout();
+
+ return (newstr);
+}
+
+char *
+xstrndup(char *str, size_t len)
+{
+ char *newstr;
+
+ if ((newstr = malloc(len + 1)) == NULL)
+ memory_bailout();
+
+ (void) strncpy(newstr, str, len);
+ newstr[len] = '\0';
+
+ return (newstr);
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+ void *mem;
+
+ if ((mem = realloc(ptr, size)) == NULL)
+ memory_bailout();
+
+ return (mem);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/memory.h b/cddl/contrib/opensolaris/tools/ctf/common/memory.h
new file mode 100644
index 0000000..88ca31b
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/memory.h
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _MEMORY_H
+#define _MEMORY_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for memory management
+ */
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *xmalloc(size_t);
+void *xcalloc(size_t);
+char *xstrdup(const char *);
+char *xstrndup(char *, size_t);
+void *xrealloc(void *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MEMORY_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/symbol.c b/cddl/contrib/opensolaris/tools/ctf/common/symbol.c
new file mode 100644
index 0000000..29796ac
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/symbol.c
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "symbol.h"
+
+int
+ignore_symbol(GElf_Sym *sym, const char *name)
+{
+ uchar_t type = GELF_ST_TYPE(sym->st_info);
+
+ /*
+ * As an optimization, we do not output function or data object
+ * records for undefined or anonymous symbols.
+ */
+ if (sym->st_shndx == SHN_UNDEF || sym->st_name == 0)
+ return (1);
+
+ /*
+ * _START_ and _END_ are added to the symbol table by the
+ * linker, and will never have associated type information.
+ */
+ if (strcmp(name, "_START_") == 0 || strcmp(name, "_END_") == 0)
+ return (1);
+
+ /*
+ * Do not output records for absolute-valued object symbols
+ * that have value zero. The compiler insists on generating
+ * things like this for __fsr_init_value settings, etc.
+ */
+ if (type == STT_OBJECT && sym->st_shndx == SHN_ABS &&
+ sym->st_value == 0)
+ return (1);
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/symbol.h b/cddl/contrib/opensolaris/tools/ctf/common/symbol.h
new file mode 100644
index 0000000..92b5e89
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/symbol.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYMBOL_H
+#define _SYMBOL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <gelf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ignore_symbol(GElf_Sym *sym, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYMBOL_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/utils.c b/cddl/contrib/opensolaris/tools/ctf/common/utils.c
new file mode 100644
index 0000000..b9db1a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/utils.c
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1998-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "utils.h"
+
+/*LINTLIBRARY*/
+
+static const char *pname;
+
+#pragma init(getpname)
+const char *
+getpname(void)
+{
+ const char *p, *q;
+
+ if (pname != NULL)
+ return (pname);
+
+ if ((p = getexecname()) != NULL)
+ q = strrchr(p, '/');
+ else
+ q = NULL;
+
+ if (q == NULL)
+ pname = p;
+ else
+ pname = q + 1;
+
+ return (pname);
+}
+
+void
+vwarn(const char *format, va_list alist)
+{
+ int err = errno;
+
+ if (pname != NULL)
+ (void) fprintf(stderr, "%s: ", pname);
+
+ (void) vfprintf(stderr, format, alist);
+
+ if (strchr(format, '\n') == NULL)
+ (void) fprintf(stderr, ": %s\n", strerror(err));
+}
+
+/*PRINTFLIKE1*/
+void
+warn(const char *format, ...)
+{
+ va_list alist;
+
+ va_start(alist, format);
+ vwarn(format, alist);
+ va_end(alist);
+}
+
+void
+vdie(const char *format, va_list alist)
+{
+ vwarn(format, alist);
+ exit(E_ERROR);
+}
+
+/*PRINTFLIKE1*/
+void
+die(const char *format, ...)
+{
+ va_list alist;
+
+ va_start(alist, format);
+ vdie(format, alist);
+ va_end(alist);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/utils.h b/cddl/contrib/opensolaris/tools/ctf/common/utils.h
new file mode 100644
index 0000000..9b07361
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/common/utils.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1998-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define E_SUCCESS 0 /* Exit status for success */
+#define E_ERROR 1 /* Exit status for error */
+#define E_USAGE 2 /* Exit status for usage error */
+
+extern void vwarn(const char *, va_list);
+extern void warn(const char *, ...);
+extern void vdie(const char *, va_list);
+extern void die(const char *, ...);
+
+extern const char *getpname(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UTILS_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/alist.c b/cddl/contrib/opensolaris/tools/ctf/cvt/alist.c
new file mode 100644
index 0000000..8e776dc
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/alist.c
@@ -0,0 +1,215 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Create, manage, and destroy association lists. alists are arrays with
+ * arbitrary index types, and are also commonly known as associative arrays.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "alist.h"
+#include "memory.h"
+#include "hash.h"
+
+#define ALIST_HASH_SIZE 997
+
+struct alist {
+ hash_t *al_elements;
+ void (*al_namefree)(void *);
+ void (*al_valfree)(void *);
+};
+
+typedef struct alist_el {
+ void *ale_name;
+ void *ale_value;
+} alist_el_t;
+
+static int
+alist_hash(int nbuckets, void *arg)
+{
+ alist_el_t *el = arg;
+ uintptr_t num = (uintptr_t)el->ale_name;
+
+ return (num % nbuckets);
+}
+
+static int
+alist_cmp(void *arg1, void *arg2)
+{
+ alist_el_t *el1 = arg1;
+ alist_el_t *el2 = arg2;
+ return ((uintptr_t)el1->ale_name != (uintptr_t)el2->ale_name);
+}
+
+alist_t *
+alist_xnew(int nbuckets, void (*namefree)(void *),
+ void (*valfree)(void *), int (*hashfn)(int, void *),
+ int (*cmpfn)(void *, void *))
+{
+ alist_t *alist;
+
+ alist = xcalloc(sizeof (alist_t));
+ alist->al_elements = hash_new(nbuckets, hashfn, cmpfn);
+ alist->al_namefree = namefree;
+ alist->al_valfree = valfree;
+
+ return (alist);
+}
+
+alist_t *
+alist_new(void (*namefree)(void *), void (*valfree)(void *))
+{
+ return (alist_xnew(ALIST_HASH_SIZE, namefree, valfree,
+ alist_hash, alist_cmp));
+}
+
+static void
+alist_free_cb(void *arg1, void *arg2)
+{
+ alist_el_t *el = arg1;
+ alist_t *alist = arg2;
+ if (alist->al_namefree)
+ alist->al_namefree(el->ale_name);
+ if (alist->al_valfree)
+ alist->al_valfree(el->ale_name);
+ free(el);
+}
+
+void
+alist_free(alist_t *alist)
+{
+ hash_free(alist->al_elements, alist_free_cb, alist);
+ free(alist);
+}
+
+void
+alist_add(alist_t *alist, void *name, void *value)
+{
+ alist_el_t *el;
+
+ el = xmalloc(sizeof (alist_el_t));
+ el->ale_name = name;
+ el->ale_value = value;
+ hash_add(alist->al_elements, el);
+}
+
+int
+alist_find(alist_t *alist, void *name, void **value)
+{
+ alist_el_t template, *retx;
+ void *ret;
+
+ template.ale_name = name;
+ if (!hash_find(alist->al_elements, &template, &ret))
+ return (0);
+
+ if (value) {
+ retx = ret;
+ *value = retx->ale_value;
+ }
+
+ return (1);
+}
+
+typedef struct alist_iter_data {
+ int (*aid_func)(void *, void *, void *);
+ void *aid_priv;
+} alist_iter_data_t;
+
+static int
+alist_iter_cb(void *arg1, void *arg2)
+{
+ alist_el_t *el = arg1;
+ alist_iter_data_t *aid = arg2;
+ return (aid->aid_func(el->ale_name, el->ale_value, aid->aid_priv));
+}
+
+int
+alist_iter(alist_t *alist, int (*func)(void *, void *, void *), void *private)
+{
+ alist_iter_data_t aid;
+
+ aid.aid_func = func;
+ aid.aid_priv = private;
+
+ return (hash_iter(alist->al_elements, alist_iter_cb, &aid));
+}
+
+/*
+ * Debugging support. Used to print the contents of an alist.
+ */
+
+void
+alist_stats(alist_t *alist, int verbose)
+{
+ printf("Alist statistics\n");
+ hash_stats(alist->al_elements, verbose);
+}
+
+static int alist_def_print_cb_key_int = 1;
+static int alist_def_print_cb_value_int = 1;
+
+static int
+alist_def_print_cb(void *key, void *value)
+{
+ printf("Key: ");
+ if (alist_def_print_cb_key_int == 1)
+ printf("%5lu ", (ulong_t)key);
+ else
+ printf("%s\n", (char *)key);
+
+ printf("Value: ");
+ if (alist_def_print_cb_value_int == 1)
+ printf("%5lu\n", (ulong_t)value);
+ else
+ printf("%s\n", (char *)key);
+
+ return (1);
+}
+
+static int
+alist_dump_cb(void *node, void *private)
+{
+ int (*printer)(void *, void *) = private;
+ alist_el_t *el = node;
+
+ printer(el->ale_name, el->ale_value);
+
+ return (1);
+}
+
+int
+alist_dump(alist_t *alist, int (*printer)(void *, void *))
+{
+ if (!printer)
+ printer = alist_def_print_cb;
+
+ return (hash_iter(alist->al_elements, alist_dump_cb, (void *)printer));
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/alist.h b/cddl/contrib/opensolaris/tools/ctf/cvt/alist.h
new file mode 100644
index 0000000..629e029
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/alist.h
@@ -0,0 +1,57 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ASSOC_H
+#define _ASSOC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Create, manage, and destroy association lists. alists are arrays with
+ * arbitrary index types.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct alist alist_t;
+
+alist_t *alist_new(void (*)(void *), void (*)(void *));
+alist_t *alist_xnew(int, void (*)(void *), void (*)(void *),
+ int (*)(int, void *), int (*)(void *, void *));
+void alist_free(alist_t *);
+void alist_add(alist_t *, void *, void *);
+int alist_find(alist_t *, void *, void **);
+int alist_iter(alist_t *, int (*)(void *, void *, void *), void *);
+void alist_stats(alist_t *, int);
+int alist_dump(alist_t *, int (*)(void *, void *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASSOC_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.c b/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.c
new file mode 100644
index 0000000..bc278b0
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.c
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file implements a barrier, a synchronization primitive designed to allow
+ * threads to wait for each other at given points. Barriers are initialized
+ * with a given number of threads, n, using barrier_init(). When a thread calls
+ * barrier_wait(), that thread blocks until n - 1 other threads reach the
+ * barrier_wait() call using the same barrier_t. When n threads have reached
+ * the barrier, they are all awakened and sent on their way. One of the threads
+ * returns from barrier_wait() with a return code of 1; the remaining threads
+ * get a return code of 0.
+ */
+
+#include <pthread.h>
+#if defined(sun)
+#include <synch.h>
+#endif
+#include <stdio.h>
+
+#include "barrier.h"
+
+void
+barrier_init(barrier_t *bar, int nthreads)
+{
+ pthread_mutex_init(&bar->bar_lock, NULL);
+#if defined(sun)
+ sema_init(&bar->bar_sem, 0, USYNC_THREAD, NULL);
+#else
+ sem_init(&bar->bar_sem, 0, 0);
+#endif
+
+ bar->bar_numin = 0;
+ bar->bar_nthr = nthreads;
+}
+
+int
+barrier_wait(barrier_t *bar)
+{
+ pthread_mutex_lock(&bar->bar_lock);
+
+ if (++bar->bar_numin < bar->bar_nthr) {
+ pthread_mutex_unlock(&bar->bar_lock);
+#if defined(sun)
+ sema_wait(&bar->bar_sem);
+#else
+ sem_wait(&bar->bar_sem);
+#endif
+
+ return (0);
+
+ } else {
+ int i;
+
+ /* reset for next use */
+ bar->bar_numin = 0;
+ for (i = 1; i < bar->bar_nthr; i++)
+#if defined(sun)
+ sema_post(&bar->bar_sem);
+#else
+ sem_post(&bar->bar_sem);
+#endif
+ pthread_mutex_unlock(&bar->bar_lock);
+
+ return (1);
+ }
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.h b/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.h
new file mode 100644
index 0000000..c7e6212
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/barrier.h
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _BARRIER_H
+#define _BARRIER_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * APIs for the barrier synchronization primitive.
+ */
+
+#if defined(sun)
+#include <synch.h>
+#else
+#include <semaphore.h>
+typedef sem_t sema_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct barrier {
+ pthread_mutex_t bar_lock; /* protects bar_numin */
+ int bar_numin; /* current number of waiters */
+
+ sema_t bar_sem; /* where everyone waits */
+ int bar_nthr; /* # of waiters to trigger release */
+} barrier_t;
+
+extern void barrier_init(barrier_t *, int);
+extern int barrier_wait(barrier_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BARRIER_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/compare.c b/cddl/contrib/opensolaris/tools/ctf/cvt/compare.c
new file mode 100644
index 0000000..26037f8
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/compare.c
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This is a test program designed to catch mismerges and mistranslations from
+ * stabs to CTF.
+ *
+ * Given a file with stabs data and a file with CTF data, determine whether
+ * or not all of the data structures and objects described by the stabs data
+ * are present in the CTF data.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "ctftools.h"
+
+char *progname;
+int debug_level = DEBUG_LEVEL;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s ctf_file stab_file\n", progname);
+}
+
+int
+main(int argc, char **argv)
+{
+ tdata_t *ctftd, *stabrtd, *stabtd, *difftd;
+ char *ctfname, *stabname;
+ int new;
+
+ progname = argv[0];
+
+ if (argc != 3) {
+ usage();
+ exit(2);
+ }
+
+ ctfname = argv[1];
+ stabname = argv[2];
+
+ stabrtd = tdata_new();
+ stabtd = tdata_new();
+ difftd = tdata_new();
+
+ if (read_stabs(stabrtd, stabname, 0) != 0)
+ merge_into_master(stabrtd, stabtd, NULL, 1);
+ else if (read_ctf(&stabname, 1, NULL, read_ctf_save_cb, &stabtd, 0)
+ == 0)
+ terminate("%s doesn't have stabs or CTF\n", stabname);
+
+ if (read_ctf(&ctfname, 1, NULL, read_ctf_save_cb, &ctftd, 0) == 0)
+ terminate("%s doesn't contain CTF data\n", ctfname);
+
+ merge_into_master(stabtd, ctftd, difftd, 0);
+
+ if ((new = hash_count(difftd->td_iihash)) != 0) {
+ (void) hash_iter(difftd->td_iihash, (int (*)())iidesc_dump,
+ NULL);
+ terminate("%s grew by %d\n", stabname, new);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
new file mode 100644
index 0000000..55dd39e
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
@@ -0,0 +1,1384 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Create and parse buffers containing CTF data.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <ctype.h>
+#include <zlib.h>
+#include <elf.h>
+
+#include "ctf_headers.h"
+#include "ctftools.h"
+#include "strtab.h"
+#include "memory.h"
+
+/*
+ * Name of the file currently being read, used to print error messages. We
+ * assume that only one file will be read at a time, and thus make no attempt
+ * to allow curfile to be used simultaneously by multiple threads.
+ *
+ * The value is only valid during a call to ctf_load.
+ */
+char *curfile;
+
+#define CTF_BUF_CHUNK_SIZE (64 * 1024)
+#define RES_BUF_CHUNK_SIZE (64 * 1024)
+
+struct ctf_buf {
+ strtab_t ctb_strtab; /* string table */
+ caddr_t ctb_base; /* pointer to base of buffer */
+ caddr_t ctb_end; /* pointer to end of buffer */
+ caddr_t ctb_ptr; /* pointer to empty buffer space */
+ size_t ctb_size; /* size of buffer */
+ int nptent; /* number of processed types */
+ int ntholes; /* number of type holes */
+};
+
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+
+#define SWAP_16(x) (x) = BSWAP_16(x)
+#define SWAP_32(x) (x) = BSWAP_32(x)
+
+static int target_requires_swap;
+
+/*PRINTFLIKE1*/
+static void
+parseterminate(const char *fmt, ...)
+{
+ static char msgbuf[1024]; /* sigh */
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap);
+ va_end(ap);
+
+ terminate("%s: %s\n", curfile, msgbuf);
+}
+
+static void
+ctf_buf_grow(ctf_buf_t *b)
+{
+ off_t ptroff = b->ctb_ptr - b->ctb_base;
+
+ b->ctb_size += CTF_BUF_CHUNK_SIZE;
+ b->ctb_base = xrealloc(b->ctb_base, b->ctb_size);
+ b->ctb_end = b->ctb_base + b->ctb_size;
+ b->ctb_ptr = b->ctb_base + ptroff;
+}
+
+static ctf_buf_t *
+ctf_buf_new(void)
+{
+ ctf_buf_t *b = xcalloc(sizeof (ctf_buf_t));
+
+ strtab_create(&b->ctb_strtab);
+ ctf_buf_grow(b);
+
+ return (b);
+}
+
+static void
+ctf_buf_free(ctf_buf_t *b)
+{
+ strtab_destroy(&b->ctb_strtab);
+ free(b->ctb_base);
+ free(b);
+}
+
+static uint_t
+ctf_buf_cur(ctf_buf_t *b)
+{
+ return (b->ctb_ptr - b->ctb_base);
+}
+
+static void
+ctf_buf_write(ctf_buf_t *b, void const *p, size_t n)
+{
+ size_t len;
+
+ while (n != 0) {
+ if (b->ctb_ptr == b->ctb_end)
+ ctf_buf_grow(b);
+
+ len = MIN((size_t)(b->ctb_end - b->ctb_ptr), n);
+ bcopy(p, b->ctb_ptr, len);
+ b->ctb_ptr += len;
+
+ p = (char const *)p + len;
+ n -= len;
+ }
+}
+
+static int
+write_label(void *arg1, void *arg2)
+{
+ labelent_t *le = arg1;
+ ctf_buf_t *b = arg2;
+ ctf_lblent_t ctl;
+
+ ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name);
+ ctl.ctl_typeidx = le->le_idx;
+
+ if (target_requires_swap) {
+ SWAP_32(ctl.ctl_label);
+ SWAP_32(ctl.ctl_typeidx);
+ }
+
+ ctf_buf_write(b, &ctl, sizeof (ctl));
+
+ return (1);
+}
+
+static void
+write_objects(iidesc_t *idp, ctf_buf_t *b)
+{
+ ushort_t id = (idp ? idp->ii_dtype->t_id : 0);
+
+ ctf_buf_write(b, &id, sizeof (id));
+
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
+ debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id);
+}
+
+static void
+write_functions(iidesc_t *idp, ctf_buf_t *b)
+{
+ ushort_t fdata[2];
+ ushort_t id;
+ int nargs;
+ int i;
+
+ if (!idp) {
+ fdata[0] = 0;
+ ctf_buf_write(b, &fdata[0], sizeof (fdata[0]));
+
+ debug(3, "Wrote function (null)\n");
+ return;
+ }
+
+ nargs = idp->ii_nargs + (idp->ii_vargs != 0);
+
+ if (nargs > CTF_MAX_VLEN) {
+ terminate("function %s has too many args: %d > %d\n",
+ idp->ii_name, nargs, CTF_MAX_VLEN);
+ }
+
+ fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs);
+ fdata[1] = idp->ii_dtype->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(fdata[0]);
+ SWAP_16(fdata[1]);
+ }
+
+ ctf_buf_write(b, fdata, sizeof (fdata));
+
+ for (i = 0; i < idp->ii_nargs; i++) {
+ id = idp->ii_args[i]->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
+ ctf_buf_write(b, &id, sizeof (id));
+ }
+
+ if (idp->ii_vargs) {
+ id = 0;
+ ctf_buf_write(b, &id, sizeof (id));
+ }
+
+ debug(3, "Wrote function %s (%d args)\n", idp->ii_name, nargs);
+}
+
+/*
+ * Depending on the size of the type being described, either a ctf_stype_t (for
+ * types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be
+ * written. We isolate the determination here so the rest of the writer code
+ * doesn't need to care.
+ */
+static void
+write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size)
+{
+ if (size > CTF_MAX_SIZE) {
+ ctt->ctt_size = CTF_LSIZE_SENT;
+ ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
+ ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
+ if (target_requires_swap) {
+ SWAP_32(ctt->ctt_name);
+ SWAP_16(ctt->ctt_info);
+ SWAP_16(ctt->ctt_size);
+ SWAP_32(ctt->ctt_lsizehi);
+ SWAP_32(ctt->ctt_lsizelo);
+ }
+ ctf_buf_write(b, ctt, sizeof (*ctt));
+ } else {
+ ctf_stype_t *cts = (ctf_stype_t *)ctt;
+
+ cts->ctt_size = (ushort_t)size;
+
+ if (target_requires_swap) {
+ SWAP_32(cts->ctt_name);
+ SWAP_16(cts->ctt_info);
+ SWAP_16(cts->ctt_size);
+ }
+
+ ctf_buf_write(b, cts, sizeof (*cts));
+ }
+}
+
+static void
+write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt)
+{
+ ctf_stype_t *cts = (ctf_stype_t *)ctt;
+
+ if (target_requires_swap) {
+ SWAP_32(cts->ctt_name);
+ SWAP_16(cts->ctt_info);
+ SWAP_16(cts->ctt_size);
+ }
+
+ ctf_buf_write(b, cts, sizeof (*cts));
+}
+
+static int
+write_type(void *arg1, void *arg2)
+{
+ tdesc_t *tp = arg1;
+ ctf_buf_t *b = arg2;
+ elist_t *ep;
+ mlist_t *mp;
+ intr_t *ip;
+
+ size_t offset;
+ uint_t encoding;
+ uint_t data;
+ int isroot = tp->t_flags & TDESC_F_ISROOT;
+ int i;
+
+ ctf_type_t ctt;
+ ctf_array_t cta;
+ ctf_member_t ctm;
+ ctf_lmember_t ctlm;
+ ctf_enum_t cte;
+ ushort_t id;
+
+ ctlm.ctlm_pad = 0;
+
+ /*
+ * There shouldn't be any holes in the type list (where a hole is
+ * defined as two consecutive tdescs without consecutive ids), but
+ * check for them just in case. If we do find holes, we need to make
+ * fake entries to fill the holes, or we won't be able to reconstruct
+ * the tree from the written data.
+ */
+ if (++b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) {
+ debug(2, "genctf: type hole from %d < x < %d\n",
+ b->nptent - 1, CTF_TYPE_TO_INDEX(tp->t_id));
+
+ ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, 0);
+ ctt.ctt_info = CTF_TYPE_INFO(0, 0, 0);
+ while (b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) {
+ write_sized_type_rec(b, &ctt, 0);
+ b->nptent++;
+ }
+ }
+
+ offset = strtab_insert(&b->ctb_strtab, tp->t_name);
+ ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
+
+ switch (tp->t_type) {
+ case INTRINSIC:
+ ip = tp->t_intr;
+ if (ip->intr_type == INTR_INT)
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_INTEGER,
+ isroot, 1);
+ else
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FLOAT, isroot, 1);
+ write_sized_type_rec(b, &ctt, tp->t_size);
+
+ encoding = 0;
+
+ if (ip->intr_type == INTR_INT) {
+ if (ip->intr_signed)
+ encoding |= CTF_INT_SIGNED;
+ if (ip->intr_iformat == 'c')
+ encoding |= CTF_INT_CHAR;
+ else if (ip->intr_iformat == 'b')
+ encoding |= CTF_INT_BOOL;
+ else if (ip->intr_iformat == 'v')
+ encoding |= CTF_INT_VARARGS;
+ } else
+ encoding = ip->intr_fformat;
+
+ data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits);
+ if (target_requires_swap) {
+ SWAP_32(data);
+ }
+ ctf_buf_write(b, &data, sizeof (data));
+ break;
+
+ case POINTER:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_POINTER, isroot, 0);
+ ctt.ctt_type = tp->t_tdesc->t_id;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ case ARRAY:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, isroot, 1);
+ write_sized_type_rec(b, &ctt, tp->t_size);
+
+ cta.cta_contents = tp->t_ardef->ad_contents->t_id;
+ cta.cta_index = tp->t_ardef->ad_idxtype->t_id;
+ cta.cta_nelems = tp->t_ardef->ad_nelems;
+ if (target_requires_swap) {
+ SWAP_16(cta.cta_contents);
+ SWAP_16(cta.cta_index);
+ SWAP_32(cta.cta_nelems);
+ }
+ ctf_buf_write(b, &cta, sizeof (cta));
+ break;
+
+ case STRUCT:
+ case UNION:
+ for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next)
+ i++; /* count up struct or union members */
+
+ if (i > CTF_MAX_VLEN) {
+ terminate("sou %s has too many members: %d > %d\n",
+ tdesc_name(tp), i, CTF_MAX_VLEN);
+ }
+
+ if (tp->t_type == STRUCT)
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, isroot, i);
+ else
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, isroot, i);
+
+ write_sized_type_rec(b, &ctt, tp->t_size);
+
+ if (tp->t_size < CTF_LSTRUCT_THRESH) {
+ for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) {
+ offset = strtab_insert(&b->ctb_strtab,
+ mp->ml_name);
+
+ ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0,
+ offset);
+ ctm.ctm_type = mp->ml_type->t_id;
+ ctm.ctm_offset = mp->ml_offset;
+ if (target_requires_swap) {
+ SWAP_32(ctm.ctm_name);
+ SWAP_16(ctm.ctm_type);
+ SWAP_16(ctm.ctm_offset);
+ }
+ ctf_buf_write(b, &ctm, sizeof (ctm));
+ }
+ } else {
+ for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) {
+ offset = strtab_insert(&b->ctb_strtab,
+ mp->ml_name);
+
+ ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0,
+ offset);
+ ctlm.ctlm_type = mp->ml_type->t_id;
+ ctlm.ctlm_offsethi =
+ CTF_OFFSET_TO_LMEMHI(mp->ml_offset);
+ ctlm.ctlm_offsetlo =
+ CTF_OFFSET_TO_LMEMLO(mp->ml_offset);
+
+ if (target_requires_swap) {
+ SWAP_32(ctlm.ctlm_name);
+ SWAP_16(ctlm.ctlm_type);
+ SWAP_32(ctlm.ctlm_offsethi);
+ SWAP_32(ctlm.ctlm_offsetlo);
+ }
+
+ ctf_buf_write(b, &ctlm, sizeof (ctlm));
+ }
+ }
+ break;
+
+ case ENUM:
+ for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next)
+ i++; /* count up enum members */
+
+ if (i > CTF_MAX_VLEN) {
+ warning("enum %s has too many values: %d > %d\n",
+ tdesc_name(tp), i, CTF_MAX_VLEN);
+ i = CTF_MAX_VLEN;
+ }
+
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i);
+ write_sized_type_rec(b, &ctt, tp->t_size);
+
+ for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) {
+ offset = strtab_insert(&b->ctb_strtab, ep->el_name);
+ cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
+ cte.cte_value = ep->el_number;
+
+ if (target_requires_swap) {
+ SWAP_32(cte.cte_name);
+ SWAP_32(cte.cte_value);
+ }
+
+ ctf_buf_write(b, &cte, sizeof (cte));
+ i--;
+ }
+ break;
+
+ case FORWARD:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, isroot, 0);
+ ctt.ctt_type = 0;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ case TYPEDEF:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0);
+ ctt.ctt_type = tp->t_tdesc->t_id;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ case VOLATILE:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_VOLATILE, isroot, 0);
+ ctt.ctt_type = tp->t_tdesc->t_id;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ case CONST:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_CONST, isroot, 0);
+ ctt.ctt_type = tp->t_tdesc->t_id;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ case FUNCTION:
+ i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs;
+
+ if (i > CTF_MAX_VLEN) {
+ terminate("function %s has too many args: %d > %d\n",
+ i, CTF_MAX_VLEN);
+ }
+
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, i);
+ ctt.ctt_type = tp->t_fndef->fn_ret->t_id;
+ write_unsized_type_rec(b, &ctt);
+
+ for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) {
+ id = tp->t_fndef->fn_args[i]->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
+ ctf_buf_write(b, &id, sizeof (id));
+ }
+
+ if (tp->t_fndef->fn_vargs) {
+ id = 0;
+ ctf_buf_write(b, &id, sizeof (id));
+ i++;
+ }
+
+ if (i & 1) {
+ id = 0;
+ ctf_buf_write(b, &id, sizeof (id));
+ }
+ break;
+
+ case RESTRICT:
+ ctt.ctt_info = CTF_TYPE_INFO(CTF_K_RESTRICT, isroot, 0);
+ ctt.ctt_type = tp->t_tdesc->t_id;
+ write_unsized_type_rec(b, &ctt);
+ break;
+
+ default:
+ warning("Can't write unknown type %d\n", tp->t_type);
+ }
+
+ debug(3, "Wrote type %d %s\n", tp->t_id, tdesc_name(tp));
+
+ return (1);
+}
+
+typedef struct resbuf {
+ caddr_t rb_base;
+ caddr_t rb_ptr;
+ size_t rb_size;
+ z_stream rb_zstr;
+} resbuf_t;
+
+static void
+rbzs_grow(resbuf_t *rb)
+{
+ off_t ptroff = (caddr_t)rb->rb_zstr.next_out - rb->rb_base;
+
+ rb->rb_size += RES_BUF_CHUNK_SIZE;
+ rb->rb_base = xrealloc(rb->rb_base, rb->rb_size);
+ rb->rb_ptr = rb->rb_base + ptroff;
+ rb->rb_zstr.next_out = (Bytef *)(rb->rb_ptr);
+ rb->rb_zstr.avail_out += RES_BUF_CHUNK_SIZE;
+}
+
+static void
+compress_start(resbuf_t *rb)
+{
+ int rc;
+
+ rb->rb_zstr.zalloc = (alloc_func)0;
+ rb->rb_zstr.zfree = (free_func)0;
+ rb->rb_zstr.opaque = (voidpf)0;
+
+ if ((rc = deflateInit(&rb->rb_zstr, Z_BEST_COMPRESSION)) != Z_OK)
+ parseterminate("zlib start failed: %s", zError(rc));
+}
+
+static ssize_t
+compress_buffer(void *buf, size_t n, void *data)
+{
+ resbuf_t *rb = (resbuf_t *)data;
+ int rc;
+
+ rb->rb_zstr.next_out = (Bytef *)rb->rb_ptr;
+ rb->rb_zstr.avail_out = rb->rb_size - (rb->rb_ptr - rb->rb_base);
+ rb->rb_zstr.next_in = buf;
+ rb->rb_zstr.avail_in = n;
+
+ while (rb->rb_zstr.avail_in) {
+ if (rb->rb_zstr.avail_out == 0)
+ rbzs_grow(rb);
+
+ if ((rc = deflate(&rb->rb_zstr, Z_NO_FLUSH)) != Z_OK)
+ parseterminate("zlib deflate failed: %s", zError(rc));
+ }
+ rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out;
+
+ return (n);
+}
+
+static void
+compress_flush(resbuf_t *rb, int type)
+{
+ int rc;
+
+ for (;;) {
+ if (rb->rb_zstr.avail_out == 0)
+ rbzs_grow(rb);
+
+ rc = deflate(&rb->rb_zstr, type);
+ if ((type == Z_FULL_FLUSH && rc == Z_BUF_ERROR) ||
+ (type == Z_FINISH && rc == Z_STREAM_END))
+ break;
+ else if (rc != Z_OK)
+ parseterminate("zlib finish failed: %s", zError(rc));
+ }
+ rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out;
+}
+
+static void
+compress_end(resbuf_t *rb)
+{
+ int rc;
+
+ compress_flush(rb, Z_FINISH);
+
+ if ((rc = deflateEnd(&rb->rb_zstr)) != Z_OK)
+ parseterminate("zlib end failed: %s", zError(rc));
+}
+
+/*
+ * Pad the buffer to a power-of-2 boundary
+ */
+static void
+pad_buffer(ctf_buf_t *buf, int align)
+{
+ uint_t cur = ctf_buf_cur(buf);
+ ssize_t topad = (align - (cur % align)) % align;
+ static const char pad[8] = { 0 };
+
+ while (topad > 0) {
+ ctf_buf_write(buf, pad, (topad > 8 ? 8 : topad));
+ topad -= 8;
+ }
+}
+
+static ssize_t
+bcopy_data(void *buf, size_t n, void *data)
+{
+ caddr_t *posp = (caddr_t *)data;
+ bcopy(buf, *posp, n);
+ *posp += n;
+ return (n);
+}
+
+static caddr_t
+write_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp)
+{
+ caddr_t outbuf;
+ caddr_t bufpos;
+
+ outbuf = xmalloc(sizeof (ctf_header_t) + (buf->ctb_ptr - buf->ctb_base)
+ + buf->ctb_strtab.str_size);
+
+ bufpos = outbuf;
+ (void) bcopy_data(h, sizeof (ctf_header_t), &bufpos);
+ (void) bcopy_data(buf->ctb_base, buf->ctb_ptr - buf->ctb_base,
+ &bufpos);
+ (void) strtab_write(&buf->ctb_strtab, bcopy_data, &bufpos);
+ *resszp = bufpos - outbuf;
+ return (outbuf);
+}
+
+/*
+ * Create the compression buffer, and fill it with the CTF and string
+ * table data. We flush the compression state between the two so the
+ * dictionary used for the string tables won't be polluted with values
+ * that made sense for the CTF data.
+ */
+static caddr_t
+write_compressed_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp)
+{
+ resbuf_t resbuf;
+ resbuf.rb_size = RES_BUF_CHUNK_SIZE;
+ resbuf.rb_base = xmalloc(resbuf.rb_size);
+ bcopy(h, resbuf.rb_base, sizeof (ctf_header_t));
+ resbuf.rb_ptr = resbuf.rb_base + sizeof (ctf_header_t);
+
+ compress_start(&resbuf);
+ (void) compress_buffer(buf->ctb_base, buf->ctb_ptr - buf->ctb_base,
+ &resbuf);
+ compress_flush(&resbuf, Z_FULL_FLUSH);
+ (void) strtab_write(&buf->ctb_strtab, compress_buffer, &resbuf);
+ compress_end(&resbuf);
+
+ *resszp = (resbuf.rb_ptr - resbuf.rb_base);
+ return (resbuf.rb_base);
+}
+
+caddr_t
+ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress)
+{
+ ctf_buf_t *buf = ctf_buf_new();
+ ctf_header_t h;
+ caddr_t outbuf;
+
+ int i;
+
+ target_requires_swap = do_compress & CTF_SWAP_BYTES;
+ do_compress &= ~CTF_SWAP_BYTES;
+
+ /*
+ * Prepare the header, and create the CTF output buffers. The data
+ * object section and function section are both lists of 2-byte
+ * integers; we pad these out to the next 4-byte boundary if needed.
+ */
+ h.cth_magic = CTF_MAGIC;
+ h.cth_version = CTF_VERSION;
+ h.cth_flags = do_compress ? CTF_F_COMPRESS : 0;
+ h.cth_parlabel = strtab_insert(&buf->ctb_strtab,
+ iiburst->iib_td->td_parlabel);
+ h.cth_parname = strtab_insert(&buf->ctb_strtab,
+ iiburst->iib_td->td_parname);
+
+ h.cth_lbloff = 0;
+ (void) list_iter(iiburst->iib_td->td_labels, write_label,
+ buf);
+
+ pad_buffer(buf, 2);
+ h.cth_objtoff = ctf_buf_cur(buf);
+ for (i = 0; i < iiburst->iib_nobjts; i++)
+ write_objects(iiburst->iib_objts[i], buf);
+
+ pad_buffer(buf, 2);
+ h.cth_funcoff = ctf_buf_cur(buf);
+ for (i = 0; i < iiburst->iib_nfuncs; i++)
+ write_functions(iiburst->iib_funcs[i], buf);
+
+ pad_buffer(buf, 4);
+ h.cth_typeoff = ctf_buf_cur(buf);
+ (void) list_iter(iiburst->iib_types, write_type, buf);
+
+ debug(2, "CTF wrote %d types\n", list_count(iiburst->iib_types));
+
+ h.cth_stroff = ctf_buf_cur(buf);
+ h.cth_strlen = strtab_size(&buf->ctb_strtab);
+
+ if (target_requires_swap) {
+ SWAP_16(h.cth_preamble.ctp_magic);
+ SWAP_32(h.cth_parlabel);
+ SWAP_32(h.cth_parname);
+ SWAP_32(h.cth_lbloff);
+ SWAP_32(h.cth_objtoff);
+ SWAP_32(h.cth_funcoff);
+ SWAP_32(h.cth_typeoff);
+ SWAP_32(h.cth_stroff);
+ SWAP_32(h.cth_strlen);
+ }
+
+ /*
+ * We only do compression for ctfmerge, as ctfconvert is only
+ * supposed to be used on intermediary build objects. This is
+ * significantly faster.
+ */
+ if (do_compress)
+ outbuf = write_compressed_buffer(&h, buf, resszp);
+ else
+ outbuf = write_buffer(&h, buf, resszp);
+
+ ctf_buf_free(buf);
+ return (outbuf);
+}
+
+static void
+get_ctt_size(ctf_type_t *ctt, size_t *sizep, size_t *incrementp)
+{
+ if (ctt->ctt_size == CTF_LSIZE_SENT) {
+ *sizep = (size_t)CTF_TYPE_LSIZE(ctt);
+ *incrementp = sizeof (ctf_type_t);
+ } else {
+ *sizep = ctt->ctt_size;
+ *incrementp = sizeof (ctf_stype_t);
+ }
+}
+
+static int
+count_types(ctf_header_t *h, caddr_t data)
+{
+ caddr_t dptr = data + h->cth_typeoff;
+ int count = 0;
+
+ dptr = data + h->cth_typeoff;
+ while (dptr < data + h->cth_stroff) {
+ void *v = (void *) dptr;
+ ctf_type_t *ctt = v;
+ size_t vlen = CTF_INFO_VLEN(ctt->ctt_info);
+ size_t size, increment;
+
+ get_ctt_size(ctt, &size, &increment);
+
+ switch (CTF_INFO_KIND(ctt->ctt_info)) {
+ case CTF_K_INTEGER:
+ case CTF_K_FLOAT:
+ dptr += 4;
+ break;
+ case CTF_K_POINTER:
+ case CTF_K_FORWARD:
+ case CTF_K_TYPEDEF:
+ case CTF_K_VOLATILE:
+ case CTF_K_CONST:
+ case CTF_K_RESTRICT:
+ case CTF_K_FUNCTION:
+ dptr += sizeof (ushort_t) * (vlen + (vlen & 1));
+ break;
+ case CTF_K_ARRAY:
+ dptr += sizeof (ctf_array_t);
+ break;
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (size < CTF_LSTRUCT_THRESH)
+ dptr += sizeof (ctf_member_t) * vlen;
+ else
+ dptr += sizeof (ctf_lmember_t) * vlen;
+ break;
+ case CTF_K_ENUM:
+ dptr += sizeof (ctf_enum_t) * vlen;
+ break;
+ case CTF_K_UNKNOWN:
+ break;
+ default:
+ parseterminate("Unknown CTF type %d (#%d) at %#x",
+ CTF_INFO_KIND(ctt->ctt_info), count, dptr - data);
+ }
+
+ dptr += increment;
+ count++;
+ }
+
+ debug(3, "CTF read %d types\n", count);
+
+ return (count);
+}
+
+/*
+ * Resurrect the labels stored in the CTF data, returning the index associated
+ * with a label provided by the caller. There are several cases, outlined
+ * below. Note that, given two labels, the one associated with the lesser type
+ * index is considered to be older than the other.
+ *
+ * 1. matchlbl == NULL - return the index of the most recent label.
+ * 2. matchlbl == "BASE" - return the index of the oldest label.
+ * 3. matchlbl != NULL, but doesn't match any labels in the section - warn
+ * the user, and proceed as if matchlbl == "BASE" (for safety).
+ * 4. matchlbl != NULL, and matches one of the labels in the section - return
+ * the type index associated with the label.
+ */
+static int
+resurrect_labels(ctf_header_t *h, tdata_t *td, caddr_t ctfdata, char *matchlbl)
+{
+ caddr_t buf = ctfdata + h->cth_lbloff;
+ caddr_t sbuf = ctfdata + h->cth_stroff;
+ size_t bufsz = h->cth_objtoff - h->cth_lbloff;
+ int lastidx = 0, baseidx = -1;
+ char *baselabel = NULL;
+ ctf_lblent_t *ctl;
+ void *v = (void *) buf;
+
+ for (ctl = v; (caddr_t)ctl < buf + bufsz; ctl++) {
+ char *label = sbuf + ctl->ctl_label;
+
+ lastidx = ctl->ctl_typeidx;
+
+ debug(3, "Resurrected label %s type idx %d\n", label, lastidx);
+
+ tdata_label_add(td, label, lastidx);
+
+ if (baseidx == -1) {
+ baseidx = lastidx;
+ baselabel = label;
+ if (matchlbl != NULL && streq(matchlbl, "BASE"))
+ return (lastidx);
+ }
+
+ if (matchlbl != NULL && streq(label, matchlbl))
+ return (lastidx);
+ }
+
+ if (matchlbl != NULL) {
+ /* User provided a label that didn't match */
+ warning("%s: Cannot find label `%s' - using base (%s)\n",
+ curfile, matchlbl, (baselabel ? baselabel : "NONE"));
+
+ tdata_label_free(td);
+ tdata_label_add(td, baselabel, baseidx);
+
+ return (baseidx);
+ }
+
+ return (lastidx);
+}
+
+static void
+resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
+ caddr_t ctfdata, symit_data_t *si)
+{
+ caddr_t buf = ctfdata + h->cth_objtoff;
+ size_t bufsz = h->cth_funcoff - h->cth_objtoff;
+ caddr_t dptr;
+
+ symit_reset(si);
+ for (dptr = buf; dptr < buf + bufsz; dptr += 2) {
+ void *v = (void *) dptr;
+ ushort_t id = *((ushort_t *)v);
+ iidesc_t *ii;
+ GElf_Sym *sym;
+
+ if (!(sym = symit_next(si, STT_OBJECT)) && id != 0) {
+ parseterminate(
+ "Unexpected end of object symbols at %x of %x",
+ dptr - buf, bufsz);
+ }
+
+ if (id == 0) {
+ debug(3, "Skipping null object\n");
+ continue;
+ } else if (id >= tdsize) {
+ parseterminate("Reference to invalid type %d", id);
+ }
+
+ ii = iidesc_new(symit_name(si));
+ ii->ii_dtype = tdarr[id];
+ if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) {
+ ii->ii_type = II_SVAR;
+ ii->ii_owner = xstrdup(symit_curfile(si));
+ } else
+ ii->ii_type = II_GVAR;
+ hash_add(td->td_iihash, ii);
+
+ debug(3, "Resurrected %s object %s (%d) from %s\n",
+ (ii->ii_type == II_GVAR ? "global" : "static"),
+ ii->ii_name, id, (ii->ii_owner ? ii->ii_owner : "(none)"));
+ }
+}
+
+static void
+resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
+ caddr_t ctfdata, symit_data_t *si)
+{
+ caddr_t buf = ctfdata + h->cth_funcoff;
+ size_t bufsz = h->cth_typeoff - h->cth_funcoff;
+ caddr_t dptr = buf;
+ iidesc_t *ii;
+ ushort_t info;
+ ushort_t retid;
+ GElf_Sym *sym;
+ int i;
+
+ symit_reset(si);
+ while (dptr < buf + bufsz) {
+ void *v = (void *) dptr;
+ info = *((ushort_t *)v);
+ dptr += 2;
+
+ if (!(sym = symit_next(si, STT_FUNC)) && info != 0)
+ parseterminate("Unexpected end of function symbols");
+
+ if (info == 0) {
+ debug(3, "Skipping null function (%s)\n",
+ symit_name(si));
+ continue;
+ }
+
+ v = (void *) dptr;
+ retid = *((ushort_t *)v);
+ dptr += 2;
+
+ if (retid >= tdsize)
+ parseterminate("Reference to invalid type %d", retid);
+
+ ii = iidesc_new(symit_name(si));
+ ii->ii_dtype = tdarr[retid];
+ if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) {
+ ii->ii_type = II_SFUN;
+ ii->ii_owner = xstrdup(symit_curfile(si));
+ } else
+ ii->ii_type = II_GFUN;
+ ii->ii_nargs = CTF_INFO_VLEN(info);
+ if (ii->ii_nargs)
+ ii->ii_args =
+ xmalloc(sizeof (tdesc_t *) * ii->ii_nargs);
+
+ for (i = 0; i < ii->ii_nargs; i++, dptr += 2) {
+ v = (void *) dptr;
+ ushort_t id = *((ushort_t *)v);
+ if (id >= tdsize)
+ parseterminate("Reference to invalid type %d",
+ id);
+ ii->ii_args[i] = tdarr[id];
+ }
+
+ if (ii->ii_nargs && ii->ii_args[ii->ii_nargs - 1] == NULL) {
+ ii->ii_nargs--;
+ ii->ii_vargs = 1;
+ }
+
+ hash_add(td->td_iihash, ii);
+
+ debug(3, "Resurrected %s function %s (%d, %d args)\n",
+ (ii->ii_type == II_GFUN ? "global" : "static"),
+ ii->ii_name, retid, ii->ii_nargs);
+ }
+}
+
+static void
+resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
+ caddr_t ctfdata, int maxid)
+{
+ caddr_t buf = ctfdata + h->cth_typeoff;
+ size_t bufsz = h->cth_stroff - h->cth_typeoff;
+ caddr_t sbuf = ctfdata + h->cth_stroff;
+ caddr_t dptr = buf;
+ tdesc_t *tdp;
+ uint_t data;
+ uint_t encoding;
+ size_t size, increment;
+ int tcnt;
+ int iicnt = 0;
+ tid_t tid, argid;
+ int kind, vlen;
+ int i;
+
+ elist_t **epp;
+ mlist_t **mpp;
+ intr_t *ip;
+
+ ctf_type_t *ctt;
+ ctf_array_t *cta;
+ ctf_enum_t *cte;
+
+ /*
+ * A maxid of zero indicates a request to resurrect all types, so reset
+ * maxid to the maximum type id.
+ */
+ if (maxid == 0)
+ maxid = CTF_MAX_TYPE;
+
+ for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) {
+ if (tid > maxid)
+ break;
+
+ if (tid >= tdsize)
+ parseterminate("Reference to invalid type %d", tid);
+
+ void *v = (void *) dptr;
+ ctt = v;
+
+ get_ctt_size(ctt, &size, &increment);
+ dptr += increment;
+
+ tdp = tdarr[tid];
+
+ if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0)
+ parseterminate(
+ "Unable to cope with non-zero strtab id");
+ if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) {
+ tdp->t_name =
+ xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name));
+ } else
+ tdp->t_name = NULL;
+
+ kind = CTF_INFO_KIND(ctt->ctt_info);
+ vlen = CTF_INFO_VLEN(ctt->ctt_info);
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ tdp->t_type = INTRINSIC;
+ tdp->t_size = size;
+
+ v = (void *) dptr;
+ data = *((uint_t *)v);
+ dptr += sizeof (uint_t);
+ encoding = CTF_INT_ENCODING(data);
+
+ ip = xmalloc(sizeof (intr_t));
+ ip->intr_type = INTR_INT;
+ ip->intr_signed = (encoding & CTF_INT_SIGNED) ? 1 : 0;
+
+ if (encoding & CTF_INT_CHAR)
+ ip->intr_iformat = 'c';
+ else if (encoding & CTF_INT_BOOL)
+ ip->intr_iformat = 'b';
+ else if (encoding & CTF_INT_VARARGS)
+ ip->intr_iformat = 'v';
+ else
+ ip->intr_iformat = '\0';
+
+ ip->intr_offset = CTF_INT_OFFSET(data);
+ ip->intr_nbits = CTF_INT_BITS(data);
+ tdp->t_intr = ip;
+ break;
+
+ case CTF_K_FLOAT:
+ tdp->t_type = INTRINSIC;
+ tdp->t_size = size;
+
+ v = (void *) dptr;
+ data = *((uint_t *)v);
+ dptr += sizeof (uint_t);
+
+ ip = xcalloc(sizeof (intr_t));
+ ip->intr_type = INTR_REAL;
+ ip->intr_fformat = CTF_FP_ENCODING(data);
+ ip->intr_offset = CTF_FP_OFFSET(data);
+ ip->intr_nbits = CTF_FP_BITS(data);
+ tdp->t_intr = ip;
+ break;
+
+ case CTF_K_POINTER:
+ tdp->t_type = POINTER;
+ tdp->t_tdesc = tdarr[ctt->ctt_type];
+ break;
+
+ case CTF_K_ARRAY:
+ tdp->t_type = ARRAY;
+ tdp->t_size = size;
+
+ v = (void *) dptr;
+ cta = v;
+ dptr += sizeof (ctf_array_t);
+
+ tdp->t_ardef = xmalloc(sizeof (ardef_t));
+ tdp->t_ardef->ad_contents = tdarr[cta->cta_contents];
+ tdp->t_ardef->ad_idxtype = tdarr[cta->cta_index];
+ tdp->t_ardef->ad_nelems = cta->cta_nelems;
+ break;
+
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION);
+ tdp->t_size = size;
+
+ if (size < CTF_LSTRUCT_THRESH) {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ ctf_member_t *ctm = v;
+ dptr += sizeof (ctf_member_t);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctm->ctm_name);
+ (*mpp)->ml_type = tdarr[ctm->ctm_type];
+ (*mpp)->ml_offset = ctm->ctm_offset;
+ (*mpp)->ml_size = 0;
+ }
+ } else {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ ctf_lmember_t *ctlm = v;
+ dptr += sizeof (ctf_lmember_t);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctlm->ctlm_name);
+ (*mpp)->ml_type =
+ tdarr[ctlm->ctlm_type];
+ (*mpp)->ml_offset =
+ (int)CTF_LMEM_OFFSET(ctlm);
+ (*mpp)->ml_size = 0;
+ }
+ }
+
+ *mpp = NULL;
+ break;
+
+ case CTF_K_ENUM:
+ tdp->t_type = ENUM;
+ tdp->t_size = size;
+
+ for (i = 0, epp = &tdp->t_emem; i < vlen;
+ i++, epp = &((*epp)->el_next)) {
+ v = (void *) dptr;
+ cte = v;
+ dptr += sizeof (ctf_enum_t);
+
+ *epp = xmalloc(sizeof (elist_t));
+ (*epp)->el_name = xstrdup(sbuf + cte->cte_name);
+ (*epp)->el_number = cte->cte_value;
+ }
+ *epp = NULL;
+ break;
+
+ case CTF_K_FORWARD:
+ tdp->t_type = FORWARD;
+ list_add(&td->td_fwdlist, tdp);
+ break;
+
+ case CTF_K_TYPEDEF:
+ tdp->t_type = TYPEDEF;
+ tdp->t_tdesc = tdarr[ctt->ctt_type];
+ break;
+
+ case CTF_K_VOLATILE:
+ tdp->t_type = VOLATILE;
+ tdp->t_tdesc = tdarr[ctt->ctt_type];
+ break;
+
+ case CTF_K_CONST:
+ tdp->t_type = CONST;
+ tdp->t_tdesc = tdarr[ctt->ctt_type];
+ break;
+
+ case CTF_K_FUNCTION:
+ tdp->t_type = FUNCTION;
+ tdp->t_fndef = xcalloc(sizeof (fndef_t));
+ tdp->t_fndef->fn_ret = tdarr[ctt->ctt_type];
+
+ v = (void *) (dptr + (sizeof (ushort_t) * (vlen - 1)));
+ if (vlen > 0 && *(ushort_t *)v == 0)
+ tdp->t_fndef->fn_vargs = 1;
+
+ tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs;
+ tdp->t_fndef->fn_args = xcalloc(sizeof (tdesc_t) *
+ vlen - tdp->t_fndef->fn_vargs);
+
+ for (i = 0; i < vlen; i++) {
+ v = (void *) dptr;
+ argid = *(ushort_t *)v;
+ dptr += sizeof (ushort_t);
+
+ if (argid != 0)
+ tdp->t_fndef->fn_args[i] = tdarr[argid];
+ }
+
+ if (vlen & 1)
+ dptr += sizeof (ushort_t);
+ break;
+
+ case CTF_K_RESTRICT:
+ tdp->t_type = RESTRICT;
+ tdp->t_tdesc = tdarr[ctt->ctt_type];
+ break;
+
+ case CTF_K_UNKNOWN:
+ break;
+
+ default:
+ warning("Can't parse unknown CTF type %d\n", kind);
+ }
+
+ if (CTF_INFO_ISROOT(ctt->ctt_info)) {
+ iidesc_t *ii = iidesc_new(tdp->t_name);
+ if (tdp->t_type == STRUCT || tdp->t_type == UNION ||
+ tdp->t_type == ENUM)
+ ii->ii_type = II_SOU;
+ else
+ ii->ii_type = II_TYPE;
+ ii->ii_dtype = tdp;
+ hash_add(td->td_iihash, ii);
+
+ iicnt++;
+ }
+
+ debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type,
+ (CTF_INFO_ISROOT(ctt->ctt_info) ? "root " : ""),
+ tdesc_name(tdp), tdp->t_id);
+ }
+
+ debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt);
+}
+
+/*
+ * For lack of other inspiration, we're going to take the boring route. We
+ * count the number of types. This lets us malloc that many tdesc structs
+ * before we start filling them in. This has the advantage of allowing us to
+ * avoid a merge-esque remap step.
+ */
+static tdata_t *
+ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label)
+{
+ tdata_t *td = tdata_new();
+ tdesc_t **tdarr;
+ int ntypes = count_types(h, buf);
+ int idx, i;
+
+ /* shudder */
+ tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1));
+ tdarr[0] = NULL;
+ for (i = 1; i <= ntypes; i++) {
+ tdarr[i] = xcalloc(sizeof (tdesc_t));
+ tdarr[i]->t_id = i;
+ }
+
+ td->td_parlabel = xstrdup(buf + h->cth_stroff + h->cth_parlabel);
+
+ /* we have the technology - we can rebuild them */
+ idx = resurrect_labels(h, td, buf, label);
+
+ resurrect_objects(h, td, tdarr, ntypes + 1, buf, si);
+ resurrect_functions(h, td, tdarr, ntypes + 1, buf, si);
+ resurrect_types(h, td, tdarr, ntypes + 1, buf, idx);
+
+ free(tdarr);
+
+ td->td_nextid = ntypes + 1;
+
+ return (td);
+}
+
+static size_t
+decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz)
+{
+ z_stream zstr;
+ int rc;
+
+ zstr.zalloc = (alloc_func)0;
+ zstr.zfree = (free_func)0;
+ zstr.opaque = (voidpf)0;
+
+ zstr.next_in = (Bytef *)cbuf;
+ zstr.avail_in = cbufsz;
+ zstr.next_out = (Bytef *)dbuf;
+ zstr.avail_out = dbufsz;
+
+ if ((rc = inflateInit(&zstr)) != Z_OK ||
+ (rc = inflate(&zstr, Z_NO_FLUSH)) != Z_STREAM_END ||
+ (rc = inflateEnd(&zstr)) != Z_OK) {
+ warning("CTF decompress zlib error %s\n", zError(rc));
+ return (0);
+ }
+
+ debug(3, "reflated %lu bytes to %lu, pointer at %d\n",
+ zstr.total_in, zstr.total_out, (caddr_t)zstr.next_in - cbuf);
+
+ return (zstr.total_out);
+}
+
+/*
+ * Reconstruct the type tree from a given buffer of CTF data. Only the types
+ * up to the type associated with the provided label, inclusive, will be
+ * reconstructed. If a NULL label is provided, all types will be reconstructed.
+ *
+ * This function won't work on files that have been uniquified.
+ */
+tdata_t *
+ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label)
+{
+ ctf_header_t *h;
+ caddr_t ctfdata;
+ size_t ctfdatasz;
+ tdata_t *td;
+
+ curfile = file;
+
+ if (bufsz < sizeof (ctf_header_t))
+ parseterminate("Corrupt CTF - short header");
+
+ void *v = (void *) buf;
+ h = v;
+ buf += sizeof (ctf_header_t);
+ bufsz -= sizeof (ctf_header_t);
+
+ if (h->cth_magic != CTF_MAGIC)
+ parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic);
+
+ if (h->cth_version != CTF_VERSION)
+ parseterminate("Unknown CTF version %d", h->cth_version);
+
+ ctfdatasz = h->cth_stroff + h->cth_strlen;
+ if (h->cth_flags & CTF_F_COMPRESS) {
+ size_t actual;
+
+ ctfdata = xmalloc(ctfdatasz);
+ if ((actual = decompress_ctf(buf, bufsz, ctfdata, ctfdatasz)) !=
+ ctfdatasz) {
+ parseterminate("Corrupt CTF - short decompression "
+ "(was %d, expecting %d)", actual, ctfdatasz);
+ }
+ } else {
+ ctfdata = buf;
+ ctfdatasz = bufsz;
+ }
+
+ td = ctf_parse(h, ctfdata, si, label);
+
+ if (h->cth_flags & CTF_F_COMPRESS)
+ free(ctfdata);
+
+ curfile = NULL;
+
+ return (td);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfconvert.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfconvert.c
new file mode 100644
index 0000000..efe6c27
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfconvert.c
@@ -0,0 +1,263 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Given a file containing sections with stabs data, convert the stabs data to
+ * CTF data, and replace the stabs sections with a CTF section.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "ctftools.h"
+#include "memory.h"
+
+const char *progname;
+int debug_level = DEBUG_LEVEL;
+
+static char *infile = NULL;
+static const char *outfile = NULL;
+static int dynsym;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "Usage: %s [-gis] -l label | -L labelenv [-o outfile] object_file\n"
+ "\n"
+ " Note: if -L labelenv is specified and labelenv is not set in\n"
+ " the environment, a default value is used.\n",
+ progname);
+}
+
+static void
+terminate_cleanup(void)
+{
+#if !defined(__FreeBSD__)
+ if (!outfile) {
+ fprintf(stderr, "Removing %s\n", infile);
+ unlink(infile);
+ }
+#endif
+}
+
+static void
+handle_sig(int sig)
+{
+ terminate("Caught signal %d - exiting\n", sig);
+}
+
+static int
+file_read(tdata_t *td, char *filename, int ignore_non_c)
+{
+ typedef int (*reader_f)(tdata_t *, Elf *, char *);
+ static reader_f readers[] = {
+ stabs_read,
+ dw_read,
+ NULL
+ };
+
+ source_types_t source_types;
+ Elf *elf;
+ int i, rc, fd;
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ terminate("failed to open %s", filename);
+
+ (void) elf_version(EV_CURRENT);
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ close(fd);
+ terminate("failed to read %s: %s\n", filename,
+ elf_errmsg(-1));
+ }
+
+ source_types = built_source_types(elf, filename);
+
+ if ((source_types == SOURCE_NONE || (source_types & SOURCE_UNKNOWN)) &&
+ ignore_non_c) {
+ debug(1, "Ignoring file %s from unknown sources\n", filename);
+ exit(0);
+ }
+
+ for (i = 0; readers[i] != NULL; i++) {
+ if ((rc = readers[i](td, elf, filename)) == 0)
+ break;
+
+ assert(rc < 0 && errno == ENOENT);
+ }
+
+ if (readers[i] == NULL) {
+ /*
+ * None of the readers found compatible type data.
+ */
+
+ if (findelfsecidx(elf, filename, ".debug") >= 0) {
+ terminate("%s: DWARF version 1 is not supported\n",
+ filename);
+ }
+
+ if (!(source_types & SOURCE_C) && ignore_non_c) {
+ debug(1, "Ignoring file %s not built from C sources\n",
+ filename);
+ exit(0);
+ }
+
+ rc = 0;
+ } else {
+ rc = 1;
+ }
+
+ (void) elf_end(elf);
+ (void) close(fd);
+
+ return (rc);
+}
+
+int
+main(int argc, char **argv)
+{
+ tdata_t *filetd, *mstrtd;
+ const char *label = NULL;
+ int verbose = 0;
+ int ignore_non_c = 0;
+ int keep_stabs = 0;
+ int c;
+
+#if defined(sun)
+ sighold(SIGINT);
+ sighold(SIGQUIT);
+ sighold(SIGTERM);
+#endif
+
+ progname = basename(argv[0]);
+
+ if (getenv("CTFCONVERT_DEBUG_LEVEL"))
+ debug_level = atoi(getenv("CTFCONVERT_DEBUG_LEVEL"));
+ if (getenv("CTFCONVERT_DEBUG_PARSE"))
+ debug_parse = atoi(getenv("CTFCONVERT_DEBUG_PARSE"));
+
+ while ((c = getopt(argc, argv, ":l:L:o:givs")) != EOF) {
+ switch (c) {
+ case 'l':
+ label = optarg;
+ break;
+ case 'L':
+ if ((label = getenv(optarg)) == NULL)
+ label = CTF_DEFAULT_LABEL;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case 's':
+ dynsym = CTF_USE_DYNSYM;
+ break;
+ case 'i':
+ ignore_non_c = 1;
+ break;
+ case 'g':
+ keep_stabs = CTF_KEEP_STABS;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage();
+ exit(2);
+ }
+ }
+
+ if (getenv("STRIPSTABS_KEEP_STABS") != NULL)
+ keep_stabs = CTF_KEEP_STABS;
+
+ if (argc - optind != 1 || label == NULL) {
+ usage();
+ exit(2);
+ }
+
+ infile = argv[optind];
+ if (access(infile, R_OK) != 0)
+ terminate("Can't access %s", infile);
+
+ /*
+ * Upon receipt of a signal, we want to clean up and exit. Our
+ * primary goal during cleanup is to restore the system to a state
+ * such that a subsequent make will eventually cause this command to
+ * be re-run. If we remove the input file (which we do if we get a
+ * signal and the user didn't specify a separate output file), make
+ * will need to rebuild the input file, and will then need to re-run
+ * ctfconvert, which is what we want.
+ */
+ set_terminate_cleanup(terminate_cleanup);
+
+#if defined(sun)
+ sigset(SIGINT, handle_sig);
+ sigset(SIGQUIT, handle_sig);
+ sigset(SIGTERM, handle_sig);
+#else
+ signal(SIGINT, handle_sig);
+ signal(SIGQUIT, handle_sig);
+ signal(SIGTERM, handle_sig);
+#endif
+
+ filetd = tdata_new();
+
+ if (!file_read(filetd, infile, ignore_non_c))
+ terminate("%s doesn't have type data to convert\n", infile);
+
+ if (verbose)
+ iidesc_stats(filetd->td_iihash);
+
+ mstrtd = tdata_new();
+ merge_into_master(filetd, mstrtd, NULL, 1);
+
+ tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);
+
+ /*
+ * If the user supplied an output file that is different from the
+ * input file, write directly to the output file. Otherwise, write
+ * to a temporary file, and replace the input file when we're done.
+ */
+ if (outfile && strcmp(infile, outfile) != 0) {
+ write_ctf(mstrtd, infile, outfile, dynsym | keep_stabs);
+ } else {
+ char *tmpname = mktmpname(infile, ".ctf");
+ write_ctf(mstrtd, infile, tmpname, dynsym | keep_stabs);
+ if (rename(tmpname, infile) != 0)
+ terminate("Couldn't rename temp file %s", tmpname);
+ free(tmpname);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
new file mode 100644
index 0000000..3e030c7
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
@@ -0,0 +1,1024 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Given several files containing CTF data, merge and uniquify that data into
+ * a single CTF section in an output file.
+ *
+ * Merges can proceed independently. As such, we perform the merges in parallel
+ * using a worker thread model. A given glob of CTF data (either all of the CTF
+ * data from a single input file, or the result of one or more merges) can only
+ * be involved in a single merge at any given time, so the process decreases in
+ * parallelism, especially towards the end, as more and more files are
+ * consolidated, finally resulting in a single merge of two large CTF graphs.
+ * Unfortunately, the last merge is also the slowest, as the two graphs being
+ * merged are each the product of merges of half of the input files.
+ *
+ * The algorithm consists of two phases, described in detail below. The first
+ * phase entails the merging of CTF data in groups of eight. The second phase
+ * takes the results of Phase I, and merges them two at a time. This disparity
+ * is due to an observation that the merge time increases at least quadratically
+ * with the size of the CTF data being merged. As such, merges of CTF graphs
+ * newly read from input files are much faster than merges of CTF graphs that
+ * are themselves the results of prior merges.
+ *
+ * A further complication is the need to ensure the repeatability of CTF merges.
+ * That is, a merge should produce the same output every time, given the same
+ * input. In both phases, this consistency requirement is met by imposing an
+ * ordering on the merge process, thus ensuring that a given set of input files
+ * are merged in the same order every time.
+ *
+ * Phase I
+ *
+ * The main thread reads the input files one by one, transforming the CTF
+ * data they contain into tdata structures. When a given file has been read
+ * and parsed, it is placed on the work queue for retrieval by worker threads.
+ *
+ * Central to Phase I is the Work In Progress (wip) array, which is used to
+ * merge batches of files in a predictable order. Files are read by the main
+ * thread, and are merged into wip array elements in round-robin order. When
+ * the number of files merged into a given array slot equals the batch size,
+ * the merged CTF graph in that array is added to the done slot in order by
+ * array slot.
+ *
+ * For example, consider a case where we have five input files, a batch size
+ * of two, a wip array size of two, and two worker threads (T1 and T2).
+ *
+ * 1. The wip array elements are assigned initial batch numbers 0 and 1.
+ * 2. T1 reads an input file from the input queue (wq_queue). This is the
+ * first input file, so it is placed into wip[0]. The second file is
+ * similarly read and placed into wip[1]. The wip array slots now contain
+ * one file each (wip_nmerged == 1).
+ * 3. T1 reads the third input file, which it merges into wip[0]. The
+ * number of files in wip[0] is equal to the batch size.
+ * 4. T2 reads the fourth input file, which it merges into wip[1]. wip[1]
+ * is now full too.
+ * 5. T2 attempts to place the contents of wip[1] on the done queue
+ * (wq_done_queue), but it can't, since the batch ID for wip[1] is 1.
+ * Batch 0 needs to be on the done queue before batch 1 can be added, so
+ * T2 blocks on wip[1]'s cv.
+ * 6. T1 attempts to place the contents of wip[0] on the done queue, and
+ * succeeds, updating wq_lastdonebatch to 0. It clears wip[0], and sets
+ * its batch ID to 2. T1 then signals wip[1]'s cv to awaken T2.
+ * 7. T2 wakes up, notices that wq_lastdonebatch is 0, which means that
+ * batch 1 can now be added. It adds wip[1] to the done queue, clears
+ * wip[1], and sets its batch ID to 3. It signals wip[0]'s cv, and
+ * restarts.
+ *
+ * The above process continues until all input files have been consumed. At
+ * this point, a pair of barriers are used to allow a single thread to move
+ * any partial batches from the wip array to the done array in batch ID order.
+ * When this is complete, wq_done_queue is moved to wq_queue, and Phase II
+ * begins.
+ *
+ * Locking Semantics (Phase I)
+ *
+ * The input queue (wq_queue) and the done queue (wq_done_queue) are
+ * protected by separate mutexes - wq_queue_lock and wq_done_queue. wip
+ * array slots are protected by their own mutexes, which must be grabbed
+ * before releasing the input queue lock. The wip array lock is dropped
+ * when the thread restarts the loop. If the array slot was full, the
+ * array lock will be held while the slot contents are added to the done
+ * queue. The done queue lock is used to protect the wip slot cv's.
+ *
+ * The pow number is protected by the queue lock. The master batch ID
+ * and last completed batch (wq_lastdonebatch) counters are protected *in
+ * Phase I* by the done queue lock.
+ *
+ * Phase II
+ *
+ * When Phase II begins, the queue consists of the merged batches from the
+ * first phase. Assume we have five batches:
+ *
+ * Q: a b c d e
+ *
+ * Using the same batch ID mechanism we used in Phase I, but without the wip
+ * array, worker threads remove two entries at a time from the beginning of
+ * the queue. These two entries are merged, and are added back to the tail
+ * of the queue, as follows:
+ *
+ * Q: a b c d e # start
+ * Q: c d e ab # a, b removed, merged, added to end
+ * Q: e ab cd # c, d removed, merged, added to end
+ * Q: cd eab # e, ab removed, merged, added to end
+ * Q: cdeab # cd, eab removed, merged, added to end
+ *
+ * When one entry remains on the queue, with no merges outstanding, Phase II
+ * finishes. We pre-determine the stopping point by pre-calculating the
+ * number of nodes that will appear on the list. In the example above, the
+ * number (wq_ninqueue) is 9. When ninqueue is 1, we conclude Phase II by
+ * signaling the main thread via wq_done_cv.
+ *
+ * Locking Semantics (Phase II)
+ *
+ * The queue (wq_queue), ninqueue, and the master batch ID and last
+ * completed batch counters are protected by wq_queue_lock. The done
+ * queue and corresponding lock are unused in Phase II as is the wip array.
+ *
+ * Uniquification
+ *
+ * We want the CTF data that goes into a given module to be as small as
+ * possible. For example, we don't want it to contain any type data that may
+ * be present in another common module. As such, after creating the master
+ * tdata_t for a given module, we can, if requested by the user, uniquify it
+ * against the tdata_t from another module (genunix in the case of the SunOS
+ * kernel). We perform a merge between the tdata_t for this module and the
+ * tdata_t from genunix. Nodes found in this module that are not present in
+ * genunix are added to a third tdata_t - the uniquified tdata_t.
+ *
+ * Additive Merges
+ *
+ * In some cases, for example if we are issuing a new version of a common
+ * module in a patch, we need to make sure that the CTF data already present
+ * in that module does not change. Changes to this data would void the CTF
+ * data in any module that uniquified against the common module. To preserve
+ * the existing data, we can perform what is known as an additive merge. In
+ * this case, a final uniquification is performed against the CTF data in the
+ * previous version of the module. The result will be the placement of new
+ * and changed data after the existing data, thus preserving the existing type
+ * ID space.
+ *
+ * Saving the result
+ *
+ * When the merges are complete, the resulting tdata_t is placed into the
+ * output file, replacing the .SUNW_ctf section (if any) already in that file.
+ *
+ * The person who changes the merging thread code in this file without updating
+ * this comment will not live to see the stock hit five.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <assert.h>
+#if defined(sun)
+#include <synch.h>
+#endif
+#include <signal.h>
+#include <libgen.h>
+#include <string.h>
+#include <errno.h>
+#if defined(sun)
+#include <alloca.h>
+#endif
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#if defined(sun)
+#include <sys/sysconf.h>
+#endif
+
+#include "ctf_headers.h"
+#include "ctftools.h"
+#include "ctfmerge.h"
+#include "traverse.h"
+#include "memory.h"
+#include "fifo.h"
+#include "barrier.h"
+
+#pragma init(bigheap)
+
+#define MERGE_PHASE1_BATCH_SIZE 8
+#define MERGE_PHASE1_MAX_SLOTS 5
+#define MERGE_INPUT_THROTTLE_LEN 10
+
+const char *progname;
+static char *outfile = NULL;
+static char *tmpname = NULL;
+static int dynsym;
+int debug_level = DEBUG_LEVEL;
+static size_t maxpgsize = 0x400000;
+
+
+void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "Usage: %s [-fgstv] -l label | -L labelenv -o outfile file ...\n"
+ " %s [-fgstv] -l label | -L labelenv -o outfile -d uniqfile\n"
+ " %*s [-g] [-D uniqlabel] file ...\n"
+ " %s [-fgstv] -l label | -L labelenv -o outfile -w withfile "
+ "file ...\n"
+ " %s [-g] -c srcfile destfile\n"
+ "\n"
+ " Note: if -L labelenv is specified and labelenv is not set in\n"
+ " the environment, a default value is used.\n",
+ progname, progname, (int)strlen(progname), " ",
+ progname, progname);
+}
+
+#if defined(sun)
+static void
+bigheap(void)
+{
+ size_t big, *size;
+ int sizes;
+ struct memcntl_mha mha;
+
+ /*
+ * First, get the available pagesizes.
+ */
+ if ((sizes = getpagesizes(NULL, 0)) == -1)
+ return;
+
+ if (sizes == 1 || (size = alloca(sizeof (size_t) * sizes)) == NULL)
+ return;
+
+ if (getpagesizes(size, sizes) == -1)
+ return;
+
+ while (size[sizes - 1] > maxpgsize)
+ sizes--;
+
+ /* set big to the largest allowed page size */
+ big = size[sizes - 1];
+ if (big & (big - 1)) {
+ /*
+ * The largest page size is not a power of two for some
+ * inexplicable reason; return.
+ */
+ return;
+ }
+
+ /*
+ * Now, align our break to the largest page size.
+ */
+ if (brk((void *)((((uintptr_t)sbrk(0) - 1) & ~(big - 1)) + big)) != 0)
+ return;
+
+ /*
+ * set the preferred page size for the heap
+ */
+ mha.mha_cmd = MHA_MAPSIZE_BSSBRK;
+ mha.mha_flags = 0;
+ mha.mha_pagesize = big;
+
+ (void) memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mha, 0, 0);
+}
+#endif
+
+static void
+finalize_phase_one(workqueue_t *wq)
+{
+ int startslot, i;
+
+ /*
+ * wip slots are cleared out only when maxbatchsz td's have been merged
+ * into them. We're not guaranteed that the number of files we're
+ * merging is a multiple of maxbatchsz, so there will be some partial
+ * groups in the wip array. Move them to the done queue in batch ID
+ * order, starting with the slot containing the next batch that would
+ * have been placed on the done queue, followed by the others.
+ * One thread will be doing this while the others wait at the barrier
+ * back in worker_thread(), so we don't need to worry about pesky things
+ * like locks.
+ */
+
+ for (startslot = -1, i = 0; i < wq->wq_nwipslots; i++) {
+ if (wq->wq_wip[i].wip_batchid == wq->wq_lastdonebatch + 1) {
+ startslot = i;
+ break;
+ }
+ }
+
+ assert(startslot != -1);
+
+ for (i = startslot; i < startslot + wq->wq_nwipslots; i++) {
+ int slotnum = i % wq->wq_nwipslots;
+ wip_t *wipslot = &wq->wq_wip[slotnum];
+
+ if (wipslot->wip_td != NULL) {
+ debug(2, "clearing slot %d (%d) (saving %d)\n",
+ slotnum, i, wipslot->wip_nmerged);
+ } else
+ debug(2, "clearing slot %d (%d)\n", slotnum, i);
+
+ if (wipslot->wip_td != NULL) {
+ fifo_add(wq->wq_donequeue, wipslot->wip_td);
+ wq->wq_wip[slotnum].wip_td = NULL;
+ }
+ }
+
+ wq->wq_lastdonebatch = wq->wq_next_batchid++;
+
+ debug(2, "phase one done: donequeue has %d items\n",
+ fifo_len(wq->wq_donequeue));
+}
+
+static void
+init_phase_two(workqueue_t *wq)
+{
+ int num;
+
+ /*
+ * We're going to continually merge the first two entries on the queue,
+ * placing the result on the end, until there's nothing left to merge.
+ * At that point, everything will have been merged into one. The
+ * initial value of ninqueue needs to be equal to the total number of
+ * entries that will show up on the queue, both at the start of the
+ * phase and as generated by merges during the phase.
+ */
+ wq->wq_ninqueue = num = fifo_len(wq->wq_donequeue);
+ while (num != 1) {
+ wq->wq_ninqueue += num / 2;
+ num = num / 2 + num % 2;
+ }
+
+ /*
+ * Move the done queue to the work queue. We won't be using the done
+ * queue in phase 2.
+ */
+ assert(fifo_len(wq->wq_queue) == 0);
+ fifo_free(wq->wq_queue, NULL);
+ wq->wq_queue = wq->wq_donequeue;
+}
+
+static void
+wip_save_work(workqueue_t *wq, wip_t *slot, int slotnum)
+{
+ pthread_mutex_lock(&wq->wq_donequeue_lock);
+
+ while (wq->wq_lastdonebatch + 1 < slot->wip_batchid)
+ pthread_cond_wait(&slot->wip_cv, &wq->wq_donequeue_lock);
+ assert(wq->wq_lastdonebatch + 1 == slot->wip_batchid);
+
+ fifo_add(wq->wq_donequeue, slot->wip_td);
+ wq->wq_lastdonebatch++;
+ pthread_cond_signal(&wq->wq_wip[(slotnum + 1) %
+ wq->wq_nwipslots].wip_cv);
+
+ /* reset the slot for next use */
+ slot->wip_td = NULL;
+ slot->wip_batchid = wq->wq_next_batchid++;
+
+ pthread_mutex_unlock(&wq->wq_donequeue_lock);
+}
+
+static void
+wip_add_work(wip_t *slot, tdata_t *pow)
+{
+ if (slot->wip_td == NULL) {
+ slot->wip_td = pow;
+ slot->wip_nmerged = 1;
+ } else {
+ debug(2, "%d: merging %p into %p\n", pthread_self(),
+ (void *)pow, (void *)slot->wip_td);
+
+ merge_into_master(pow, slot->wip_td, NULL, 0);
+ tdata_free(pow);
+
+ slot->wip_nmerged++;
+ }
+}
+
+static void
+worker_runphase1(workqueue_t *wq)
+{
+ wip_t *wipslot;
+ tdata_t *pow;
+ int wipslotnum, pownum;
+
+ for (;;) {
+ pthread_mutex_lock(&wq->wq_queue_lock);
+
+ while (fifo_empty(wq->wq_queue)) {
+ if (wq->wq_nomorefiles == 1) {
+ pthread_cond_broadcast(&wq->wq_work_avail);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+
+ /* on to phase 2 ... */
+ return;
+ }
+
+ pthread_cond_wait(&wq->wq_work_avail,
+ &wq->wq_queue_lock);
+ }
+
+ /* there's work to be done! */
+ pow = fifo_remove(wq->wq_queue);
+ pownum = wq->wq_nextpownum++;
+ pthread_cond_broadcast(&wq->wq_work_removed);
+
+ assert(pow != NULL);
+
+ /* merge it into the right slot */
+ wipslotnum = pownum % wq->wq_nwipslots;
+ wipslot = &wq->wq_wip[wipslotnum];
+
+ pthread_mutex_lock(&wipslot->wip_lock);
+
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+
+ wip_add_work(wipslot, pow);
+
+ if (wipslot->wip_nmerged == wq->wq_maxbatchsz)
+ wip_save_work(wq, wipslot, wipslotnum);
+
+ pthread_mutex_unlock(&wipslot->wip_lock);
+ }
+}
+
+static void
+worker_runphase2(workqueue_t *wq)
+{
+ tdata_t *pow1, *pow2;
+ int batchid;
+
+ for (;;) {
+ pthread_mutex_lock(&wq->wq_queue_lock);
+
+ if (wq->wq_ninqueue == 1) {
+ pthread_cond_broadcast(&wq->wq_work_avail);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+
+ debug(2, "%d: entering p2 completion barrier\n",
+ pthread_self());
+ if (barrier_wait(&wq->wq_bar1)) {
+ pthread_mutex_lock(&wq->wq_queue_lock);
+ wq->wq_alldone = 1;
+ pthread_cond_signal(&wq->wq_alldone_cv);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+ }
+
+ return;
+ }
+
+ if (fifo_len(wq->wq_queue) < 2) {
+ pthread_cond_wait(&wq->wq_work_avail,
+ &wq->wq_queue_lock);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+ continue;
+ }
+
+ /* there's work to be done! */
+ pow1 = fifo_remove(wq->wq_queue);
+ pow2 = fifo_remove(wq->wq_queue);
+ wq->wq_ninqueue -= 2;
+
+ batchid = wq->wq_next_batchid++;
+
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+
+ debug(2, "%d: merging %p into %p\n", pthread_self(),
+ (void *)pow1, (void *)pow2);
+ merge_into_master(pow1, pow2, NULL, 0);
+ tdata_free(pow1);
+
+ /*
+ * merging is complete. place at the tail of the queue in
+ * proper order.
+ */
+ pthread_mutex_lock(&wq->wq_queue_lock);
+ while (wq->wq_lastdonebatch + 1 != batchid) {
+ pthread_cond_wait(&wq->wq_done_cv,
+ &wq->wq_queue_lock);
+ }
+
+ wq->wq_lastdonebatch = batchid;
+
+ fifo_add(wq->wq_queue, pow2);
+ debug(2, "%d: added %p to queue, len now %d, ninqueue %d\n",
+ pthread_self(), (void *)pow2, fifo_len(wq->wq_queue),
+ wq->wq_ninqueue);
+ pthread_cond_broadcast(&wq->wq_done_cv);
+ pthread_cond_signal(&wq->wq_work_avail);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+ }
+}
+
+/*
+ * Main loop for worker threads.
+ */
+static void
+worker_thread(workqueue_t *wq)
+{
+ worker_runphase1(wq);
+
+ debug(2, "%d: entering first barrier\n", pthread_self());
+
+ if (barrier_wait(&wq->wq_bar1)) {
+
+ debug(2, "%d: doing work in first barrier\n", pthread_self());
+
+ finalize_phase_one(wq);
+
+ init_phase_two(wq);
+
+ debug(2, "%d: ninqueue is %d, %d on queue\n", pthread_self(),
+ wq->wq_ninqueue, fifo_len(wq->wq_queue));
+ }
+
+ debug(2, "%d: entering second barrier\n", pthread_self());
+
+ (void) barrier_wait(&wq->wq_bar2);
+
+ debug(2, "%d: phase 1 complete\n", pthread_self());
+
+ worker_runphase2(wq);
+}
+
+/*
+ * Pass a tdata_t tree, built from an input file, off to the work queue for
+ * consumption by worker threads.
+ */
+static int
+merge_ctf_cb(tdata_t *td, char *name, void *arg)
+{
+ workqueue_t *wq = arg;
+
+ debug(3, "Adding tdata %p for processing\n", (void *)td);
+
+ pthread_mutex_lock(&wq->wq_queue_lock);
+ while (fifo_len(wq->wq_queue) > wq->wq_ithrottle) {
+ debug(2, "Throttling input (len = %d, throttle = %d)\n",
+ fifo_len(wq->wq_queue), wq->wq_ithrottle);
+ pthread_cond_wait(&wq->wq_work_removed, &wq->wq_queue_lock);
+ }
+
+ fifo_add(wq->wq_queue, td);
+ debug(1, "Thread %d announcing %s\n", pthread_self(), name);
+ pthread_cond_broadcast(&wq->wq_work_avail);
+ pthread_mutex_unlock(&wq->wq_queue_lock);
+
+ return (1);
+}
+
+/*
+ * This program is intended to be invoked from a Makefile, as part of the build.
+ * As such, in the event of a failure or user-initiated interrupt (^C), we need
+ * to ensure that a subsequent re-make will cause ctfmerge to be executed again.
+ * Unfortunately, ctfmerge will usually be invoked directly after (and as part
+ * of the same Makefile rule as) a link, and will operate on the linked file
+ * in place. If we merely exit upon receipt of a SIGINT, a subsequent make
+ * will notice that the *linked* file is newer than the object files, and thus
+ * will not reinvoke ctfmerge. The only way to ensure that a subsequent make
+ * reinvokes ctfmerge, is to remove the file to which we are adding CTF
+ * data (confusingly named the output file). This means that the link will need
+ * to happen again, but links are generally fast, and we can't allow the merge
+ * to be skipped.
+ *
+ * Another possibility would be to block SIGINT entirely - to always run to
+ * completion. The run time of ctfmerge can, however, be measured in minutes
+ * in some cases, so this is not a valid option.
+ */
+static void
+handle_sig(int sig)
+{
+ terminate("Caught signal %d - exiting\n", sig);
+}
+
+static void
+terminate_cleanup(void)
+{
+ int dounlink = getenv("CTFMERGE_TERMINATE_NO_UNLINK") ? 0 : 1;
+
+ if (tmpname != NULL && dounlink)
+ unlink(tmpname);
+
+ if (outfile == NULL)
+ return;
+
+#if !defined(__FreeBSD__)
+ if (dounlink) {
+ fprintf(stderr, "Removing %s\n", outfile);
+ unlink(outfile);
+ }
+#endif
+}
+
+static void
+copy_ctf_data(char *srcfile, char *destfile, int keep_stabs)
+{
+ tdata_t *srctd;
+
+ if (read_ctf(&srcfile, 1, NULL, read_ctf_save_cb, &srctd, 1) == 0)
+ terminate("No CTF data found in source file %s\n", srcfile);
+
+ tmpname = mktmpname(destfile, ".ctf");
+ write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | CTF_SWAP_BYTES | keep_stabs);
+ if (rename(tmpname, destfile) != 0) {
+ terminate("Couldn't rename temp file %s to %s", tmpname,
+ destfile);
+ }
+ free(tmpname);
+ tdata_free(srctd);
+}
+
+static void
+wq_init(workqueue_t *wq, int nfiles)
+{
+ int throttle, nslots, i;
+
+ if (getenv("CTFMERGE_MAX_SLOTS"))
+ nslots = atoi(getenv("CTFMERGE_MAX_SLOTS"));
+ else
+ nslots = MERGE_PHASE1_MAX_SLOTS;
+
+ if (getenv("CTFMERGE_PHASE1_BATCH_SIZE"))
+ wq->wq_maxbatchsz = atoi(getenv("CTFMERGE_PHASE1_BATCH_SIZE"));
+ else
+ wq->wq_maxbatchsz = MERGE_PHASE1_BATCH_SIZE;
+
+ nslots = MIN(nslots, (nfiles + wq->wq_maxbatchsz - 1) /
+ wq->wq_maxbatchsz);
+
+ wq->wq_wip = xcalloc(sizeof (wip_t) * nslots);
+ wq->wq_nwipslots = nslots;
+ wq->wq_nthreads = MIN(sysconf(_SC_NPROCESSORS_ONLN) * 3 / 2, nslots);
+ wq->wq_thread = xmalloc(sizeof (pthread_t) * wq->wq_nthreads);
+
+ if (getenv("CTFMERGE_INPUT_THROTTLE"))
+ throttle = atoi(getenv("CTFMERGE_INPUT_THROTTLE"));
+ else
+ throttle = MERGE_INPUT_THROTTLE_LEN;
+ wq->wq_ithrottle = throttle * wq->wq_nthreads;
+
+ debug(1, "Using %d slots, %d threads\n", wq->wq_nwipslots,
+ wq->wq_nthreads);
+
+ wq->wq_next_batchid = 0;
+
+ for (i = 0; i < nslots; i++) {
+ pthread_mutex_init(&wq->wq_wip[i].wip_lock, NULL);
+ wq->wq_wip[i].wip_batchid = wq->wq_next_batchid++;
+ }
+
+ pthread_mutex_init(&wq->wq_queue_lock, NULL);
+ wq->wq_queue = fifo_new();
+ pthread_cond_init(&wq->wq_work_avail, NULL);
+ pthread_cond_init(&wq->wq_work_removed, NULL);
+ wq->wq_ninqueue = nfiles;
+ wq->wq_nextpownum = 0;
+
+ pthread_mutex_init(&wq->wq_donequeue_lock, NULL);
+ wq->wq_donequeue = fifo_new();
+ wq->wq_lastdonebatch = -1;
+
+ pthread_cond_init(&wq->wq_done_cv, NULL);
+
+ pthread_cond_init(&wq->wq_alldone_cv, NULL);
+ wq->wq_alldone = 0;
+
+ barrier_init(&wq->wq_bar1, wq->wq_nthreads);
+ barrier_init(&wq->wq_bar2, wq->wq_nthreads);
+
+ wq->wq_nomorefiles = 0;
+}
+
+static void
+start_threads(workqueue_t *wq)
+{
+ sigset_t sets;
+ int i;
+
+ sigemptyset(&sets);
+ sigaddset(&sets, SIGINT);
+ sigaddset(&sets, SIGQUIT);
+ sigaddset(&sets, SIGTERM);
+ pthread_sigmask(SIG_BLOCK, &sets, NULL);
+
+ for (i = 0; i < wq->wq_nthreads; i++) {
+ pthread_create(&wq->wq_thread[i], NULL,
+ (void *(*)(void *))worker_thread, wq);
+ }
+
+#if defined(sun)
+ sigset(SIGINT, handle_sig);
+ sigset(SIGQUIT, handle_sig);
+ sigset(SIGTERM, handle_sig);
+#else
+ signal(SIGINT, handle_sig);
+ signal(SIGQUIT, handle_sig);
+ signal(SIGTERM, handle_sig);
+#endif
+ pthread_sigmask(SIG_UNBLOCK, &sets, NULL);
+}
+
+static void
+join_threads(workqueue_t *wq)
+{
+ int i;
+
+ for (i = 0; i < wq->wq_nthreads; i++) {
+ pthread_join(wq->wq_thread[i], NULL);
+ }
+}
+
+static int
+strcompare(const void *p1, const void *p2)
+{
+ char *s1 = *((char **)p1);
+ char *s2 = *((char **)p2);
+
+ return (strcmp(s1, s2));
+}
+
+/*
+ * Core work queue structure; passed to worker threads on thread creation
+ * as the main point of coordination. Allocate as a static structure; we
+ * could have put this into a local variable in main, but passing a pointer
+ * into your stack to another thread is fragile at best and leads to some
+ * hard-to-debug failure modes.
+ */
+static workqueue_t wq;
+
+int
+main(int argc, char **argv)
+{
+ tdata_t *mstrtd, *savetd;
+ char *uniqfile = NULL, *uniqlabel = NULL;
+ char *withfile = NULL;
+ char *label = NULL;
+ char **ifiles, **tifiles;
+ int verbose = 0, docopy = 0;
+ int write_fuzzy_match = 0;
+ int keep_stabs = 0;
+ int require_ctf = 0;
+ int nifiles, nielems;
+ int c, i, idx, tidx, err;
+
+ progname = basename(argv[0]);
+
+ if (getenv("CTFMERGE_DEBUG_LEVEL"))
+ debug_level = atoi(getenv("CTFMERGE_DEBUG_LEVEL"));
+
+ err = 0;
+ while ((c = getopt(argc, argv, ":cd:D:fgl:L:o:tvw:s")) != EOF) {
+ switch (c) {
+ case 'c':
+ docopy = 1;
+ break;
+ case 'd':
+ /* Uniquify against `uniqfile' */
+ uniqfile = optarg;
+ break;
+ case 'D':
+ /* Uniquify against label `uniqlabel' in `uniqfile' */
+ uniqlabel = optarg;
+ break;
+ case 'f':
+ write_fuzzy_match = CTF_FUZZY_MATCH;
+ break;
+ case 'g':
+ keep_stabs = CTF_KEEP_STABS;
+ break;
+ case 'l':
+ /* Label merged types with `label' */
+ label = optarg;
+ break;
+ case 'L':
+ /* Label merged types with getenv(`label`) */
+ if ((label = getenv(optarg)) == NULL)
+ label = CTF_DEFAULT_LABEL;
+ break;
+ case 'o':
+ /* Place merged types in CTF section in `outfile' */
+ outfile = optarg;
+ break;
+ case 't':
+ /* Insist *all* object files built from C have CTF */
+ require_ctf = 1;
+ break;
+ case 'v':
+ /* More debugging information */
+ verbose = 1;
+ break;
+ case 'w':
+ /* Additive merge with data from `withfile' */
+ withfile = optarg;
+ break;
+ case 's':
+ /* use the dynsym rather than the symtab */
+ dynsym = CTF_USE_DYNSYM;
+ break;
+ default:
+ usage();
+ exit(2);
+ }
+ }
+
+ /* Validate arguments */
+ if (docopy) {
+ if (uniqfile != NULL || uniqlabel != NULL || label != NULL ||
+ outfile != NULL || withfile != NULL || dynsym != 0)
+ err++;
+
+ if (argc - optind != 2)
+ err++;
+ } else {
+ if (uniqfile != NULL && withfile != NULL)
+ err++;
+
+ if (uniqlabel != NULL && uniqfile == NULL)
+ err++;
+
+ if (outfile == NULL || label == NULL)
+ err++;
+
+ if (argc - optind == 0)
+ err++;
+ }
+
+ if (err) {
+ usage();
+ exit(2);
+ }
+
+ if (getenv("STRIPSTABS_KEEP_STABS") != NULL)
+ keep_stabs = CTF_KEEP_STABS;
+
+ if (uniqfile && access(uniqfile, R_OK) != 0) {
+ warning("Uniquification file %s couldn't be opened and "
+ "will be ignored.\n", uniqfile);
+ uniqfile = NULL;
+ }
+ if (withfile && access(withfile, R_OK) != 0) {
+ warning("With file %s couldn't be opened and will be "
+ "ignored.\n", withfile);
+ withfile = NULL;
+ }
+ if (outfile && access(outfile, R_OK|W_OK) != 0)
+ terminate("Cannot open output file %s for r/w", outfile);
+
+ /*
+ * This is ugly, but we don't want to have to have a separate tool
+ * (yet) just for copying an ELF section with our specific requirements,
+ * so we shoe-horn a copier into ctfmerge.
+ */
+ if (docopy) {
+ copy_ctf_data(argv[optind], argv[optind + 1], keep_stabs);
+
+ exit(0);
+ }
+
+ set_terminate_cleanup(terminate_cleanup);
+
+ /* Sort the input files and strip out duplicates */
+ nifiles = argc - optind;
+ ifiles = xmalloc(sizeof (char *) * nifiles);
+ tifiles = xmalloc(sizeof (char *) * nifiles);
+
+ for (i = 0; i < nifiles; i++)
+ tifiles[i] = argv[optind + i];
+ qsort(tifiles, nifiles, sizeof (char *), (int (*)())strcompare);
+
+ ifiles[0] = tifiles[0];
+ for (idx = 0, tidx = 1; tidx < nifiles; tidx++) {
+ if (strcmp(ifiles[idx], tifiles[tidx]) != 0)
+ ifiles[++idx] = tifiles[tidx];
+ }
+ nifiles = idx + 1;
+
+ /* Make sure they all exist */
+ if ((nielems = count_files(ifiles, nifiles)) < 0)
+ terminate("Some input files were inaccessible\n");
+
+ /* Prepare for the merge */
+ wq_init(&wq, nielems);
+
+ start_threads(&wq);
+
+ /*
+ * Start the merge
+ *
+ * We're reading everything from each of the object files, so we
+ * don't need to specify labels.
+ */
+ if (read_ctf(ifiles, nifiles, NULL, merge_ctf_cb,
+ &wq, require_ctf) == 0) {
+ /*
+ * If we're verifying that C files have CTF, it's safe to
+ * assume that in this case, we're building only from assembly
+ * inputs.
+ */
+ if (require_ctf)
+ exit(0);
+ terminate("No ctf sections found to merge\n");
+ }
+
+ pthread_mutex_lock(&wq.wq_queue_lock);
+ wq.wq_nomorefiles = 1;
+ pthread_cond_broadcast(&wq.wq_work_avail);
+ pthread_mutex_unlock(&wq.wq_queue_lock);
+
+ pthread_mutex_lock(&wq.wq_queue_lock);
+ while (wq.wq_alldone == 0)
+ pthread_cond_wait(&wq.wq_alldone_cv, &wq.wq_queue_lock);
+ pthread_mutex_unlock(&wq.wq_queue_lock);
+
+ join_threads(&wq);
+
+ /*
+ * All requested files have been merged, with the resulting tree in
+ * mstrtd. savetd is the tree that will be placed into the output file.
+ *
+ * Regardless of whether we're doing a normal uniquification or an
+ * additive merge, we need a type tree that has been uniquified
+ * against uniqfile or withfile, as appropriate.
+ *
+ * If we're doing a uniquification, we stuff the resulting tree into
+ * outfile. Otherwise, we add the tree to the tree already in withfile.
+ */
+ assert(fifo_len(wq.wq_queue) == 1);
+ mstrtd = fifo_remove(wq.wq_queue);
+
+ if (verbose || debug_level) {
+ debug(2, "Statistics for td %p\n", (void *)mstrtd);
+
+ iidesc_stats(mstrtd->td_iihash);
+ }
+
+ if (uniqfile != NULL || withfile != NULL) {
+ char *reffile, *reflabel = NULL;
+ tdata_t *reftd;
+
+ if (uniqfile != NULL) {
+ reffile = uniqfile;
+ reflabel = uniqlabel;
+ } else
+ reffile = withfile;
+
+ if (read_ctf(&reffile, 1, reflabel, read_ctf_save_cb,
+ &reftd, require_ctf) == 0) {
+ terminate("No CTF data found in reference file %s\n",
+ reffile);
+ }
+
+ savetd = tdata_new();
+
+ if (CTF_TYPE_ISCHILD(reftd->td_nextid))
+ terminate("No room for additional types in master\n");
+
+ savetd->td_nextid = withfile ? reftd->td_nextid :
+ CTF_INDEX_TO_TYPE(1, TRUE);
+ merge_into_master(mstrtd, reftd, savetd, 0);
+
+ tdata_label_add(savetd, label, CTF_LABEL_LASTIDX);
+
+ if (withfile) {
+ /*
+ * savetd holds the new data to be added to the withfile
+ */
+ tdata_t *withtd = reftd;
+
+ tdata_merge(withtd, savetd);
+
+ savetd = withtd;
+ } else {
+ char uniqname[MAXPATHLEN];
+ labelent_t *parle;
+
+ parle = tdata_label_top(reftd);
+
+ savetd->td_parlabel = xstrdup(parle->le_name);
+
+ strncpy(uniqname, reffile, sizeof (uniqname));
+ uniqname[MAXPATHLEN - 1] = '\0';
+ savetd->td_parname = xstrdup(basename(uniqname));
+ }
+
+ } else {
+ /*
+ * No post processing. Write the merged tree as-is into the
+ * output file.
+ */
+ tdata_label_free(mstrtd);
+ tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);
+
+ savetd = mstrtd;
+ }
+
+ tmpname = mktmpname(outfile, ".ctf");
+ write_ctf(savetd, outfile, tmpname,
+ CTF_COMPRESS | CTF_SWAP_BYTES | write_fuzzy_match | dynsym | keep_stabs);
+ if (rename(tmpname, outfile) != 0)
+ terminate("Couldn't rename output temp file %s", tmpname);
+ free(tmpname);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h
new file mode 100644
index 0000000..ce40803
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CTFMERGE_H
+#define _CTFMERGE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Merging structures used in ctfmerge. See ctfmerge.c for locking semantics.
+ */
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ctftools.h"
+#include "barrier.h"
+#include "fifo.h"
+
+typedef struct wip {
+ pthread_mutex_t wip_lock;
+ pthread_cond_t wip_cv;
+ tdata_t *wip_td;
+ int wip_nmerged;
+ int wip_batchid;
+} wip_t;
+
+typedef struct workqueue {
+ int wq_next_batchid;
+
+ int wq_maxbatchsz;
+
+ wip_t *wq_wip;
+ int wq_nwipslots;
+ int wq_nthreads;
+ int wq_ithrottle;
+
+ pthread_mutex_t wq_queue_lock;
+ fifo_t *wq_queue;
+ pthread_cond_t wq_work_avail;
+ pthread_cond_t wq_work_removed;
+ int wq_ninqueue;
+ int wq_nextpownum;
+
+ pthread_mutex_t wq_donequeue_lock;
+ fifo_t *wq_donequeue;
+ int wq_lastdonebatch;
+ pthread_cond_t wq_done_cv;
+
+ pthread_cond_t wq_alldone_cv; /* protected by queue_lock */
+ int wq_alldone;
+
+ int wq_nomorefiles;
+
+ pthread_t *wq_thread;
+
+ barrier_t wq_bar1;
+ barrier_t wq_bar2;
+} workqueue_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CTFMERGE_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
new file mode 100644
index 0000000..93a540d
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
@@ -0,0 +1,454 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CTFTOOLS_H
+#define _CTFTOOLS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Functions and data structures used in the manipulation of stabs and CTF data
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "list.h"
+#include "hash.h"
+
+#ifndef DEBUG_LEVEL
+#define DEBUG_LEVEL 0
+#endif
+#ifndef DEBUG_PARSE
+#define DEBUG_PARSE 0
+#endif
+
+#ifndef DEBUG_STREAM
+#define DEBUG_STREAM stderr
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#endif
+
+#define TRUE 1
+#define FALSE 0
+
+#define CTF_ELF_SCN_NAME ".SUNW_ctf"
+
+#define CTF_LABEL_LASTIDX -1
+
+#define CTF_DEFAULT_LABEL "*** No Label Provided ***"
+
+/*
+ * Default hash sizes
+ */
+#define TDATA_LAYOUT_HASH_SIZE 8191 /* A tdesc hash based on layout */
+#define TDATA_ID_HASH_SIZE 997 /* A tdesc hash based on type id */
+#define IIDESC_HASH_SIZE 8191 /* Hash of iidesc's */
+
+/*
+ * The default function argument array size. We'll realloc the array larger
+ * if we need to, but we want a default value that will allow us to avoid
+ * reallocation in the common case.
+ */
+#define FUNCARG_DEF 5
+
+extern const char *progname;
+extern int debug_level;
+extern int debug_parse;
+extern char *curhdr;
+
+/*
+ * This is a partial copy of the stab.h that DevPro includes with their
+ * compiler.
+ */
+typedef struct stab {
+ uint32_t n_strx;
+ uint8_t n_type;
+ int8_t n_other;
+ int16_t n_desc;
+ uint32_t n_value;
+} stab_t;
+
+#define N_GSYM 0x20 /* global symbol: name,,0,type,0 */
+#define N_FUN 0x24 /* procedure: name,,0,linenumber,0 */
+#define N_STSYM 0x26 /* static symbol: name,,0,type,0 or section relative */
+#define N_LCSYM 0x28 /* .lcomm symbol: name,,0,type,0 or section relative */
+#define N_ROSYM 0x2c /* ro_data: name,,0,type,0 or section relative */
+#define N_OPT 0x3c /* compiler options */
+#define N_RSYM 0x40 /* register sym: name,,0,type,register */
+#define N_SO 0x64 /* source file name: name,,0,0,0 */
+#define N_LSYM 0x80 /* local sym: name,,0,type,offset */
+#define N_SOL 0x84 /* #included file name: name,,0,0,0 */
+#define N_PSYM 0xa0 /* parameter: name,,0,type,offset */
+#define N_LBRAC 0xc0 /* left bracket: 0,,0,nesting level,function relative */
+#define N_RBRAC 0xe0 /* right bracket: 0,,0,nesting level,func relative */
+#define N_BINCL 0x82 /* header file: name,,0,0,0 */
+#define N_EINCL 0xa2 /* end of include file */
+
+/*
+ * Nodes in the type tree
+ *
+ * Each node consists of a single tdesc_t, with one of several auxiliary
+ * structures linked in via the `data' union.
+ */
+
+/* The type of tdesc_t node */
+typedef enum stabtype {
+ STABTYPE_FIRST, /* do not use */
+ INTRINSIC,
+ POINTER,
+ ARRAY,
+ FUNCTION,
+ STRUCT,
+ UNION,
+ ENUM,
+ FORWARD,
+ TYPEDEF,
+ TYPEDEF_UNRES,
+ VOLATILE,
+ CONST,
+ RESTRICT,
+ STABTYPE_LAST /* do not use */
+} stabtype_t;
+
+typedef struct tdesc tdesc_t;
+
+/* Auxiliary structure for array tdesc_t */
+typedef struct ardef {
+ tdesc_t *ad_contents;
+ tdesc_t *ad_idxtype;
+ uint_t ad_nelems;
+} ardef_t;
+
+/* Auxiliary structure for structure/union tdesc_t */
+typedef struct mlist {
+ int ml_offset; /* Offset from start of structure (in bits) */
+ int ml_size; /* Member size (in bits) */
+ char *ml_name; /* Member name */
+ struct tdesc *ml_type; /* Member type */
+ struct mlist *ml_next; /* Next member */
+} mlist_t;
+
+/* Auxiliary structure for enum tdesc_t */
+typedef struct elist {
+ char *el_name;
+ int el_number;
+ struct elist *el_next;
+} elist_t;
+
+/* Auxiliary structure for intrinsics (integers and reals) */
+typedef enum {
+ INTR_INT,
+ INTR_REAL
+} intrtype_t;
+
+typedef struct intr {
+ intrtype_t intr_type;
+ int intr_signed;
+ union {
+ char _iformat;
+ int _fformat;
+ } _u;
+ int intr_offset;
+ int intr_nbits;
+} intr_t;
+
+#define intr_iformat _u._iformat
+#define intr_fformat _u._fformat
+
+typedef struct fnarg {
+ char *fna_name;
+ struct tdesc *fna_type;
+} fnarg_t;
+
+#define FN_F_GLOBAL 0x1
+#define FN_F_VARARGS 0x2
+
+typedef struct fndef {
+ struct tdesc *fn_ret;
+ uint_t fn_nargs;
+ tdesc_t **fn_args;
+ uint_t fn_vargs;
+} fndef_t;
+
+typedef int32_t tid_t;
+
+/*
+ * The tdesc_t (Type DESCription) is the basic node type used in the stabs data
+ * structure. Each data node gets a tdesc structure. Each node is linked into
+ * a directed graph (think of it as a tree with multiple roots and multiple
+ * leaves), with the root nodes at the top, and intrinsics at the bottom. The
+ * root nodes, which are pointed to by iidesc nodes, correspond to the types,
+ * globals, and statics defined by the stabs.
+ */
+struct tdesc {
+ char *t_name;
+ tdesc_t *t_next; /* Name hash next pointer */
+
+ tid_t t_id;
+ tdesc_t *t_hash; /* ID hash next pointer */
+
+ stabtype_t t_type;
+ int t_size; /* Size in bytes of object represented by this node */
+
+ union {
+ intr_t *intr; /* int, real */
+ tdesc_t *tdesc; /* ptr, typedef, vol, const, restr */
+ ardef_t *ardef; /* array */
+ mlist_t *members; /* struct, union */
+ elist_t *emem; /* enum */
+ fndef_t *fndef; /* function - first is return type */
+ } t_data;
+
+ int t_flags;
+ int t_vgen; /* Visitation generation (see traverse.c) */
+ int t_emark; /* Equality mark (see equiv_cb() in merge.c) */
+};
+
+#define t_intr t_data.intr
+#define t_tdesc t_data.tdesc
+#define t_ardef t_data.ardef
+#define t_members t_data.members
+#define t_emem t_data.emem
+#define t_fndef t_data.fndef
+
+#define TDESC_F_ISROOT 0x1 /* Has an iidesc_t (see below) */
+#define TDESC_F_GLOBAL 0x2
+#define TDESC_F_RESOLVED 0x4
+
+/*
+ * iidesc_t (Interesting Item DESCription) nodes point to tdesc_t nodes that
+ * correspond to "interesting" stabs. A stab is interesting if it defines a
+ * global or static variable, a global or static function, or a data type.
+ */
+typedef enum iitype {
+ II_NOT = 0,
+ II_GFUN, /* Global function */
+ II_SFUN, /* Static function */
+ II_GVAR, /* Global variable */
+ II_SVAR, /* Static variable */
+ II_PSYM, /* Function argument */
+ II_SOU, /* Struct or union */
+ II_TYPE /* Type (typedef) */
+} iitype_t;
+
+typedef struct iidesc {
+ iitype_t ii_type;
+ char *ii_name;
+ tdesc_t *ii_dtype;
+ char *ii_owner; /* File that defined this node */
+ int ii_flags;
+
+ /* Function arguments (if any) */
+ int ii_nargs;
+ tdesc_t **ii_args;
+ int ii_vargs; /* Function uses varargs */
+} iidesc_t;
+
+#define IIDESC_F_USED 0x1 /* Write this iidesc out */
+
+/*
+ * labelent_t nodes identify labels and corresponding type ranges associated
+ * with them. The label in a given labelent_t is associated with types with
+ * ids <= le_idx.
+ */
+typedef struct labelent {
+ char *le_name;
+ int le_idx;
+} labelent_t;
+
+/*
+ * The tdata_t (Type DATA) structure contains or references all type data for
+ * a given file or, during merging, several files.
+ */
+typedef struct tdata {
+ int td_curemark; /* Equality mark (see merge.c) */
+ int td_curvgen; /* Visitation generation (see traverse.c) */
+ int td_nextid; /* The ID for the next tdesc_t created */
+ hash_t *td_iihash; /* The iidesc_t nodes for this file */
+
+ hash_t *td_layouthash; /* The tdesc nodes, hashed by structure */
+ hash_t *td_idhash; /* The tdesc nodes, hashed by type id */
+ list_t *td_fwdlist; /* All forward declaration tdesc nodes */
+
+ char *td_parlabel; /* Top label uniq'd against in parent */
+ char *td_parname; /* Basename of parent */
+ list_t *td_labels; /* Labels and their type ranges */
+
+ pthread_mutex_t td_mergelock;
+
+ int td_ref;
+} tdata_t;
+
+/*
+ * By design, the iidesc hash is heterogeneous. The CTF emitter, on the
+ * other hand, needs to be able to access the elements of the list by type,
+ * and in a specific sorted order. An iiburst holds these elements in that
+ * order. (A burster is a machine that separates carbon-copy forms)
+ */
+typedef struct iiburst {
+ int iib_nfuncs;
+ int iib_curfunc;
+ iidesc_t **iib_funcs;
+
+ int iib_nobjts;
+ int iib_curobjt;
+ iidesc_t **iib_objts;
+
+ list_t *iib_types;
+ int iib_maxtypeid;
+
+ tdata_t *iib_td;
+ struct tdtrav_data *iib_tdtd; /* tdtrav_data_t */
+} iiburst_t;
+
+typedef struct ctf_buf ctf_buf_t;
+
+typedef struct symit_data symit_data_t;
+
+/* fixup_tdescs.c */
+void cvt_fixstabs(tdata_t *);
+void cvt_fixups(tdata_t *, size_t);
+
+/* ctf.c */
+caddr_t ctf_gen(iiburst_t *, size_t *, int);
+tdata_t *ctf_load(char *, caddr_t, size_t, symit_data_t *, char *);
+
+/* iidesc.c */
+iidesc_t *iidesc_new(char *);
+int iidesc_hash(int, void *);
+void iter_iidescs_by_name(tdata_t *, const char *,
+ int (*)(void *, void *), void *);
+iidesc_t *iidesc_dup(iidesc_t *);
+iidesc_t *iidesc_dup_rename(iidesc_t *, char const *, char const *);
+void iidesc_add(hash_t *, iidesc_t *);
+void iidesc_free(void *, void *);
+int iidesc_count_type(void *, void *);
+void iidesc_stats(hash_t *);
+int iidesc_dump(iidesc_t *);
+
+/* input.c */
+typedef enum source_types {
+ SOURCE_NONE = 0,
+ SOURCE_UNKNOWN = 1,
+ SOURCE_C = 2,
+ SOURCE_S = 4
+} source_types_t;
+
+source_types_t built_source_types(Elf *, const char *);
+int count_files(char **, int);
+int read_ctf(char **, int, char *, int (*)(tdata_t *, char *, void *),
+ void *, int);
+int read_ctf_save_cb(tdata_t *, char *, void *);
+symit_data_t *symit_new(Elf *, const char *);
+void symit_reset(symit_data_t *);
+char *symit_curfile(symit_data_t *);
+GElf_Sym *symit_next(symit_data_t *, int);
+char *symit_name(symit_data_t *);
+void symit_free(symit_data_t *);
+
+/* merge.c */
+void merge_into_master(tdata_t *, tdata_t *, tdata_t *, int);
+
+/* output.c */
+#define CTF_FUZZY_MATCH 0x1 /* match local symbols to global CTF */
+#define CTF_USE_DYNSYM 0x2 /* use .dynsym not .symtab */
+#define CTF_COMPRESS 0x4 /* compress CTF output */
+#define CTF_KEEP_STABS 0x8 /* keep .stabs sections */
+#define CTF_SWAP_BYTES 0x10 /* target byte order is different from host */
+
+void write_ctf(tdata_t *, const char *, const char *, int);
+
+/* parse.c */
+void parse_init(tdata_t *);
+void parse_finish(tdata_t *);
+int parse_stab(stab_t *, char *, iidesc_t **);
+tdesc_t *lookup(int);
+tdesc_t *lookupname(const char *);
+void check_hash(void);
+void resolve_typed_bitfields(void);
+
+/* stabs.c */
+int stabs_read(tdata_t *, Elf *, char *);
+
+/* dwarf.c */
+int dw_read(tdata_t *, Elf *, char *);
+const char *dw_tag2str(uint_t);
+
+/* tdata.c */
+tdata_t *tdata_new(void);
+void tdata_free(tdata_t *);
+void tdata_build_hashes(tdata_t *td);
+const char *tdesc_name(tdesc_t *);
+int tdesc_idhash(int, void *);
+int tdesc_idcmp(void *, void *);
+int tdesc_namehash(int, void *);
+int tdesc_namecmp(void *, void *);
+int tdesc_layouthash(int, void *);
+int tdesc_layoutcmp(void *, void *);
+void tdesc_free(tdesc_t *);
+void tdata_label_add(tdata_t *, const char *, int);
+labelent_t *tdata_label_top(tdata_t *);
+int tdata_label_find(tdata_t *, char *);
+void tdata_label_free(tdata_t *);
+void tdata_merge(tdata_t *, tdata_t *);
+void tdata_label_newmax(tdata_t *, int);
+
+/* util.c */
+int streq(const char *, const char *);
+int findelfsecidx(Elf *, const char *, const char *);
+size_t elf_ptrsz(Elf *);
+char *mktmpname(const char *, const char *);
+void terminate(const char *, ...);
+void aborterr(const char *, ...);
+void set_terminate_cleanup(void (*)(void));
+void elfterminate(const char *, const char *, ...);
+void warning(const char *, ...);
+void vadebug(int, const char *, va_list);
+void debug(int, const char *, ...);
+
+
+void watch_dump(int);
+void watch_set(void *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CTFTOOLS_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
new file mode 100644
index 0000000..19aeff2
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
@@ -0,0 +1,1848 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * DWARF to tdata conversion
+ *
+ * For the most part, conversion is straightforward, proceeding in two passes.
+ * On the first pass, we iterate through every die, creating new type nodes as
+ * necessary. Referenced tdesc_t's are created in an uninitialized state, thus
+ * allowing type reference pointers to be filled in. If the tdesc_t
+ * corresponding to a given die can be completely filled out (sizes and offsets
+ * calculated, and so forth) without using any referenced types, the tdesc_t is
+ * marked as resolved. Consider an array type. If the type corresponding to
+ * the array contents has not yet been processed, we will create a blank tdesc
+ * for the contents type (only the type ID will be filled in, relying upon the
+ * later portion of the first pass to encounter and complete the referenced
+ * type). We will then attempt to determine the size of the array. If the
+ * array has a byte size attribute, we will have completely characterized the
+ * array type, and will be able to mark it as resolved. The lack of a byte
+ * size attribute, on the other hand, will prevent us from fully resolving the
+ * type, as the size will only be calculable with reference to the contents
+ * type, which has not, as yet, been encountered. The array type will thus be
+ * left without the resolved flag, and the first pass will continue.
+ *
+ * When we begin the second pass, we will have created tdesc_t nodes for every
+ * type in the section. We will traverse the tree, from the iidescs down,
+ * processing each unresolved node. As the referenced nodes will have been
+ * populated, the array type used in our example above will be able to use the
+ * size of the referenced types (if available) to determine its own type. The
+ * traversal will be repeated until all types have been resolved or we have
+ * failed to make progress. When all tdescs have been resolved, the conversion
+ * is complete.
+ *
+ * There are, as always, a few special cases that are handled during the first
+ * and second passes:
+ *
+ * 1. Empty enums - GCC will occasionally emit an enum without any members.
+ * Later on in the file, it will emit the same enum type, though this time
+ * with the full complement of members. All references to the memberless
+ * enum need to be redirected to the full definition. During the first
+ * pass, each enum is entered in dm_enumhash, along with a pointer to its
+ * corresponding tdesc_t. If, during the second pass, we encounter a
+ * memberless enum, we use the hash to locate the full definition. All
+ * tdescs referencing the empty enum are then redirected.
+ *
+ * 2. Forward declarations - If the compiler sees a forward declaration for
+ * a structure, followed by the definition of that structure, it will emit
+ * DWARF data for both the forward declaration and the definition. We need
+ * to resolve the forward declarations when possible, by redirecting
+ * forward-referencing tdescs to the actual struct/union definitions. This
+ * redirection is done completely within the first pass. We begin by
+ * recording all forward declarations in dw_fwdhash. When we define a
+ * structure, we check to see if there have been any corresponding forward
+ * declarations. If so, we redirect the tdescs which referenced the forward
+ * declarations to the structure or union definition.
+ *
+ * XXX see if a post traverser will allow the elimination of repeated pass 2
+ * traversals.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <libelf.h>
+#include <libdwarf.h>
+#include <libgen.h>
+#include <dwarf.h>
+
+#include "ctf_headers.h"
+#include "ctftools.h"
+#include "memory.h"
+#include "list.h"
+#include "traverse.h"
+
+/* The version of DWARF which we support. */
+#define DWARF_VERSION 2
+
+/*
+ * We need to define a couple of our own intrinsics, to smooth out some of the
+ * differences between the GCC and DevPro DWARF emitters. See the referenced
+ * routines and the special cases in the file comment for more details.
+ *
+ * Type IDs are 32 bits wide. We're going to use the top of that field to
+ * indicate types that we've created ourselves.
+ */
+#define TID_FILEMAX 0x3fffffff /* highest tid from file */
+#define TID_VOID 0x40000001 /* see die_void() */
+#define TID_LONG 0x40000002 /* see die_array() */
+
+#define TID_MFGTID_BASE 0x40000003 /* first mfg'd tid */
+
+/*
+ * To reduce the staggering amount of error-handling code that would otherwise
+ * be required, the attribute-retrieval routines handle most of their own
+ * errors. If the following flag is supplied as the value of the `req'
+ * argument, they will also handle the absence of a requested attribute by
+ * terminating the program.
+ */
+#define DW_ATTR_REQ 1
+
+#define TDESC_HASH_BUCKETS 511
+
+typedef struct dwarf {
+ Dwarf_Debug dw_dw; /* for libdwarf */
+ Dwarf_Error dw_err; /* for libdwarf */
+ Dwarf_Off dw_maxoff; /* highest legal offset in this cu */
+ tdata_t *dw_td; /* root of the tdesc/iidesc tree */
+ hash_t *dw_tidhash; /* hash of tdescs by t_id */
+ hash_t *dw_fwdhash; /* hash of fwd decls by name */
+ hash_t *dw_enumhash; /* hash of memberless enums by name */
+ tdesc_t *dw_void; /* manufactured void type */
+ tdesc_t *dw_long; /* manufactured long type for arrays */
+ size_t dw_ptrsz; /* size of a pointer in this file */
+ tid_t dw_mfgtid_last; /* last mfg'd type ID used */
+ uint_t dw_nunres; /* count of unresolved types */
+ char *dw_cuname; /* name of compilation unit */
+} dwarf_t;
+
+static void die_create_one(dwarf_t *, Dwarf_Die);
+static void die_create(dwarf_t *, Dwarf_Die);
+
+static tid_t
+mfgtid_next(dwarf_t *dw)
+{
+ return (++dw->dw_mfgtid_last);
+}
+
+static void
+tdesc_add(dwarf_t *dw, tdesc_t *tdp)
+{
+ hash_add(dw->dw_tidhash, tdp);
+}
+
+static tdesc_t *
+tdesc_lookup(dwarf_t *dw, int tid)
+{
+ tdesc_t tmpl;
+ void *tdp;
+
+ tmpl.t_id = tid;
+
+ if (hash_find(dw->dw_tidhash, &tmpl, &tdp))
+ return (tdp);
+ else
+ return (NULL);
+}
+
+/*
+ * Resolve a tdesc down to a node which should have a size. Returns the size,
+ * zero if the size hasn't yet been determined.
+ */
+static size_t
+tdesc_size(tdesc_t *tdp)
+{
+ for (;;) {
+ switch (tdp->t_type) {
+ case INTRINSIC:
+ case POINTER:
+ case ARRAY:
+ case FUNCTION:
+ case STRUCT:
+ case UNION:
+ case ENUM:
+ return (tdp->t_size);
+
+ case FORWARD:
+ return (0);
+
+ case TYPEDEF:
+ case VOLATILE:
+ case CONST:
+ case RESTRICT:
+ tdp = tdp->t_tdesc;
+ continue;
+
+ case 0: /* not yet defined */
+ return (0);
+
+ default:
+ terminate("tdp %u: tdesc_size on unknown type %d\n",
+ tdp->t_id, tdp->t_type);
+ }
+ }
+}
+
+static size_t
+tdesc_bitsize(tdesc_t *tdp)
+{
+ for (;;) {
+ switch (tdp->t_type) {
+ case INTRINSIC:
+ return (tdp->t_intr->intr_nbits);
+
+ case ARRAY:
+ case FUNCTION:
+ case STRUCT:
+ case UNION:
+ case ENUM:
+ case POINTER:
+ return (tdp->t_size * NBBY);
+
+ case FORWARD:
+ return (0);
+
+ case TYPEDEF:
+ case VOLATILE:
+ case RESTRICT:
+ case CONST:
+ tdp = tdp->t_tdesc;
+ continue;
+
+ case 0: /* not yet defined */
+ return (0);
+
+ default:
+ terminate("tdp %u: tdesc_bitsize on unknown type %d\n",
+ tdp->t_id, tdp->t_type);
+ }
+ }
+}
+
+static tdesc_t *
+tdesc_basetype(tdesc_t *tdp)
+{
+ for (;;) {
+ switch (tdp->t_type) {
+ case TYPEDEF:
+ case VOLATILE:
+ case RESTRICT:
+ case CONST:
+ tdp = tdp->t_tdesc;
+ break;
+ case 0: /* not yet defined */
+ return (NULL);
+ default:
+ return (tdp);
+ }
+ }
+}
+
+static Dwarf_Off
+die_off(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Off off;
+
+ if (dwarf_dieoffset(die, &off, &dw->dw_err) == DW_DLV_OK)
+ return (off);
+
+ terminate("failed to get offset for die: %s\n",
+ dwarf_errmsg(&dw->dw_err));
+ /*NOTREACHED*/
+ return (0);
+}
+
+static Dwarf_Die
+die_sibling(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Die sib;
+ int rc;
+
+ if ((rc = dwarf_siblingof(dw->dw_dw, die, &sib, &dw->dw_err)) ==
+ DW_DLV_OK)
+ return (sib);
+ else if (rc == DW_DLV_NO_ENTRY)
+ return (NULL);
+
+ terminate("die %llu: failed to find type sibling: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ /*NOTREACHED*/
+ return (NULL);
+}
+
+static Dwarf_Die
+die_child(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Die child;
+ int rc;
+
+ if ((rc = dwarf_child(die, &child, &dw->dw_err)) == DW_DLV_OK)
+ return (child);
+ else if (rc == DW_DLV_NO_ENTRY)
+ return (NULL);
+
+ terminate("die %llu: failed to find type child: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ /*NOTREACHED*/
+ return (NULL);
+}
+
+static Dwarf_Half
+die_tag(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Half tag;
+
+ if (dwarf_tag(die, &tag, &dw->dw_err) == DW_DLV_OK)
+ return (tag);
+
+ terminate("die %llu: failed to get tag for type: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ /*NOTREACHED*/
+ return (0);
+}
+
+static Dwarf_Attribute
+die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req)
+{
+ Dwarf_Attribute attr;
+ int rc;
+
+ if ((rc = dwarf_attr(die, name, &attr, &dw->dw_err)) == DW_DLV_OK) {
+ return (attr);
+ } else if (rc == DW_DLV_NO_ENTRY) {
+ if (req) {
+ terminate("die %llu: no attr 0x%x\n", die_off(dw, die),
+ name);
+ } else {
+ return (NULL);
+ }
+ }
+
+ terminate("die %llu: failed to get attribute for type: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ /*NOTREACHED*/
+ return (NULL);
+}
+
+static int
+die_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp,
+ int req)
+{
+ *valp = 0;
+ if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
+ if (req)
+ terminate("die %llu: failed to get signed: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+die_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp,
+ int req)
+{
+ *valp = 0;
+ if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
+ if (req)
+ terminate("die %llu: failed to get unsigned: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req)
+{
+ *valp = 0;
+
+ if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
+ if (req)
+ terminate("die %llu: failed to get flag: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req)
+{
+ const char *str = NULL;
+
+ if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE ||
+ str == NULL) {
+ if (req)
+ terminate("die %llu: failed to get string: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ else
+ *strp = NULL;
+ return (0);
+ } else
+ *strp = xstrdup(str);
+
+ return (1);
+}
+
+static Dwarf_Off
+die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
+{
+ Dwarf_Off off;
+
+ if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) {
+ terminate("die %llu: failed to get ref: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+ }
+
+ return (off);
+}
+
+static char *
+die_name(dwarf_t *dw, Dwarf_Die die)
+{
+ char *str = NULL;
+
+ (void) die_string(dw, die, DW_AT_name, &str, 0);
+
+ return (str);
+}
+
+static int
+die_isdecl(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Bool val;
+
+ return (die_bool(dw, die, DW_AT_declaration, &val, 0) && val);
+}
+
+static int
+die_isglobal(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Signed vis;
+ Dwarf_Bool ext;
+
+ /*
+ * Some compilers (gcc) use DW_AT_external to indicate function
+ * visibility. Others (Sun) use DW_AT_visibility.
+ */
+ if (die_signed(dw, die, DW_AT_visibility, &vis, 0))
+ return (vis == DW_VIS_exported);
+ else
+ return (die_bool(dw, die, DW_AT_external, &ext, 0) && ext);
+}
+
+static tdesc_t *
+die_add(dwarf_t *dw, Dwarf_Off off)
+{
+ tdesc_t *tdp = xcalloc(sizeof (tdesc_t));
+
+ tdp->t_id = off;
+
+ tdesc_add(dw, tdp);
+
+ return (tdp);
+}
+
+static tdesc_t *
+die_lookup_pass1(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
+{
+ Dwarf_Off ref = die_attr_ref(dw, die, name);
+ tdesc_t *tdp;
+
+ if ((tdp = tdesc_lookup(dw, ref)) != NULL)
+ return (tdp);
+
+ return (die_add(dw, ref));
+}
+
+static int
+die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
+ Dwarf_Unsigned *valp, int req __unused)
+{
+ Dwarf_Locdesc *loc = NULL;
+ Dwarf_Signed locnum = 0;
+
+ if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK)
+ return (0);
+
+ if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
+ terminate("die %llu: cannot parse member offset\n",
+ die_off(dw, die));
+ }
+
+ *valp = loc->ld_s->lr_number;
+
+ if (loc != NULL)
+ if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK)
+ terminate("die %llu: cannot free location descriptor: %s\n",
+ die_off(dw, die), dwarf_errmsg(&dw->dw_err));
+
+ return (1);
+}
+
+static tdesc_t *
+tdesc_intr_common(dwarf_t *dw, int tid, const char *name, size_t sz)
+{
+ tdesc_t *tdp;
+ intr_t *intr;
+
+ intr = xcalloc(sizeof (intr_t));
+ intr->intr_type = INTR_INT;
+ intr->intr_signed = 1;
+ intr->intr_nbits = sz * NBBY;
+
+ tdp = xcalloc(sizeof (tdesc_t));
+ tdp->t_name = xstrdup(name);
+ tdp->t_size = sz;
+ tdp->t_id = tid;
+ tdp->t_type = INTRINSIC;
+ tdp->t_intr = intr;
+ tdp->t_flags = TDESC_F_RESOLVED;
+
+ tdesc_add(dw, tdp);
+
+ return (tdp);
+}
+
+/*
+ * Manufacture a void type. Used for gcc-emitted stabs, where the lack of a
+ * type reference implies a reference to a void type. A void *, for example
+ * will be represented by a pointer die without a DW_AT_type. CTF requires
+ * that pointer nodes point to something, so we'll create a void for use as
+ * the target. Note that the DWARF data may already create a void type. Ours
+ * would then be a duplicate, but it'll be removed in the self-uniquification
+ * merge performed at the completion of DWARF->tdesc conversion.
+ */
+static tdesc_t *
+tdesc_intr_void(dwarf_t *dw)
+{
+ if (dw->dw_void == NULL)
+ dw->dw_void = tdesc_intr_common(dw, TID_VOID, "void", 0);
+
+ return (dw->dw_void);
+}
+
+static tdesc_t *
+tdesc_intr_long(dwarf_t *dw)
+{
+ if (dw->dw_long == NULL) {
+ dw->dw_long = tdesc_intr_common(dw, TID_LONG, "long",
+ dw->dw_ptrsz);
+ }
+
+ return (dw->dw_long);
+}
+
+/*
+ * Used for creating bitfield types. We create a copy of an existing intrinsic,
+ * adjusting the size of the copy to match what the caller requested. The
+ * caller can then use the copy as the type for a bitfield structure member.
+ */
+static tdesc_t *
+tdesc_intr_clone(dwarf_t *dw, tdesc_t *old, size_t bitsz)
+{
+ tdesc_t *new = xcalloc(sizeof (tdesc_t));
+
+ if (!(old->t_flags & TDESC_F_RESOLVED)) {
+ terminate("tdp %u: attempt to make a bit field from an "
+ "unresolved type\n", old->t_id);
+ }
+
+ new->t_name = xstrdup(old->t_name);
+ new->t_size = old->t_size;
+ new->t_id = mfgtid_next(dw);
+ new->t_type = INTRINSIC;
+ new->t_flags = TDESC_F_RESOLVED;
+
+ new->t_intr = xcalloc(sizeof (intr_t));
+ bcopy(old->t_intr, new->t_intr, sizeof (intr_t));
+ new->t_intr->intr_nbits = bitsz;
+
+ tdesc_add(dw, new);
+
+ return (new);
+}
+
+static void
+tdesc_array_create(dwarf_t *dw, Dwarf_Die dim, tdesc_t *arrtdp,
+ tdesc_t *dimtdp)
+{
+ Dwarf_Unsigned uval;
+ Dwarf_Signed sval;
+ tdesc_t *ctdp = NULL;
+ Dwarf_Die dim2;
+ ardef_t *ar;
+
+ if ((dim2 = die_sibling(dw, dim)) == NULL) {
+ ctdp = arrtdp;
+ } else if (die_tag(dw, dim2) == DW_TAG_subrange_type) {
+ ctdp = xcalloc(sizeof (tdesc_t));
+ ctdp->t_id = mfgtid_next(dw);
+ debug(3, "die %llu: creating new type %u for sub-dimension\n",
+ die_off(dw, dim2), ctdp->t_id);
+ tdesc_array_create(dw, dim2, arrtdp, ctdp);
+ } else {
+ terminate("die %llu: unexpected non-subrange node in array\n",
+ die_off(dw, dim2));
+ }
+
+ dimtdp->t_type = ARRAY;
+ dimtdp->t_ardef = ar = xcalloc(sizeof (ardef_t));
+
+ /*
+ * Array bounds can be signed or unsigned, but there are several kinds
+ * of signless forms (data1, data2, etc) that take their sign from the
+ * routine that is trying to interpret them. That is, data1 can be
+ * either signed or unsigned, depending on whether you use the signed or
+ * unsigned accessor function. GCC will use the signless forms to store
+ * unsigned values which have their high bit set, so we need to try to
+ * read them first as unsigned to get positive values. We could also
+ * try signed first, falling back to unsigned if we got a negative
+ * value.
+ */
+ if (die_unsigned(dw, dim, DW_AT_upper_bound, &uval, 0))
+ ar->ad_nelems = uval + 1;
+ else if (die_signed(dw, dim, DW_AT_upper_bound, &sval, 0))
+ ar->ad_nelems = sval + 1;
+ else
+ ar->ad_nelems = 0;
+
+ /*
+ * Different compilers use different index types. Force the type to be
+ * a common, known value (long).
+ */
+ ar->ad_idxtype = tdesc_intr_long(dw);
+ ar->ad_contents = ctdp;
+
+ if (ar->ad_contents->t_size != 0) {
+ dimtdp->t_size = ar->ad_contents->t_size * ar->ad_nelems;
+ dimtdp->t_flags |= TDESC_F_RESOLVED;
+ }
+}
+
+/*
+ * Create a tdesc from an array node. Some arrays will come with byte size
+ * attributes, and thus can be resolved immediately. Others don't, and will
+ * need to wait until the second pass for resolution.
+ */
+static void
+die_array_create(dwarf_t *dw, Dwarf_Die arr, Dwarf_Off off, tdesc_t *tdp)
+{
+ tdesc_t *arrtdp = die_lookup_pass1(dw, arr, DW_AT_type);
+ Dwarf_Unsigned uval;
+ Dwarf_Die dim;
+
+ debug(3, "die %llu <%llx>: creating array\n", off, off);
+
+ if ((dim = die_child(dw, arr)) == NULL ||
+ die_tag(dw, dim) != DW_TAG_subrange_type)
+ terminate("die %llu: failed to retrieve array bounds\n", off);
+
+ tdesc_array_create(dw, dim, arrtdp, tdp);
+
+ if (die_unsigned(dw, arr, DW_AT_byte_size, &uval, 0)) {
+ tdesc_t *dimtdp;
+ int flags;
+
+ tdp->t_size = uval;
+
+ /*
+ * Ensure that sub-dimensions have sizes too before marking
+ * as resolved.
+ */
+ flags = TDESC_F_RESOLVED;
+ for (dimtdp = tdp->t_ardef->ad_contents;
+ dimtdp->t_type == ARRAY;
+ dimtdp = dimtdp->t_ardef->ad_contents) {
+ if (!(dimtdp->t_flags & TDESC_F_RESOLVED)) {
+ flags = 0;
+ break;
+ }
+ }
+
+ tdp->t_flags |= flags;
+ }
+
+ debug(3, "die %llu <%llx>: array nelems %u size %u\n", off, off,
+ tdp->t_ardef->ad_nelems, tdp->t_size);
+}
+
+/*ARGSUSED1*/
+static int
+die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
+{
+ dwarf_t *dw = private;
+ size_t sz;
+
+ if (tdp->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ debug(3, "trying to resolve array %d (cont %d)\n", tdp->t_id,
+ tdp->t_ardef->ad_contents->t_id);
+
+ if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0) {
+ debug(3, "unable to resolve array %s (%d) contents %d\n",
+ tdesc_name(tdp), tdp->t_id,
+ tdp->t_ardef->ad_contents->t_id);
+
+ dw->dw_nunres++;
+ return (1);
+ }
+
+ tdp->t_size = sz * tdp->t_ardef->ad_nelems;
+ tdp->t_flags |= TDESC_F_RESOLVED;
+
+ debug(3, "resolved array %d: %u bytes\n", tdp->t_id, tdp->t_size);
+
+ return (1);
+}
+
+/*ARGSUSED1*/
+static int
+die_array_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused)
+{
+ tdesc_t *cont = tdp->t_ardef->ad_contents;
+
+ if (tdp->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ fprintf(stderr, "Array %d: failed to size contents type %s (%d)\n",
+ tdp->t_id, tdesc_name(cont), cont->t_id);
+
+ return (1);
+}
+
+/*
+ * Most enums (those with members) will be resolved during this first pass.
+ * Others - those without members (see the file comment) - won't be, and will
+ * need to wait until the second pass when they can be matched with their full
+ * definitions.
+ */
+static void
+die_enum_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ Dwarf_Die mem;
+ Dwarf_Unsigned uval;
+ Dwarf_Signed sval;
+
+ debug(3, "die %llu: creating enum\n", off);
+
+ tdp->t_type = ENUM;
+
+ (void) die_unsigned(dw, die, DW_AT_byte_size, &uval, DW_ATTR_REQ);
+ tdp->t_size = uval;
+
+ if ((mem = die_child(dw, die)) != NULL) {
+ elist_t **elastp = &tdp->t_emem;
+
+ do {
+ elist_t *el;
+
+ if (die_tag(dw, mem) != DW_TAG_enumerator) {
+ /* Nested type declaration */
+ die_create_one(dw, mem);
+ continue;
+ }
+
+ el = xcalloc(sizeof (elist_t));
+ el->el_name = die_name(dw, mem);
+
+ if (die_signed(dw, mem, DW_AT_const_value, &sval, 0)) {
+ el->el_number = sval;
+ } else if (die_unsigned(dw, mem, DW_AT_const_value,
+ &uval, 0)) {
+ el->el_number = uval;
+ } else {
+ terminate("die %llu: enum %llu: member without "
+ "value\n", off, die_off(dw, mem));
+ }
+
+ debug(3, "die %llu: enum %llu: created %s = %d\n", off,
+ die_off(dw, mem), el->el_name, el->el_number);
+
+ *elastp = el;
+ elastp = &el->el_next;
+
+ } while ((mem = die_sibling(dw, mem)) != NULL);
+
+ hash_add(dw->dw_enumhash, tdp);
+
+ tdp->t_flags |= TDESC_F_RESOLVED;
+
+ if (tdp->t_name != NULL) {
+ iidesc_t *ii = xcalloc(sizeof (iidesc_t));
+ ii->ii_type = II_SOU;
+ ii->ii_name = xstrdup(tdp->t_name);
+ ii->ii_dtype = tdp;
+
+ iidesc_add(dw->dw_td->td_iihash, ii);
+ }
+ }
+}
+
+static int
+die_enum_match(void *arg1, void *arg2)
+{
+ tdesc_t *tdp = arg1, **fullp = arg2;
+
+ if (tdp->t_emem != NULL) {
+ *fullp = tdp;
+ return (-1); /* stop the iteration */
+ }
+
+ return (0);
+}
+
+/*ARGSUSED1*/
+static int
+die_enum_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
+{
+ dwarf_t *dw = private;
+ tdesc_t *full = NULL;
+
+ if (tdp->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ (void) hash_find_iter(dw->dw_enumhash, tdp, die_enum_match, &full);
+
+ /*
+ * The answer to this one won't change from iteration to iteration,
+ * so don't even try.
+ */
+ if (full == NULL) {
+ terminate("tdp %u: enum %s has no members\n", tdp->t_id,
+ tdesc_name(tdp));
+ }
+
+ debug(3, "tdp %u: enum %s redirected to %u\n", tdp->t_id,
+ tdesc_name(tdp), full->t_id);
+
+ tdp->t_flags |= TDESC_F_RESOLVED;
+
+ return (1);
+}
+
+static int
+die_fwd_map(void *arg1, void *arg2)
+{
+ tdesc_t *fwd = arg1, *sou = arg2;
+
+ debug(3, "tdp %u: mapped forward %s to sou %u\n", fwd->t_id,
+ tdesc_name(fwd), sou->t_id);
+ fwd->t_tdesc = sou;
+
+ return (0);
+}
+
+/*
+ * Structures and unions will never be resolved during the first pass, as we
+ * won't be able to fully determine the member sizes. The second pass, which
+ * have access to sizing information, will be able to complete the resolution.
+ */
+static void
+die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
+ int type, const char *typename)
+{
+ Dwarf_Unsigned sz, bitsz, bitoff;
+ Dwarf_Die mem;
+ mlist_t *ml, **mlastp;
+ iidesc_t *ii;
+
+ tdp->t_type = (die_isdecl(dw, str) ? FORWARD : type);
+
+ debug(3, "die %llu: creating %s %s\n", off,
+ (tdp->t_type == FORWARD ? "forward decl" : typename),
+ tdesc_name(tdp));
+
+ if (tdp->t_type == FORWARD) {
+ hash_add(dw->dw_fwdhash, tdp);
+ return;
+ }
+
+ (void) hash_find_iter(dw->dw_fwdhash, tdp, die_fwd_map, tdp);
+
+ (void) die_unsigned(dw, str, DW_AT_byte_size, &sz, DW_ATTR_REQ);
+ tdp->t_size = sz;
+
+ /*
+ * GCC allows empty SOUs as an extension.
+ */
+ if ((mem = die_child(dw, str)) == NULL) {
+ goto out;
+ }
+
+ mlastp = &tdp->t_members;
+
+ do {
+ Dwarf_Off memoff = die_off(dw, mem);
+ Dwarf_Half tag = die_tag(dw, mem);
+ Dwarf_Unsigned mloff;
+
+ if (tag != DW_TAG_member) {
+ /* Nested type declaration */
+ die_create_one(dw, mem);
+ continue;
+ }
+
+ debug(3, "die %llu: mem %llu: creating member\n", off, memoff);
+
+ ml = xcalloc(sizeof (mlist_t));
+
+ /*
+ * This could be a GCC anon struct/union member, so we'll allow
+ * an empty name, even though nothing can really handle them
+ * properly. Note that some versions of GCC miss out debug
+ * info for anon structs, though recent versions are fixed (gcc
+ * bug 11816).
+ */
+ if ((ml->ml_name = die_name(dw, mem)) == NULL)
+ ml->ml_name = NULL;
+
+ ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type);
+
+ if (die_mem_offset(dw, mem, DW_AT_data_member_location,
+ &mloff, 0)) {
+ debug(3, "die %llu: got mloff %llx\n", off,
+ (u_longlong_t)mloff);
+ ml->ml_offset = mloff * 8;
+ }
+
+ if (die_unsigned(dw, mem, DW_AT_bit_size, &bitsz, 0))
+ ml->ml_size = bitsz;
+ else
+ ml->ml_size = tdesc_bitsize(ml->ml_type);
+
+ if (die_unsigned(dw, mem, DW_AT_bit_offset, &bitoff, 0)) {
+#if BYTE_ORDER == _BIG_ENDIAN
+ ml->ml_offset += bitoff;
+#else
+ ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff -
+ ml->ml_size;
+#endif
+ }
+
+ debug(3, "die %llu: mem %llu: created \"%s\" (off %u sz %u)\n",
+ off, memoff, ml->ml_name, ml->ml_offset, ml->ml_size);
+
+ *mlastp = ml;
+ mlastp = &ml->ml_next;
+ } while ((mem = die_sibling(dw, mem)) != NULL);
+
+ /*
+ * GCC will attempt to eliminate unused types, thus decreasing the
+ * size of the emitted dwarf. That is, if you declare a foo_t in your
+ * header, include said header in your source file, and neglect to
+ * actually use (directly or indirectly) the foo_t in the source file,
+ * the foo_t won't make it into the emitted DWARF. So, at least, goes
+ * the theory.
+ *
+ * Occasionally, it'll emit the DW_TAG_structure_type for the foo_t,
+ * and then neglect to emit the members. Strangely, the loner struct
+ * tag will always be followed by a proper nested declaration of
+ * something else. This is clearly a bug, but we're not going to have
+ * time to get it fixed before this goo goes back, so we'll have to work
+ * around it. If we see a no-membered struct with a nested declaration
+ * (i.e. die_child of the struct tag won't be null), we'll ignore it.
+ * Being paranoid, we won't simply remove it from the hash. Instead,
+ * we'll decline to create an iidesc for it, thus ensuring that this
+ * type won't make it into the output file. To be safe, we'll also
+ * change the name.
+ */
+ if (tdp->t_members == NULL) {
+ const char *old = tdesc_name(tdp);
+ size_t newsz = 7 + strlen(old) + 1;
+ char *new = xmalloc(newsz);
+ (void) snprintf(new, newsz, "orphan %s", old);
+
+ debug(3, "die %llu: worked around %s %s\n", off, typename, old);
+
+ if (tdp->t_name != NULL)
+ free(tdp->t_name);
+ tdp->t_name = new;
+ return;
+ }
+
+out:
+ if (tdp->t_name != NULL) {
+ ii = xcalloc(sizeof (iidesc_t));
+ ii->ii_type = II_SOU;
+ ii->ii_name = xstrdup(tdp->t_name);
+ ii->ii_dtype = tdp;
+
+ iidesc_add(dw->dw_td->td_iihash, ii);
+ }
+}
+
+static void
+die_struct_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_sou_create(dw, die, off, tdp, STRUCT, "struct");
+}
+
+static void
+die_union_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_sou_create(dw, die, off, tdp, UNION, "union");
+}
+
+/*ARGSUSED1*/
+static int
+die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
+{
+ dwarf_t *dw = private;
+ mlist_t *ml;
+ tdesc_t *mt;
+
+ if (tdp->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ debug(3, "resolving sou %s\n", tdesc_name(tdp));
+
+ for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
+ if (ml->ml_size == 0) {
+ mt = tdesc_basetype(ml->ml_type);
+
+ if ((ml->ml_size = tdesc_bitsize(mt)) != 0)
+ continue;
+
+ /*
+ * For empty members, or GCC/C99 flexible array
+ * members, a size of 0 is correct.
+ */
+ if (mt->t_members == NULL)
+ continue;
+ if (mt->t_type == ARRAY && mt->t_ardef->ad_nelems == 0)
+ continue;
+
+ dw->dw_nunres++;
+ return (1);
+ }
+
+ if ((mt = tdesc_basetype(ml->ml_type)) == NULL) {
+ dw->dw_nunres++;
+ return (1);
+ }
+
+ if (ml->ml_size != 0 && mt->t_type == INTRINSIC &&
+ mt->t_intr->intr_nbits != ml->ml_size) {
+ /*
+ * This member is a bitfield, and needs to reference
+ * an intrinsic type with the same width. If the
+ * currently-referenced type isn't of the same width,
+ * we'll copy it, adjusting the width of the copy to
+ * the size we'd like.
+ */
+ debug(3, "tdp %u: creating bitfield for %d bits\n",
+ tdp->t_id, ml->ml_size);
+
+ ml->ml_type = tdesc_intr_clone(dw, mt, ml->ml_size);
+ }
+ }
+
+ tdp->t_flags |= TDESC_F_RESOLVED;
+
+ return (1);
+}
+
+/*ARGSUSED1*/
+static int
+die_sou_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused)
+{
+ const char *typename = (tdp->t_type == STRUCT ? "struct" : "union");
+ mlist_t *ml;
+
+ if (tdp->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
+ if (ml->ml_size == 0) {
+ fprintf(stderr, "%s %d <%x>: failed to size member \"%s\" "
+ "of type %s (%d <%x>)\n", typename, tdp->t_id,
+ tdp->t_id,
+ ml->ml_name, tdesc_name(ml->ml_type),
+ ml->ml_type->t_id, ml->ml_type->t_id);
+ }
+ }
+
+ return (1);
+}
+
+static void
+die_funcptr_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ Dwarf_Attribute attr;
+ Dwarf_Half tag;
+ Dwarf_Die arg;
+ fndef_t *fn;
+ int i;
+
+ debug(3, "die %llu <%llx>: creating function pointer\n", off, off);
+
+ /*
+ * We'll begin by processing any type definition nodes that may be
+ * lurking underneath this one.
+ */
+ for (arg = die_child(dw, die); arg != NULL;
+ arg = die_sibling(dw, arg)) {
+ if ((tag = die_tag(dw, arg)) != DW_TAG_formal_parameter &&
+ tag != DW_TAG_unspecified_parameters) {
+ /* Nested type declaration */
+ die_create_one(dw, arg);
+ }
+ }
+
+ if (die_isdecl(dw, die)) {
+ /*
+ * This is a prototype. We don't add prototypes to the
+ * tree, so we're going to drop the tdesc. Unfortunately,
+ * it has already been added to the tree. Nobody will reference
+ * it, though, and it will be leaked.
+ */
+ return;
+ }
+
+ fn = xcalloc(sizeof (fndef_t));
+
+ tdp->t_type = FUNCTION;
+
+ if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
+ fn->fn_ret = die_lookup_pass1(dw, die, DW_AT_type);
+ } else {
+ fn->fn_ret = tdesc_intr_void(dw);
+ }
+
+ /*
+ * Count the arguments to the function, then read them in.
+ */
+ for (fn->fn_nargs = 0, arg = die_child(dw, die); arg != NULL;
+ arg = die_sibling(dw, arg)) {
+ if ((tag = die_tag(dw, arg)) == DW_TAG_formal_parameter)
+ fn->fn_nargs++;
+ else if (tag == DW_TAG_unspecified_parameters &&
+ fn->fn_nargs > 0)
+ fn->fn_vargs = 1;
+ }
+
+ if (fn->fn_nargs != 0) {
+ debug(3, "die %llu: adding %d argument%s\n", off, fn->fn_nargs,
+ (fn->fn_nargs > 1 ? "s" : ""));
+
+ fn->fn_args = xcalloc(sizeof (tdesc_t *) * fn->fn_nargs);
+ for (i = 0, arg = die_child(dw, die);
+ arg != NULL && i < (int) fn->fn_nargs;
+ arg = die_sibling(dw, arg)) {
+ if (die_tag(dw, arg) != DW_TAG_formal_parameter)
+ continue;
+
+ fn->fn_args[i++] = die_lookup_pass1(dw, arg,
+ DW_AT_type);
+ }
+ }
+
+ tdp->t_fndef = fn;
+ tdp->t_flags |= TDESC_F_RESOLVED;
+}
+
+/*
+ * GCC and DevPro use different names for the base types. While the terms are
+ * the same, they are arranged in a different order. Some terms, such as int,
+ * are implied in one, and explicitly named in the other. Given a base type
+ * as input, this routine will return a common name, along with an intr_t
+ * that reflects said name.
+ */
+static intr_t *
+die_base_name_parse(const char *name, char **newp)
+{
+ char buf[100];
+ char const *base;
+ char *c;
+ int nlong = 0, nshort = 0, nchar = 0, nint = 0;
+ int sign = 1;
+ char fmt = '\0';
+ intr_t *intr;
+
+ if (strlen(name) > sizeof (buf) - 1)
+ terminate("base type name \"%s\" is too long\n", name);
+
+ strncpy(buf, name, sizeof (buf));
+
+ for (c = strtok(buf, " "); c != NULL; c = strtok(NULL, " ")) {
+ if (strcmp(c, "signed") == 0)
+ sign = 1;
+ else if (strcmp(c, "unsigned") == 0)
+ sign = 0;
+ else if (strcmp(c, "long") == 0)
+ nlong++;
+ else if (strcmp(c, "char") == 0) {
+ nchar++;
+ fmt = 'c';
+ } else if (strcmp(c, "short") == 0)
+ nshort++;
+ else if (strcmp(c, "int") == 0)
+ nint++;
+ else {
+ /*
+ * If we don't recognize any of the tokens, we'll tell
+ * the caller to fall back to the dwarf-provided
+ * encoding information.
+ */
+ return (NULL);
+ }
+ }
+
+ if (nchar > 1 || nshort > 1 || nint > 1 || nlong > 2)
+ return (NULL);
+
+ if (nchar > 0) {
+ if (nlong > 0 || nshort > 0 || nint > 0)
+ return (NULL);
+
+ base = "char";
+
+ } else if (nshort > 0) {
+ if (nlong > 0)
+ return (NULL);
+
+ base = "short";
+
+ } else if (nlong > 0) {
+ base = "long";
+
+ } else {
+ base = "int";
+ }
+
+ intr = xcalloc(sizeof (intr_t));
+ intr->intr_type = INTR_INT;
+ intr->intr_signed = sign;
+ intr->intr_iformat = fmt;
+
+ snprintf(buf, sizeof (buf), "%s%s%s",
+ (sign ? "" : "unsigned "),
+ (nlong > 1 ? "long " : ""),
+ base);
+
+ *newp = xstrdup(buf);
+ return (intr);
+}
+
+typedef struct fp_size_map {
+ size_t fsm_typesz[2]; /* size of {32,64} type */
+ uint_t fsm_enc[3]; /* CTF_FP_* for {bare,cplx,imagry} type */
+} fp_size_map_t;
+
+static const fp_size_map_t fp_encodings[] = {
+ { { 4, 4 }, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } },
+ { { 8, 8 }, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } },
+#ifdef __sparc
+ { { 16, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
+#else
+ { { 12, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } },
+#endif
+ { { 0, 0 }, { 0, 0, 0 } }
+};
+
+static uint_t
+die_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Signed enc, size_t sz)
+{
+ const fp_size_map_t *map = fp_encodings;
+ uint_t szidx = dw->dw_ptrsz == sizeof (uint64_t);
+ uint_t mult = 1, col = 0;
+
+ if (enc == DW_ATE_complex_float) {
+ mult = 2;
+ col = 1;
+ } else if (enc == DW_ATE_imaginary_float
+#if defined(sun)
+ || enc == DW_ATE_SUN_imaginary_float
+#endif
+ )
+ col = 2;
+
+ while (map->fsm_typesz[szidx] != 0) {
+ if (map->fsm_typesz[szidx] * mult == sz)
+ return (map->fsm_enc[col]);
+ map++;
+ }
+
+ terminate("die %llu: unrecognized real type size %u\n", off, sz);
+ /*NOTREACHED*/
+ return (0);
+}
+
+static intr_t *
+die_base_from_dwarf(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, size_t sz)
+{
+ intr_t *intr = xcalloc(sizeof (intr_t));
+ Dwarf_Signed enc;
+
+ (void) die_signed(dw, base, DW_AT_encoding, &enc, DW_ATTR_REQ);
+
+ switch (enc) {
+ case DW_ATE_unsigned:
+ case DW_ATE_address:
+ intr->intr_type = INTR_INT;
+ break;
+ case DW_ATE_unsigned_char:
+ intr->intr_type = INTR_INT;
+ intr->intr_iformat = 'c';
+ break;
+ case DW_ATE_signed:
+ intr->intr_type = INTR_INT;
+ intr->intr_signed = 1;
+ break;
+ case DW_ATE_signed_char:
+ intr->intr_type = INTR_INT;
+ intr->intr_signed = 1;
+ intr->intr_iformat = 'c';
+ break;
+ case DW_ATE_boolean:
+ intr->intr_type = INTR_INT;
+ intr->intr_signed = 1;
+ intr->intr_iformat = 'b';
+ break;
+ case DW_ATE_float:
+ case DW_ATE_complex_float:
+ case DW_ATE_imaginary_float:
+#if defined(sun)
+ case DW_ATE_SUN_imaginary_float:
+ case DW_ATE_SUN_interval_float:
+#endif
+ intr->intr_type = INTR_REAL;
+ intr->intr_signed = 1;
+ intr->intr_fformat = die_base_type2enc(dw, off, enc, sz);
+ break;
+ default:
+ terminate("die %llu: unknown base type encoding 0x%llx\n",
+ off, enc);
+ }
+
+ return (intr);
+}
+
+static void
+die_base_create(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, tdesc_t *tdp)
+{
+ Dwarf_Unsigned sz;
+ intr_t *intr;
+ char *new;
+
+ debug(3, "die %llu: creating base type\n", off);
+
+ /*
+ * The compilers have their own clever (internally inconsistent) ideas
+ * as to what base types should look like. Some times gcc will, for
+ * example, use DW_ATE_signed_char for char. Other times, however, it
+ * will use DW_ATE_signed. Needless to say, this causes some problems
+ * down the road, particularly with merging. We do, however, use the
+ * DWARF idea of type sizes, as this allows us to avoid caring about
+ * the data model.
+ */
+ (void) die_unsigned(dw, base, DW_AT_byte_size, &sz, DW_ATTR_REQ);
+
+ if (tdp->t_name == NULL)
+ terminate("die %llu: base type without name\n", off);
+
+ /* XXX make a name parser for float too */
+ if ((intr = die_base_name_parse(tdp->t_name, &new)) != NULL) {
+ /* Found it. We'll use the parsed version */
+ debug(3, "die %llu: name \"%s\" remapped to \"%s\"\n", off,
+ tdesc_name(tdp), new);
+
+ free(tdp->t_name);
+ tdp->t_name = new;
+ } else {
+ /*
+ * We didn't recognize the type, so we'll create an intr_t
+ * based on the DWARF data.
+ */
+ debug(3, "die %llu: using dwarf data for base \"%s\"\n", off,
+ tdesc_name(tdp));
+
+ intr = die_base_from_dwarf(dw, base, off, sz);
+ }
+
+ intr->intr_nbits = sz * 8;
+
+ tdp->t_type = INTRINSIC;
+ tdp->t_intr = intr;
+ tdp->t_size = sz;
+
+ tdp->t_flags |= TDESC_F_RESOLVED;
+}
+
+static void
+die_through_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp,
+ int type, const char *typename)
+{
+ Dwarf_Attribute attr;
+
+ debug(3, "die %llu <%llx>: creating %s type %d\n", off, off, typename, type);
+
+ tdp->t_type = type;
+
+ if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) {
+ tdp->t_tdesc = die_lookup_pass1(dw, die, DW_AT_type);
+ } else {
+ tdp->t_tdesc = tdesc_intr_void(dw);
+ }
+
+ if (type == POINTER)
+ tdp->t_size = dw->dw_ptrsz;
+
+ tdp->t_flags |= TDESC_F_RESOLVED;
+
+ if (type == TYPEDEF) {
+ iidesc_t *ii = xcalloc(sizeof (iidesc_t));
+ ii->ii_type = II_TYPE;
+ ii->ii_name = xstrdup(tdp->t_name);
+ ii->ii_dtype = tdp;
+
+ iidesc_add(dw->dw_td->td_iihash, ii);
+ }
+}
+
+static void
+die_typedef_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_through_create(dw, die, off, tdp, TYPEDEF, "typedef");
+}
+
+static void
+die_const_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_through_create(dw, die, off, tdp, CONST, "const");
+}
+
+static void
+die_pointer_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_through_create(dw, die, off, tdp, POINTER, "pointer");
+}
+
+static void
+die_restrict_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_through_create(dw, die, off, tdp, RESTRICT, "restrict");
+}
+
+static void
+die_volatile_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp)
+{
+ die_through_create(dw, die, off, tdp, VOLATILE, "volatile");
+}
+
+/*ARGSUSED3*/
+static void
+die_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused)
+{
+ Dwarf_Die arg;
+ Dwarf_Half tag;
+ iidesc_t *ii;
+ char *name;
+
+ debug(3, "die %llu <%llx>: creating function definition\n", off, off);
+
+ /*
+ * We'll begin by processing any type definition nodes that may be
+ * lurking underneath this one.
+ */
+ for (arg = die_child(dw, die); arg != NULL;
+ arg = die_sibling(dw, arg)) {
+ if ((tag = die_tag(dw, arg)) != DW_TAG_formal_parameter &&
+ tag != DW_TAG_variable) {
+ /* Nested type declaration */
+ die_create_one(dw, arg);
+ }
+ }
+
+ if (die_isdecl(dw, die) || (name = die_name(dw, die)) == NULL) {
+ /*
+ * We process neither prototypes nor subprograms without
+ * names.
+ */
+ return;
+ }
+
+ ii = xcalloc(sizeof (iidesc_t));
+ ii->ii_type = die_isglobal(dw, die) ? II_GFUN : II_SFUN;
+ ii->ii_name = name;
+ if (ii->ii_type == II_SFUN)
+ ii->ii_owner = xstrdup(dw->dw_cuname);
+
+ debug(3, "die %llu: function %s is %s\n", off, ii->ii_name,
+ (ii->ii_type == II_GFUN ? "global" : "static"));
+
+ if (die_attr(dw, die, DW_AT_type, 0) != NULL)
+ ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type);
+ else
+ ii->ii_dtype = tdesc_intr_void(dw);
+
+ for (arg = die_child(dw, die); arg != NULL;
+ arg = die_sibling(dw, arg)) {
+ char *name1;
+
+ debug(3, "die %llu: looking at sub member at %llu\n",
+ off, die_off(dw, die));
+
+ if (die_tag(dw, arg) != DW_TAG_formal_parameter)
+ continue;
+
+ if ((name1 = die_name(dw, arg)) == NULL) {
+ terminate("die %llu: func arg %d has no name\n",
+ off, ii->ii_nargs + 1);
+ }
+
+ if (strcmp(name1, "...") == 0) {
+ free(name1);
+ ii->ii_vargs = 1;
+ continue;
+ }
+
+ ii->ii_nargs++;
+ }
+
+ if (ii->ii_nargs > 0) {
+ int i;
+
+ debug(3, "die %llu: function has %d argument%s\n", off,
+ ii->ii_nargs, (ii->ii_nargs == 1 ? "" : "s"));
+
+ ii->ii_args = xcalloc(sizeof (tdesc_t) * ii->ii_nargs);
+
+ for (arg = die_child(dw, die), i = 0;
+ arg != NULL && i < ii->ii_nargs;
+ arg = die_sibling(dw, arg)) {
+ if (die_tag(dw, arg) != DW_TAG_formal_parameter)
+ continue;
+
+ ii->ii_args[i++] = die_lookup_pass1(dw, arg,
+ DW_AT_type);
+ }
+ }
+
+ iidesc_add(dw->dw_td->td_iihash, ii);
+}
+
+/*ARGSUSED3*/
+static void
+die_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused)
+{
+ iidesc_t *ii;
+ char *name;
+
+ debug(3, "die %llu: creating object definition\n", off);
+
+ if (die_isdecl(dw, die) || (name = die_name(dw, die)) == NULL)
+ return; /* skip prototypes and nameless objects */
+
+ ii = xcalloc(sizeof (iidesc_t));
+ ii->ii_type = die_isglobal(dw, die) ? II_GVAR : II_SVAR;
+ ii->ii_name = name;
+ ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type);
+ if (ii->ii_type == II_SVAR)
+ ii->ii_owner = xstrdup(dw->dw_cuname);
+
+ iidesc_add(dw->dw_td->td_iihash, ii);
+}
+
+/*ARGSUSED2*/
+static int
+die_fwd_resolve(tdesc_t *fwd, tdesc_t **fwdp, void *private __unused)
+{
+ if (fwd->t_flags & TDESC_F_RESOLVED)
+ return (1);
+
+ if (fwd->t_tdesc != NULL) {
+ debug(3, "tdp %u: unforwarded %s\n", fwd->t_id,
+ tdesc_name(fwd));
+ *fwdp = fwd->t_tdesc;
+ }
+
+ fwd->t_flags |= TDESC_F_RESOLVED;
+
+ return (1);
+}
+
+/*ARGSUSED*/
+static void
+die_lexblk_descend(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off __unused, tdesc_t *tdp __unused)
+{
+ Dwarf_Die child = die_child(dw, die);
+
+ if (child != NULL)
+ die_create(dw, child);
+}
+
+/*
+ * Used to map the die to a routine which can parse it, using the tag to do the
+ * mapping. While the processing of most tags entails the creation of a tdesc,
+ * there are a few which don't - primarily those which result in the creation of
+ * iidescs which refer to existing tdescs.
+ */
+
+#define DW_F_NOTDP 0x1 /* Don't create a tdesc for the creator */
+
+typedef struct die_creator {
+ Dwarf_Half dc_tag;
+ uint16_t dc_flags;
+ void (*dc_create)(dwarf_t *, Dwarf_Die, Dwarf_Off, tdesc_t *);
+} die_creator_t;
+
+static const die_creator_t die_creators[] = {
+ { DW_TAG_array_type, 0, die_array_create },
+ { DW_TAG_enumeration_type, 0, die_enum_create },
+ { DW_TAG_lexical_block, DW_F_NOTDP, die_lexblk_descend },
+ { DW_TAG_pointer_type, 0, die_pointer_create },
+ { DW_TAG_structure_type, 0, die_struct_create },
+ { DW_TAG_subroutine_type, 0, die_funcptr_create },
+ { DW_TAG_typedef, 0, die_typedef_create },
+ { DW_TAG_union_type, 0, die_union_create },
+ { DW_TAG_base_type, 0, die_base_create },
+ { DW_TAG_const_type, 0, die_const_create },
+ { DW_TAG_subprogram, DW_F_NOTDP, die_function_create },
+ { DW_TAG_variable, DW_F_NOTDP, die_variable_create },
+ { DW_TAG_volatile_type, 0, die_volatile_create },
+ { DW_TAG_restrict_type, 0, die_restrict_create },
+ { 0, 0, NULL }
+};
+
+static const die_creator_t *
+die_tag2ctor(Dwarf_Half tag)
+{
+ const die_creator_t *dc;
+
+ for (dc = die_creators; dc->dc_create != NULL; dc++) {
+ if (dc->dc_tag == tag)
+ return (dc);
+ }
+
+ return (NULL);
+}
+
+static void
+die_create_one(dwarf_t *dw, Dwarf_Die die)
+{
+ Dwarf_Off off = die_off(dw, die);
+ const die_creator_t *dc;
+ Dwarf_Half tag;
+ tdesc_t *tdp;
+
+ debug(3, "die %llu <%llx>: create_one\n", off, off);
+
+ if (off > dw->dw_maxoff) {
+ terminate("illegal die offset %llu (max %llu)\n", off,
+ dw->dw_maxoff);
+ }
+
+ tag = die_tag(dw, die);
+
+ if ((dc = die_tag2ctor(tag)) == NULL) {
+ debug(2, "die %llu: ignoring tag type %x\n", off, tag);
+ return;
+ }
+
+ if ((tdp = tdesc_lookup(dw, off)) == NULL &&
+ !(dc->dc_flags & DW_F_NOTDP)) {
+ tdp = xcalloc(sizeof (tdesc_t));
+ tdp->t_id = off;
+ tdesc_add(dw, tdp);
+ }
+
+ if (tdp != NULL)
+ tdp->t_name = die_name(dw, die);
+
+ dc->dc_create(dw, die, off, tdp);
+}
+
+static void
+die_create(dwarf_t *dw, Dwarf_Die die)
+{
+ do {
+ die_create_one(dw, die);
+ } while ((die = die_sibling(dw, die)) != NULL);
+}
+
+static tdtrav_cb_f die_resolvers[] = {
+ NULL,
+ NULL, /* intrinsic */
+ NULL, /* pointer */
+ die_array_resolve, /* array */
+ NULL, /* function */
+ die_sou_resolve, /* struct */
+ die_sou_resolve, /* union */
+ die_enum_resolve, /* enum */
+ die_fwd_resolve, /* forward */
+ NULL, /* typedef */
+ NULL, /* typedef unres */
+ NULL, /* volatile */
+ NULL, /* const */
+ NULL, /* restrict */
+};
+
+static tdtrav_cb_f die_fail_reporters[] = {
+ NULL,
+ NULL, /* intrinsic */
+ NULL, /* pointer */
+ die_array_failed, /* array */
+ NULL, /* function */
+ die_sou_failed, /* struct */
+ die_sou_failed, /* union */
+ NULL, /* enum */
+ NULL, /* forward */
+ NULL, /* typedef */
+ NULL, /* typedef unres */
+ NULL, /* volatile */
+ NULL, /* const */
+ NULL, /* restrict */
+};
+
+static void
+die_resolve(dwarf_t *dw)
+{
+ int last = -1;
+ int pass = 0;
+
+ do {
+ pass++;
+ dw->dw_nunres = 0;
+
+ (void) iitraverse_hash(dw->dw_td->td_iihash,
+ &dw->dw_td->td_curvgen, NULL, NULL, die_resolvers, dw);
+
+ debug(3, "resolve: pass %d, %u left\n", pass, dw->dw_nunres);
+
+ if ((int) dw->dw_nunres == last) {
+ fprintf(stderr, "%s: failed to resolve the following "
+ "types:\n", progname);
+
+ (void) iitraverse_hash(dw->dw_td->td_iihash,
+ &dw->dw_td->td_curvgen, NULL, NULL,
+ die_fail_reporters, dw);
+
+ terminate("failed to resolve types\n");
+ }
+
+ last = dw->dw_nunres;
+
+ } while (dw->dw_nunres != 0);
+}
+
+/*ARGSUSED*/
+int
+dw_read(tdata_t *td, Elf *elf, char *filename __unused)
+{
+ Dwarf_Unsigned abboff, hdrlen, nxthdr;
+ Dwarf_Half vers, addrsz;
+ Dwarf_Die cu = 0;
+ Dwarf_Die child = 0;
+ dwarf_t dw;
+ char *prod = NULL;
+ int rc;
+
+ bzero(&dw, sizeof (dwarf_t));
+ dw.dw_td = td;
+ dw.dw_ptrsz = elf_ptrsz(elf);
+ dw.dw_mfgtid_last = TID_MFGTID_BASE;
+ dw.dw_tidhash = hash_new(TDESC_HASH_BUCKETS, tdesc_idhash, tdesc_idcmp);
+ dw.dw_fwdhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
+ tdesc_namecmp);
+ dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
+ tdesc_namecmp);
+
+ if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw,
+ &dw.dw_err)) == DW_DLV_NO_ENTRY) {
+ errno = ENOENT;
+ return (-1);
+ } else if (rc != DW_DLV_OK) {
+ if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
+ /*
+ * There's no type data in the DWARF section, but
+ * libdwarf is too clever to handle that properly.
+ */
+ return (0);
+ }
+
+ terminate("failed to initialize DWARF: %s\n",
+ dwarf_errmsg(&dw.dw_err));
+ }
+
+ if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
+ &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
+ terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err));
+
+ if ((cu = die_sibling(&dw, NULL)) == NULL)
+ terminate("file does not contain dwarf type data "
+ "(try compiling with -g)\n");
+
+ dw.dw_maxoff = nxthdr - 1;
+
+ if (dw.dw_maxoff > TID_FILEMAX)
+ terminate("file contains too many types\n");
+
+ debug(1, "DWARF version: %d\n", vers);
+ if (vers != DWARF_VERSION) {
+ terminate("file contains incompatible version %d DWARF code "
+ "(version 2 required)\n", vers);
+ }
+
+ if (die_string(&dw, cu, DW_AT_producer, &prod, 0)) {
+ debug(1, "DWARF emitter: %s\n", prod);
+ free(prod);
+ }
+
+ if ((dw.dw_cuname = die_name(&dw, cu)) != NULL) {
+ char *base = xstrdup(basename(dw.dw_cuname));
+ free(dw.dw_cuname);
+ dw.dw_cuname = base;
+
+ debug(1, "CU name: %s\n", dw.dw_cuname);
+ }
+
+ if ((child = die_child(&dw, cu)) != NULL)
+ die_create(&dw, child);
+
+ if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
+ &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY)
+ terminate("multiple compilation units not supported\n");
+
+ (void) dwarf_finish(&dw.dw_dw, &dw.dw_err);
+
+ die_resolve(&dw);
+
+ cvt_fixups(td, dw.dw_ptrsz);
+
+ /* leak the dwarf_t */
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.c b/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.c
new file mode 100644
index 0000000..fb9a11f
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.c
@@ -0,0 +1,153 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating a FIFO queue
+ */
+
+#include <stdlib.h>
+
+#include "fifo.h"
+#include "memory.h"
+
+typedef struct fifonode {
+ void *fn_data;
+ struct fifonode *fn_next;
+} fifonode_t;
+
+struct fifo {
+ fifonode_t *f_head;
+ fifonode_t *f_tail;
+};
+
+fifo_t *
+fifo_new(void)
+{
+ fifo_t *f;
+
+ f = xcalloc(sizeof (fifo_t));
+
+ return (f);
+}
+
+/* Add to the end of the fifo */
+void
+fifo_add(fifo_t *f, void *data)
+{
+ fifonode_t *fn = xmalloc(sizeof (fifonode_t));
+
+ fn->fn_data = data;
+ fn->fn_next = NULL;
+
+ if (f->f_tail == NULL)
+ f->f_head = f->f_tail = fn;
+ else {
+ f->f_tail->fn_next = fn;
+ f->f_tail = fn;
+ }
+}
+
+/* Remove from the front of the fifo */
+void *
+fifo_remove(fifo_t *f)
+{
+ fifonode_t *fn;
+ void *data;
+
+ if ((fn = f->f_head) == NULL)
+ return (NULL);
+
+ data = fn->fn_data;
+ if ((f->f_head = fn->fn_next) == NULL)
+ f->f_tail = NULL;
+
+ free(fn);
+
+ return (data);
+}
+
+/*ARGSUSED*/
+static void
+fifo_nullfree(void *arg)
+{
+ /* this function intentionally left blank */
+}
+
+/* Free an entire fifo */
+void
+fifo_free(fifo_t *f, void (*freefn)(void *))
+{
+ fifonode_t *fn = f->f_head;
+ fifonode_t *tmp;
+
+ if (freefn == NULL)
+ freefn = fifo_nullfree;
+
+ while (fn) {
+ (*freefn)(fn->fn_data);
+
+ tmp = fn;
+ fn = fn->fn_next;
+ free(tmp);
+ }
+
+ free(f);
+}
+
+int
+fifo_len(fifo_t *f)
+{
+ fifonode_t *fn;
+ int i;
+
+ for (i = 0, fn = f->f_head; fn; fn = fn->fn_next, i++);
+
+ return (i);
+}
+
+int
+fifo_empty(fifo_t *f)
+{
+ return (f->f_head == NULL);
+}
+
+int
+fifo_iter(fifo_t *f, int (*iter)(void *data, void *arg), void *arg)
+{
+ fifonode_t *fn;
+ int rc;
+ int ret = 0;
+
+ for (fn = f->f_head; fn; fn = fn->fn_next) {
+ if ((rc = iter(fn->fn_data, arg)) < 0)
+ return (-1);
+ ret += rc;
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.h b/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.h
new file mode 100644
index 0000000..e4b948a
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/fifo.h
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FIFO_H
+#define _FIFO_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating a FIFO queue
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct fifo fifo_t;
+
+extern fifo_t *fifo_new(void);
+extern void fifo_add(fifo_t *, void *);
+extern void *fifo_remove(fifo_t *);
+extern void fifo_free(fifo_t *, void (*)(void *));
+extern int fifo_len(fifo_t *);
+extern int fifo_empty(fifo_t *);
+extern int fifo_iter(fifo_t *, int (*)(void *, void *), void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FIFO_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/fixup_tdescs.c b/cddl/contrib/opensolaris/tools/ctf/cvt/fixup_tdescs.c
new file mode 100644
index 0000000..b239a62
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/fixup_tdescs.c
@@ -0,0 +1,279 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Workarounds for stabs generation bugs in the compiler and general needed
+ * fixups.
+ */
+
+#include <stdio.h>
+#include <strings.h>
+
+#include "ctf_headers.h"
+#include "ctftools.h"
+#include "hash.h"
+#include "memory.h"
+
+/*
+ * Due to 4432619, the 6.1 compiler will sometimes incorrectly generate pointer
+ * stabs. Given a struct foo, and a corresponding typedef struct foo foo_t.
+ * In some cases, when faced with a pointer to a foo_t, the compiler will
+ * sometimes generate a stab that describes a pointer to a struct foo.
+ * Regardless of correctness, this breaks merges, as it occurs inconsistently
+ * by file. The following two routines know how to recognize and repair foo_t *
+ * and foo_t ** bugs in a specific set of cases. There is no general way to
+ * solve this problem without a fix to the compiler. In general, cases should
+ * only be added to these routines to fix merging problems in genunix.
+ */
+static void
+fix_ptrptr_to_struct(tdata_t *td)
+{
+ const char *strs[2] = { "as", "fdbuffer" };
+ const char *mems[2] = { "a_objectdir", "fd_shadow" };
+ const char *acts[2] = { "vnode", "page" };
+ const char *tgts[2] = { "vnode_t", "page_t" };
+ tdesc_t *str;
+ tdesc_t *act, *tgt;
+ tdesc_t *p1, *p2;
+ mlist_t *ml;
+ int i;
+
+ for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) {
+ if (!(str = lookupname(strs[i])) || str->t_type != STRUCT)
+ continue;
+
+ for (ml = str->t_members; ml; ml = ml->ml_next) {
+ if (streq(ml->ml_name, mems[i]))
+ break;
+ }
+ if (!ml)
+ continue;
+
+ if (ml->ml_type->t_type != POINTER || ml->ml_type->t_name ||
+ ml->ml_type->t_tdesc->t_type != POINTER ||
+ ml->ml_type->t_tdesc->t_name)
+ continue;
+
+ act = ml->ml_type->t_tdesc->t_tdesc;
+ if (act->t_type != STRUCT || !streq(act->t_name, acts[i]))
+ continue;
+
+ if (!(tgt = lookupname(tgts[i])) || tgt->t_type != TYPEDEF)
+ continue;
+
+ /* We have an instance of the bug */
+ p2 = xcalloc(sizeof (*p2));
+ p2->t_type = POINTER;
+ p2->t_id = td->td_nextid++;
+ p2->t_tdesc = tgt;
+
+ p1 = xcalloc(sizeof (*p1));
+ p1->t_type = POINTER;
+ p1->t_id = td->td_nextid++;
+ p1->t_tdesc = p2;
+
+ ml->ml_type = p1;
+
+ debug(3, "Fixed %s->%s => ptrptr struct %s bug\n",
+ strs[i], mems[i], acts[i]);
+ }
+}
+
+static void
+fix_ptr_to_struct(tdata_t *td)
+{
+ const char *strs[2] = { "vmem", "id_space" };
+ const char *mems[2] = { NULL, "is_vmem" };
+ tdesc_t *ptr = NULL;
+ tdesc_t *str, *vmt;
+ mlist_t *ml;
+ int i;
+
+ if ((vmt = lookupname("vmem_t")) == NULL || vmt->t_type != TYPEDEF)
+ return;
+
+ for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) {
+ if (!(str = lookupname(strs[i])) || str->t_type != STRUCT)
+ continue;
+
+ for (ml = str->t_members; ml; ml = ml->ml_next) {
+ if (mems[i] && !streq(ml->ml_name, mems[i]))
+ continue;
+
+ if (ml->ml_type->t_type != POINTER ||
+ ml->ml_type->t_name ||
+ (ml->ml_type->t_tdesc->t_type != STRUCT &&
+ ml->ml_type->t_tdesc->t_type != FORWARD) ||
+ !streq(ml->ml_type->t_tdesc->t_name, "vmem"))
+ continue;
+
+ debug(3, "Fixed %s->%s => ptr struct vmem bug\n",
+ strs[i], ml->ml_name);
+
+ if (!ptr) {
+ ptr = xcalloc(sizeof (*ptr));
+ ptr->t_type = POINTER;
+ ptr->t_id = td->td_nextid++;
+ ptr->t_tdesc = vmt;
+ }
+
+ ml->ml_type = ptr;
+ }
+ }
+}
+
+/*
+ * Fix stabs generation bugs. These routines must be run before the
+ * post-conversion merge
+ */
+void
+cvt_fixstabs(tdata_t *td)
+{
+ fix_ptrptr_to_struct(td);
+ fix_ptr_to_struct(td);
+}
+
+struct match {
+ tdesc_t *m_ret;
+ const char *m_name;
+};
+
+static int
+matching_iidesc(void *arg1, void *arg2)
+{
+ iidesc_t *iidesc = arg1;
+ struct match *match = arg2;
+ if (!streq(iidesc->ii_name, match->m_name))
+ return (0);
+
+ if (iidesc->ii_type != II_TYPE && iidesc->ii_type != II_SOU)
+ return (0);
+
+ match->m_ret = iidesc->ii_dtype;
+ return (-1);
+}
+
+static tdesc_t *
+lookup_tdesc(tdata_t *td, char const *name)
+{
+ struct match match = { NULL, name };
+ iter_iidescs_by_name(td, name, matching_iidesc, &match);
+ return (match.m_ret);
+}
+
+/*
+ * The cpu structure grows, with the addition of a machcpu member, if
+ * _MACHDEP is defined. This means that, for example, the cpu structure
+ * in unix is different from the cpu structure in genunix. As one might
+ * expect, this causes merges to fail. Since everyone indirectly contains
+ * a pointer to a CPU structure, the failed merges can cause massive amounts
+ * of duplication. In the case of unix uniquifying against genunix, upwards
+ * of 50% of the structures were unmerged due to this problem. We fix this
+ * by adding a cpu_m member. If machcpu hasn't been defined in our module,
+ * we make a forward node for it.
+ */
+static void
+fix_small_cpu_struct(tdata_t *td, size_t ptrsize)
+{
+ tdesc_t *cput, *cpu;
+ tdesc_t *machcpu;
+ mlist_t *ml, *lml;
+ mlist_t *cpum;
+ int foundcpucyc = 0;
+
+ /*
+ * We're going to take the circuitous route finding the cpu structure,
+ * because we want to make sure that we find the right one. It would
+ * be nice if we could verify the header name too. DWARF might not
+ * have the cpu_t, so we let this pass.
+ */
+ if ((cput = lookup_tdesc(td, "cpu_t")) != NULL) {
+ if (cput->t_type != TYPEDEF)
+ return;
+ cpu = cput->t_tdesc;
+ } else {
+ cpu = lookup_tdesc(td, "cpu");
+ }
+
+ if (cpu == NULL)
+ return;
+
+ if (!streq(cpu->t_name, "cpu") || cpu->t_type != STRUCT)
+ return;
+
+ for (ml = cpu->t_members, lml = NULL; ml;
+ lml = ml, ml = ml->ml_next) {
+ if (strcmp(ml->ml_name, "cpu_cyclic") == 0)
+ foundcpucyc = 1;
+ }
+
+ if (foundcpucyc == 0 || lml == NULL ||
+ strcmp(lml->ml_name, "cpu_m") == 0)
+ return;
+
+ /*
+ * We need to derive the right offset for the fake cpu_m member. To do
+ * that, we require a special unused member to be the last member
+ * before the 'cpu_m', that we encode knowledge of here. ABI alignment
+ * on all platforms is such that we only need to add a pointer-size
+ * number of bits to get the right offset for cpu_m. This would most
+ * likely break if gcc's -malign-double were ever used, but that option
+ * breaks the ABI anyway.
+ */
+ if (!streq(lml->ml_name, "cpu_m_pad") &&
+ getenv("CTFCONVERT_PERMISSIVE") == NULL) {
+ terminate("last cpu_t member before cpu_m is %s; "
+ "it must be cpu_m_pad.\n", lml->ml_name);
+ }
+
+ if ((machcpu = lookup_tdesc(td, "machcpu")) == NULL) {
+ machcpu = xcalloc(sizeof (*machcpu));
+ machcpu->t_name = xstrdup("machcpu");
+ machcpu->t_id = td->td_nextid++;
+ machcpu->t_type = FORWARD;
+ } else if (machcpu->t_type != STRUCT) {
+ return;
+ }
+
+ debug(3, "Adding cpu_m machcpu %s to cpu struct\n",
+ (machcpu->t_type == FORWARD ? "forward" : "struct"));
+
+ cpum = xmalloc(sizeof (*cpum));
+ cpum->ml_offset = lml->ml_offset + (ptrsize * NBBY);
+ cpum->ml_size = 0;
+ cpum->ml_name = xstrdup("cpu_m");
+ cpum->ml_type = machcpu;
+ cpum->ml_next = NULL;
+
+ lml->ml_next = cpum;
+}
+
+void
+cvt_fixups(tdata_t *td, size_t ptrsize)
+{
+ fix_small_cpu_struct(td, ptrsize);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/hash.c b/cddl/contrib/opensolaris/tools/ctf/cvt/hash.c
new file mode 100644
index 0000000..36ed45a
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/hash.c
@@ -0,0 +1,291 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating hash tables
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+
+#include "hash.h"
+#include "memory.h"
+#include "list.h"
+
+struct hash {
+ int h_nbuckets;
+ list_t **h_buckets;
+
+ int (*h_hashfn)(int, void *);
+ int (*h_cmp)(void *, void *);
+};
+
+struct hash_data {
+ hash_t *hd_hash;
+ int (*hd_fun)(void *, void *);
+ void *hd_key;
+ void *hd_private;
+
+ void *hd_ret;
+};
+
+static int
+hash_def_hash(int nbuckets, void *arg)
+{
+ uintptr_t data = (uintptr_t) arg;
+ return (data % nbuckets);
+}
+
+static int
+hash_def_cmp(void *d1, void *d2)
+{
+ return (d1 != d2);
+}
+
+
+int
+hash_name(int nbuckets, const char *name)
+{
+ const char *c;
+ ulong_t g;
+ int h = 0;
+
+ for (c = name; *c; c++) {
+ h = (h << 4) + *c;
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ return (h % nbuckets);
+}
+
+hash_t *
+hash_new(int nbuckets, int (*hashfn)(int, void *), int (*cmp)(void *, void *))
+{
+ hash_t *hash;
+
+ hash = xmalloc(sizeof (hash_t));
+ hash->h_buckets = xcalloc(sizeof (list_t *) * nbuckets);
+ hash->h_nbuckets = nbuckets;
+ hash->h_hashfn = hashfn ? hashfn : hash_def_hash;
+ hash->h_cmp = cmp ? cmp : hash_def_cmp;
+
+ return (hash);
+}
+
+void
+hash_add(hash_t *hash, void *key)
+{
+ int bucket = hash->h_hashfn(hash->h_nbuckets, key);
+
+ list_add(&hash->h_buckets[bucket], key);
+}
+
+static int
+hash_add_cb(void *node, void *private)
+{
+ hash_add((hash_t *)private, node);
+ return (0);
+}
+
+void
+hash_merge(hash_t *to, hash_t *from)
+{
+ (void) hash_iter(from, hash_add_cb, to);
+}
+
+static int
+hash_remove_cb(void *key1, void *key2, void *arg)
+{
+ hash_t *hash = arg;
+ return (hash->h_cmp(key1, key2));
+}
+
+void
+hash_remove(hash_t *hash, void *key)
+{
+ int bucket = hash->h_hashfn(hash->h_nbuckets, key);
+
+ (void) list_remove(&hash->h_buckets[bucket], key,
+ hash_remove_cb, hash);
+}
+
+int
+hash_match(hash_t *hash, void *key, int (*fun)(void *, void *),
+ void *private)
+{
+ int bucket = hash->h_hashfn(hash->h_nbuckets, key);
+
+ return (list_iter(hash->h_buckets[bucket], fun, private) < 0);
+}
+
+static int
+hash_find_list_cb(void *node, void *arg)
+{
+ struct hash_data *hd = arg;
+ int cbrc;
+ int rc = 0;
+
+ if (hd->hd_hash->h_cmp(hd->hd_key, node) == 0) {
+ if ((cbrc = hd->hd_fun(node, hd->hd_private)) < 0)
+ return (cbrc);
+ rc += cbrc;
+ }
+
+ return (rc);
+}
+
+int
+hash_find_iter(hash_t *hash, void *key, int (*fun)(void *, void *),
+ void *private)
+{
+ int bucket = hash->h_hashfn(hash->h_nbuckets, key);
+ struct hash_data hd;
+
+ hd.hd_hash = hash;
+ hd.hd_fun = fun;
+ hd.hd_key = key;
+ hd.hd_private = private;
+
+ return (list_iter(hash->h_buckets[bucket], hash_find_list_cb,
+ &hd));
+}
+
+/* stop on first match */
+static int
+hash_find_first_cb(void *node, void *arg)
+{
+ struct hash_data *hd = arg;
+ if (hd->hd_hash->h_cmp(hd->hd_key, node) == 0) {
+ hd->hd_ret = node;
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+hash_find(hash_t *hash, void *key, void **value)
+{
+ int ret;
+ struct hash_data hd;
+
+ hd.hd_hash = hash;
+ hd.hd_fun = hash_find_first_cb;
+ hd.hd_key = key;
+
+ ret = hash_match(hash, key, hash_find_first_cb, &hd);
+ if (ret && value)
+ *value = hd.hd_ret;
+
+ return (ret);
+}
+
+int
+hash_iter(hash_t *hash, int (*fun)(void *, void *), void *private)
+{
+ int cumrc = 0;
+ int cbrc;
+ int i;
+
+ for (i = 0; i < hash->h_nbuckets; i++) {
+ if (hash->h_buckets[i] != NULL) {
+ if ((cbrc = list_iter(hash->h_buckets[i], fun,
+ private)) < 0)
+ return (cbrc);
+ cumrc += cbrc;
+ }
+ }
+
+ return (cumrc);
+}
+
+int
+hash_count(hash_t *hash)
+{
+ int num, i;
+
+ for (num = 0, i = 0; i < hash->h_nbuckets; i++)
+ num += list_count(hash->h_buckets[i]);
+
+ return (num);
+}
+
+void
+hash_free(hash_t *hash, void (*datafree)(void *, void *), void *private)
+{
+ int i;
+
+ if (hash == NULL)
+ return;
+
+ for (i = 0; i < hash->h_nbuckets; i++)
+ list_free(hash->h_buckets[i], datafree, private);
+ free(hash->h_buckets);
+ free(hash);
+}
+
+void
+hash_stats(hash_t *hash, int verbose)
+{
+ int min = list_count(hash->h_buckets[0]);
+ int minidx = 0;
+ int max = min;
+ int maxidx = 0;
+ int tot = min;
+ int count;
+ int i;
+
+ if (min && verbose)
+ printf("%3d: %d\n", 0, min);
+ for (i = 1; i < hash->h_nbuckets; i++) {
+ count = list_count(hash->h_buckets[i]);
+ if (min > count) {
+ min = count;
+ minidx = i;
+ }
+ if (max < count) {
+ max = count;
+ maxidx = i;
+ }
+ if (count && verbose)
+ printf("%3d: %d\n", i, count);
+ tot += count;
+ }
+
+ printf("Hash statistics:\n");
+ printf(" Buckets: %d\n", hash->h_nbuckets);
+ printf(" Items : %d\n", tot);
+ printf(" Min/Max: %d in #%d, %d in #%d\n", min, minidx, max, maxidx);
+ printf(" Average: %5.2f\n", (float)tot / (float)hash->h_nbuckets);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/hash.h b/cddl/contrib/opensolaris/tools/ctf/cvt/hash.h
new file mode 100644
index 0000000..94d93d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/hash.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HASH_H
+#define _HASH_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating hash tables
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct hash hash_t;
+
+hash_t *hash_new(int, int (*)(int, void *), int (*)(void *, void *));
+void hash_add(hash_t *, void *);
+void hash_merge(hash_t *, hash_t *);
+void hash_remove(hash_t *, void *);
+int hash_find(hash_t *, void *, void **);
+int hash_find_iter(hash_t *, void *, int (*)(void *, void *), void *);
+int hash_iter(hash_t *, int (*)(void *, void *), void *);
+int hash_match(hash_t *, void *, int (*)(void *, void *), void *);
+int hash_count(hash_t *);
+int hash_name(int, const char *);
+void hash_stats(hash_t *, int);
+void hash_free(hash_t *, void (*)(void *, void *), void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HASH_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/iidesc.c b/cddl/contrib/opensolaris/tools/ctf/cvt/iidesc.c
new file mode 100644
index 0000000..fc1cefc
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/iidesc.c
@@ -0,0 +1,197 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating iidesc_t structures
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include "ctftools.h"
+#include "memory.h"
+#include "list.h"
+#include "hash.h"
+
+typedef struct iidesc_find {
+ iidesc_t *iif_tgt;
+ iidesc_t *iif_ret;
+} iidesc_find_t;
+
+iidesc_t *
+iidesc_new(char *name)
+{
+ iidesc_t *ii;
+
+ ii = xcalloc(sizeof (iidesc_t));
+ if (name)
+ ii->ii_name = xstrdup(name);
+
+ return (ii);
+}
+
+int
+iidesc_hash(int nbuckets, void *arg)
+{
+ iidesc_t *ii = arg;
+ int h = 0;
+
+ if (ii->ii_name)
+ return (hash_name(nbuckets, ii->ii_name));
+
+ return (h);
+}
+
+static int
+iidesc_cmp(void *arg1, void *arg2)
+{
+ iidesc_t *src = arg1;
+ iidesc_find_t *find = arg2;
+ iidesc_t *tgt = find->iif_tgt;
+
+ if (src->ii_type != tgt->ii_type ||
+ !streq(src->ii_name, tgt->ii_name))
+ return (0);
+
+ find->iif_ret = src;
+
+ return (-1);
+}
+
+void
+iidesc_add(hash_t *hash, iidesc_t *new)
+{
+ iidesc_find_t find;
+
+ find.iif_tgt = new;
+ find.iif_ret = NULL;
+
+ (void) hash_match(hash, new, iidesc_cmp, &find);
+
+ if (find.iif_ret != NULL) {
+ iidesc_t *old = find.iif_ret;
+ iidesc_t tmp;
+ /* replacing existing one */
+ bcopy(old, &tmp, sizeof (tmp));
+ bcopy(new, old, sizeof (*old));
+ bcopy(&tmp, new, sizeof (*new));
+
+ iidesc_free(new, NULL);
+ return;
+ }
+
+ hash_add(hash, new);
+}
+
+void
+iter_iidescs_by_name(tdata_t *td, char const *name,
+ int (*func)(void *, void *), void *data)
+{
+ iidesc_t tmpdesc;
+ bzero(&tmpdesc, sizeof(tmpdesc));
+ tmpdesc.ii_name = xstrdup(name);
+ (void) hash_match(td->td_iihash, &tmpdesc, func, data);
+ free(tmpdesc.ii_name);
+}
+
+iidesc_t *
+iidesc_dup(iidesc_t *src)
+{
+ iidesc_t *tgt;
+
+ tgt = xmalloc(sizeof (iidesc_t));
+ bcopy(src, tgt, sizeof (iidesc_t));
+
+ tgt->ii_name = src->ii_name ? xstrdup(src->ii_name) : NULL;
+ tgt->ii_owner = src->ii_owner ? xstrdup(src->ii_owner) : NULL;
+
+ if (tgt->ii_nargs) {
+ tgt->ii_args = xmalloc(sizeof (tdesc_t *) * tgt->ii_nargs);
+ bcopy(src->ii_args, tgt->ii_args,
+ sizeof (tdesc_t *) * tgt->ii_nargs);
+ }
+
+ return (tgt);
+}
+
+iidesc_t *
+iidesc_dup_rename(iidesc_t *src, char const *name, char const *owner)
+{
+ iidesc_t *tgt = iidesc_dup(src);
+ free(tgt->ii_name);
+ free(tgt->ii_owner);
+
+ tgt->ii_name = name ? xstrdup(name) : NULL;
+ tgt->ii_owner = owner ? xstrdup(owner) : NULL;
+
+ return (tgt);
+}
+
+/*ARGSUSED*/
+void
+iidesc_free(void *arg, void *private __unused)
+{
+ iidesc_t *idp = arg;
+ if (idp->ii_name)
+ free(idp->ii_name);
+ if (idp->ii_nargs)
+ free(idp->ii_args);
+ if (idp->ii_owner)
+ free(idp->ii_owner);
+ free(idp);
+}
+
+int
+iidesc_dump(iidesc_t *ii)
+{
+ printf("type: %d name %s\n", ii->ii_type,
+ (ii->ii_name ? ii->ii_name : "(anon)"));
+
+ return (0);
+}
+
+int
+iidesc_count_type(void *data, void *private)
+{
+ iidesc_t *ii = data;
+ iitype_t match = (iitype_t)private;
+
+ return (ii->ii_type == match);
+}
+
+void
+iidesc_stats(hash_t *ii)
+{
+ printf("GFun: %5d SFun: %5d GVar: %5d SVar: %5d T %5d SOU: %5d\n",
+ hash_iter(ii, iidesc_count_type, (void *)II_GFUN),
+ hash_iter(ii, iidesc_count_type, (void *)II_SFUN),
+ hash_iter(ii, iidesc_count_type, (void *)II_GVAR),
+ hash_iter(ii, iidesc_count_type, (void *)II_SVAR),
+ hash_iter(ii, iidesc_count_type, (void *)II_TYPE),
+ hash_iter(ii, iidesc_count_type, (void *)II_SOU));
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/input.c b/cddl/contrib/opensolaris/tools/ctf/cvt/input.c
new file mode 100644
index 0000000..67ebde7
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/input.c
@@ -0,0 +1,419 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for retrieving CTF data from a .SUNW_ctf ELF section
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <gelf.h>
+#include <strings.h>
+#include <sys/types.h>
+
+#include "ctftools.h"
+#include "memory.h"
+#include "symbol.h"
+
+typedef int read_cb_f(tdata_t *, char *, void *);
+
+/*
+ * Return the source types that the object was generated from.
+ */
+source_types_t
+built_source_types(Elf *elf, char const *file)
+{
+ source_types_t types = SOURCE_NONE;
+ symit_data_t *si;
+
+ if ((si = symit_new(elf, file)) == NULL)
+ return (SOURCE_NONE);
+
+ while (symit_next(si, STT_FILE) != NULL) {
+ char *name = symit_name(si);
+ size_t len = strlen(name);
+ if (len < 2 || name[len - 2] != '.') {
+ types |= SOURCE_UNKNOWN;
+ continue;
+ }
+
+ switch (name[len - 1]) {
+ case 'c':
+ types |= SOURCE_C;
+ break;
+ case 'h':
+ /* ignore */
+ break;
+ case 's':
+ case 'S':
+ types |= SOURCE_S;
+ break;
+ default:
+ types |= SOURCE_UNKNOWN;
+ }
+ }
+
+ symit_free(si);
+ return (types);
+}
+
+static int
+read_file(Elf *elf, char *file, char *label, read_cb_f *func, void *arg,
+ int require_ctf)
+{
+ Elf_Scn *ctfscn;
+ Elf_Data *ctfdata = NULL;
+ symit_data_t *si = NULL;
+ int ctfscnidx;
+ tdata_t *td;
+
+ if ((ctfscnidx = findelfsecidx(elf, file, ".SUNW_ctf")) < 0) {
+ if (require_ctf &&
+ (built_source_types(elf, file) & SOURCE_C)) {
+ terminate("Input file %s was partially built from "
+ "C sources, but no CTF data was present\n", file);
+ }
+ return (0);
+ }
+
+ if ((ctfscn = elf_getscn(elf, ctfscnidx)) == NULL ||
+ (ctfdata = elf_getdata(ctfscn, NULL)) == NULL)
+ elfterminate(file, "Cannot read CTF section");
+
+ /* Reconstruction of type tree */
+ if ((si = symit_new(elf, file)) == NULL) {
+ warning("%s has no symbol table - skipping", file);
+ return (0);
+ }
+
+ td = ctf_load(file, ctfdata->d_buf, ctfdata->d_size, si, label);
+ tdata_build_hashes(td);
+
+ symit_free(si);
+
+ if (td != NULL) {
+ if (func(td, file, arg) < 0)
+ return (-1);
+ else
+ return (1);
+ }
+ return (0);
+}
+
+static int
+read_archive(int fd, Elf *elf, char *file, char *label, read_cb_f *func,
+ void *arg, int require_ctf)
+{
+ Elf *melf;
+ Elf_Cmd cmd = ELF_C_READ;
+ Elf_Arhdr *arh;
+ int secnum = 1, found = 0;
+
+ while ((melf = elf_begin(fd, cmd, elf)) != NULL) {
+ int rc = 0;
+
+ if ((arh = elf_getarhdr(melf)) == NULL) {
+ elfterminate(file, "Can't get archive header for "
+ "member %d", secnum);
+ }
+
+ /* skip special sections - their names begin with "/" */
+ if (*arh->ar_name != '/') {
+ size_t memlen = strlen(file) + 1 +
+ strlen(arh->ar_name) + 1 + 1;
+ char *memname = xmalloc(memlen);
+
+ snprintf(memname, memlen, "%s(%s)", file, arh->ar_name);
+
+ switch (elf_kind(melf)) {
+ case ELF_K_AR:
+ rc = read_archive(fd, melf, memname, label,
+ func, arg, require_ctf);
+ break;
+ case ELF_K_ELF:
+ rc = read_file(melf, memname, label,
+ func, arg, require_ctf);
+ break;
+ default:
+ terminate("%s: Unknown elf kind %d\n",
+ memname, elf_kind(melf));
+ }
+
+ free(memname);
+ }
+
+ cmd = elf_next(melf);
+ (void) elf_end(melf);
+ secnum++;
+
+ if (rc < 0)
+ return (rc);
+ else
+ found += rc;
+ }
+
+ return (found);
+}
+
+static int
+read_ctf_common(char *file, char *label, read_cb_f *func, void *arg,
+ int require_ctf)
+{
+ Elf *elf;
+ int found = 0;
+ int fd;
+
+ debug(3, "Reading %s (label %s)\n", file, (label ? label : "NONE"));
+
+ (void) elf_version(EV_CURRENT);
+
+ if ((fd = open(file, O_RDONLY)) < 0)
+ terminate("%s: Cannot open for reading", file);
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
+ elfterminate(file, "Cannot read");
+
+ switch (elf_kind(elf)) {
+ case ELF_K_AR:
+ found = read_archive(fd, elf, file, label,
+ func, arg, require_ctf);
+ break;
+
+ case ELF_K_ELF:
+ found = read_file(elf, file, label,
+ func, arg, require_ctf);
+ break;
+
+ default:
+ terminate("%s: Unknown elf kind %d\n", file, elf_kind(elf));
+ }
+
+ (void) elf_end(elf);
+ (void) close(fd);
+
+ return (found);
+}
+
+/*ARGSUSED*/
+int
+read_ctf_save_cb(tdata_t *td, char *name __unused, void *retp)
+{
+ tdata_t **tdp = retp;
+
+ *tdp = td;
+
+ return (1);
+}
+
+int
+read_ctf(char **files, int n, char *label, read_cb_f *func, void *private,
+ int require_ctf)
+{
+ int found;
+ int i, rc;
+
+ for (i = 0, found = 0; i < n; i++) {
+ if ((rc = read_ctf_common(files[i], label, func,
+ private, require_ctf)) < 0)
+ return (rc);
+ found += rc;
+ }
+
+ return (found);
+}
+
+static int
+count_archive(int fd, Elf *elf, char *file)
+{
+ Elf *melf;
+ Elf_Cmd cmd = ELF_C_READ;
+ Elf_Arhdr *arh;
+ int nfiles = 0, err = 0;
+
+ while ((melf = elf_begin(fd, cmd, elf)) != NULL) {
+ if ((arh = elf_getarhdr(melf)) == NULL) {
+ warning("Can't process input archive %s\n",
+ file);
+ err++;
+ }
+
+ if (*arh->ar_name != '/')
+ nfiles++;
+
+ cmd = elf_next(melf);
+ (void) elf_end(melf);
+ }
+
+ if (err > 0)
+ return (-1);
+
+ return (nfiles);
+}
+
+int
+count_files(char **files, int n)
+{
+ int nfiles = 0, err = 0;
+ Elf *elf;
+ int fd, rc, i;
+
+ (void) elf_version(EV_CURRENT);
+
+ for (i = 0; i < n; i++) {
+ char *file = files[i];
+
+ if ((fd = open(file, O_RDONLY)) < 0) {
+ warning("Can't read input file %s", file);
+ err++;
+ continue;
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ warning("Can't open input file %s: %s\n", file,
+ elf_errmsg(-1));
+ err++;
+ (void) close(fd);
+ continue;
+ }
+
+ switch (elf_kind(elf)) {
+ case ELF_K_AR:
+ if ((rc = count_archive(fd, elf, file)) < 0)
+ err++;
+ else
+ nfiles += rc;
+ break;
+ case ELF_K_ELF:
+ nfiles++;
+ break;
+ default:
+ warning("Input file %s is corrupt\n", file);
+ err++;
+ }
+
+ (void) elf_end(elf);
+ (void) close(fd);
+ }
+
+ if (err > 0)
+ return (-1);
+
+ debug(2, "Found %d files in %d input files\n", nfiles, n);
+
+ return (nfiles);
+}
+
+struct symit_data {
+ GElf_Shdr si_shdr;
+ Elf_Data *si_symd;
+ Elf_Data *si_strd;
+ GElf_Sym si_cursym;
+ char *si_curname;
+ char *si_curfile;
+ int si_nument;
+ int si_next;
+};
+
+symit_data_t *
+symit_new(Elf *elf, const char *file)
+{
+ symit_data_t *si;
+ Elf_Scn *scn;
+ int symtabidx;
+
+ if ((symtabidx = findelfsecidx(elf, file, ".symtab")) < 0)
+ return (NULL);
+
+ si = xcalloc(sizeof (symit_data_t));
+
+ if ((scn = elf_getscn(elf, symtabidx)) == NULL ||
+ gelf_getshdr(scn, &si->si_shdr) == NULL ||
+ (si->si_symd = elf_getdata(scn, NULL)) == NULL)
+ elfterminate(file, "Cannot read .symtab");
+
+ if ((scn = elf_getscn(elf, si->si_shdr.sh_link)) == NULL ||
+ (si->si_strd = elf_getdata(scn, NULL)) == NULL)
+ elfterminate(file, "Cannot read strings for .symtab");
+
+ si->si_nument = si->si_shdr.sh_size / si->si_shdr.sh_entsize;
+
+ return (si);
+}
+
+void
+symit_free(symit_data_t *si)
+{
+ free(si);
+}
+
+void
+symit_reset(symit_data_t *si)
+{
+ si->si_next = 0;
+}
+
+char *
+symit_curfile(symit_data_t *si)
+{
+ return (si->si_curfile);
+}
+
+GElf_Sym *
+symit_next(symit_data_t *si, int type)
+{
+ GElf_Sym sym;
+ int check_sym = (type == STT_OBJECT || type == STT_FUNC);
+
+ for (; si->si_next < si->si_nument; si->si_next++) {
+ gelf_getsym(si->si_symd, si->si_next, &si->si_cursym);
+ gelf_getsym(si->si_symd, si->si_next, &sym);
+ si->si_curname = (caddr_t)si->si_strd->d_buf + sym.st_name;
+
+ if (GELF_ST_TYPE(sym.st_info) == STT_FILE)
+ si->si_curfile = si->si_curname;
+
+ if (GELF_ST_TYPE(sym.st_info) != type ||
+ sym.st_shndx == SHN_UNDEF)
+ continue;
+
+ if (check_sym && ignore_symbol(&sym, si->si_curname))
+ continue;
+
+ si->si_next++;
+
+ return (&si->si_cursym);
+ }
+
+ return (NULL);
+}
+
+char *
+symit_name(symit_data_t *si)
+{
+ return (si->si_curname);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c
new file mode 100644
index 0000000..2ef37d4
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c
@@ -0,0 +1,1143 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file contains routines that merge one tdata_t tree, called the child,
+ * into another, called the parent. Note that these names are used mainly for
+ * convenience and to represent the direction of the merge. They are not meant
+ * to imply any relationship between the tdata_t graphs prior to the merge.
+ *
+ * tdata_t structures contain two main elements - a hash of iidesc_t nodes, and
+ * a directed graph of tdesc_t nodes, pointed to by the iidesc_t nodes. Simply
+ * put, we merge the tdesc_t graphs, followed by the iidesc_t nodes, and then we
+ * clean up loose ends.
+ *
+ * The algorithm is as follows:
+ *
+ * 1. Mapping iidesc_t nodes
+ *
+ * For each child iidesc_t node, we first try to map its tdesc_t subgraph
+ * against the tdesc_t graph in the parent. For each node in the child subgraph
+ * that exists in the parent, a mapping between the two (between their type IDs)
+ * is established. For the child nodes that cannot be mapped onto existing
+ * parent nodes, a mapping is established between the child node ID and a
+ * newly-allocated ID that the node will use when it is re-created in the
+ * parent. These unmappable nodes are added to the md_tdtba (tdesc_t To Be
+ * Added) hash, which tracks nodes that need to be created in the parent.
+ *
+ * If all of the nodes in the subgraph for an iidesc_t in the child can be
+ * mapped to existing nodes in the parent, then we can try to map the child
+ * iidesc_t onto an iidesc_t in the parent. If we cannot find an equivalent
+ * iidesc_t, or if we were not able to completely map the tdesc_t subgraph(s),
+ * then we add this iidesc_t to the md_iitba (iidesc_t To Be Added) list. This
+ * list tracks iidesc_t nodes that are to be created in the parent.
+ *
+ * While visiting the tdesc_t nodes, we may discover a forward declaration (a
+ * FORWARD tdesc_t) in the parent that is resolved in the child. That is, there
+ * may be a structure or union definition in the child with the same name as the
+ * forward declaration in the parent. If we find such a node, we record an
+ * association in the md_fdida (Forward => Definition ID Association) list
+ * between the parent ID of the forward declaration and the ID that the
+ * definition will use when re-created in the parent.
+ *
+ * 2. Creating new tdesc_t nodes (the md_tdtba hash)
+ *
+ * We have now attempted to map all tdesc_t nodes from the child into the
+ * parent, and have, in md_tdtba, a hash of all tdesc_t nodes that need to be
+ * created (or, as we so wittily call it, conjured) in the parent. We iterate
+ * through this hash, creating the indicated tdesc_t nodes. For a given tdesc_t
+ * node, conjuring requires two steps - the copying of the common tdesc_t data
+ * (name, type, etc) from the child node, and the creation of links from the
+ * newly-created node to the parent equivalents of other tdesc_t nodes pointed
+ * to by node being conjured. Note that in some cases, the targets of these
+ * links will be on the md_tdtba hash themselves, and may not have been created
+ * yet. As such, we can't establish the links from these new nodes into the
+ * parent graph. We therefore conjure them with links to nodes in the *child*
+ * graph, and add pointers to the links to be created to the md_tdtbr (tdesc_t
+ * To Be Remapped) hash. For example, a POINTER tdesc_t that could not be
+ * resolved would have its &tdesc_t->t_tdesc added to md_tdtbr.
+ *
+ * 3. Creating new iidesc_t nodes (the md_iitba list)
+ *
+ * When we have completed step 2, all tdesc_t nodes have been created (or
+ * already existed) in the parent. Some of them may have incorrect links (the
+ * members of the md_tdtbr list), but they've all been created. As such, we can
+ * create all of the iidesc_t nodes, as we can attach the tdesc_t subgraph
+ * pointers correctly. We create each node, and attach the pointers to the
+ * appropriate parts of the parent tdesc_t graph.
+ *
+ * 4. Resolving newly-created tdesc_t node links (the md_tdtbr list)
+ *
+ * As in step 3, we rely on the fact that all of the tdesc_t nodes have been
+ * created. Each entry in the md_tdtbr list is a pointer to where a link into
+ * the parent will be established. As saved in the md_tdtbr list, these
+ * pointers point into the child tdesc_t subgraph. We can thus get the target
+ * type ID from the child, look at the ID mapping to determine the desired link
+ * target, and redirect the link accordingly.
+ *
+ * 5. Parent => child forward declaration resolution
+ *
+ * If entries were made in the md_fdida list in step 1, we have forward
+ * declarations in the parent that need to be resolved to their definitions
+ * re-created in step 2 from the child. Using the md_fdida list, we can locate
+ * the definition for the forward declaration, and we can redirect all inbound
+ * edges to the forward declaration node to the actual definition.
+ *
+ * A pox on the house of anyone who changes the algorithm without updating
+ * this comment.
+ */
+
+#include <stdio.h>
+#include <strings.h>
+#include <assert.h>
+#include <pthread.h>
+
+#include "ctf_headers.h"
+#include "ctftools.h"
+#include "list.h"
+#include "alist.h"
+#include "memory.h"
+#include "traverse.h"
+
+typedef struct equiv_data equiv_data_t;
+typedef struct merge_cb_data merge_cb_data_t;
+
+/*
+ * There are two traversals in this file, for equivalency and for tdesc_t
+ * re-creation, that do not fit into the tdtraverse() framework. We have our
+ * own traversal mechanism and ops vector here for those two cases.
+ */
+typedef struct tdesc_ops {
+ const char *name;
+ int (*equiv)(tdesc_t *, tdesc_t *, equiv_data_t *);
+ tdesc_t *(*conjure)(tdesc_t *, int, merge_cb_data_t *);
+} tdesc_ops_t;
+extern tdesc_ops_t tdesc_ops[];
+
+/*
+ * The workhorse structure of tdata_t merging. Holds all lists of nodes to be
+ * processed during various phases of the merge algorithm.
+ */
+struct merge_cb_data {
+ tdata_t *md_parent;
+ tdata_t *md_tgt;
+ alist_t *md_ta; /* Type Association */
+ alist_t *md_fdida; /* Forward -> Definition ID Association */
+ list_t **md_iitba; /* iidesc_t nodes To Be Added to the parent */
+ hash_t *md_tdtba; /* tdesc_t nodes To Be Added to the parent */
+ list_t **md_tdtbr; /* tdesc_t nodes To Be Remapped */
+ int md_flags;
+}; /* merge_cb_data_t */
+
+/*
+ * When we first create a tdata_t from stabs data, we will have duplicate nodes.
+ * Normal merges, however, assume that the child tdata_t is already self-unique,
+ * and for speed reasons do not attempt to self-uniquify. If this flag is set,
+ * the merge algorithm will self-uniquify by avoiding the insertion of
+ * duplicates in the md_tdtdba list.
+ */
+#define MCD_F_SELFUNIQUIFY 0x1
+
+/*
+ * When we merge the CTF data for the modules, we don't want it to contain any
+ * data that can be found in the reference module (usually genunix). If this
+ * flag is set, we're doing a merge between the fully merged tdata_t for this
+ * module and the tdata_t for the reference module, with the data unique to this
+ * module ending up in a third tdata_t. It is this third tdata_t that will end
+ * up in the .SUNW_ctf section for the module.
+ */
+#define MCD_F_REFMERGE 0x2
+
+/*
+ * Mapping of child type IDs to parent type IDs
+ */
+
+static void
+add_mapping(alist_t *ta, tid_t srcid, tid_t tgtid)
+{
+ debug(3, "Adding mapping %u <%x> => %u <%x>\n", srcid, srcid, tgtid, tgtid);
+
+ assert(!alist_find(ta, (void *)(uintptr_t)srcid, NULL));
+ assert(srcid != 0 && tgtid != 0);
+
+ alist_add(ta, (void *)(uintptr_t)srcid, (void *)(uintptr_t)tgtid);
+}
+
+static tid_t
+get_mapping(alist_t *ta, int srcid)
+{
+ void *ltgtid;
+
+ if (alist_find(ta, (void *)(uintptr_t)srcid, (void **)&ltgtid))
+ return ((uintptr_t)ltgtid);
+ else
+ return (0);
+}
+
+/*
+ * Determining equivalence of tdesc_t subgraphs
+ */
+
+struct equiv_data {
+ alist_t *ed_ta;
+ tdesc_t *ed_node;
+ tdesc_t *ed_tgt;
+
+ int ed_clear_mark;
+ int ed_cur_mark;
+ int ed_selfuniquify;
+}; /* equiv_data_t */
+
+static int equiv_node(tdesc_t *, tdesc_t *, equiv_data_t *);
+
+/*ARGSUSED2*/
+static int
+equiv_intrinsic(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed __unused)
+{
+ intr_t *si = stdp->t_intr;
+ intr_t *ti = ttdp->t_intr;
+
+ if (si->intr_type != ti->intr_type ||
+ si->intr_signed != ti->intr_signed ||
+ si->intr_offset != ti->intr_offset ||
+ si->intr_nbits != ti->intr_nbits)
+ return (0);
+
+ if (si->intr_type == INTR_INT &&
+ si->intr_iformat != ti->intr_iformat)
+ return (0);
+ else if (si->intr_type == INTR_REAL &&
+ si->intr_fformat != ti->intr_fformat)
+ return (0);
+
+ return (1);
+}
+
+static int
+equiv_plain(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed)
+{
+ return (equiv_node(stdp->t_tdesc, ttdp->t_tdesc, ed));
+}
+
+static int
+equiv_function(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed)
+{
+ fndef_t *fn1 = stdp->t_fndef, *fn2 = ttdp->t_fndef;
+ int i;
+
+ if (fn1->fn_nargs != fn2->fn_nargs ||
+ fn1->fn_vargs != fn2->fn_vargs)
+ return (0);
+
+ if (!equiv_node(fn1->fn_ret, fn2->fn_ret, ed))
+ return (0);
+
+ for (i = 0; i < (int) fn1->fn_nargs; i++) {
+ if (!equiv_node(fn1->fn_args[i], fn2->fn_args[i], ed))
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+equiv_array(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed)
+{
+ ardef_t *ar1 = stdp->t_ardef, *ar2 = ttdp->t_ardef;
+
+ if (!equiv_node(ar1->ad_contents, ar2->ad_contents, ed) ||
+ !equiv_node(ar1->ad_idxtype, ar2->ad_idxtype, ed))
+ return (0);
+
+ if (ar1->ad_nelems != ar2->ad_nelems)
+ return (0);
+
+ return (1);
+}
+
+static int
+equiv_su(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed)
+{
+ mlist_t *ml1 = stdp->t_members, *ml2 = ttdp->t_members;
+ mlist_t *olm1 = NULL;
+
+ while (ml1 && ml2) {
+ if (ml1->ml_offset != ml2->ml_offset ||
+ strcmp(ml1->ml_name, ml2->ml_name) != 0)
+ return (0);
+
+ /*
+ * Don't do the recursive equivalency checking more than
+ * we have to.
+ */
+ if (olm1 == NULL || olm1->ml_type->t_id != ml1->ml_type->t_id) {
+ if (ml1->ml_size != ml2->ml_size ||
+ !equiv_node(ml1->ml_type, ml2->ml_type, ed))
+ return (0);
+ }
+
+ olm1 = ml1;
+ ml1 = ml1->ml_next;
+ ml2 = ml2->ml_next;
+ }
+
+ if (ml1 || ml2)
+ return (0);
+
+ return (1);
+}
+
+/*ARGSUSED2*/
+static int
+equiv_enum(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed __unused)
+{
+ elist_t *el1 = stdp->t_emem;
+ elist_t *el2 = ttdp->t_emem;
+
+ while (el1 && el2) {
+ if (el1->el_number != el2->el_number ||
+ strcmp(el1->el_name, el2->el_name) != 0)
+ return (0);
+
+ el1 = el1->el_next;
+ el2 = el2->el_next;
+ }
+
+ if (el1 || el2)
+ return (0);
+
+ return (1);
+}
+
+/*ARGSUSED*/
+static int
+equiv_assert(tdesc_t *stdp __unused, tdesc_t *ttdp __unused, equiv_data_t *ed __unused)
+{
+ /* foul, evil, and very bad - this is a "shouldn't happen" */
+ assert(1 == 0);
+
+ return (0);
+}
+
+static int
+fwd_equiv(tdesc_t *ctdp, tdesc_t *mtdp)
+{
+ tdesc_t *defn = (ctdp->t_type == FORWARD ? mtdp : ctdp);
+
+ return (defn->t_type == STRUCT || defn->t_type == UNION);
+}
+
+static int
+equiv_node(tdesc_t *ctdp, tdesc_t *mtdp, equiv_data_t *ed)
+{
+ int (*equiv)(tdesc_t *, tdesc_t *, equiv_data_t *);
+ int mapping;
+
+ if (ctdp->t_emark > ed->ed_clear_mark ||
+ mtdp->t_emark > ed->ed_clear_mark)
+ return (ctdp->t_emark == mtdp->t_emark);
+
+ /*
+ * In normal (non-self-uniquify) mode, we don't want to do equivalency
+ * checking on a subgraph that has already been checked. If a mapping
+ * has already been established for a given child node, we can simply
+ * compare the mapping for the child node with the ID of the parent
+ * node. If we are in self-uniquify mode, then we're comparing two
+ * subgraphs within the child graph, and thus need to ignore any
+ * type mappings that have been created, as they are only valid into the
+ * parent.
+ */
+ if ((mapping = get_mapping(ed->ed_ta, ctdp->t_id)) > 0 &&
+ mapping == mtdp->t_id && !ed->ed_selfuniquify)
+ return (1);
+
+ if (!streq(ctdp->t_name, mtdp->t_name))
+ return (0);
+
+ if (ctdp->t_type != mtdp->t_type) {
+ if (ctdp->t_type == FORWARD || mtdp->t_type == FORWARD)
+ return (fwd_equiv(ctdp, mtdp));
+ else
+ return (0);
+ }
+
+ ctdp->t_emark = ed->ed_cur_mark;
+ mtdp->t_emark = ed->ed_cur_mark;
+ ed->ed_cur_mark++;
+
+ if ((equiv = tdesc_ops[ctdp->t_type].equiv) != NULL)
+ return (equiv(ctdp, mtdp, ed));
+
+ return (1);
+}
+
+/*
+ * We perform an equivalency check on two subgraphs by traversing through them
+ * in lockstep. If a given node is equivalent in both the parent and the child,
+ * we mark it in both subgraphs, using the t_emark field, with a monotonically
+ * increasing number. If, in the course of the traversal, we reach a node that
+ * we have visited and numbered during this equivalency check, we have a cycle.
+ * If the previously-visited nodes don't have the same emark, then the edges
+ * that brought us to these nodes are not equivalent, and so the check ends.
+ * If the emarks are the same, the edges are equivalent. We then backtrack and
+ * continue the traversal. If we have exhausted all edges in the subgraph, and
+ * have not found any inequivalent nodes, then the subgraphs are equivalent.
+ */
+static int
+equiv_cb(void *bucket, void *arg)
+{
+ equiv_data_t *ed = arg;
+ tdesc_t *mtdp = bucket;
+ tdesc_t *ctdp = ed->ed_node;
+
+ ed->ed_clear_mark = ed->ed_cur_mark + 1;
+ ed->ed_cur_mark = ed->ed_clear_mark + 1;
+
+ if (equiv_node(ctdp, mtdp, ed)) {
+ debug(3, "equiv_node matched %d <%x> %d <%x>\n",
+ ctdp->t_id, ctdp->t_id, mtdp->t_id, mtdp->t_id);
+ ed->ed_tgt = mtdp;
+ /* matched. stop looking */
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*ARGSUSED1*/
+static int
+map_td_tree_pre(tdesc_t *ctdp, tdesc_t **ctdpp __unused, void *private)
+{
+ merge_cb_data_t *mcd = private;
+
+ if (get_mapping(mcd->md_ta, ctdp->t_id) > 0)
+ return (0);
+
+ return (1);
+}
+
+/*ARGSUSED1*/
+static int
+map_td_tree_post(tdesc_t *ctdp, tdesc_t **ctdpp __unused, void *private)
+{
+ merge_cb_data_t *mcd = private;
+ equiv_data_t ed;
+
+ ed.ed_ta = mcd->md_ta;
+ ed.ed_clear_mark = mcd->md_parent->td_curemark;
+ ed.ed_cur_mark = mcd->md_parent->td_curemark + 1;
+ ed.ed_node = ctdp;
+ ed.ed_selfuniquify = 0;
+
+ debug(3, "map_td_tree_post on %d <%x> %s\n", ctdp->t_id, ctdp->t_id,tdesc_name(ctdp));
+
+ if (hash_find_iter(mcd->md_parent->td_layouthash, ctdp,
+ equiv_cb, &ed) < 0) {
+ /* We found an equivalent node */
+ if (ed.ed_tgt->t_type == FORWARD && ctdp->t_type != FORWARD) {
+ int id = mcd->md_tgt->td_nextid++;
+
+ debug(3, "Creating new defn type %d <%x>\n", id, id);
+ add_mapping(mcd->md_ta, ctdp->t_id, id);
+ alist_add(mcd->md_fdida, (void *)(ulong_t)ed.ed_tgt,
+ (void *)(ulong_t)id);
+ hash_add(mcd->md_tdtba, ctdp);
+ } else
+ add_mapping(mcd->md_ta, ctdp->t_id, ed.ed_tgt->t_id);
+
+ } else if (debug_level > 1 && hash_iter(mcd->md_parent->td_idhash,
+ equiv_cb, &ed) < 0) {
+ /*
+ * We didn't find an equivalent node by looking through the
+ * layout hash, but we somehow found it by performing an
+ * exhaustive search through the entire graph. This usually
+ * means that the "name" hash function is broken.
+ */
+ aborterr("Second pass for %d (%s) == %d\n", ctdp->t_id,
+ tdesc_name(ctdp), ed.ed_tgt->t_id);
+ } else {
+ int id = mcd->md_tgt->td_nextid++;
+
+ debug(3, "Creating new type %d <%x>\n", id, id);
+ add_mapping(mcd->md_ta, ctdp->t_id, id);
+ hash_add(mcd->md_tdtba, ctdp);
+ }
+
+ mcd->md_parent->td_curemark = ed.ed_cur_mark + 1;
+
+ return (1);
+}
+
+/*ARGSUSED1*/
+static int
+map_td_tree_self_post(tdesc_t *ctdp, tdesc_t **ctdpp __unused, void *private)
+{
+ merge_cb_data_t *mcd = private;
+ equiv_data_t ed;
+
+ ed.ed_ta = mcd->md_ta;
+ ed.ed_clear_mark = mcd->md_parent->td_curemark;
+ ed.ed_cur_mark = mcd->md_parent->td_curemark + 1;
+ ed.ed_node = ctdp;
+ ed.ed_selfuniquify = 1;
+ ed.ed_tgt = NULL;
+
+ if (hash_find_iter(mcd->md_tdtba, ctdp, equiv_cb, &ed) < 0) {
+ debug(3, "Self check found %d <%x> in %d <%x>\n", ctdp->t_id,
+ ctdp->t_id, ed.ed_tgt->t_id, ed.ed_tgt->t_id);
+ add_mapping(mcd->md_ta, ctdp->t_id,
+ get_mapping(mcd->md_ta, ed.ed_tgt->t_id));
+ } else if (debug_level > 1 && hash_iter(mcd->md_tdtba,
+ equiv_cb, &ed) < 0) {
+ /*
+ * We didn't find an equivalent node using the quick way (going
+ * through the hash normally), but we did find it by iterating
+ * through the entire hash. This usually means that the hash
+ * function is broken.
+ */
+ aborterr("Self-unique second pass for %d <%x> (%s) == %d <%x>\n",
+ ctdp->t_id, ctdp->t_id, tdesc_name(ctdp), ed.ed_tgt->t_id,
+ ed.ed_tgt->t_id);
+ } else {
+ int id = mcd->md_tgt->td_nextid++;
+
+ debug(3, "Creating new type %d <%x>\n", id, id);
+ add_mapping(mcd->md_ta, ctdp->t_id, id);
+ hash_add(mcd->md_tdtba, ctdp);
+ }
+
+ mcd->md_parent->td_curemark = ed.ed_cur_mark + 1;
+
+ return (1);
+}
+
+static tdtrav_cb_f map_pre[] = {
+ NULL,
+ map_td_tree_pre, /* intrinsic */
+ map_td_tree_pre, /* pointer */
+ map_td_tree_pre, /* array */
+ map_td_tree_pre, /* function */
+ map_td_tree_pre, /* struct */
+ map_td_tree_pre, /* union */
+ map_td_tree_pre, /* enum */
+ map_td_tree_pre, /* forward */
+ map_td_tree_pre, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ map_td_tree_pre, /* volatile */
+ map_td_tree_pre, /* const */
+ map_td_tree_pre /* restrict */
+};
+
+static tdtrav_cb_f map_post[] = {
+ NULL,
+ map_td_tree_post, /* intrinsic */
+ map_td_tree_post, /* pointer */
+ map_td_tree_post, /* array */
+ map_td_tree_post, /* function */
+ map_td_tree_post, /* struct */
+ map_td_tree_post, /* union */
+ map_td_tree_post, /* enum */
+ map_td_tree_post, /* forward */
+ map_td_tree_post, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ map_td_tree_post, /* volatile */
+ map_td_tree_post, /* const */
+ map_td_tree_post /* restrict */
+};
+
+static tdtrav_cb_f map_self_post[] = {
+ NULL,
+ map_td_tree_self_post, /* intrinsic */
+ map_td_tree_self_post, /* pointer */
+ map_td_tree_self_post, /* array */
+ map_td_tree_self_post, /* function */
+ map_td_tree_self_post, /* struct */
+ map_td_tree_self_post, /* union */
+ map_td_tree_self_post, /* enum */
+ map_td_tree_self_post, /* forward */
+ map_td_tree_self_post, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ map_td_tree_self_post, /* volatile */
+ map_td_tree_self_post, /* const */
+ map_td_tree_self_post /* restrict */
+};
+
+/*
+ * Determining equivalence of iidesc_t nodes
+ */
+
+typedef struct iifind_data {
+ iidesc_t *iif_template;
+ alist_t *iif_ta;
+ int iif_newidx;
+ int iif_refmerge;
+} iifind_data_t;
+
+/*
+ * Check to see if this iidesc_t (node) - the current one on the list we're
+ * iterating through - matches the target one (iif->iif_template). Return -1
+ * if it matches, to stop the iteration.
+ */
+static int
+iidesc_match(void *data, void *arg)
+{
+ iidesc_t *node = data;
+ iifind_data_t *iif = arg;
+ int i;
+
+ if (node->ii_type != iif->iif_template->ii_type ||
+ !streq(node->ii_name, iif->iif_template->ii_name) ||
+ node->ii_dtype->t_id != iif->iif_newidx)
+ return (0);
+
+ if ((node->ii_type == II_SVAR || node->ii_type == II_SFUN) &&
+ !streq(node->ii_owner, iif->iif_template->ii_owner))
+ return (0);
+
+ if (node->ii_nargs != iif->iif_template->ii_nargs)
+ return (0);
+
+ for (i = 0; i < node->ii_nargs; i++) {
+ if (get_mapping(iif->iif_ta,
+ iif->iif_template->ii_args[i]->t_id) !=
+ node->ii_args[i]->t_id)
+ return (0);
+ }
+
+ if (iif->iif_refmerge) {
+ switch (iif->iif_template->ii_type) {
+ case II_GFUN:
+ case II_SFUN:
+ case II_GVAR:
+ case II_SVAR:
+ debug(3, "suppressing duping of %d %s from %s\n",
+ iif->iif_template->ii_type,
+ iif->iif_template->ii_name,
+ (iif->iif_template->ii_owner ?
+ iif->iif_template->ii_owner : "NULL"));
+ return (0);
+ case II_NOT:
+ case II_PSYM:
+ case II_SOU:
+ case II_TYPE:
+ break;
+ }
+ }
+
+ return (-1);
+}
+
+static int
+merge_type_cb(void *data, void *arg)
+{
+ iidesc_t *sii = data;
+ merge_cb_data_t *mcd = arg;
+ iifind_data_t iif;
+ tdtrav_cb_f *post;
+
+ post = (mcd->md_flags & MCD_F_SELFUNIQUIFY ? map_self_post : map_post);
+
+ /* Map the tdesc nodes */
+ (void) iitraverse(sii, &mcd->md_parent->td_curvgen, NULL, map_pre, post,
+ mcd);
+
+ /* Map the iidesc nodes */
+ iif.iif_template = sii;
+ iif.iif_ta = mcd->md_ta;
+ iif.iif_newidx = get_mapping(mcd->md_ta, sii->ii_dtype->t_id);
+ iif.iif_refmerge = (mcd->md_flags & MCD_F_REFMERGE);
+
+ if (hash_match(mcd->md_parent->td_iihash, sii, iidesc_match,
+ &iif) == 1)
+ /* successfully mapped */
+ return (1);
+
+ debug(3, "tba %s (%d)\n", (sii->ii_name ? sii->ii_name : "(anon)"),
+ sii->ii_type);
+
+ list_add(mcd->md_iitba, sii);
+
+ return (0);
+}
+
+static int
+remap_node(tdesc_t **tgtp, tdesc_t *oldtgt, int selftid, tdesc_t *newself,
+ merge_cb_data_t *mcd)
+{
+ tdesc_t *tgt = NULL;
+ tdesc_t template;
+ int oldid = oldtgt->t_id;
+
+ if (oldid == selftid) {
+ *tgtp = newself;
+ return (1);
+ }
+
+ if ((template.t_id = get_mapping(mcd->md_ta, oldid)) == 0)
+ aborterr("failed to get mapping for tid %d <%x>\n", oldid, oldid);
+
+ if (!hash_find(mcd->md_parent->td_idhash, (void *)&template,
+ (void *)&tgt) && (!(mcd->md_flags & MCD_F_REFMERGE) ||
+ !hash_find(mcd->md_tgt->td_idhash, (void *)&template,
+ (void *)&tgt))) {
+ debug(3, "Remap couldn't find %d <%x> (from %d <%x>)\n", template.t_id,
+ template.t_id, oldid, oldid);
+ *tgtp = oldtgt;
+ list_add(mcd->md_tdtbr, tgtp);
+ return (0);
+ }
+
+ *tgtp = tgt;
+ return (1);
+}
+
+static tdesc_t *
+conjure_template(tdesc_t *old, int newselfid)
+{
+ tdesc_t *new = xcalloc(sizeof (tdesc_t));
+
+ new->t_name = old->t_name ? xstrdup(old->t_name) : NULL;
+ new->t_type = old->t_type;
+ new->t_size = old->t_size;
+ new->t_id = newselfid;
+ new->t_flags = old->t_flags;
+
+ return (new);
+}
+
+/*ARGSUSED2*/
+static tdesc_t *
+conjure_intrinsic(tdesc_t *old, int newselfid, merge_cb_data_t *mcd __unused)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+
+ new->t_intr = xmalloc(sizeof (intr_t));
+ bcopy(old->t_intr, new->t_intr, sizeof (intr_t));
+
+ return (new);
+}
+
+static tdesc_t *
+conjure_plain(tdesc_t *old, int newselfid, merge_cb_data_t *mcd)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+
+ (void) remap_node(&new->t_tdesc, old->t_tdesc, old->t_id, new, mcd);
+
+ return (new);
+}
+
+static tdesc_t *
+conjure_function(tdesc_t *old, int newselfid, merge_cb_data_t *mcd)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+ fndef_t *nfn = xmalloc(sizeof (fndef_t));
+ fndef_t *ofn = old->t_fndef;
+ int i;
+
+ (void) remap_node(&nfn->fn_ret, ofn->fn_ret, old->t_id, new, mcd);
+
+ nfn->fn_nargs = ofn->fn_nargs;
+ nfn->fn_vargs = ofn->fn_vargs;
+
+ if (nfn->fn_nargs > 0)
+ nfn->fn_args = xcalloc(sizeof (tdesc_t *) * ofn->fn_nargs);
+
+ for (i = 0; i < (int) ofn->fn_nargs; i++) {
+ (void) remap_node(&nfn->fn_args[i], ofn->fn_args[i], old->t_id,
+ new, mcd);
+ }
+
+ new->t_fndef = nfn;
+
+ return (new);
+}
+
+static tdesc_t *
+conjure_array(tdesc_t *old, int newselfid, merge_cb_data_t *mcd)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+ ardef_t *nar = xmalloc(sizeof (ardef_t));
+ ardef_t *oar = old->t_ardef;
+
+ (void) remap_node(&nar->ad_contents, oar->ad_contents, old->t_id, new,
+ mcd);
+ (void) remap_node(&nar->ad_idxtype, oar->ad_idxtype, old->t_id, new,
+ mcd);
+
+ nar->ad_nelems = oar->ad_nelems;
+
+ new->t_ardef = nar;
+
+ return (new);
+}
+
+static tdesc_t *
+conjure_su(tdesc_t *old, int newselfid, merge_cb_data_t *mcd)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+ mlist_t *omem, **nmemp;
+
+ for (omem = old->t_members, nmemp = &new->t_members;
+ omem; omem = omem->ml_next, nmemp = &((*nmemp)->ml_next)) {
+ *nmemp = xmalloc(sizeof (mlist_t));
+ (*nmemp)->ml_offset = omem->ml_offset;
+ (*nmemp)->ml_size = omem->ml_size;
+ (*nmemp)->ml_name = xstrdup(omem->ml_name ? omem->ml_name : "empty omem->ml_name");
+ (void) remap_node(&((*nmemp)->ml_type), omem->ml_type,
+ old->t_id, new, mcd);
+ }
+ *nmemp = NULL;
+
+ return (new);
+}
+
+/*ARGSUSED2*/
+static tdesc_t *
+conjure_enum(tdesc_t *old, int newselfid, merge_cb_data_t *mcd __unused)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+ elist_t *oel, **nelp;
+
+ for (oel = old->t_emem, nelp = &new->t_emem;
+ oel; oel = oel->el_next, nelp = &((*nelp)->el_next)) {
+ *nelp = xmalloc(sizeof (elist_t));
+ (*nelp)->el_name = xstrdup(oel->el_name);
+ (*nelp)->el_number = oel->el_number;
+ }
+ *nelp = NULL;
+
+ return (new);
+}
+
+/*ARGSUSED2*/
+static tdesc_t *
+conjure_forward(tdesc_t *old, int newselfid, merge_cb_data_t *mcd)
+{
+ tdesc_t *new = conjure_template(old, newselfid);
+
+ list_add(&mcd->md_tgt->td_fwdlist, new);
+
+ return (new);
+}
+
+/*ARGSUSED*/
+static tdesc_t *
+conjure_assert(tdesc_t *old __unused, int newselfid __unused, merge_cb_data_t *mcd __unused)
+{
+ assert(1 == 0);
+ return (NULL);
+}
+
+static iidesc_t *
+conjure_iidesc(iidesc_t *old, merge_cb_data_t *mcd)
+{
+ iidesc_t *new = iidesc_dup(old);
+ int i;
+
+ (void) remap_node(&new->ii_dtype, old->ii_dtype, -1, NULL, mcd);
+ for (i = 0; i < new->ii_nargs; i++) {
+ (void) remap_node(&new->ii_args[i], old->ii_args[i], -1, NULL,
+ mcd);
+ }
+
+ return (new);
+}
+
+static int
+fwd_redir(tdesc_t *fwd, tdesc_t **fwdp, void *private)
+{
+ alist_t *map = private;
+ void *defn;
+
+ if (!alist_find(map, (void *)fwd, (void **)&defn))
+ return (0);
+
+ debug(3, "Redirecting an edge to %s\n", tdesc_name(defn));
+
+ *fwdp = defn;
+
+ return (1);
+}
+
+static tdtrav_cb_f fwd_redir_cbs[] = {
+ NULL,
+ NULL, /* intrinsic */
+ NULL, /* pointer */
+ NULL, /* array */
+ NULL, /* function */
+ NULL, /* struct */
+ NULL, /* union */
+ NULL, /* enum */
+ fwd_redir, /* forward */
+ NULL, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ NULL, /* volatile */
+ NULL, /* const */
+ NULL /* restrict */
+};
+
+typedef struct redir_mstr_data {
+ tdata_t *rmd_tgt;
+ alist_t *rmd_map;
+} redir_mstr_data_t;
+
+static int
+redir_mstr_fwd_cb(void *name, void *value, void *arg)
+{
+ tdesc_t *fwd = name;
+ int defnid = (uintptr_t)value;
+ redir_mstr_data_t *rmd = arg;
+ tdesc_t template;
+ tdesc_t *defn;
+
+ template.t_id = defnid;
+
+ if (!hash_find(rmd->rmd_tgt->td_idhash, (void *)&template,
+ (void *)&defn)) {
+ aborterr("Couldn't unforward %d (%s)\n", defnid,
+ tdesc_name(defn));
+ }
+
+ debug(3, "Forward map: resolved %d to %s\n", defnid, tdesc_name(defn));
+
+ alist_add(rmd->rmd_map, (void *)fwd, (void *)defn);
+
+ return (1);
+}
+
+static void
+redir_mstr_fwds(merge_cb_data_t *mcd)
+{
+ redir_mstr_data_t rmd;
+ alist_t *map = alist_new(NULL, NULL);
+
+ rmd.rmd_tgt = mcd->md_tgt;
+ rmd.rmd_map = map;
+
+ if (alist_iter(mcd->md_fdida, redir_mstr_fwd_cb, &rmd)) {
+ (void) iitraverse_hash(mcd->md_tgt->td_iihash,
+ &mcd->md_tgt->td_curvgen, fwd_redir_cbs, NULL, NULL, map);
+ }
+
+ alist_free(map);
+}
+
+static int
+add_iitba_cb(void *data, void *private)
+{
+ merge_cb_data_t *mcd = private;
+ iidesc_t *tba = data;
+ iidesc_t *new;
+ iifind_data_t iif;
+ int newidx;
+
+ newidx = get_mapping(mcd->md_ta, tba->ii_dtype->t_id);
+ assert(newidx != -1);
+
+ (void) list_remove(mcd->md_iitba, data, NULL, NULL);
+
+ iif.iif_template = tba;
+ iif.iif_ta = mcd->md_ta;
+ iif.iif_newidx = newidx;
+ iif.iif_refmerge = (mcd->md_flags & MCD_F_REFMERGE);
+
+ if (hash_match(mcd->md_parent->td_iihash, tba, iidesc_match,
+ &iif) == 1) {
+ debug(3, "iidesc_t %s already exists\n",
+ (tba->ii_name ? tba->ii_name : "(anon)"));
+ return (1);
+ }
+
+ new = conjure_iidesc(tba, mcd);
+ hash_add(mcd->md_tgt->td_iihash, new);
+
+ return (1);
+}
+
+static int
+add_tdesc(tdesc_t *oldtdp, int newid, merge_cb_data_t *mcd)
+{
+ tdesc_t *newtdp;
+ tdesc_t template;
+
+ template.t_id = newid;
+ assert(hash_find(mcd->md_parent->td_idhash,
+ (void *)&template, NULL) == 0);
+
+ debug(3, "trying to conjure %d %s (%d, <%x>) as %d, <%x>\n",
+ oldtdp->t_type, tdesc_name(oldtdp), oldtdp->t_id,
+ oldtdp->t_id, newid, newid);
+
+ if ((newtdp = tdesc_ops[oldtdp->t_type].conjure(oldtdp, newid,
+ mcd)) == NULL)
+ /* couldn't map everything */
+ return (0);
+
+ debug(3, "succeeded\n");
+
+ hash_add(mcd->md_tgt->td_idhash, newtdp);
+ hash_add(mcd->md_tgt->td_layouthash, newtdp);
+
+ return (1);
+}
+
+static int
+add_tdtba_cb(void *data, void *arg)
+{
+ tdesc_t *tdp = data;
+ merge_cb_data_t *mcd = arg;
+ int newid;
+ int rc;
+
+ newid = get_mapping(mcd->md_ta, tdp->t_id);
+ assert(newid != -1);
+
+ if ((rc = add_tdesc(tdp, newid, mcd)))
+ hash_remove(mcd->md_tdtba, (void *)tdp);
+
+ return (rc);
+}
+
+static int
+add_tdtbr_cb(void *data, void *arg)
+{
+ tdesc_t **tdpp = data;
+ merge_cb_data_t *mcd = arg;
+
+ debug(3, "Remapping %s (%d)\n", tdesc_name(*tdpp), (*tdpp)->t_id);
+
+ if (!remap_node(tdpp, *tdpp, -1, NULL, mcd))
+ return (0);
+
+ (void) list_remove(mcd->md_tdtbr, (void *)tdpp, NULL, NULL);
+ return (1);
+}
+
+static void
+merge_types(hash_t *src, merge_cb_data_t *mcd)
+{
+ list_t *iitba = NULL;
+ list_t *tdtbr = NULL;
+ int iirc, tdrc;
+
+ mcd->md_iitba = &iitba;
+ mcd->md_tdtba = hash_new(TDATA_LAYOUT_HASH_SIZE, tdesc_layouthash,
+ tdesc_layoutcmp);
+ mcd->md_tdtbr = &tdtbr;
+
+ (void) hash_iter(src, merge_type_cb, mcd);
+
+ tdrc = hash_iter(mcd->md_tdtba, add_tdtba_cb, mcd);
+ debug(3, "add_tdtba_cb added %d items\n", tdrc);
+
+ iirc = list_iter(*mcd->md_iitba, add_iitba_cb, mcd);
+ debug(3, "add_iitba_cb added %d items\n", iirc);
+
+ assert(list_count(*mcd->md_iitba) == 0 &&
+ hash_count(mcd->md_tdtba) == 0);
+
+ tdrc = list_iter(*mcd->md_tdtbr, add_tdtbr_cb, mcd);
+ debug(3, "add_tdtbr_cb added %d items\n", tdrc);
+
+ if (list_count(*mcd->md_tdtbr) != 0)
+ aborterr("Couldn't remap all nodes\n");
+
+ /*
+ * We now have an alist of master forwards and the ids of the new master
+ * definitions for those forwards in mcd->md_fdida. By this point,
+ * we're guaranteed that all of the master definitions referenced in
+ * fdida have been added to the master tree. We now traverse through
+ * the master tree, redirecting all edges inbound to forwards that have
+ * definitions to those definitions.
+ */
+ if (mcd->md_parent == mcd->md_tgt) {
+ redir_mstr_fwds(mcd);
+ }
+}
+
+void
+merge_into_master(tdata_t *cur, tdata_t *mstr, tdata_t *tgt, int selfuniquify)
+{
+ merge_cb_data_t mcd;
+
+ cur->td_ref++;
+ mstr->td_ref++;
+ if (tgt)
+ tgt->td_ref++;
+
+ assert(cur->td_ref == 1 && mstr->td_ref == 1 &&
+ (tgt == NULL || tgt->td_ref == 1));
+
+ mcd.md_parent = mstr;
+ mcd.md_tgt = (tgt ? tgt : mstr);
+ mcd.md_ta = alist_new(NULL, NULL);
+ mcd.md_fdida = alist_new(NULL, NULL);
+ mcd.md_flags = 0;
+
+ if (selfuniquify)
+ mcd.md_flags |= MCD_F_SELFUNIQUIFY;
+ if (tgt)
+ mcd.md_flags |= MCD_F_REFMERGE;
+
+ mstr->td_curvgen = MAX(mstr->td_curvgen, cur->td_curvgen);
+ mstr->td_curemark = MAX(mstr->td_curemark, cur->td_curemark);
+
+ merge_types(cur->td_iihash, &mcd);
+
+ if (debug_level >= 3) {
+ debug(3, "Type association stats\n");
+ alist_stats(mcd.md_ta, 0);
+ debug(3, "Layout hash stats\n");
+ hash_stats(mcd.md_tgt->td_layouthash, 1);
+ }
+
+ alist_free(mcd.md_fdida);
+ alist_free(mcd.md_ta);
+
+ cur->td_ref--;
+ mstr->td_ref--;
+ if (tgt)
+ tgt->td_ref--;
+}
+
+tdesc_ops_t tdesc_ops[] = {
+ { "ERROR! BAD tdesc TYPE", NULL, NULL },
+ { "intrinsic", equiv_intrinsic, conjure_intrinsic },
+ { "pointer", equiv_plain, conjure_plain },
+ { "array", equiv_array, conjure_array },
+ { "function", equiv_function, conjure_function },
+ { "struct", equiv_su, conjure_su },
+ { "union", equiv_su, conjure_su },
+ { "enum", equiv_enum, conjure_enum },
+ { "forward", NULL, conjure_forward },
+ { "typedef", equiv_plain, conjure_plain },
+ { "typedef_unres", equiv_assert, conjure_assert },
+ { "volatile", equiv_plain, conjure_plain },
+ { "const", equiv_plain, conjure_plain },
+ { "restrict", equiv_plain, conjure_plain }
+};
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
new file mode 100644
index 0000000..af79769
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
@@ -0,0 +1,777 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for preparing tdata trees for conversion into CTF data, and
+ * for placing the resulting data into an output file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <unistd.h>
+
+#include "ctftools.h"
+#include "list.h"
+#include "memory.h"
+#include "traverse.h"
+#include "symbol.h"
+
+typedef struct iidesc_match {
+ int iim_fuzzy;
+ iidesc_t *iim_ret;
+ char *iim_name;
+ char *iim_file;
+ uchar_t iim_bind;
+} iidesc_match_t;
+
+static int
+burst_iitypes(void *data, void *arg)
+{
+ iidesc_t *ii = data;
+ iiburst_t *iiburst = arg;
+
+ switch (ii->ii_type) {
+ case II_GFUN:
+ case II_SFUN:
+ case II_GVAR:
+ case II_SVAR:
+ if (!(ii->ii_flags & IIDESC_F_USED))
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ ii->ii_dtype->t_flags |= TDESC_F_ISROOT;
+ (void) iitraverse_td(ii, iiburst->iib_tdtd);
+ return (1);
+}
+
+/*ARGSUSED1*/
+static int
+save_type_by_id(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
+{
+ iiburst_t *iiburst = private;
+
+ /*
+ * Doing this on every node is horribly inefficient, but given that
+ * we may be suppressing some types, we can't trust nextid in the
+ * tdata_t.
+ */
+ if (tdp->t_id > iiburst->iib_maxtypeid)
+ iiburst->iib_maxtypeid = tdp->t_id;
+
+ slist_add(&iiburst->iib_types, tdp, tdesc_idcmp);
+
+ return (1);
+}
+
+static tdtrav_cb_f burst_types_cbs[] = {
+ NULL,
+ save_type_by_id, /* intrinsic */
+ save_type_by_id, /* pointer */
+ save_type_by_id, /* array */
+ save_type_by_id, /* function */
+ save_type_by_id, /* struct */
+ save_type_by_id, /* union */
+ save_type_by_id, /* enum */
+ save_type_by_id, /* forward */
+ save_type_by_id, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ save_type_by_id, /* volatile */
+ save_type_by_id, /* const */
+ save_type_by_id /* restrict */
+};
+
+
+static iiburst_t *
+iiburst_new(tdata_t *td, int max)
+{
+ iiburst_t *iiburst = xcalloc(sizeof (iiburst_t));
+ iiburst->iib_td = td;
+ iiburst->iib_funcs = xcalloc(sizeof (iidesc_t *) * max);
+ iiburst->iib_nfuncs = 0;
+ iiburst->iib_objts = xcalloc(sizeof (iidesc_t *) * max);
+ iiburst->iib_nobjts = 0;
+ return (iiburst);
+}
+
+static void
+iiburst_types(iiburst_t *iiburst)
+{
+ tdtrav_data_t tdtd;
+
+ tdtrav_init(&tdtd, &iiburst->iib_td->td_curvgen, NULL, burst_types_cbs,
+ NULL, (void *)iiburst);
+
+ iiburst->iib_tdtd = &tdtd;
+
+ (void) hash_iter(iiburst->iib_td->td_iihash, burst_iitypes, iiburst);
+}
+
+static void
+iiburst_free(iiburst_t *iiburst)
+{
+ free(iiburst->iib_funcs);
+ free(iiburst->iib_objts);
+ list_free(iiburst->iib_types, NULL, NULL);
+ free(iiburst);
+}
+
+/*
+ * See if this iidesc matches the ELF symbol data we pass in.
+ *
+ * A fuzzy match is where we have a local symbol matching the name of a
+ * global type description. This is common when a mapfile is used for a
+ * DSO, but we don't accept it by default.
+ *
+ * A weak fuzzy match is when a weak symbol was resolved and matched to
+ * a global type description.
+ */
+static int
+matching_iidesc(void *arg1, void *arg2)
+{
+ iidesc_t *iidesc = arg1;
+ iidesc_match_t *match = arg2;
+ if (streq(iidesc->ii_name, match->iim_name) == 0)
+ return (0);
+
+ switch (iidesc->ii_type) {
+ case II_GFUN:
+ case II_GVAR:
+ if (match->iim_bind == STB_GLOBAL) {
+ match->iim_ret = iidesc;
+ return (-1);
+ } else if (match->iim_fuzzy && match->iim_ret == NULL) {
+ match->iim_ret = iidesc;
+ /* continue to look for strong match */
+ return (0);
+ }
+ break;
+ case II_SFUN:
+ case II_SVAR:
+ if (match->iim_bind == STB_LOCAL &&
+ match->iim_file != NULL &&
+ streq(iidesc->ii_owner, match->iim_file)) {
+ match->iim_ret = iidesc;
+ return (-1);
+ }
+ break;
+ default:
+ break;
+ }
+ return (0);
+}
+
+static iidesc_t *
+find_iidesc(tdata_t *td, iidesc_match_t *match)
+{
+ match->iim_ret = NULL;
+ iter_iidescs_by_name(td, match->iim_name,
+ matching_iidesc, match);
+ return (match->iim_ret);
+}
+
+/*
+ * If we have a weak symbol, attempt to find the strong symbol it will
+ * resolve to. Note: the code where this actually happens is in
+ * sym_process() in cmd/sgs/libld/common/syms.c
+ *
+ * Finding the matching symbol is unfortunately not trivial. For a
+ * symbol to be a candidate, it must:
+ *
+ * - have the same type (function, object)
+ * - have the same value (address)
+ * - have the same size
+ * - not be another weak symbol
+ * - belong to the same section (checked via section index)
+ *
+ * If such a candidate is global, then we assume we've found it. The
+ * linker generates the symbol table such that the curfile might be
+ * incorrect; this is OK for global symbols, since find_iidesc() doesn't
+ * need to check for the source file for the symbol.
+ *
+ * We might have found a strong local symbol, where the curfile is
+ * accurate and matches that of the weak symbol. We assume this is a
+ * reasonable match.
+ *
+ * If we've got a local symbol with a non-matching curfile, there are
+ * two possibilities. Either this is a completely different symbol, or
+ * it's a once-global symbol that was scoped to local via a mapfile. In
+ * the latter case, curfile is likely inaccurate since the linker does
+ * not preserve the needed curfile in the order of the symbol table (see
+ * the comments about locally scoped symbols in libld's update_osym()).
+ * As we can't tell this case from the former one, we use this symbol
+ * iff no other matching symbol is found.
+ *
+ * What we really need here is a SUNW section containing weak<->strong
+ * mappings that we can consume.
+ */
+static int
+check_for_weak(GElf_Sym *weak, char const *weakfile,
+ Elf_Data *data, int nent, Elf_Data *strdata,
+ GElf_Sym *retsym, char **curfilep)
+{
+ char *curfile = NULL;
+ char *tmpfile1 = NULL;
+ GElf_Sym tmpsym;
+ int candidate = 0;
+ int i;
+ tmpsym.st_info = 0;
+ tmpsym.st_name = 0;
+
+ if (GELF_ST_BIND(weak->st_info) != STB_WEAK)
+ return (0);
+
+ for (i = 0; i < nent; i++) {
+ GElf_Sym sym;
+ uchar_t type;
+
+ if (gelf_getsym(data, i, &sym) == NULL)
+ continue;
+
+ type = GELF_ST_TYPE(sym.st_info);
+
+ if (type == STT_FILE)
+ curfile = (char *)strdata->d_buf + sym.st_name;
+
+ if (GELF_ST_TYPE(weak->st_info) != type ||
+ weak->st_value != sym.st_value)
+ continue;
+
+ if (weak->st_size != sym.st_size)
+ continue;
+
+ if (GELF_ST_BIND(sym.st_info) == STB_WEAK)
+ continue;
+
+ if (sym.st_shndx != weak->st_shndx)
+ continue;
+
+ if (GELF_ST_BIND(sym.st_info) == STB_LOCAL &&
+ (curfile == NULL || weakfile == NULL ||
+ strcmp(curfile, weakfile) != 0)) {
+ candidate = 1;
+ tmpfile1 = curfile;
+ tmpsym = sym;
+ continue;
+ }
+
+ *curfilep = curfile;
+ *retsym = sym;
+ return (1);
+ }
+
+ if (candidate) {
+ *curfilep = tmpfile1;
+ *retsym = tmpsym;
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * When we've found the underlying symbol's type description
+ * for a weak symbol, we need to copy it and rename it to match
+ * the weak symbol. We also need to add it to the td so it's
+ * handled along with the others later.
+ */
+static iidesc_t *
+copy_from_strong(tdata_t *td, GElf_Sym *sym, iidesc_t *strongdesc,
+ const char *weakname, const char *weakfile)
+{
+ iidesc_t *new = iidesc_dup_rename(strongdesc, weakname, weakfile);
+ uchar_t type = GELF_ST_TYPE(sym->st_info);
+
+ switch (type) {
+ case STT_OBJECT:
+ new->ii_type = II_GVAR;
+ break;
+ case STT_FUNC:
+ new->ii_type = II_GFUN;
+ break;
+ }
+
+ hash_add(td->td_iihash, new);
+
+ return (new);
+}
+
+/*
+ * Process the symbol table of the output file, associating each symbol
+ * with a type description if possible, and sorting them into functions
+ * and data, maintaining symbol table order.
+ */
+static iiburst_t *
+sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
+ int dynsym)
+{
+ iiburst_t *iiburst;
+ Elf_Scn *scn;
+ GElf_Shdr shdr;
+ Elf_Data *data, *strdata;
+ int i, stidx;
+ int nent;
+ iidesc_match_t match;
+
+ match.iim_fuzzy = fuzzymatch;
+ match.iim_file = NULL;
+
+ if ((stidx = findelfsecidx(elf, file,
+ dynsym ? ".dynsym" : ".symtab")) < 0)
+ terminate("%s: Can't open symbol table\n", file);
+ scn = elf_getscn(elf, stidx);
+ data = elf_getdata(scn, NULL);
+ gelf_getshdr(scn, &shdr);
+ nent = shdr.sh_size / shdr.sh_entsize;
+
+ scn = elf_getscn(elf, shdr.sh_link);
+ strdata = elf_getdata(scn, NULL);
+
+ iiburst = iiburst_new(td, nent);
+
+ for (i = 0; i < nent; i++) {
+ GElf_Sym sym;
+ char *bname;
+ iidesc_t **tolist;
+ GElf_Sym ssym;
+ iidesc_match_t smatch;
+ int *curr;
+ iidesc_t *iidesc;
+
+ if (gelf_getsym(data, i, &sym) == NULL)
+ elfterminate(file, "Couldn't read symbol %d", i);
+
+ match.iim_name = (char *)strdata->d_buf + sym.st_name;
+ match.iim_bind = GELF_ST_BIND(sym.st_info);
+
+ switch (GELF_ST_TYPE(sym.st_info)) {
+ case STT_FILE:
+ bname = strrchr(match.iim_name, '/');
+ match.iim_file = bname == NULL ? match.iim_name : bname + 1;
+ continue;
+ case STT_OBJECT:
+ tolist = iiburst->iib_objts;
+ curr = &iiburst->iib_nobjts;
+ break;
+ case STT_FUNC:
+ tolist = iiburst->iib_funcs;
+ curr = &iiburst->iib_nfuncs;
+ break;
+ default:
+ continue;
+ }
+
+ if (ignore_symbol(&sym, match.iim_name))
+ continue;
+
+ iidesc = find_iidesc(td, &match);
+
+ if (iidesc != NULL) {
+ tolist[*curr] = iidesc;
+ iidesc->ii_flags |= IIDESC_F_USED;
+ (*curr)++;
+ continue;
+ }
+
+ if (!check_for_weak(&sym, match.iim_file, data, nent, strdata,
+ &ssym, &smatch.iim_file)) {
+ (*curr)++;
+ continue;
+ }
+
+ smatch.iim_fuzzy = fuzzymatch;
+ smatch.iim_name = (char *)strdata->d_buf + ssym.st_name;
+ smatch.iim_bind = GELF_ST_BIND(ssym.st_info);
+
+ debug(3, "Weak symbol %s resolved to %s\n", match.iim_name,
+ smatch.iim_name);
+
+ iidesc = find_iidesc(td, &smatch);
+
+ if (iidesc != NULL) {
+ tolist[*curr] = copy_from_strong(td, &sym,
+ iidesc, match.iim_name, match.iim_file);
+ tolist[*curr]->ii_flags |= IIDESC_F_USED;
+ }
+
+ (*curr)++;
+ }
+
+ /*
+ * Stabs are generated for every function declared in a given C source
+ * file. When converting an object file, we may encounter a stab that
+ * has no symbol table entry because the optimizer has decided to omit
+ * that item (for example, an unreferenced static function). We may
+ * see iidescs that do not have an associated symtab entry, and so
+ * we do not write records for those functions into the CTF data.
+ * All others get marked as a root by this function.
+ */
+ iiburst_types(iiburst);
+
+ /*
+ * By not adding some of the functions and/or objects, we may have
+ * caused some types that were referenced solely by those
+ * functions/objects to be suppressed. This could cause a label,
+ * generated prior to the evisceration, to be incorrect. Find the
+ * highest type index, and change the label indicies to be no higher
+ * than this value.
+ */
+ tdata_label_newmax(td, iiburst->iib_maxtypeid);
+
+ return (iiburst);
+}
+
+static void
+write_file(Elf *src, const char *srcname, Elf *dst, const char *dstname,
+ caddr_t ctfdata, size_t ctfsize, int flags)
+{
+ GElf_Ehdr sehdr, dehdr;
+ Elf_Scn *sscn, *dscn;
+ Elf_Data *sdata, *ddata;
+ GElf_Shdr shdr;
+ GElf_Word symtab_type;
+ int symtab_idx = -1;
+ off_t new_offset = 0;
+ off_t ctfnameoff = 0;
+ int dynsym = (flags & CTF_USE_DYNSYM);
+ int keep_stabs = (flags & CTF_KEEP_STABS);
+ int *secxlate;
+ int srcidx, dstidx;
+ int curnmoff = 0;
+ int changing = 0;
+ int pad;
+ int i;
+
+ if (gelf_newehdr(dst, gelf_getclass(src)) == NULL)
+ elfterminate(dstname, "Cannot copy ehdr to temp file");
+ gelf_getehdr(src, &sehdr);
+ memcpy(&dehdr, &sehdr, sizeof (GElf_Ehdr));
+ gelf_update_ehdr(dst, &dehdr);
+
+ symtab_type = dynsym ? SHT_DYNSYM : SHT_SYMTAB;
+
+ /*
+ * Neither the existing stab sections nor the SUNW_ctf sections (new or
+ * existing) are SHF_ALLOC'd, so they won't be in areas referenced by
+ * program headers. As such, we can just blindly copy the program
+ * headers from the existing file to the new file.
+ */
+ if (sehdr.e_phnum != 0) {
+ (void) elf_flagelf(dst, ELF_C_SET, ELF_F_LAYOUT);
+ if (gelf_newphdr(dst, sehdr.e_phnum) == NULL)
+ elfterminate(dstname, "Cannot make phdrs in temp file");
+
+ for (i = 0; i < sehdr.e_phnum; i++) {
+ GElf_Phdr phdr;
+
+ gelf_getphdr(src, i, &phdr);
+ gelf_update_phdr(dst, i, &phdr);
+ }
+ }
+
+ secxlate = xmalloc(sizeof (int) * sehdr.e_shnum);
+ for (srcidx = dstidx = 0; srcidx < sehdr.e_shnum; srcidx++) {
+ Elf_Scn *scn = elf_getscn(src, srcidx);
+ GElf_Shdr shdr1;
+ char *sname;
+
+ gelf_getshdr(scn, &shdr1);
+ sname = elf_strptr(src, sehdr.e_shstrndx, shdr1.sh_name);
+ if (sname == NULL) {
+ elfterminate(srcname, "Can't find string at %u",
+ shdr1.sh_name);
+ }
+
+ if (strcmp(sname, CTF_ELF_SCN_NAME) == 0) {
+ secxlate[srcidx] = -1;
+ } else if (!keep_stabs &&
+ (strncmp(sname, ".stab", 5) == 0 ||
+ strncmp(sname, ".debug", 6) == 0 ||
+ strncmp(sname, ".rel.debug", 10) == 0 ||
+ strncmp(sname, ".rela.debug", 11) == 0)) {
+ secxlate[srcidx] = -1;
+ } else if (dynsym && shdr1.sh_type == SHT_SYMTAB) {
+ /*
+ * If we're building CTF against the dynsym,
+ * we'll rip out the symtab so debuggers aren't
+ * confused.
+ */
+ secxlate[srcidx] = -1;
+ } else {
+ secxlate[srcidx] = dstidx++;
+ curnmoff += strlen(sname) + 1;
+ }
+
+ new_offset = (off_t)dehdr.e_phoff;
+ }
+
+ for (srcidx = 1; srcidx < sehdr.e_shnum; srcidx++) {
+ char *sname;
+
+ sscn = elf_getscn(src, srcidx);
+ gelf_getshdr(sscn, &shdr);
+
+ if (secxlate[srcidx] == -1) {
+ changing = 1;
+ continue;
+ }
+
+ dscn = elf_newscn(dst);
+
+ /*
+ * If this file has program headers, we need to explicitly lay
+ * out sections. If none of the sections prior to this one have
+ * been removed, then we can just use the existing location. If
+ * one or more sections have been changed, then we need to
+ * adjust this one to avoid holes.
+ */
+ if (changing && sehdr.e_phnum != 0) {
+ pad = new_offset % shdr.sh_addralign;
+
+ if (pad)
+ new_offset += shdr.sh_addralign - pad;
+ shdr.sh_offset = new_offset;
+ }
+
+ shdr.sh_link = secxlate[shdr.sh_link];
+
+ if (shdr.sh_type == SHT_REL || shdr.sh_type == SHT_RELA)
+ shdr.sh_info = secxlate[shdr.sh_info];
+
+ sname = elf_strptr(src, sehdr.e_shstrndx, shdr.sh_name);
+ if (sname == NULL) {
+ elfterminate(srcname, "Can't find string at %u",
+ shdr.sh_name);
+ }
+
+#if !defined(sun)
+ if (gelf_update_shdr(dscn, &shdr) == 0)
+ elfterminate(dstname, "Cannot update sect %s", sname);
+#endif
+
+ if ((sdata = elf_getdata(sscn, NULL)) == NULL)
+ elfterminate(srcname, "Cannot get sect %s data", sname);
+ if ((ddata = elf_newdata(dscn)) == NULL)
+ elfterminate(dstname, "Can't make sect %s data", sname);
+#if defined(sun)
+ bcopy(sdata, ddata, sizeof (Elf_Data));
+#else
+ /*
+ * FreeBSD's Elf_Data has private fields which the
+ * elf_* routines manage. Simply copying the
+ * entire structure corrupts the data. So we need
+ * to copy the public fields explictly.
+ */
+ ddata->d_align = sdata->d_align;
+ ddata->d_off = sdata->d_off;
+ ddata->d_size = sdata->d_size;
+ ddata->d_type = sdata->d_type;
+ ddata->d_version = sdata->d_version;
+#endif
+
+ if (srcidx == sehdr.e_shstrndx) {
+ char seclen = strlen(CTF_ELF_SCN_NAME);
+
+ ddata->d_buf = xmalloc(ddata->d_size + shdr.sh_size +
+ seclen + 1);
+ bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
+ strcpy((caddr_t)ddata->d_buf + shdr.sh_size,
+ CTF_ELF_SCN_NAME);
+ ctfnameoff = (off_t)shdr.sh_size;
+ shdr.sh_size += seclen + 1;
+ ddata->d_size += seclen + 1;
+
+ if (sehdr.e_phnum != 0)
+ changing = 1;
+ }
+
+ if (shdr.sh_type == symtab_type && shdr.sh_entsize != 0) {
+ int nsym = shdr.sh_size / shdr.sh_entsize;
+
+ symtab_idx = secxlate[srcidx];
+
+ ddata->d_buf = xmalloc(shdr.sh_size);
+ bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
+
+ for (i = 0; i < nsym; i++) {
+ GElf_Sym sym;
+ short newscn;
+
+ if (gelf_getsym(ddata, i, &sym) == NULL)
+ printf("Could not get symbol %d\n",i);
+
+ if (sym.st_shndx >= SHN_LORESERVE)
+ continue;
+
+ if ((newscn = secxlate[sym.st_shndx]) !=
+ sym.st_shndx) {
+ sym.st_shndx =
+ (newscn == -1 ? 1 : newscn);
+
+ gelf_update_sym(ddata, i, &sym);
+ }
+ }
+ }
+
+#if !defined(sun)
+ if (ddata->d_buf == NULL && sdata->d_buf != NULL) {
+ ddata->d_buf = xmalloc(shdr.sh_size);
+ bcopy(sdata->d_buf, ddata->d_buf, shdr.sh_size);
+ }
+#endif
+
+ if (gelf_update_shdr(dscn, &shdr) == 0)
+ elfterminate(dstname, "Cannot update sect %s", sname);
+
+ new_offset = (off_t)shdr.sh_offset;
+ if (shdr.sh_type != SHT_NOBITS)
+ new_offset += shdr.sh_size;
+ }
+
+ if (symtab_idx == -1) {
+ terminate("%s: Cannot find %s section\n", srcname,
+ dynsym ? "SHT_DYNSYM" : "SHT_SYMTAB");
+ }
+
+ /* Add the ctf section */
+ dscn = elf_newscn(dst);
+ gelf_getshdr(dscn, &shdr);
+ shdr.sh_name = ctfnameoff;
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_size = ctfsize;
+ shdr.sh_link = symtab_idx;
+ shdr.sh_addralign = 4;
+ if (changing && sehdr.e_phnum != 0) {
+ pad = new_offset % shdr.sh_addralign;
+
+ if (pad)
+ new_offset += shdr.sh_addralign - pad;
+
+ shdr.sh_offset = new_offset;
+ new_offset += shdr.sh_size;
+ }
+
+ ddata = elf_newdata(dscn);
+ ddata->d_buf = ctfdata;
+ ddata->d_size = ctfsize;
+ ddata->d_align = shdr.sh_addralign;
+ ddata->d_off = 0;
+
+ gelf_update_shdr(dscn, &shdr);
+
+ /* update the section header location */
+ if (sehdr.e_phnum != 0) {
+ size_t align = gelf_fsize(dst, ELF_T_ADDR, 1, EV_CURRENT);
+ size_t r = new_offset % align;
+
+ if (r)
+ new_offset += align - r;
+
+ dehdr.e_shoff = new_offset;
+ }
+
+ /* commit to disk */
+ dehdr.e_shstrndx = secxlate[sehdr.e_shstrndx];
+ gelf_update_ehdr(dst, &dehdr);
+ if (elf_update(dst, ELF_C_WRITE) < 0)
+ elfterminate(dstname, "Cannot finalize temp file");
+
+ free(secxlate);
+}
+
+static caddr_t
+make_ctf_data(tdata_t *td, Elf *elf, const char *file, size_t *lenp, int flags)
+{
+ iiburst_t *iiburst;
+ caddr_t data;
+
+ iiburst = sort_iidescs(elf, file, td, flags & CTF_FUZZY_MATCH,
+ flags & CTF_USE_DYNSYM);
+ data = ctf_gen(iiburst, lenp, flags & (CTF_COMPRESS | CTF_SWAP_BYTES));
+
+ iiburst_free(iiburst);
+
+ return (data);
+}
+
+void
+write_ctf(tdata_t *td, const char *curname, const char *newname, int flags)
+{
+ struct stat st;
+ Elf *elf = NULL;
+ Elf *telf = NULL;
+ GElf_Ehdr ehdr;
+ caddr_t data;
+ size_t len;
+ int fd = -1;
+ int tfd = -1;
+ int byteorder;
+
+ (void) elf_version(EV_CURRENT);
+ if ((fd = open(curname, O_RDONLY)) < 0 || fstat(fd, &st) < 0)
+ terminate("%s: Cannot open for re-reading", curname);
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
+ elfterminate(curname, "Cannot re-read");
+
+ if ((tfd = open(newname, O_RDWR | O_CREAT | O_TRUNC, st.st_mode)) < 0)
+ terminate("Cannot open temp file %s for writing", newname);
+ if ((telf = elf_begin(tfd, ELF_C_WRITE, NULL)) == NULL)
+ elfterminate(curname, "Cannot write");
+
+ if (gelf_getehdr(elf, &ehdr)) {
+#if BYTE_ORDER == _BIG_ENDIAN
+ byteorder = ELFDATA2MSB;
+#else
+ byteorder = ELFDATA2LSB;
+#endif
+ /*
+ * If target and host has the same byte order
+ * clear byte swapping request
+ */
+ if (ehdr.e_ident[EI_DATA] == byteorder)
+ flags &= ~CTF_SWAP_BYTES;
+ }
+ else
+ elfterminate(curname, "Failed to get EHDR");
+
+ data = make_ctf_data(td, elf, curname, &len, flags);
+ write_file(elf, curname, telf, newname, data, len, flags);
+ free(data);
+
+ elf_end(telf);
+ elf_end(elf);
+ (void) close(fd);
+ (void) close(tfd);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
new file mode 100644
index 0000000..1dca82a
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
@@ -0,0 +1,1210 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file is a sewer.
+ */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <assert.h>
+#include <strings.h>
+#include <setjmp.h>
+#include <ctype.h>
+#include <uts/common/sys/ctf.h>
+
+#include "ctftools.h"
+#include "memory.h"
+#include "list.h"
+
+#define HASH(NUM) ((int)(NUM & (BUCKETS - 1)))
+#define BUCKETS 128
+
+#define TYPEPAIRMULT 10000
+#define MAKETYPEID(file, num) ((file) * TYPEPAIRMULT + num)
+#define TYPEFILE(tid) ((tid) / TYPEPAIRMULT)
+#define TYPENUM(tid) ((tid) % TYPEPAIRMULT)
+
+#define expected(a, b, c) _expected(a, b, c, __LINE__)
+
+static int faketypenumber = 100000000;
+
+static tdesc_t *hash_table[BUCKETS];
+static tdesc_t *name_table[BUCKETS];
+
+list_t *typedbitfldmems;
+
+static void reset(void);
+static jmp_buf resetbuf;
+
+static char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp);
+static void enumdef(char *cp, tdesc_t **rtdp);
+static int compute_sum(const char *w);
+
+static char *number(char *cp, int *n);
+static char *name(char *cp, char **w);
+static char *id(char *cp, int *h);
+static char *whitesp(char *cp);
+static void addhash(tdesc_t *tdp, int num);
+static int tagadd(char *w, int h, tdesc_t *tdp);
+static char *tdefdecl(char *cp, int h, tdesc_t **rtdp);
+static char *intrinsic(char *cp, tdesc_t **rtdp);
+static char *arraydef(char *cp, tdesc_t **rtdp);
+
+int debug_parse = DEBUG_PARSE;
+
+/*PRINTFLIKE3*/
+static void
+parse_debug(int level, char *cp, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[1024];
+ char tmp[32];
+ int i;
+
+ if (level > debug_level || !debug_parse)
+ return;
+
+ if (cp != NULL) {
+ for (i = 0; i < 30; i++) {
+ if (cp[i] == '\0')
+ break;
+ if (!iscntrl(cp[i]))
+ tmp[i] = cp[i];
+ }
+ tmp[i] = '\0';
+ (void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp);
+ } else {
+ strcpy(buf, fmt);
+ strcat(buf, "\n");
+ }
+
+ va_start(ap, fmt);
+ vadebug(level, buf, ap);
+ va_end(ap);
+}
+
+/* Report unexpected syntax in stabs. */
+static void
+_expected(
+ const char *who, /* what function, or part thereof, is reporting */
+ const char *what, /* what was expected */
+ const char *where, /* where we were in the line of input */
+ int line)
+{
+ fprintf(stderr, "%s, expecting \"%s\" at \"%s\"\n", who, what, where);
+ fprintf(stderr, "code line: %d, file %s\n", line,
+ (curhdr ? curhdr : "NO FILE"));
+ reset();
+}
+
+/*ARGSUSED*/
+void
+parse_init(tdata_t *td __unused)
+{
+ int i;
+
+ for (i = 0; i < BUCKETS; i++) {
+ hash_table[i] = NULL;
+ name_table[i] = NULL;
+ }
+
+ if (typedbitfldmems != NULL) {
+ list_free(typedbitfldmems, NULL, NULL);
+ typedbitfldmems = NULL;
+ }
+}
+
+void
+parse_finish(tdata_t *td)
+{
+ td->td_nextid = ++faketypenumber;
+}
+
+static tdesc_t *
+unres_new(int tid)
+{
+ tdesc_t *tdp;
+
+ tdp = xcalloc(sizeof (*tdp));
+ tdp->t_type = TYPEDEF_UNRES;
+ tdp->t_id = tid;
+
+ return (tdp);
+}
+
+static char *
+read_tid(char *cp, tdesc_t **tdpp)
+{
+ tdesc_t *tdp;
+ int tid;
+
+ cp = id(cp, &tid);
+
+ assert(tid != 0);
+
+ if (*cp == '=') {
+ if (!(cp = tdefdecl(cp + 1, tid, &tdp)))
+ return (NULL);
+ if (tdp->t_id && tdp->t_id != tid) {
+ tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
+
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = tdp;
+ tdp = ntdp;
+ }
+ addhash(tdp, tid);
+ } else if ((tdp = lookup(tid)) == NULL)
+ tdp = unres_new(tid);
+
+ *tdpp = tdp;
+ return (cp);
+}
+
+static iitype_t
+parse_fun(char *cp, iidesc_t *ii)
+{
+ iitype_t iitype = 0;
+ tdesc_t *tdp;
+ tdesc_t **args = NULL;
+ int nargs = 0;
+ int va = 0;
+
+ /*
+ * name:P prototype
+ * name:F global function
+ * name:f static function
+ */
+ switch (*cp++) {
+ case 'P':
+ iitype = II_NOT; /* not interesting */
+ break;
+
+ case 'F':
+ iitype = II_GFUN;
+ break;
+
+ case 'f':
+ iitype = II_SFUN;
+ break;
+
+ default:
+ expected("parse_nfun", "[PfF]", cp - 1);
+ }
+
+ if (!(cp = read_tid(cp, &tdp)))
+ return (-1);
+
+ if (*cp)
+ args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF);
+
+ while (*cp && *++cp) {
+ if (*cp == '0') {
+ va = 1;
+ continue;
+ }
+
+ nargs++;
+ if (nargs > FUNCARG_DEF)
+ args = xrealloc(args, sizeof (tdesc_t *) * nargs);
+ if (!(cp = read_tid(cp, &args[nargs - 1])))
+ return (-1);
+ }
+
+ ii->ii_type = iitype;
+ ii->ii_dtype = tdp;
+ ii->ii_nargs = nargs;
+ ii->ii_args = args;
+ ii->ii_vargs = va;
+
+ return (iitype);
+}
+
+static iitype_t
+parse_sym(char *cp, iidesc_t *ii)
+{
+ tdesc_t *tdp;
+ iitype_t iitype = 0;
+
+ /*
+ * name:G global variable
+ * name:S static variable
+ */
+ switch (*cp++) {
+ case 'G':
+ iitype = II_GVAR;
+ break;
+ case 'S':
+ iitype = II_SVAR;
+ break;
+ case 'p':
+ iitype = II_PSYM;
+ break;
+ case '(':
+ cp--;
+ /*FALLTHROUGH*/
+ case 'r':
+ case 'V':
+ iitype = II_NOT; /* not interesting */
+ break;
+ default:
+ expected("parse_sym", "[GprSV(]", cp - 1);
+ }
+
+ if (!(cp = read_tid(cp, &tdp)))
+ return (-1);
+
+ ii->ii_type = iitype;
+ ii->ii_dtype = tdp;
+
+ return (iitype);
+}
+
+static iitype_t
+parse_type(char *cp, iidesc_t *ii)
+{
+ tdesc_t *tdp, *ntdp;
+ int tid;
+
+ if (*cp++ != 't')
+ expected("parse_type", "t (type)", cp - 1);
+
+ cp = id(cp, &tid);
+ if ((tdp = lookup(tid)) == NULL) {
+ if (*cp++ != '=')
+ expected("parse_type", "= (definition)", cp - 1);
+
+ (void) tdefdecl(cp, tid, &tdp);
+
+ if (tdp->t_id == tid) {
+ assert(tdp->t_type != TYPEDEF);
+ assert(!lookup(tdp->t_id));
+
+ if (!streq(tdp->t_name, ii->ii_name)) {
+ ntdp = xcalloc(sizeof (*ntdp));
+ ntdp->t_name = xstrdup(ii->ii_name);
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = tdp;
+ tdp->t_id = faketypenumber++;
+ tdp = ntdp;
+ }
+ } else if (tdp->t_id == 0) {
+ assert(tdp->t_type == FORWARD ||
+ tdp->t_type == INTRINSIC);
+
+ if (tdp->t_name && !streq(tdp->t_name, ii->ii_name)) {
+ ntdp = xcalloc(sizeof (*ntdp));
+ ntdp->t_name = xstrdup(ii->ii_name);
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = tdp;
+ tdp->t_id = faketypenumber++;
+ tdp = ntdp;
+ }
+ } else if (tdp->t_id != tid) {
+ ntdp = xcalloc(sizeof (*ntdp));
+ ntdp->t_name = xstrdup(ii->ii_name);
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = tdp;
+ tdp = ntdp;
+ }
+
+ if (tagadd(ii->ii_name, tid, tdp) < 0)
+ return (-1);
+ }
+
+ ii->ii_type = II_TYPE;
+ ii->ii_dtype = tdp;
+ return (II_TYPE);
+}
+
+static iitype_t
+parse_sou(char *cp, iidesc_t *idp)
+{
+ tdesc_t *rtdp;
+ int tid;
+
+ if (*cp++ != 'T')
+ expected("parse_sou", "T (sou)", cp - 1);
+
+ cp = id(cp, &tid);
+ if (*cp++ != '=')
+ expected("parse_sou", "= (definition)", cp - 1);
+
+ parse_debug(1, NULL, "parse_sou: declaring '%s'", idp->ii_name ?
+ idp->ii_name : "(anon)");
+ if ((rtdp = lookup(tid)) != NULL) {
+ if (idp->ii_name != NULL) {
+ if (rtdp->t_name != NULL &&
+ strcmp(rtdp->t_name, idp->ii_name) != 0) {
+ tdesc_t *tdp;
+
+ tdp = xcalloc(sizeof (*tdp));
+ tdp->t_name = xstrdup(idp->ii_name);
+ tdp->t_type = TYPEDEF;
+ tdp->t_tdesc = rtdp;
+ addhash(tdp, tid); /* for *(x,y) types */
+ parse_debug(3, NULL, " %s defined as %s(%d)",
+ idp->ii_name, tdesc_name(rtdp), tid);
+ } else if (rtdp->t_name == NULL) {
+ rtdp->t_name = xstrdup(idp->ii_name);
+ addhash(rtdp, tid);
+ }
+ }
+ } else {
+ rtdp = xcalloc(sizeof (*rtdp));
+ rtdp->t_name = idp->ii_name ? xstrdup(idp->ii_name) : NULL;
+ addhash(rtdp, tid);
+ }
+
+ switch (*cp++) {
+ case 's':
+ (void) soudef(cp, STRUCT, &rtdp);
+ break;
+ case 'u':
+ (void) soudef(cp, UNION, &rtdp);
+ break;
+ case 'e':
+ enumdef(cp, &rtdp);
+ break;
+ default:
+ expected("parse_sou", "<tag type s/u/e>", cp - 1);
+ break;
+ }
+
+ idp->ii_type = II_SOU;
+ idp->ii_dtype = rtdp;
+ return (II_SOU);
+}
+
+int
+parse_stab(stab_t *stab, char *cp, iidesc_t **iidescp)
+{
+ iidesc_t *ii = NULL;
+ iitype_t (*parse)(char *, iidesc_t *);
+ int rc;
+
+ /*
+ * set up for reset()
+ */
+ if (setjmp(resetbuf))
+ return (-1);
+
+ cp = whitesp(cp);
+ ii = iidesc_new(NULL);
+ cp = name(cp, &ii->ii_name);
+
+ switch (stab->n_type) {
+ case N_FUN:
+ parse = parse_fun;
+ break;
+
+ case N_LSYM:
+ if (*cp == 't')
+ parse = parse_type;
+ else if (*cp == 'T')
+ parse = parse_sou;
+ else
+ parse = parse_sym;
+ break;
+
+ case N_GSYM:
+ case N_LCSYM:
+ case N_PSYM:
+ case N_ROSYM:
+ case N_RSYM:
+ case N_STSYM:
+ parse = parse_sym;
+ break;
+ default:
+ parse_debug(1, cp, "Unknown stab type %#x", stab->n_type);
+ bzero(&resetbuf, sizeof (resetbuf));
+ return (-1);
+ }
+
+ rc = parse(cp, ii);
+ bzero(&resetbuf, sizeof (resetbuf));
+
+ if (rc < 0 || ii->ii_type == II_NOT) {
+ iidesc_free(ii, NULL);
+ return (rc);
+ }
+
+ *iidescp = ii;
+
+ return (1);
+}
+
+/*
+ * Check if we have this node in the hash table already
+ */
+tdesc_t *
+lookup(int h)
+{
+ int bucket = HASH(h);
+ tdesc_t *tdp = hash_table[bucket];
+
+ while (tdp != NULL) {
+ if (tdp->t_id == h)
+ return (tdp);
+ tdp = tdp->t_hash;
+ }
+ return (NULL);
+}
+
+static char *
+whitesp(char *cp)
+{
+ char c;
+
+ for (c = *cp++; isspace(c); c = *cp++)
+ ;
+ --cp;
+ return (cp);
+}
+
+static char *
+name(char *cp, char **w)
+{
+ char *new, *orig, c;
+ int len;
+
+ orig = cp;
+ c = *cp++;
+ if (c == ':')
+ *w = NULL;
+ else if (isalpha(c) || strchr("_.$#", c)) {
+ for (c = *cp++; isalnum(c) || strchr(" _.$#", c); c = *cp++)
+ ;
+ if (c != ':')
+ reset();
+ len = cp - orig;
+ new = xmalloc(len);
+ while (orig < cp - 1)
+ *new++ = *orig++;
+ *new = '\0';
+ *w = new - (len - 1);
+ } else
+ reset();
+
+ return (cp);
+}
+
+static char *
+number(char *cp, int *n)
+{
+ char *next;
+
+ *n = (int)strtol(cp, &next, 10);
+ if (next == cp)
+ expected("number", "<number>", cp);
+ return (next);
+}
+
+static char *
+id(char *cp, int *h)
+{
+ int n1, n2;
+
+ if (*cp == '(') { /* SunPro style */
+ cp++;
+ cp = number(cp, &n1);
+ if (*cp++ != ',')
+ expected("id", ",", cp - 1);
+ cp = number(cp, &n2);
+ if (*cp++ != ')')
+ expected("id", ")", cp - 1);
+ *h = MAKETYPEID(n1, n2);
+ } else if (isdigit(*cp)) { /* gcc style */
+ cp = number(cp, &n1);
+ *h = n1;
+ } else {
+ expected("id", "(/0-9", cp);
+ }
+ return (cp);
+}
+
+static int
+tagadd(char *w, int h, tdesc_t *tdp)
+{
+ tdesc_t *otdp;
+
+ tdp->t_name = w;
+ if (!(otdp = lookup(h)))
+ addhash(tdp, h);
+ else if (otdp != tdp) {
+ warning("duplicate entry\n");
+ warning(" old: %s %d (%d,%d)\n", tdesc_name(otdp),
+ otdp->t_type, TYPEFILE(otdp->t_id), TYPENUM(otdp->t_id));
+ warning(" new: %s %d (%d,%d)\n", tdesc_name(tdp),
+ tdp->t_type, TYPEFILE(tdp->t_id), TYPENUM(tdp->t_id));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static char *
+tdefdecl(char *cp, int h, tdesc_t **rtdp)
+{
+ tdesc_t *ntdp;
+ char *w;
+ int c, h2;
+ char type;
+
+ parse_debug(3, cp, "tdefdecl h=%d", h);
+
+ /* Type codes */
+ switch (type = *cp) {
+ case 'b': /* integer */
+ case 'R': /* fp */
+ cp = intrinsic(cp, rtdp);
+ break;
+ case '(': /* equiv to another type */
+ cp = id(cp, &h2);
+ ntdp = lookup(h2);
+
+ if (ntdp != NULL && *cp == '=') {
+ if (ntdp->t_type == FORWARD && *(cp + 1) == 'x') {
+ /*
+ * The 6.2 compiler, and possibly others, will
+ * sometimes emit the same stab for a forward
+ * declaration twice. That is, "(1,2)=xsfoo:"
+ * will sometimes show up in two different
+ * places. This is, of course, quite fun. We
+ * want CTF to work in spite of the compiler,
+ * so we'll let this one through.
+ */
+ char *c2 = cp + 2;
+ char *nm;
+
+ if (!strchr("sue", *c2++)) {
+ expected("tdefdecl/x-redefine", "[sue]",
+ c2 - 1);
+ }
+
+ c2 = name(c2, &nm);
+ if (strcmp(nm, ntdp->t_name) != 0) {
+ terminate("Stabs error: Attempt to "
+ "redefine type (%d,%d) as "
+ "something else: %s\n",
+ TYPEFILE(h2), TYPENUM(h2),
+ c2 - 1);
+ }
+ free(nm);
+
+ h2 = faketypenumber++;
+ ntdp = NULL;
+ } else {
+ terminate("Stabs error: Attempting to "
+ "redefine type (%d,%d)\n", TYPEFILE(h2),
+ TYPENUM(h2));
+ }
+ }
+
+ if (ntdp == NULL) { /* if that type isn't defined yet */
+ if (*cp != '=') {
+ /* record it as unresolved */
+ parse_debug(3, NULL, "tdefdecl unres type %d",
+ h2);
+ *rtdp = calloc(sizeof (**rtdp), 1);
+ (*rtdp)->t_type = TYPEDEF_UNRES;
+ (*rtdp)->t_id = h2;
+ break;
+ } else
+ cp++;
+
+ /* define a new type */
+ cp = tdefdecl(cp, h2, rtdp);
+ if ((*rtdp)->t_id && (*rtdp)->t_id != h2) {
+ ntdp = calloc(sizeof (*ntdp), 1);
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = *rtdp;
+ *rtdp = ntdp;
+ }
+
+ addhash(*rtdp, h2);
+
+ } else { /* that type is already defined */
+ if (ntdp->t_type != TYPEDEF || ntdp->t_name != NULL) {
+ *rtdp = ntdp;
+ } else {
+ parse_debug(3, NULL,
+ "No duplicate typedef anon for ref");
+ *rtdp = ntdp;
+ }
+ }
+ break;
+ case '*':
+ ntdp = NULL;
+ cp = tdefdecl(cp + 1, h, &ntdp);
+ if (ntdp == NULL)
+ expected("tdefdecl/*", "id", cp);
+
+ if (!ntdp->t_id)
+ ntdp->t_id = faketypenumber++;
+
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = POINTER;
+ (*rtdp)->t_size = 0;
+ (*rtdp)->t_id = h;
+ (*rtdp)->t_tdesc = ntdp;
+ break;
+ case 'f':
+ cp = tdefdecl(cp + 1, h, &ntdp);
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = FUNCTION;
+ (*rtdp)->t_size = 0;
+ (*rtdp)->t_id = h;
+ (*rtdp)->t_fndef = xcalloc(sizeof (fndef_t));
+ /*
+ * The 6.1 compiler will sometimes generate incorrect stabs for
+ * function pointers (it'll get the return type wrong). This
+ * causes merges to fail. We therefore treat function pointers
+ * as if they all point to functions that return int. When
+ * 4432549 is fixed, the lookupname() call below should be
+ * replaced with `ntdp'.
+ */
+ (*rtdp)->t_fndef->fn_ret = lookupname("int");
+ break;
+ case 'a':
+ case 'z':
+ cp++;
+ if (*cp++ != 'r')
+ expected("tdefdecl/[az]", "r", cp - 1);
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = ARRAY;
+ (*rtdp)->t_id = h;
+ cp = arraydef(cp, rtdp);
+ break;
+ case 'x':
+ c = *++cp;
+ if (c != 's' && c != 'u' && c != 'e')
+ expected("tdefdecl/x", "[sue]", cp - 1);
+ cp = name(cp + 1, &w);
+
+ ntdp = xcalloc(sizeof (*ntdp));
+ ntdp->t_type = FORWARD;
+ ntdp->t_name = w;
+ /*
+ * We explicitly don't set t_id here - the caller will do it.
+ * The caller may want to use a real type ID, or they may
+ * choose to make one up.
+ */
+
+ *rtdp = ntdp;
+ break;
+
+ case 'B': /* volatile */
+ cp = tdefdecl(cp + 1, h, &ntdp);
+
+ if (!ntdp->t_id)
+ ntdp->t_id = faketypenumber++;
+
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = VOLATILE;
+ (*rtdp)->t_size = 0;
+ (*rtdp)->t_tdesc = ntdp;
+ (*rtdp)->t_id = h;
+ break;
+
+ case 'k': /* const */
+ cp = tdefdecl(cp + 1, h, &ntdp);
+
+ if (!ntdp->t_id)
+ ntdp->t_id = faketypenumber++;
+
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = CONST;
+ (*rtdp)->t_size = 0;
+ (*rtdp)->t_tdesc = ntdp;
+ (*rtdp)->t_id = h;
+ break;
+
+ case 'K': /* restricted */
+ cp = tdefdecl(cp + 1, h, &ntdp);
+
+ if (!ntdp->t_id)
+ ntdp->t_id = faketypenumber++;
+
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_type = RESTRICT;
+ (*rtdp)->t_size = 0;
+ (*rtdp)->t_tdesc = ntdp;
+ (*rtdp)->t_id = h;
+ break;
+
+ case 'u':
+ case 's':
+ cp++;
+
+ *rtdp = xcalloc(sizeof (**rtdp));
+ (*rtdp)->t_name = NULL;
+ cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
+ break;
+ default:
+ expected("tdefdecl", "<type code>", cp);
+ }
+ return (cp);
+}
+
+static char *
+intrinsic(char *cp, tdesc_t **rtdp)
+{
+ intr_t *intr = xcalloc(sizeof (intr_t));
+ tdesc_t *tdp;
+ int width, fmt, i;
+
+ switch (*cp++) {
+ case 'b':
+ intr->intr_type = INTR_INT;
+ if (*cp == 's')
+ intr->intr_signed = 1;
+ else if (*cp != 'u')
+ expected("intrinsic/b", "[su]", cp);
+ cp++;
+
+ if (strchr("cbv", *cp))
+ intr->intr_iformat = *cp++;
+
+ cp = number(cp, &width);
+ if (*cp++ != ';')
+ expected("intrinsic/b", "; (post-width)", cp - 1);
+
+ cp = number(cp, &intr->intr_offset);
+ if (*cp++ != ';')
+ expected("intrinsic/b", "; (post-offset)", cp - 1);
+
+ cp = number(cp, &intr->intr_nbits);
+ break;
+
+ case 'R':
+ intr->intr_type = INTR_REAL;
+ for (fmt = 0, i = 0; isdigit(*(cp + i)); i++)
+ fmt = fmt * 10 + (*(cp + i) - '0');
+
+ if (fmt < 1 || fmt > CTF_FP_MAX)
+ expected("intrinsic/R", "number <= CTF_FP_MAX", cp);
+
+ intr->intr_fformat = fmt;
+ cp += i;
+
+ if (*cp++ != ';')
+ expected("intrinsic/R", ";", cp - 1);
+ cp = number(cp, &width);
+
+ intr->intr_nbits = width * 8;
+ break;
+ }
+
+ tdp = xcalloc(sizeof (*tdp));
+ tdp->t_type = INTRINSIC;
+ tdp->t_size = width;
+ tdp->t_name = NULL;
+ tdp->t_intr = intr;
+ parse_debug(3, NULL, "intrinsic: size=%d", width);
+ *rtdp = tdp;
+
+ return (cp);
+}
+
+static tdesc_t *
+bitintrinsic(tdesc_t *template, int nbits)
+{
+ tdesc_t *newtdp = xcalloc(sizeof (tdesc_t));
+
+ newtdp->t_name = xstrdup(template->t_name);
+ newtdp->t_id = faketypenumber++;
+ newtdp->t_type = INTRINSIC;
+ newtdp->t_size = template->t_size;
+ newtdp->t_intr = xmalloc(sizeof (intr_t));
+ bcopy(template->t_intr, newtdp->t_intr, sizeof (intr_t));
+ newtdp->t_intr->intr_nbits = nbits;
+
+ return (newtdp);
+}
+
+static char *
+offsize(char *cp, mlist_t *mlp)
+{
+ int offset, size;
+
+ if (*cp == ',')
+ cp++;
+ cp = number(cp, &offset);
+ if (*cp++ != ',')
+ expected("offsize/2", ",", cp - 1);
+ cp = number(cp, &size);
+ if (*cp++ != ';')
+ expected("offsize/3", ";", cp - 1);
+ mlp->ml_offset = offset;
+ mlp->ml_size = size;
+ return (cp);
+}
+
+static tdesc_t *
+find_intrinsic(tdesc_t *tdp)
+{
+ for (;;) {
+ switch (tdp->t_type) {
+ case TYPEDEF:
+ case VOLATILE:
+ case CONST:
+ case RESTRICT:
+ tdp = tdp->t_tdesc;
+ break;
+
+ default:
+ return (tdp);
+ }
+ }
+}
+
+static char *
+soudef(char *cp, stabtype_t type, tdesc_t **rtdp)
+{
+ mlist_t *mlp, **prev;
+ char *w;
+ int h;
+ int size;
+ tdesc_t *tdp, *itdp;
+
+ cp = number(cp, &size);
+ (*rtdp)->t_size = size;
+ (*rtdp)->t_type = type; /* s or u */
+
+ /*
+ * An '@' here indicates a bitmask follows. This is so the
+ * compiler can pass information to debuggers about how structures
+ * are passed in the v9 world. We don't need this information
+ * so we skip over it.
+ */
+ if (cp[0] == '@') {
+ cp += 3;
+ }
+
+ parse_debug(3, cp, "soudef: %s size=%d", tdesc_name(*rtdp),
+ (*rtdp)->t_size);
+
+ prev = &((*rtdp)->t_members);
+ /* now fill up the fields */
+ while ((*cp != '\0') && (*cp != ';')) { /* signifies end of fields */
+ mlp = xcalloc(sizeof (*mlp));
+ *prev = mlp;
+ cp = name(cp, &w);
+ mlp->ml_name = w;
+ cp = id(cp, &h);
+ /*
+ * find the tdesc struct in the hash table for this type
+ * and stick a ptr in here
+ */
+ tdp = lookup(h);
+ if (tdp == NULL) { /* not in hash list */
+ parse_debug(3, NULL, " defines %s (%d)", w, h);
+ if (*cp++ != '=') {
+ tdp = unres_new(h);
+ parse_debug(3, NULL,
+ " refers to %s (unresolved %d)",
+ (w ? w : "anon"), h);
+ } else {
+ cp = tdefdecl(cp, h, &tdp);
+
+ if (tdp->t_id && tdp->t_id != h) {
+ tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
+
+ ntdp->t_type = TYPEDEF;
+ ntdp->t_tdesc = tdp;
+ tdp = ntdp;
+ }
+
+ addhash(tdp, h);
+ parse_debug(4, cp,
+ " soudef now looking at ");
+ cp++;
+ }
+ } else {
+ parse_debug(3, NULL, " refers to %s (%d, %s)",
+ w ? w : "anon", h, tdesc_name(tdp));
+ }
+
+ cp = offsize(cp, mlp);
+
+ itdp = find_intrinsic(tdp);
+ if (itdp->t_type == INTRINSIC) {
+ if (mlp->ml_size != itdp->t_intr->intr_nbits) {
+ parse_debug(4, cp, "making %d bit intrinsic "
+ "from %s", mlp->ml_size, tdesc_name(itdp));
+ mlp->ml_type = bitintrinsic(itdp, mlp->ml_size);
+ } else
+ mlp->ml_type = tdp;
+ } else if (itdp->t_type == TYPEDEF_UNRES) {
+ list_add(&typedbitfldmems, mlp);
+ mlp->ml_type = tdp;
+ } else {
+ mlp->ml_type = tdp;
+ }
+
+ /* cp is now pointing to next field */
+ prev = &mlp->ml_next;
+ }
+ return (cp);
+}
+
+static char *
+arraydef(char *cp, tdesc_t **rtdp)
+{
+ int start, end, h;
+
+ cp = id(cp, &h);
+ if (*cp++ != ';')
+ expected("arraydef/1", ";", cp - 1);
+
+ (*rtdp)->t_ardef = xcalloc(sizeof (ardef_t));
+ (*rtdp)->t_ardef->ad_idxtype = lookup(h);
+
+ cp = number(cp, &start); /* lower */
+ if (*cp++ != ';')
+ expected("arraydef/2", ";", cp - 1);
+
+ if (*cp == 'S') {
+ /*
+ * variable length array - treat as null dimensioned
+ *
+ * For VLA variables on sparc, SS12 generated stab entry
+ * looks as follows:
+ * .stabs "buf:(0,28)=zr(0,4);0;S-12;(0,1)", 0x80, 0, 0, -16
+ * Whereas SS12u1 generated stab entry looks like this:
+ * .stabs "buf:(0,28)=zr(0,4);0;S0;(0,1)", 0x80, 0, 0, 0
+ * On x86, both versions generate the first type of entry.
+ * We should be able to parse both.
+ */
+ cp++;
+ if (*cp == '-')
+ cp++;
+ cp = number(cp, &end);
+ end = start;
+ } else {
+ /*
+ * normal fixed-dimension array
+ * Stab entry for this looks as follows :
+ * .stabs "x:(0,28)=ar(0,4);0;9;(0,3)", 0x80, 0, 40, 0
+ */
+ cp = number(cp, &end); /* upper */
+ }
+
+ if (*cp++ != ';')
+ expected("arraydef/3", ";", cp - 1);
+ (*rtdp)->t_ardef->ad_nelems = end - start + 1;
+ cp = tdefdecl(cp, h, &((*rtdp)->t_ardef->ad_contents));
+
+ parse_debug(3, cp, "defined array idx type %d %d-%d next ",
+ h, start, end);
+
+ return (cp);
+}
+
+static void
+enumdef(char *cp, tdesc_t **rtdp)
+{
+ elist_t *elp, **prev;
+ char *w;
+
+ (*rtdp)->t_type = ENUM;
+ (*rtdp)->t_emem = NULL;
+
+ prev = &((*rtdp)->t_emem);
+ while (*cp != ';') {
+ elp = xcalloc(sizeof (*elp));
+ elp->el_next = NULL;
+ *prev = elp;
+ cp = name(cp, &w);
+ elp->el_name = w;
+ cp = number(cp, &elp->el_number);
+ parse_debug(3, NULL, "enum %s: %s=%d", tdesc_name(*rtdp),
+ elp->el_name, elp->el_number);
+ prev = &elp->el_next;
+ if (*cp++ != ',')
+ expected("enumdef", ",", cp - 1);
+ }
+}
+
+static tdesc_t *
+lookup_name(tdesc_t **hash, const char *name1)
+{
+ int bucket = compute_sum(name1);
+ tdesc_t *tdp, *ttdp = NULL;
+
+ for (tdp = hash[bucket]; tdp != NULL; tdp = tdp->t_next) {
+ if (tdp->t_name != NULL && strcmp(tdp->t_name, name1) == 0) {
+ if (tdp->t_type == STRUCT || tdp->t_type == UNION ||
+ tdp->t_type == ENUM || tdp->t_type == INTRINSIC)
+ return (tdp);
+ if (tdp->t_type == TYPEDEF)
+ ttdp = tdp;
+ }
+ }
+ return (ttdp);
+}
+
+tdesc_t *
+lookupname(const char *name1)
+{
+ return (lookup_name(name_table, name1));
+}
+
+/*
+ * Add a node to the hash queues.
+ */
+static void
+addhash(tdesc_t *tdp, int num)
+{
+ int hash = HASH(num);
+ tdesc_t *ttdp;
+ char added_num = 0, added_name = 0;
+
+ /*
+ * If it already exists in the hash table don't add it again
+ * (but still check to see if the name should be hashed).
+ */
+ ttdp = lookup(num);
+
+ if (ttdp == NULL) {
+ tdp->t_id = num;
+ tdp->t_hash = hash_table[hash];
+ hash_table[hash] = tdp;
+ added_num = 1;
+ }
+
+ if (tdp->t_name != NULL) {
+ ttdp = lookupname(tdp->t_name);
+ if (ttdp == NULL) {
+ hash = compute_sum(tdp->t_name);
+ tdp->t_next = name_table[hash];
+ name_table[hash] = tdp;
+ added_name = 1;
+ }
+ }
+ if (!added_num && !added_name) {
+ terminate("stabs: broken hash\n");
+ }
+}
+
+static int
+compute_sum(const char *w)
+{
+ char c;
+ int sum;
+
+ for (sum = 0; (c = *w) != '\0'; sum += c, w++)
+ ;
+ return (HASH(sum));
+}
+
+static void
+reset(void)
+{
+ longjmp(resetbuf, 1);
+}
+
+void
+check_hash(void)
+{
+ tdesc_t *tdp;
+ int i;
+
+ printf("checking hash\n");
+ for (i = 0; i < BUCKETS; i++) {
+ if (hash_table[i]) {
+ for (tdp = hash_table[i]->t_hash;
+ tdp && tdp != hash_table[i];
+ tdp = tdp->t_hash)
+ continue;
+ if (tdp) {
+ terminate("cycle in hash bucket %d\n", i);
+ return;
+ }
+ }
+
+ if (name_table[i]) {
+ for (tdp = name_table[i]->t_next;
+ tdp && tdp != name_table[i];
+ tdp = tdp->t_next)
+ continue;
+ if (tdp) {
+ terminate("cycle in name bucket %d\n", i);
+ return;
+ }
+ }
+ }
+ printf("done\n");
+}
+
+/*ARGSUSED1*/
+static int
+resolve_typed_bitfields_cb(void *arg, void *private __unused)
+{
+ mlist_t *ml = arg;
+ tdesc_t *tdp = ml->ml_type;
+
+ debug(3, "Resolving typed bitfields (member %s)\n",
+ (ml->ml_name ? ml->ml_name : "(anon)"));
+
+ while (tdp) {
+ switch (tdp->t_type) {
+ case INTRINSIC:
+ if (ml->ml_size != tdp->t_intr->intr_nbits) {
+ debug(3, "making %d bit intrinsic from %s",
+ ml->ml_size, tdesc_name(tdp));
+ ml->ml_type = bitintrinsic(tdp, ml->ml_size);
+ } else {
+ debug(3, "using existing %d bit %s intrinsic",
+ ml->ml_size, tdesc_name(tdp));
+ ml->ml_type = tdp;
+ }
+ return (1);
+
+ case POINTER:
+ case TYPEDEF:
+ case VOLATILE:
+ case CONST:
+ case RESTRICT:
+ tdp = tdp->t_tdesc;
+ break;
+
+ default:
+ return (1);
+ }
+ }
+
+ terminate("type chain for bitfield member %s has a NULL", ml->ml_name);
+ /*NOTREACHED*/
+ return (0);
+}
+
+void
+resolve_typed_bitfields(void)
+{
+ (void) list_iter(typedbitfldmems,
+ resolve_typed_bitfields_cb, NULL);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/stabs.c b/cddl/contrib/opensolaris/tools/ctf/cvt/stabs.c
new file mode 100644
index 0000000..c0c68b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/stabs.c
@@ -0,0 +1,381 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines used to read stabs data from a file, and to build a tdata structure
+ * based on the interesting parts of that data.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <libgen.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include "ctftools.h"
+#include "list.h"
+#include "stack.h"
+#include "memory.h"
+#include "traverse.h"
+
+char *curhdr;
+
+/*
+ * The stabs generator will sometimes reference types before they've been
+ * defined. If this is the case, a TYPEDEF_UNRES tdesc will be generated.
+ * Note that this is different from a forward declaration, in which the
+ * stab is defined, but is defined as something that doesn't exist yet.
+ * When we have read all of the stabs from the file, we can go back and
+ * fix up all of the unresolved types. We should be able to fix all of them.
+ */
+/*ARGSUSED2*/
+static int
+resolve_tou_node(tdesc_t *node, tdesc_t **nodep, void *private __unused)
+{
+ tdesc_t *new;
+
+ debug(3, "Trying to resolve %s (%d)\n", tdesc_name(node), node->t_id);
+ new = lookup(node->t_id);
+
+ if (new == NULL) {
+ terminate("Couldn't resolve type %d\n", node->t_id);
+ }
+
+ debug(3, " Resolving to %d\n", new->t_id);
+
+ *nodep = new;
+
+ return (1);
+}
+
+/*ARGSUSED*/
+static int
+resolve_fwd_node(tdesc_t *node, tdesc_t **nodep, void *private __unused)
+{
+ tdesc_t *new = lookupname(node->t_name);
+
+ debug(3, "Trying to unforward %s (%d)\n", tdesc_name(node), node->t_id);
+
+ if (!new || (new->t_type != STRUCT && new->t_type != UNION))
+ return (0);
+
+ debug(3, " Unforwarded to %d\n", new->t_id);
+
+ *nodep = new;
+
+ return (1);
+}
+
+static tdtrav_cb_f resolve_cbs[] = {
+ NULL,
+ NULL, /* intrinsic */
+ NULL, /* pointer */
+ NULL, /* array */
+ NULL, /* function */
+ NULL, /* struct */
+ NULL, /* union */
+ NULL, /* enum */
+ resolve_fwd_node, /* forward */
+ NULL, /* typedef */
+ resolve_tou_node, /* typedef unres */
+ NULL, /* volatile */
+ NULL, /* const */
+ NULL, /* restrict */
+};
+
+static void
+resolve_nodes(tdata_t *td)
+{
+ debug(2, "Resolving unresolved stabs\n");
+
+ (void) iitraverse_hash(td->td_iihash, &td->td_curvgen, resolve_cbs,
+ NULL, NULL, td);
+}
+
+static char *
+concat(char *s1, char *s2, int s2strip)
+{
+ int savelen = strlen(s2) - s2strip;
+ int newlen = (s1 ? strlen(s1) : 0) + savelen + 1;
+ char *out;
+
+ out = xrealloc(s1, newlen);
+ if (s1)
+ strncpy(out + strlen(out), s2, savelen);
+ else
+ strncpy(out, s2, savelen);
+
+ out[newlen - 1] = '\0';
+
+ return (out);
+}
+
+/*
+ * N_FUN stabs come with their arguments in promoted form. In order to get the
+ * actual arguments, we need to wait for the N_PSYM stabs that will come towards
+ * the end of the function. These routines free the arguments (fnarg_free) we
+ * got from the N_FUN stab and add (fnarg_add) the ones from the N_PSYM stabs.
+ */
+static void
+fnarg_add(iidesc_t *curfun, iidesc_t *arg)
+{
+ curfun->ii_nargs++;
+
+ if (curfun->ii_nargs == 1)
+ curfun->ii_args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF);
+ else if (curfun->ii_nargs > FUNCARG_DEF) {
+ curfun->ii_args = xrealloc(curfun->ii_args,
+ sizeof (tdesc_t *) * curfun->ii_nargs);
+ }
+
+ curfun->ii_args[curfun->ii_nargs - 1] = arg->ii_dtype;
+ arg->ii_dtype = NULL;
+}
+
+static void
+fnarg_free(iidesc_t *ii)
+{
+ ii->ii_nargs = 0;
+ free(ii->ii_args);
+ ii->ii_args = NULL;
+}
+
+/*
+ * Read the stabs from the stab ELF section, and turn them into a tdesc tree,
+ * assembled under an iidesc list.
+ */
+int
+stabs_read(tdata_t *td, Elf *elf, char *file)
+{
+ Elf_Scn *scn;
+ Elf_Data *data;
+ stab_t *stab;
+ stk_t *file_stack;
+ iidesc_t *iidescp;
+ iidesc_t *curfun = NULL;
+ char curpath[MAXPATHLEN];
+ char *curfile = NULL;
+ char *str;
+ char *fstr = NULL, *ofstr = NULL;
+ int stabidx, stabstridx;
+ int nstabs, rc, i;
+ int scope = 0;
+
+ if (!((stabidx = findelfsecidx(elf, file, ".stab.excl")) >= 0 &&
+ (stabstridx = findelfsecidx(elf, file, ".stab.exclstr")) >= 0) &&
+ !((stabidx = findelfsecidx(elf, file, ".stab")) >= 0 &&
+ (stabstridx = findelfsecidx(elf, file, ".stabstr")) >= 0)) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ file_stack = stack_new(free);
+
+ stack_push(file_stack, file);
+ curhdr = file;
+
+ debug(3, "Found stabs in %d, strings in %d\n", stabidx, stabstridx);
+
+ scn = elf_getscn(elf, stabidx);
+ data = elf_rawdata(scn, NULL);
+ nstabs = data->d_size / sizeof (stab_t);
+
+ parse_init(td);
+ for (i = 0; i < nstabs; i++) {
+ stab = &((stab_t *)data->d_buf)[i];
+
+ /* We don't want any local definitions */
+ if (stab->n_type == N_LBRAC) {
+ scope++;
+ debug(3, "stab %d: opening scope (%d)\n", i + 1, scope);
+ continue;
+ } else if (stab->n_type == N_RBRAC) {
+ scope--;
+ debug(3, "stab %d: closing scope (%d)\n", i + 1, scope);
+ continue;
+ } else if (stab->n_type == N_EINCL) {
+ /*
+ * There's a bug in the 5.2 (Taz) compilers that causes
+ * them to emit an extra N_EINCL if there's no actual
+ * text in the file being compiled. To work around this
+ * bug, we explicitly check to make sure we're not
+ * trying to pop a stack that only has the outer scope
+ * on it.
+ */
+ if (stack_level(file_stack) != 1) {
+ str = (char *)stack_pop(file_stack);
+ free(str);
+ curhdr = (char *)stack_peek(file_stack);
+ }
+ }
+
+ /* We only care about a subset of the stabs */
+ if (!(stab->n_type == N_FUN || stab->n_type == N_GSYM ||
+ stab->n_type == N_LCSYM || stab->n_type == N_LSYM ||
+ stab->n_type == N_PSYM || stab->n_type == N_ROSYM ||
+ stab->n_type == N_RSYM ||
+ stab->n_type == N_STSYM || stab->n_type == N_BINCL ||
+ stab->n_type == N_SO || stab->n_type == N_OPT))
+ continue;
+
+ if ((str = elf_strptr(elf, stabstridx,
+ (size_t)stab->n_strx)) == NULL) {
+ terminate("%s: Can't find string at %u for stab %d\n",
+ file, stab->n_strx, i);
+ }
+
+ if (stab->n_type == N_BINCL) {
+ curhdr = xstrdup(str);
+ stack_push(file_stack, curhdr);
+ continue;
+ } else if (stab->n_type == N_SO) {
+ if (str[strlen(str) - 1] != '/') {
+ strcpy(curpath, str);
+ curfile = basename(curpath);
+ }
+ continue;
+ } else if (stab->n_type == N_OPT) {
+ if (strcmp(str, "gcc2_compiled.") == 0) {
+ terminate("%s: GCC-generated stabs are "
+ "unsupported. Use DWARF instead.\n", file);
+ }
+ continue;
+ }
+
+ if (str[strlen(str) - 1] == '\\') {
+ int offset = 1;
+ /*
+ * There's a bug in the compilers that causes them to
+ * generate \ for continuations with just -g (this is
+ * ok), and \\ for continuations with -g -O (this is
+ * broken). This bug is "fixed" in the 6.2 compilers
+ * via the elimination of continuation stabs.
+ */
+ if (str[strlen(str) - 2] == '\\')
+ offset = 2;
+ fstr = concat(fstr, str, offset);
+ continue;
+ } else
+ fstr = concat(fstr, str, 0);
+
+ debug(3, "%4d: .stabs \"%s\", %#x, %d, %hd, %d (from %s)\n", i,
+ fstr, stab->n_type, 0, stab->n_desc,
+ stab->n_value, curhdr);
+
+ if (debug_level >= 3)
+ check_hash();
+
+ /*
+ * Sometimes the compiler stutters, and emits the same stab
+ * twice. This is bad for the parser, which will attempt to
+ * redefine the type IDs indicated in the stabs. This is
+ * compiler bug 4433511.
+ */
+ if (ofstr && strcmp(fstr, ofstr) == 0) {
+ debug(3, "Stutter stab\n");
+ free(fstr);
+ fstr = NULL;
+ continue;
+ }
+
+ if (ofstr)
+ free(ofstr);
+ ofstr = fstr;
+
+ iidescp = NULL;
+
+ if ((rc = parse_stab(stab, fstr, &iidescp)) < 0) {
+ terminate("%s: Couldn't parse stab \"%s\" "
+ "(source file %s)\n", file, str, curhdr);
+ }
+
+ if (rc == 0)
+ goto parse_loop_end;
+
+ /* Make sure the scope tracking is working correctly */
+ assert(stab->n_type != N_FUN || (iidescp->ii_type != II_GFUN &&
+ iidescp->ii_type != II_SFUN) || scope == 0);
+
+ /*
+ * The only things we care about that are in local scope are
+ * the N_PSYM stabs.
+ */
+ if (scope && stab->n_type != N_PSYM) {
+ if (iidescp)
+ iidesc_free(iidescp, NULL);
+ goto parse_loop_end;
+ }
+
+ switch (iidescp->ii_type) {
+ case II_SFUN:
+ iidescp->ii_owner = xstrdup(curfile);
+ /*FALLTHROUGH*/
+ case II_GFUN:
+ curfun = iidescp;
+ fnarg_free(iidescp);
+ iidesc_add(td->td_iihash, iidescp);
+ break;
+
+ case II_SVAR:
+ iidescp->ii_owner = xstrdup(curfile);
+ /*FALLTHROUGH*/
+ case II_GVAR:
+ case II_TYPE:
+ case II_SOU:
+ iidesc_add(td->td_iihash, iidescp);
+ break;
+
+ case II_PSYM:
+ fnarg_add(curfun, iidescp);
+ iidesc_free(iidescp, NULL);
+ break;
+ default:
+ aborterr("invalid ii_type %d for stab type %d",
+ iidescp->ii_type, stab->n_type);
+ }
+
+parse_loop_end:
+ fstr = NULL;
+ }
+
+ if (ofstr)
+ free(ofstr);
+
+ resolve_nodes(td);
+ resolve_typed_bitfields();
+ parse_finish(td);
+
+ cvt_fixstabs(td);
+ cvt_fixups(td, elf_ptrsz(elf));
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/stack.c b/cddl/contrib/opensolaris/tools/ctf/cvt/stack.c
new file mode 100644
index 0000000..7c36cd5
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/stack.c
@@ -0,0 +1,112 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating stacks
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "stack.h"
+#include "memory.h"
+
+#define STACK_SEEDSIZE 5
+
+struct stk {
+ int st_nument;
+ int st_top;
+ void **st_data;
+
+ void (*st_free)(void *);
+};
+
+stk_t *
+stack_new(void (*freep)(void *))
+{
+ stk_t *sp;
+
+ sp = xmalloc(sizeof (stk_t));
+ sp->st_nument = STACK_SEEDSIZE;
+ sp->st_top = -1;
+ sp->st_data = xmalloc(sizeof (void *) * sp->st_nument);
+ sp->st_free = freep;
+
+ return (sp);
+}
+
+void
+stack_free(stk_t *sp)
+{
+ int i;
+
+ if (sp->st_free) {
+ for (i = 0; i <= sp->st_top; i++)
+ sp->st_free(sp->st_data[i]);
+ }
+ free(sp->st_data);
+ free(sp);
+}
+
+void *
+stack_pop(stk_t *sp)
+{
+ assert(sp->st_top >= 0);
+
+ return (sp->st_data[sp->st_top--]);
+}
+
+void *
+stack_peek(stk_t *sp)
+{
+ if (sp->st_top == -1)
+ return (NULL);
+
+ return (sp->st_data[sp->st_top]);
+}
+
+void
+stack_push(stk_t *sp, void *data)
+{
+ sp->st_top++;
+
+ if (sp->st_top == sp->st_nument) {
+ sp->st_nument += STACK_SEEDSIZE;
+ sp->st_data = xrealloc(sp->st_data,
+ sizeof (void *) * sp->st_nument);
+ }
+
+ sp->st_data[sp->st_top] = data;
+}
+
+int
+stack_level(stk_t *sp)
+{
+ return (sp->st_top + 1);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/stack.h b/cddl/contrib/opensolaris/tools/ctf/cvt/stack.h
new file mode 100644
index 0000000..7dca7cf
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/stack.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _STACK_H
+#define _STACK_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines for manipulating stacks
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct stk stk_t;
+
+stk_t *stack_new(void (*)(void *));
+void stack_free(stk_t *);
+void *stack_pop(stk_t *);
+void *stack_peek(stk_t *);
+void stack_push(stk_t *, void *);
+int stack_level(stk_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STACK_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.c b/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.c
new file mode 100644
index 0000000..d8b2bf0
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.c
@@ -0,0 +1,258 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "strtab.h"
+#include "memory.h"
+
+#define STRTAB_HASHSZ 211 /* use a prime number of hash buckets */
+#define STRTAB_BUFSZ (64 * 1024) /* use 64K data buffers by default */
+
+static void
+strtab_grow(strtab_t *sp)
+{
+ sp->str_nbufs++;
+ sp->str_bufs = xrealloc(sp->str_bufs, sp->str_nbufs * sizeof (char *));
+ sp->str_ptr = xmalloc(sp->str_bufsz);
+ sp->str_bufs[sp->str_nbufs - 1] = sp->str_ptr;
+}
+
+void
+strtab_create(strtab_t *sp)
+{
+ sp->str_hash = xcalloc(STRTAB_HASHSZ * sizeof (strhash_t *));
+ sp->str_hashsz = STRTAB_HASHSZ;
+ sp->str_bufs = NULL;
+ sp->str_ptr = NULL;
+ sp->str_nbufs = 0;
+ sp->str_bufsz = STRTAB_BUFSZ;
+ sp->str_nstrs = 1;
+ sp->str_size = 1;
+
+ strtab_grow(sp);
+ *sp->str_ptr++ = '\0';
+}
+
+void
+strtab_destroy(strtab_t *sp)
+{
+ strhash_t *hp, *hq;
+ ulong_t i;
+
+ for (i = 0; i < sp->str_hashsz; i++) {
+ for (hp = sp->str_hash[i]; hp != NULL; hp = hq) {
+ hq = hp->str_next;
+ free(hp);
+ }
+ }
+
+ for (i = 0; i < sp->str_nbufs; i++)
+ free(sp->str_bufs[i]);
+
+ free(sp->str_hash);
+ free(sp->str_bufs);
+}
+
+static ulong_t
+strtab_hash(const char *key, size_t *len)
+{
+ ulong_t g, h = 0;
+ const char *p;
+ size_t n = 0;
+
+ for (p = key; *p != '\0'; p++, n++) {
+ h = (h << 4) + *p;
+
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ *len = n;
+ return (h);
+}
+
+static int
+strtab_compare(strtab_t *sp, strhash_t *hp, const char *str, size_t len)
+{
+ ulong_t b = hp->str_buf;
+ const char *buf = hp->str_data;
+ size_t resid, n;
+ int rv;
+
+ while (len != 0) {
+ if (buf == sp->str_bufs[b] + sp->str_bufsz)
+ buf = sp->str_bufs[++b];
+
+ resid = sp->str_bufs[b] + sp->str_bufsz - buf;
+ n = MIN(resid, len);
+
+ if ((rv = strncmp(buf, str, n)) != 0)
+ return (rv);
+
+ buf += n;
+ str += n;
+ len -= n;
+ }
+
+ return (0);
+}
+
+static void
+strtab_copyin(strtab_t *sp, const char *str, size_t len)
+{
+ ulong_t b = sp->str_nbufs - 1;
+ size_t resid, n;
+
+ while (len != 0) {
+ if (sp->str_ptr == sp->str_bufs[b] + sp->str_bufsz) {
+ strtab_grow(sp);
+ b++;
+ }
+
+ resid = sp->str_bufs[b] + sp->str_bufsz - sp->str_ptr;
+ n = MIN(resid, len);
+ bcopy(str, sp->str_ptr, n);
+
+ sp->str_ptr += n;
+ str += n;
+ len -= n;
+ }
+}
+
+size_t
+strtab_insert(strtab_t *sp, const char *str)
+{
+ strhash_t *hp;
+ size_t len;
+ ulong_t h;
+
+ if (str == NULL || str[0] == '\0')
+ return (0); /* we keep a \0 at offset 0 to simplify things */
+
+ h = strtab_hash(str, &len) % sp->str_hashsz;
+
+ /*
+ * If the string is already in our hash table, just return the offset
+ * of the existing string element and do not add a duplicate string.
+ */
+ for (hp = sp->str_hash[h]; hp != NULL; hp = hp->str_next) {
+ if (strtab_compare(sp, hp, str, len + 1) == 0)
+ return (hp->str_off);
+ }
+
+ /*
+ * Create a new hash bucket, initialize it, and insert it at the front
+ * of the hash chain for the appropriate bucket.
+ */
+ hp = xmalloc(sizeof (strhash_t));
+
+ hp->str_data = sp->str_ptr;
+ hp->str_buf = sp->str_nbufs - 1;
+ hp->str_off = sp->str_size;
+ hp->str_len = len;
+ hp->str_next = sp->str_hash[h];
+
+ sp->str_hash[h] = hp;
+
+ /*
+ * Now copy the string data into our buffer list, and then update
+ * the global counts of strings and bytes. Return str's byte offset.
+ */
+ strtab_copyin(sp, str, len + 1);
+ sp->str_nstrs++;
+ sp->str_size += len + 1;
+
+ return (hp->str_off);
+}
+
+size_t
+strtab_size(const strtab_t *sp)
+{
+ return (sp->str_size);
+}
+
+ssize_t
+strtab_write(const strtab_t *sp,
+ ssize_t (*func)(void *, size_t, void *), void *priv)
+{
+ ssize_t res, total = 0;
+ ulong_t i;
+ size_t n;
+
+ for (i = 0; i < sp->str_nbufs; i++, total += res) {
+ if (i == sp->str_nbufs - 1)
+ n = sp->str_ptr - sp->str_bufs[i];
+ else
+ n = sp->str_bufsz;
+
+ if ((res = func(sp->str_bufs[i], n, priv)) <= 0)
+ break;
+ }
+
+ if (total == 0 && sp->str_size != 0)
+ return (-1);
+
+ return (total);
+}
+
+void
+strtab_print(const strtab_t *sp)
+{
+ const strhash_t *hp;
+ ulong_t i;
+
+ for (i = 0; i < sp->str_hashsz; i++) {
+ for (hp = sp->str_hash[i]; hp != NULL; hp = hp->str_next) {
+ const char *buf = hp->str_data;
+ ulong_t b = hp->str_buf;
+ size_t resid, len, n;
+
+ (void) printf("[%lu] %lu \"", (ulong_t)hp->str_off, b);
+
+ for (len = hp->str_len; len != 0; len -= n) {
+ if (buf == sp->str_bufs[b] + sp->str_bufsz)
+ buf = sp->str_bufs[++b];
+
+ resid = sp->str_bufs[b] + sp->str_bufsz - buf;
+ n = MIN(resid, len);
+
+ (void) printf("%.*s", (int)n, buf);
+ buf += n;
+ }
+
+ (void) printf("\"\n");
+ }
+ }
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.h b/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.h
new file mode 100644
index 0000000..13c1e59
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/strtab.h
@@ -0,0 +1,69 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _STRTAB_H
+#define _STRTAB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct strhash {
+ const char *str_data; /* pointer to actual string data */
+ ulong_t str_buf; /* index of string data buffer */
+ size_t str_off; /* offset in bytes of this string */
+ size_t str_len; /* length in bytes of this string */
+ struct strhash *str_next; /* next string in hash chain */
+} strhash_t;
+
+typedef struct strtab {
+ strhash_t **str_hash; /* array of hash buckets */
+ ulong_t str_hashsz; /* size of hash bucket array */
+ char **str_bufs; /* array of buffer pointers */
+ char *str_ptr; /* pointer to current buffer location */
+ ulong_t str_nbufs; /* size of buffer pointer array */
+ size_t str_bufsz; /* size of individual buffer */
+ ulong_t str_nstrs; /* total number of strings in strtab */
+ size_t str_size; /* total size of strings in bytes */
+} strtab_t;
+
+extern void strtab_create(strtab_t *);
+extern void strtab_destroy(strtab_t *);
+extern size_t strtab_insert(strtab_t *, const char *);
+extern size_t strtab_size(const strtab_t *);
+extern ssize_t strtab_write(const strtab_t *,
+ ssize_t (*)(void *, size_t, void *), void *);
+extern void strtab_print(const strtab_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STRTAB_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c b/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c
new file mode 100644
index 0000000..1ccd6cd
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c
@@ -0,0 +1,487 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Routines for manipulating tdesc and tdata structures
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <pthread.h>
+
+#include "ctftools.h"
+#include "memory.h"
+#include "traverse.h"
+
+/*
+ * The layout hash is used during the equivalency checking. We have a node in
+ * the child graph that may be equivalent to a node in the parent graph. To
+ * find the corresponding node (if any) in the parent, we need a quick way to
+ * get to all nodes in the parent that look like the node in the child. Since a
+ * large number of nodes don't have names, we need to incorporate the layout of
+ * the node into the hash. If we don't, we'll end up with the vast majority of
+ * nodes in bucket zero, with one or two nodes in each of the remaining buckets.
+ *
+ * There are a couple of constraints, both of which concern forward
+ * declarations. Recall that a forward declaration tdesc is equivalent to a
+ * tdesc that actually defines the structure or union. As such, we cannot
+ * incorporate anything into the hash for a named struct or union node that
+ * couldn't be found by looking at the forward, and vice versa.
+ */
+int
+tdesc_layouthash(int nbuckets, void *node)
+{
+ tdesc_t *tdp = node;
+ char *name = NULL;
+ ulong_t h = 0;
+
+ if (tdp->t_name)
+ name = tdp->t_name;
+ else {
+ switch (tdp->t_type) {
+ case POINTER:
+ case TYPEDEF:
+ case VOLATILE:
+ case CONST:
+ case RESTRICT:
+ name = tdp->t_tdesc->t_name;
+ break;
+ case FUNCTION:
+ h = tdp->t_fndef->fn_nargs +
+ tdp->t_fndef->fn_vargs;
+ name = tdp->t_fndef->fn_ret->t_name;
+ break;
+ case ARRAY:
+ h = tdp->t_ardef->ad_nelems;
+ name = tdp->t_ardef->ad_contents->t_name;
+ break;
+ case STRUCT:
+ case UNION:
+ /*
+ * Unnamed structures, which cannot have forward
+ * declarations pointing to them. We can therefore
+ * incorporate the name of the first member into
+ * the hash value, assuming there are any.
+ */
+ if (tdp->t_members != NULL)
+ name = tdp->t_members->ml_name;
+ break;
+ case ENUM:
+ /* Use the first element in the hash value */
+ name = tdp->t_emem->el_name;
+ break;
+ default:
+ /*
+ * Intrinsics, forwards, and typedefs all have
+ * names.
+ */
+ warning("Unexpected unnamed %d tdesc (ID %d)\n",
+ tdp->t_type, tdp->t_id);
+ }
+ }
+
+ if (name)
+ return (hash_name(nbuckets, name));
+
+ return (h % nbuckets);
+}
+
+int
+tdesc_layoutcmp(void *arg1, void *arg2)
+{
+ tdesc_t *tdp1 = arg1, *tdp2 = arg2;
+
+ if (tdp1->t_name == NULL) {
+ if (tdp2->t_name == NULL)
+ return (0);
+ else
+ return (-1);
+ } else if (tdp2->t_name == NULL)
+ return (1);
+ else
+ return (strcmp(tdp1->t_name, tdp2->t_name));
+}
+
+int
+tdesc_idhash(int nbuckets, void *data)
+{
+ tdesc_t *tdp = data;
+
+ return (tdp->t_id % nbuckets);
+}
+
+int
+tdesc_idcmp(void *arg1, void *arg2)
+{
+ tdesc_t *tdp1 = arg1, *tdp2 = arg2;
+
+ if (tdp1->t_id == tdp2->t_id)
+ return (0);
+ else
+ return (tdp1->t_id > tdp2->t_id ? 1 : -1);
+}
+
+int
+tdesc_namehash(int nbuckets, void *data)
+{
+ tdesc_t *tdp = data;
+ ulong_t h, g;
+ char *c;
+
+ if (tdp->t_name == NULL)
+ return (0);
+
+ for (h = 0, c = tdp->t_name; *c; c++) {
+ h = (h << 4) + *c;
+ if ((g = (h & 0xf0000000)) != 0) {
+ h ^= (g >> 24);
+ h ^= g;
+ }
+ }
+
+ return (h % nbuckets);
+}
+
+int
+tdesc_namecmp(void *arg1, void *arg2)
+{
+ tdesc_t *tdp1 = arg1, *tdp2 = arg2;
+
+ return (!streq(tdp1->t_name, tdp2->t_name));
+}
+
+#if defined(sun)
+/*ARGSUSED1*/
+static int
+tdesc_print(void *data, void *private __unused)
+{
+ tdesc_t *tdp = data;
+
+ printf("%7d %s\n", tdp->t_id, tdesc_name(tdp));
+
+ return (1);
+}
+#endif
+
+static void
+free_intr(tdesc_t *tdp)
+{
+ free(tdp->t_intr);
+}
+
+static void
+free_ardef(tdesc_t *tdp)
+{
+ free(tdp->t_ardef);
+}
+
+static void
+free_mlist(tdesc_t *tdp)
+{
+ mlist_t *ml = tdp->t_members;
+ mlist_t *oml;
+
+ while (ml) {
+ oml = ml;
+ ml = ml->ml_next;
+
+ if (oml->ml_name)
+ free(oml->ml_name);
+ free(oml);
+ }
+}
+
+static void
+free_elist(tdesc_t *tdp)
+{
+ elist_t *el = tdp->t_emem;
+ elist_t *oel;
+
+ while (el) {
+ oel = el;
+ el = el->el_next;
+
+ if (oel->el_name)
+ free(oel->el_name);
+ free(oel);
+ }
+}
+
+static void (*free_cbs[])(tdesc_t *) = {
+ NULL,
+ free_intr,
+ NULL,
+ free_ardef,
+ NULL,
+ free_mlist,
+ free_mlist,
+ free_elist,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*ARGSUSED1*/
+static void
+tdesc_free_cb(void *arg, void *private __unused)
+{
+ tdesc_t *tdp = arg;
+ if (tdp->t_name)
+ free(tdp->t_name);
+ if (free_cbs[tdp->t_type])
+ free_cbs[tdp->t_type](tdp);
+ free(tdp);
+
+ return;
+}
+
+void
+tdesc_free(tdesc_t *tdp)
+{
+ tdesc_free_cb(tdp, NULL);
+}
+
+static int
+tdata_label_cmp(void *arg1, void *arg2)
+{
+ labelent_t *le1 = arg1;
+ labelent_t *le2 = arg2;
+ return (le1->le_idx - le2->le_idx);
+}
+
+void
+tdata_label_add(tdata_t *td, const char *label, int idx)
+{
+ labelent_t *le = xmalloc(sizeof (*le));
+
+ le->le_name = xstrdup(label);
+ le->le_idx = (idx == -1 ? td->td_nextid - 1 : idx);
+
+ slist_add(&td->td_labels, le, tdata_label_cmp);
+}
+
+static int
+tdata_label_top_cb(void *data, void *arg)
+{
+ labelent_t *le = data;
+ labelent_t **topp = arg;
+
+ *topp = le;
+
+ return (1);
+}
+
+labelent_t *
+tdata_label_top(tdata_t *td)
+{
+ labelent_t *top = NULL;
+
+ (void) list_iter(td->td_labels, tdata_label_top_cb, &top);
+
+ return (top);
+}
+
+static int
+tdata_label_find_cb(void *arg1, void *arg2)
+{
+ labelent_t *le = arg1;
+ labelent_t *tmpl = arg2;
+ return (streq(le->le_name, tmpl->le_name));
+}
+
+int
+tdata_label_find(tdata_t *td, char *label)
+{
+ labelent_t let;
+ labelent_t *ret;
+
+ if (streq(label, "BASE")) {
+ ret = (labelent_t *)list_first(td->td_labels);
+ return (ret ? ret->le_idx : -1);
+ }
+
+ let.le_name = label;
+
+ if (!(ret = (labelent_t *)list_find(td->td_labels, &let,
+ tdata_label_find_cb)))
+ return (-1);
+
+ return (ret->le_idx);
+}
+
+static int
+tdata_label_newmax_cb(void *data, void *arg)
+{
+ labelent_t *le = data;
+ int *newmaxp = arg;
+
+ if (le->le_idx > *newmaxp) {
+ le->le_idx = *newmaxp;
+ return (1);
+ }
+
+ return (0);
+}
+
+void
+tdata_label_newmax(tdata_t *td, int newmax)
+{
+ (void) list_iter(td->td_labels, tdata_label_newmax_cb, &newmax);
+}
+
+/*ARGSUSED1*/
+static void
+tdata_label_free_cb(void *arg, void *private __unused)
+{
+ labelent_t *le = arg;
+ if (le->le_name)
+ free(le->le_name);
+ free(le);
+}
+
+void
+tdata_label_free(tdata_t *td)
+{
+ list_free(td->td_labels, tdata_label_free_cb, NULL);
+ td->td_labels = NULL;
+}
+
+tdata_t *
+tdata_new(void)
+{
+ tdata_t *new = xcalloc(sizeof (tdata_t));
+
+ new->td_layouthash = hash_new(TDATA_LAYOUT_HASH_SIZE, tdesc_layouthash,
+ tdesc_layoutcmp);
+ new->td_idhash = hash_new(TDATA_ID_HASH_SIZE, tdesc_idhash,
+ tdesc_idcmp);
+ /*
+ * This is also traversed as a list, but amortized O(1)
+ * lookup massively impacts part of the merge phase, so
+ * we store the iidescs as a hash.
+ */
+ new->td_iihash = hash_new(IIDESC_HASH_SIZE, iidesc_hash, NULL);
+ new->td_nextid = 1;
+ new->td_curvgen = 1;
+
+ pthread_mutex_init(&new->td_mergelock, NULL);
+
+ return (new);
+}
+
+void
+tdata_free(tdata_t *td)
+{
+ hash_free(td->td_iihash, iidesc_free, NULL);
+ hash_free(td->td_layouthash, tdesc_free_cb, NULL);
+ hash_free(td->td_idhash, NULL, NULL);
+ list_free(td->td_fwdlist, NULL, NULL);
+
+ tdata_label_free(td);
+
+ free(td->td_parlabel);
+ free(td->td_parname);
+
+ pthread_mutex_destroy(&td->td_mergelock);
+
+ free(td);
+}
+
+/*ARGSUSED1*/
+static int
+build_hashes(tdesc_t *ctdp, tdesc_t **ctdpp __unused, void *private)
+{
+ tdata_t *td = private;
+
+ hash_add(td->td_idhash, ctdp);
+ hash_add(td->td_layouthash, ctdp);
+
+ return (1);
+}
+
+static tdtrav_cb_f build_hashes_cbs[] = {
+ NULL,
+ build_hashes, /* intrinsic */
+ build_hashes, /* pointer */
+ build_hashes, /* array */
+ build_hashes, /* function */
+ build_hashes, /* struct */
+ build_hashes, /* union */
+ build_hashes, /* enum */
+ build_hashes, /* forward */
+ build_hashes, /* typedef */
+ tdtrav_assert, /* typedef_unres */
+ build_hashes, /* volatile */
+ build_hashes, /* const */
+ build_hashes /* restrict */
+};
+
+static void
+tdata_build_hashes_common(tdata_t *td, hash_t *hash)
+{
+ (void) iitraverse_hash(hash, &td->td_curvgen, NULL, NULL,
+ build_hashes_cbs, td);
+}
+
+void
+tdata_build_hashes(tdata_t *td)
+{
+ tdata_build_hashes_common(td, td->td_iihash);
+}
+
+/* Merge td2 into td1. td2 is destroyed by the merge */
+void
+tdata_merge(tdata_t *td1, tdata_t *td2)
+{
+ td1->td_curemark = MAX(td1->td_curemark, td2->td_curemark);
+ td1->td_curvgen = MAX(td1->td_curvgen, td2->td_curvgen);
+ td1->td_nextid = MAX(td1->td_nextid, td2->td_nextid);
+
+ hash_merge(td1->td_iihash, td2->td_iihash);
+
+ /* Add td2's type tree to the hashes */
+ tdata_build_hashes_common(td1, td2->td_iihash);
+
+ list_concat(&td1->td_fwdlist, td2->td_fwdlist);
+ td2->td_fwdlist = NULL;
+
+ slist_merge(&td1->td_labels, td2->td_labels,
+ tdata_label_cmp);
+ td2->td_labels = NULL;
+
+ /* free the td2 hashes (data is now part of td1) */
+
+ hash_free(td2->td_layouthash, NULL, NULL);
+ td2->td_layouthash = NULL;
+
+ hash_free(td2->td_iihash, NULL, NULL);
+ td2->td_iihash = NULL;
+
+ tdata_free(td2);
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
new file mode 100644
index 0000000..feb9908
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
@@ -0,0 +1,226 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines used to traverse tdesc trees, invoking user-supplied callbacks
+ * as the tree is traversed.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "ctftools.h"
+#include "traverse.h"
+#include "memory.h"
+
+int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);
+tdtrav_cb_f tdnops[];
+
+void
+tdtrav_init(tdtrav_data_t *tdtd, int *vgenp, tdtrav_cb_f *firstops,
+ tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
+{
+ tdtd->vgen = ++(*vgenp);
+ tdtd->firstops = firstops ? firstops : tdnops;
+ tdtd->preops = preops ? preops : tdnops;
+ tdtd->postops = postops ? postops : tdnops;
+ tdtd->private = private;
+}
+
+static int
+tdtrav_plain(tdesc_t *this, tdtrav_data_t *tdtd)
+{
+ return (tdtraverse(this->t_tdesc, &this->t_tdesc, tdtd));
+}
+
+static int
+tdtrav_func(tdesc_t *this, tdtrav_data_t *tdtd)
+{
+ fndef_t *fn = this->t_fndef;
+ int i, rc;
+
+ if ((rc = tdtraverse(fn->fn_ret, &fn->fn_ret, tdtd)) < 0)
+ return (rc);
+
+ for (i = 0; i < (int) fn->fn_nargs; i++) {
+ if ((rc = tdtraverse(fn->fn_args[i], &fn->fn_args[i],
+ tdtd)) < 0)
+ return (rc);
+ }
+
+ return (0);
+}
+
+static int
+tdtrav_array(tdesc_t *this, tdtrav_data_t *tdtd)
+{
+ ardef_t *ardef = this->t_ardef;
+ int rc;
+
+ if ((rc = tdtraverse(ardef->ad_contents, &ardef->ad_contents,
+ tdtd)) < 0)
+ return (rc);
+
+ return (tdtraverse(ardef->ad_idxtype, &ardef->ad_idxtype, tdtd));
+}
+
+static int
+tdtrav_su(tdesc_t *this, tdtrav_data_t *tdtd)
+{
+ mlist_t *ml;
+ int rc = 0;
+
+ for (ml = this->t_members; ml; ml = ml->ml_next) {
+ if ((rc = tdtraverse(ml->ml_type, &ml->ml_type, tdtd)) < 0)
+ return (rc);
+ }
+
+ return (rc);
+}
+
+/*ARGSUSED*/
+int
+tdtrav_assert(tdesc_t *node __unused, tdesc_t **nodep __unused, void *private __unused)
+{
+ assert(1 == 0);
+
+ return (-1);
+}
+
+tdtrav_cb_f tdnops[] = {
+ NULL,
+ NULL, /* intrinsic */
+ NULL, /* pointer */
+ NULL, /* array */
+ NULL, /* function */
+ NULL, /* struct */
+ NULL, /* union */
+ NULL, /* enum */
+ NULL, /* forward */
+ NULL, /* typedef */
+ NULL, /* typedef_unres */
+ NULL, /* volatile */
+ NULL, /* const */
+ NULL /* restrict */
+};
+
+int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {
+ NULL,
+ NULL, /* intrinsic */
+ tdtrav_plain, /* pointer */
+ tdtrav_array, /* array */
+ tdtrav_func, /* function */
+ tdtrav_su, /* struct */
+ tdtrav_su, /* union */
+ NULL, /* enum */
+ NULL, /* forward */
+ tdtrav_plain, /* typedef */
+ NULL, /* typedef_unres */
+ tdtrav_plain, /* volatile */
+ tdtrav_plain, /* const */
+ tdtrav_plain /* restrict */
+};
+
+int
+tdtraverse(tdesc_t *this, tdesc_t **thisp, tdtrav_data_t *tdtd)
+{
+ tdtrav_cb_f travcb;
+ int (*descender)(tdesc_t *, tdtrav_data_t *);
+ int descend = 1;
+ int rc;
+
+ if ((travcb = tdtd->firstops[this->t_type]) != NULL) {
+ if ((rc = travcb(this, thisp, tdtd->private)) < 0)
+ return (rc);
+ else if (rc == 0)
+ descend = 0;
+ }
+
+ if (this->t_vgen == tdtd->vgen)
+ return (1);
+ this->t_vgen = tdtd->vgen;
+
+ if (descend && (travcb = tdtd->preops[this->t_type]) != NULL) {
+ if ((rc = travcb(this, thisp, tdtd->private)) < 0)
+ return (rc);
+ else if (rc == 0)
+ descend = 0;
+ }
+
+ if (descend) {
+ if ((descender = tddescenders[this->t_type]) != NULL &&
+ (rc = descender(this, tdtd)) < 0)
+ return (rc);
+
+ if ((travcb = tdtd->postops[this->t_type]) != NULL &&
+ (rc = travcb(this, thisp, tdtd->private)) < 0)
+ return (rc);
+ }
+
+ return (1);
+}
+
+int
+iitraverse_td(void *arg1, void *arg2)
+{
+ iidesc_t *ii = arg1;
+ tdtrav_data_t *tdtd = arg2;
+ int i, rc;
+
+ if ((rc = tdtraverse(ii->ii_dtype, &ii->ii_dtype, tdtd)) < 0)
+ return (rc);
+
+ for (i = 0; i < ii->ii_nargs; i++) {
+ if ((rc = tdtraverse(ii->ii_args[i], &ii->ii_args[i],
+ tdtd)) < 0)
+ return (rc);
+ }
+
+ return (1);
+}
+
+int
+iitraverse(iidesc_t *ii, int *vgenp, tdtrav_cb_f *firstops, tdtrav_cb_f *preops,
+ tdtrav_cb_f *postops, void *private)
+{
+ tdtrav_data_t tdtd;
+
+ tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
+
+ return (iitraverse_td(ii, &tdtd));
+}
+
+int
+iitraverse_hash(hash_t *iihash, int *vgenp, tdtrav_cb_f *firstops,
+ tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
+{
+ tdtrav_data_t tdtd;
+
+ tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
+
+ return (hash_iter(iihash, iitraverse_td, &tdtd));
+}
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.h b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.h
new file mode 100644
index 0000000..6a56370
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.h
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TRAVERSE_H
+#define _TRAVERSE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Routines used to traverse tdesc trees, invoking user-supplied callbacks
+ * as the tree is traversed.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ctftools.h"
+
+typedef int (*tdtrav_cb_f)(tdesc_t *, tdesc_t **, void *);
+
+typedef struct tdtrav_data {
+ int vgen;
+
+ tdtrav_cb_f *firstops;
+ tdtrav_cb_f *preops;
+ tdtrav_cb_f *postops;
+
+ void *private;
+} tdtrav_data_t;
+
+void tdtrav_init(tdtrav_data_t *, int *, tdtrav_cb_f *, tdtrav_cb_f *,
+ tdtrav_cb_f *, void *);
+int tdtraverse(tdesc_t *, tdesc_t **, tdtrav_data_t *);
+
+int iitraverse(iidesc_t *, int *, tdtrav_cb_f *, tdtrav_cb_f *, tdtrav_cb_f *,
+ void *);
+int iitraverse_hash(hash_t *, int *, tdtrav_cb_f *, tdtrav_cb_f *,
+ tdtrav_cb_f *, void *);
+int iitraverse_td(void *, void *);
+
+int tdtrav_assert(tdesc_t *, tdesc_t **, void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TRAVERSE_H */
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/util.c b/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
new file mode 100644
index 0000000..0f36fa0
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
@@ -0,0 +1,283 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Utility functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include "ctftools.h"
+#include "memory.h"
+
+static void (*terminate_cleanup)(void) = NULL;
+
+/* returns 1 if s1 == s2, 0 otherwise */
+int
+streq(const char *s1, const char *s2)
+{
+ if (s1 == NULL) {
+ if (s2 != NULL)
+ return (0);
+ } else if (s2 == NULL)
+ return (0);
+ else if (strcmp(s1, s2) != 0)
+ return (0);
+
+ return (1);
+}
+
+int
+findelfsecidx(Elf *elf, const char *file, const char *tofind)
+{
+ Elf_Scn *scn = NULL;
+ GElf_Ehdr ehdr;
+ GElf_Shdr shdr;
+
+ if (gelf_getehdr(elf, &ehdr) == NULL)
+ elfterminate(file, "Couldn't read ehdr");
+
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ char *name;
+
+ if (gelf_getshdr(scn, &shdr) == NULL) {
+ elfterminate(file,
+ "Couldn't read header for section %d",
+ elf_ndxscn(scn));
+ }
+
+ if ((name = elf_strptr(elf, ehdr.e_shstrndx,
+ (size_t)shdr.sh_name)) == NULL) {
+ elfterminate(file,
+ "Couldn't get name for section %d",
+ elf_ndxscn(scn));
+ }
+
+ if (strcmp(name, tofind) == 0)
+ return (elf_ndxscn(scn));
+ }
+
+ return (-1);
+}
+
+size_t
+elf_ptrsz(Elf *elf)
+{
+ GElf_Ehdr ehdr;
+
+ if (gelf_getehdr(elf, &ehdr) == NULL) {
+ terminate("failed to read ELF header: %s\n",
+ elf_errmsg(-1));
+ }
+
+ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+ return (4);
+ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ return (8);
+ else
+ terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);
+
+ /*NOTREACHED*/
+ return (0);
+}
+
+/*PRINTFLIKE2*/
+static void
+whine(const char *type, const char *format, va_list ap)
+{
+ int error = errno;
+
+ fprintf(stderr, "%s: %s: ", type, progname);
+ vfprintf(stderr, format, ap);
+
+ if (format[strlen(format) - 1] != '\n')
+ fprintf(stderr, ": %s\n", strerror(error));
+}
+
+void
+set_terminate_cleanup(void (*cleanup)(void))
+{
+ terminate_cleanup = cleanup;
+}
+
+/*PRINTFLIKE1*/
+void
+terminate(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ whine("ERROR", format, ap);
+ va_end(ap);
+
+ if (terminate_cleanup)
+ terminate_cleanup();
+
+ if (getenv("CTF_ABORT_ON_TERMINATE") != NULL)
+ abort();
+#if defined(__FreeBSD__)
+/*
+ * For the time being just output the termination message, but don't
+ * return an exit status that would cause the build to fail. We need
+ * to get as much stuff built as possible before going back and
+ * figuring out what is wrong with certain files.
+ */
+ exit(0);
+#else
+ exit(1);
+#endif
+}
+
+/*PRINTFLIKE1*/
+void
+aborterr(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ whine("ERROR", format, ap);
+ va_end(ap);
+
+#if defined(sun)
+ abort();
+#else
+ exit(0);
+#endif
+}
+
+/*PRINTFLIKE1*/
+void
+warning(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ whine("WARNING", format, ap);
+ va_end(ap);
+
+ if (debug_level >= 3)
+ terminate("Termination due to warning\n");
+}
+
+/*PRINTFLIKE2*/
+void
+vadebug(int level, const char *format, va_list ap)
+{
+ if (level > debug_level)
+ return;
+
+ (void) fprintf(DEBUG_STREAM, "DEBUG: ");
+ (void) vfprintf(DEBUG_STREAM, format, ap);
+ fflush(DEBUG_STREAM);
+}
+
+/*PRINTFLIKE2*/
+void
+debug(int level, const char *format, ...)
+{
+ va_list ap;
+
+ if (level > debug_level)
+ return;
+
+ va_start(ap, format);
+ (void) vadebug(level, format, ap);
+ va_end(ap);
+}
+
+char *
+mktmpname(const char *origname, const char *suffix)
+{
+ char *newname;
+
+ newname = xmalloc(strlen(origname) + strlen(suffix) + 1);
+ (void) strcpy(newname, origname);
+ (void) strcat(newname, suffix);
+ return (newname);
+}
+
+/*PRINTFLIKE2*/
+void
+elfterminate(const char *file, const char *fmt, ...)
+{
+ static char msgbuf[BUFSIZ];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap);
+ va_end(ap);
+
+ terminate("%s: %s: %s\n", file, msgbuf, elf_errmsg(-1));
+}
+
+const char *
+tdesc_name(tdesc_t *tdp)
+{
+ return (tdp->t_name == NULL ? "(anon)" : tdp->t_name);
+}
+
+char *watch_address = NULL;
+int watch_length = 0;
+
+void
+watch_set(void *addr, int len)
+{
+ watch_address = addr;
+ watch_length = len;
+}
+
+void
+watch_dump(int v)
+{
+ char *p = watch_address;
+ int i;
+
+ if (watch_address == NULL || watch_length == 0)
+ return;
+
+ printf("%d: watch %p len %d\n",v,watch_address,watch_length);
+ for (i = 0; i < watch_length; i++) {
+ if (*p >= 0x20 && *p < 0x7f) {
+ printf(" %c",*p++ & 0xff);
+ } else {
+ printf(" %02x",*p++ & 0xff);
+ }
+ }
+ printf("\n");
+
+}
+
+
diff --git a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
new file mode 100644
index 0000000..740485d
--- /dev/null
+++ b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
@@ -0,0 +1,1028 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <zlib.h>
+
+#include "ctf_headers.h"
+#include "utils.h"
+#include "symbol.h"
+
+#define WARN(x) { warn(x); return (E_ERROR); }
+
+/*
+ * Flags that indicate what data is to be displayed. An explicit `all' value is
+ * provided to allow the code to distinguish between a request for everything
+ * (currently requested by invoking ctfdump without flags) and individual
+ * requests for all of the types of data (an invocation with all flags). In the
+ * former case, we want to be able to implicitly adjust the definition of `all'
+ * based on the CTF version of the file being dumped. For example, if a v2 file
+ * is being dumped, `all' includes F_LABEL - a request to dump the label
+ * section. If a v1 file is being dumped, `all' does not include F_LABEL,
+ * because v1 CTF doesn't support labels. We need to be able to distinguish
+ * between `ctfdump foo', which has an implicit request for labels if `foo'
+ * supports them, and `ctfdump -l foo', which has an explicity request. In the
+ * latter case, we exit with an error if `foo' is a v1 CTF file.
+ */
+static enum {
+ F_DATA = 0x01, /* show data object section */
+ F_FUNC = 0x02, /* show function section */
+ F_HDR = 0x04, /* show header */
+ F_STR = 0x08, /* show string table */
+ F_TYPES = 0x10, /* show type section */
+ F_STATS = 0x20, /* show statistics */
+ F_LABEL = 0x40, /* show label section */
+ F_ALL = 0x80, /* explicit request for `all' */
+ F_ALLMSK = 0xff /* show all sections and statistics */
+} flags = 0;
+
+static struct {
+ ulong_t s_ndata; /* total number of data objects */
+ ulong_t s_nfunc; /* total number of functions */
+ ulong_t s_nargs; /* total number of function arguments */
+ ulong_t s_argmax; /* longest argument list */
+ ulong_t s_ntypes; /* total number of types */
+ ulong_t s_types[16]; /* number of types by kind */
+ ulong_t s_nsmem; /* total number of struct members */
+ ulong_t s_nsbytes; /* total size of all structs */
+ ulong_t s_smmax; /* largest struct in terms of members */
+ ulong_t s_sbmax; /* largest struct in terms of bytes */
+ ulong_t s_numem; /* total number of union members */
+ ulong_t s_nubytes; /* total size of all unions */
+ ulong_t s_ummax; /* largest union in terms of members */
+ ulong_t s_ubmax; /* largest union in terms of bytes */
+ ulong_t s_nemem; /* total number of enum members */
+ ulong_t s_emmax; /* largest enum in terms of members */
+ ulong_t s_nstr; /* total number of strings */
+ size_t s_strlen; /* total length of all strings */
+ size_t s_strmax; /* longest string length */
+} stats;
+
+typedef struct ctf_data {
+ caddr_t cd_ctfdata; /* Pointer to the CTF data */
+ size_t cd_ctflen; /* Length of CTF data */
+
+ /*
+ * cd_symdata will be non-NULL if the CTF data is being retrieved from
+ * an ELF file with a symbol table. cd_strdata and cd_nsyms should be
+ * used only if cd_symdata is non-NULL.
+ */
+ Elf_Data *cd_symdata; /* Symbol table */
+ Elf_Data *cd_strdata; /* Symbol table strings */
+ int cd_nsyms; /* Number of symbol table entries */
+} ctf_data_t;
+
+static const char *
+ref_to_str(uint_t name, const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ size_t offset = CTF_NAME_OFFSET(name);
+ const char *s = cd->cd_ctfdata + hp->cth_stroff + offset;
+
+ if (CTF_NAME_STID(name) != CTF_STRTAB_0)
+ return ("<< ??? - name in external strtab >>");
+
+ if (offset >= hp->cth_strlen)
+ return ("<< ??? - name exceeds strlab len >>");
+
+ if (hp->cth_stroff + offset >= cd->cd_ctflen)
+ return ("<< ??? - file truncated >>");
+
+ if (s[0] == '\0')
+ return ("(anon)");
+
+ return (s);
+}
+
+static const char *
+int_encoding_to_str(uint_t encoding)
+{
+ static char buf[32];
+
+ if (encoding == 0 || (encoding & ~(CTF_INT_SIGNED | CTF_INT_CHAR |
+ CTF_INT_BOOL | CTF_INT_VARARGS)) != 0)
+ (void) snprintf(buf, sizeof (buf), " 0x%x", encoding);
+ else {
+ buf[0] = '\0';
+ if (encoding & CTF_INT_SIGNED)
+ (void) strcat(buf, " SIGNED");
+ if (encoding & CTF_INT_CHAR)
+ (void) strcat(buf, " CHAR");
+ if (encoding & CTF_INT_BOOL)
+ (void) strcat(buf, " BOOL");
+ if (encoding & CTF_INT_VARARGS)
+ (void) strcat(buf, " VARARGS");
+ }
+
+ return (buf + 1);
+}
+
+static const char *
+fp_encoding_to_str(uint_t encoding)
+{
+ static const char *const encs[] = {
+ NULL, "SINGLE", "DOUBLE", "COMPLEX", "DCOMPLEX", "LDCOMPLEX",
+ "LDOUBLE", "INTERVAL", "DINTERVAL", "LDINTERVAL", "IMAGINARY",
+ "DIMAGINARY", "LDIMAGINARY"
+ };
+
+ static char buf[16];
+
+ if (encoding < 1 || encoding >= (sizeof (encs) / sizeof (char *))) {
+ (void) snprintf(buf, sizeof (buf), "%u", encoding);
+ return (buf);
+ }
+
+ return (encs[encoding]);
+}
+
+static void
+print_line(const char *s)
+{
+ static const char line[] = "----------------------------------------"
+ "----------------------------------------";
+ (void) printf("\n%s%.*s\n\n", s, (int)(78 - strlen(s)), line);
+}
+
+static int
+print_header(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ print_line("- CTF Header ");
+
+ (void) printf(" cth_magic = 0x%04x\n", hp->cth_magic);
+ (void) printf(" cth_version = %u\n", hp->cth_version);
+ (void) printf(" cth_flags = 0x%02x\n", hp->cth_flags);
+ (void) printf(" cth_parlabel = %s\n",
+ ref_to_str(hp->cth_parlabel, hp, cd));
+ (void) printf(" cth_parname = %s\n",
+ ref_to_str(hp->cth_parname, hp, cd));
+ (void) printf(" cth_lbloff = %u\n", hp->cth_lbloff);
+ (void) printf(" cth_objtoff = %u\n", hp->cth_objtoff);
+ (void) printf(" cth_funcoff = %u\n", hp->cth_funcoff);
+ (void) printf(" cth_typeoff = %u\n", hp->cth_typeoff);
+ (void) printf(" cth_stroff = %u\n", hp->cth_stroff);
+ (void) printf(" cth_strlen = %u\n", hp->cth_strlen);
+
+ return (E_SUCCESS);
+}
+
+static int
+print_labeltable(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ void *v = (void *) (cd->cd_ctfdata + hp->cth_lbloff);
+ const ctf_lblent_t *ctl = v;
+ ulong_t i, n = (hp->cth_objtoff - hp->cth_lbloff) / sizeof (*ctl);
+
+ print_line("- Label Table ");
+
+ if (hp->cth_lbloff & 3)
+ WARN("cth_lbloff is not aligned properly\n");
+ if (hp->cth_lbloff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_lbloff is corrupt\n");
+ if (hp->cth_objtoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_objtoff is corrupt\n");
+ if (hp->cth_lbloff > hp->cth_objtoff)
+ WARN("file is corrupt -- cth_lbloff > cth_objtoff\n");
+
+ for (i = 0; i < n; i++, ctl++) {
+ (void) printf(" %5u %s\n", ctl->ctl_typeidx,
+ ref_to_str(ctl->ctl_label, hp, cd));
+ }
+
+ return (E_SUCCESS);
+}
+
+/*
+ * Given the current symbol index (-1 to start at the beginning of the symbol
+ * table) and the type of symbol to match, this function returns the index of
+ * the next matching symbol (if any), and places the name of that symbol in
+ * *namep. If no symbol is found, -1 is returned.
+ */
+static int
+next_sym(const ctf_data_t *cd, const int symidx, const uchar_t matchtype,
+ char **namep)
+{
+ int i;
+
+ for (i = symidx + 1; i < cd->cd_nsyms; i++) {
+ GElf_Sym sym;
+ char *name;
+ int type;
+
+ if (gelf_getsym(cd->cd_symdata, i, &sym) == 0)
+ return (-1);
+
+ name = (char *)cd->cd_strdata->d_buf + sym.st_name;
+ type = GELF_ST_TYPE(sym.st_info);
+
+ /*
+ * Skip various types of symbol table entries.
+ */
+ if (type != matchtype || ignore_symbol(&sym, name))
+ continue;
+
+ /* Found one */
+ *namep = name;
+ return (i);
+ }
+
+ return (-1);
+}
+
+static int
+read_data(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ void *v = (void *) (cd->cd_ctfdata + hp->cth_objtoff);
+ const ushort_t *idp = v;
+ ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / sizeof (ushort_t);
+
+ if (flags != F_STATS)
+ print_line("- Data Objects ");
+
+ if (hp->cth_objtoff & 1)
+ WARN("cth_objtoff is not aligned properly\n");
+ if (hp->cth_objtoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_objtoff is corrupt\n");
+ if (hp->cth_funcoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_funcoff is corrupt\n");
+ if (hp->cth_objtoff > hp->cth_funcoff)
+ WARN("file is corrupt -- cth_objtoff > cth_funcoff\n");
+
+ if (flags != F_STATS) {
+ int symidx, len, i;
+ char *name = NULL;
+
+ for (symidx = -1, i = 0; i < (int) n; i++) {
+ int nextsym;
+
+ if (cd->cd_symdata == NULL || (nextsym = next_sym(cd,
+ symidx, STT_OBJECT, &name)) < 0)
+ name = NULL;
+ else
+ symidx = nextsym;
+
+ len = printf(" [%u] %u", i, *idp++);
+ if (name != NULL)
+ (void) printf("%*s%s (%u)", (15 - len), "",
+ name, symidx);
+ (void) putchar('\n');
+ }
+ }
+
+ stats.s_ndata = n;
+ return (E_SUCCESS);
+}
+
+static int
+read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ void *v = (void *) (cd->cd_ctfdata + hp->cth_funcoff);
+ const ushort_t *fp = v;
+
+ v = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
+ const ushort_t *end = v;
+
+ ulong_t id;
+ int symidx;
+
+ if (flags != F_STATS)
+ print_line("- Functions ");
+
+ if (hp->cth_funcoff & 1)
+ WARN("cth_funcoff is not aligned properly\n");
+ if (hp->cth_funcoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_funcoff is corrupt\n");
+ if (hp->cth_typeoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_typeoff is corrupt\n");
+ if (hp->cth_funcoff > hp->cth_typeoff)
+ WARN("file is corrupt -- cth_funcoff > cth_typeoff\n");
+
+ for (symidx = -1, id = 0; fp < end; id++) {
+ ushort_t info = *fp++;
+ ushort_t kind = CTF_INFO_KIND(info);
+ ushort_t n = CTF_INFO_VLEN(info);
+ ushort_t i;
+ int nextsym;
+ char *name;
+
+ if (cd->cd_symdata == NULL || (nextsym = next_sym(cd, symidx,
+ STT_FUNC, &name)) < 0)
+ name = NULL;
+ else
+ symidx = nextsym;
+
+ if (kind == CTF_K_UNKNOWN && n == 0)
+ continue; /* skip padding */
+
+ if (kind != CTF_K_FUNCTION) {
+ (void) printf(" [%lu] unexpected kind -- %u\n",
+ id, kind);
+ return (E_ERROR);
+ }
+
+ if (fp + n > end) {
+ (void) printf(" [%lu] vlen %u extends past section "
+ "boundary\n", id, n);
+ return (E_ERROR);
+ }
+
+ if (flags != F_STATS) {
+ (void) printf(" [%lu] FUNC ", id);
+ if (name != NULL)
+ (void) printf("(%s) ", name);
+ (void) printf("returns: %u args: (", *fp++);
+
+ if (n != 0) {
+ (void) printf("%u", *fp++);
+ for (i = 1; i < n; i++)
+ (void) printf(", %u", *fp++);
+ }
+
+ (void) printf(")\n");
+ } else
+ fp += n + 1; /* skip to next function definition */
+
+ stats.s_nfunc++;
+ stats.s_nargs += n;
+ stats.s_argmax = MAX(stats.s_argmax, n);
+ }
+
+ return (E_SUCCESS);
+}
+
+static int
+read_types(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ void *v = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
+ const ctf_type_t *tp = v;
+
+ v = (void *) (cd->cd_ctfdata + hp->cth_stroff);
+ const ctf_type_t *end = v;
+
+ ulong_t id;
+
+ if (flags != F_STATS)
+ print_line("- Types ");
+
+ if (hp->cth_typeoff & 3)
+ WARN("cth_typeoff is not aligned properly\n");
+ if (hp->cth_typeoff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_typeoff is corrupt\n");
+ if (hp->cth_stroff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_stroff is corrupt\n");
+ if (hp->cth_typeoff > hp->cth_stroff)
+ WARN("file is corrupt -- cth_typeoff > cth_stroff\n");
+
+ id = 1;
+ if (hp->cth_parlabel || hp->cth_parname)
+ id += 1 << CTF_PARENT_SHIFT;
+
+ for (/* */; tp < end; id++) {
+ ulong_t i, n = CTF_INFO_VLEN(tp->ctt_info);
+ size_t size, increment, vlen = 0;
+ int kind = CTF_INFO_KIND(tp->ctt_info);
+
+ union {
+ const void *ptr;
+ ctf_array_t *ap;
+ const ctf_member_t *mp;
+ const ctf_lmember_t *lmp;
+ const ctf_enum_t *ep;
+ const ushort_t *argp;
+ } u;
+
+ if (flags != F_STATS) {
+ (void) printf(" %c%lu%c ",
+ "[<"[CTF_INFO_ISROOT(tp->ctt_info)], id,
+ "]>"[CTF_INFO_ISROOT(tp->ctt_info)]);
+ }
+
+ if (tp->ctt_size == CTF_LSIZE_SENT) {
+ increment = sizeof (ctf_type_t);
+ size = (size_t)CTF_TYPE_LSIZE(tp);
+ } else {
+ increment = sizeof (ctf_stype_t);
+ size = tp->ctt_size;
+ }
+ u.ptr = (const char *)tp + increment;
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ if (flags != F_STATS) {
+ uint_t encoding = *((const uint_t *)u.ptr);
+
+ (void) printf("INTEGER %s encoding=%s offset=%u"
+ " bits=%u", ref_to_str(tp->ctt_name, hp,
+ cd), int_encoding_to_str(
+ CTF_INT_ENCODING(encoding)),
+ CTF_INT_OFFSET(encoding),
+ CTF_INT_BITS(encoding));
+ }
+ vlen = sizeof (uint_t);
+ break;
+
+ case CTF_K_FLOAT:
+ if (flags != F_STATS) {
+ uint_t encoding = *((const uint_t *)u.ptr);
+
+ (void) printf("FLOAT %s encoding=%s offset=%u "
+ "bits=%u", ref_to_str(tp->ctt_name, hp,
+ cd), fp_encoding_to_str(
+ CTF_FP_ENCODING(encoding)),
+ CTF_FP_OFFSET(encoding),
+ CTF_FP_BITS(encoding));
+ }
+ vlen = sizeof (uint_t);
+ break;
+
+ case CTF_K_POINTER:
+ if (flags != F_STATS) {
+ (void) printf("POINTER %s refers to %u",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+ }
+ break;
+
+ case CTF_K_ARRAY:
+ if (flags != F_STATS) {
+ (void) printf("ARRAY %s content: %u index: %u "
+ "nelems: %u\n", ref_to_str(tp->ctt_name,
+ hp, cd), u.ap->cta_contents,
+ u.ap->cta_index, u.ap->cta_nelems);
+ }
+ vlen = sizeof (ctf_array_t);
+ break;
+
+ case CTF_K_FUNCTION:
+ if (flags != F_STATS) {
+ (void) printf("FUNCTION %s returns: %u args: (",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+
+ if (n != 0) {
+ (void) printf("%u", *u.argp++);
+ for (i = 1; i < n; i++, u.argp++)
+ (void) printf(", %u", *u.argp);
+ }
+
+ (void) printf(")");
+ }
+
+ vlen = sizeof (ushort_t) * (n + (n & 1));
+ break;
+
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ if (kind == CTF_K_STRUCT) {
+ stats.s_nsmem += n;
+ stats.s_smmax = MAX(stats.s_smmax, n);
+ stats.s_nsbytes += size;
+ stats.s_sbmax = MAX(stats.s_sbmax, size);
+
+ if (flags != F_STATS)
+ (void) printf("STRUCT");
+ } else {
+ stats.s_numem += n;
+ stats.s_ummax = MAX(stats.s_ummax, n);
+ stats.s_nubytes += size;
+ stats.s_ubmax = MAX(stats.s_ubmax, size);
+
+ if (flags != F_STATS)
+ (void) printf("UNION");
+ }
+
+ if (flags != F_STATS) {
+ (void) printf(" %s (%zd bytes)\n",
+ ref_to_str(tp->ctt_name, hp, cd), size);
+
+ if (size >= CTF_LSTRUCT_THRESH) {
+ for (i = 0; i < n; i++, u.lmp++) {
+ (void) printf(
+ "\t%s type=%u off=%llu\n",
+ ref_to_str(u.lmp->ctlm_name,
+ hp, cd), u.lmp->ctlm_type,
+ (unsigned long long)
+ CTF_LMEM_OFFSET(u.lmp));
+ }
+ } else {
+ for (i = 0; i < n; i++, u.mp++) {
+ (void) printf(
+ "\t%s type=%u off=%u\n",
+ ref_to_str(u.mp->ctm_name,
+ hp, cd), u.mp->ctm_type,
+ u.mp->ctm_offset);
+ }
+ }
+ }
+
+ vlen = n * (size >= CTF_LSTRUCT_THRESH ?
+ sizeof (ctf_lmember_t) : sizeof (ctf_member_t));
+ break;
+
+ case CTF_K_ENUM:
+ if (flags != F_STATS) {
+ (void) printf("ENUM %s\n",
+ ref_to_str(tp->ctt_name, hp, cd));
+
+ for (i = 0; i < n; i++, u.ep++) {
+ (void) printf("\t%s = %d\n",
+ ref_to_str(u.ep->cte_name, hp, cd),
+ u.ep->cte_value);
+ }
+ }
+
+ stats.s_nemem += n;
+ stats.s_emmax = MAX(stats.s_emmax, n);
+
+ vlen = sizeof (ctf_enum_t) * n;
+ break;
+
+ case CTF_K_FORWARD:
+ if (flags != F_STATS) {
+ (void) printf("FORWARD %s",
+ ref_to_str(tp->ctt_name, hp, cd));
+ }
+ break;
+
+ case CTF_K_TYPEDEF:
+ if (flags != F_STATS) {
+ (void) printf("TYPEDEF %s refers to %u",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+ }
+ break;
+
+ case CTF_K_VOLATILE:
+ if (flags != F_STATS) {
+ (void) printf("VOLATILE %s refers to %u",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+ }
+ break;
+
+ case CTF_K_CONST:
+ if (flags != F_STATS) {
+ (void) printf("CONST %s refers to %u",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+ }
+ break;
+
+ case CTF_K_RESTRICT:
+ if (flags != F_STATS) {
+ (void) printf("RESTRICT %s refers to %u",
+ ref_to_str(tp->ctt_name, hp, cd),
+ tp->ctt_type);
+ }
+ break;
+
+ case CTF_K_UNKNOWN:
+ break; /* hole in type id space */
+
+ default:
+ (void) printf("unexpected kind %u\n", kind);
+ return (E_ERROR);
+ }
+
+ if (flags != F_STATS)
+ (void) printf("\n");
+
+ stats.s_ntypes++;
+ stats.s_types[kind]++;
+
+ tp = (ctf_type_t *)((uintptr_t)tp + increment + vlen);
+ }
+
+ return (E_SUCCESS);
+}
+
+static int
+read_strtab(const ctf_header_t *hp, const ctf_data_t *cd)
+{
+ size_t n, off, len = hp->cth_strlen;
+ const char *s = cd->cd_ctfdata + hp->cth_stroff;
+
+ if (flags != F_STATS)
+ print_line("- String Table ");
+
+ if (hp->cth_stroff >= cd->cd_ctflen)
+ WARN("file is truncated or cth_stroff is corrupt\n");
+ if (hp->cth_stroff + hp->cth_strlen > cd->cd_ctflen)
+ WARN("file is truncated or cth_strlen is corrupt\n");
+
+ for (off = 0; len != 0; off += n) {
+ if (flags != F_STATS) {
+ (void) printf(" [%lu] %s\n", (ulong_t)off,
+ s[0] == '\0' ? "\\0" : s);
+ }
+ n = strlen(s) + 1;
+ len -= n;
+ s += n;
+
+ stats.s_nstr++;
+ stats.s_strlen += n;
+ stats.s_strmax = MAX(stats.s_strmax, n);
+ }
+
+ return (E_SUCCESS);
+}
+
+static void
+long_stat(const char *name, ulong_t value)
+{
+ (void) printf(" %-36s= %lu\n", name, value);
+}
+
+static void
+fp_stat(const char *name, float value)
+{
+ (void) printf(" %-36s= %.2f\n", name, value);
+}
+
+static int
+print_stats(void)
+{
+ print_line("- CTF Statistics ");
+
+ long_stat("total number of data objects", stats.s_ndata);
+ (void) printf("\n");
+
+ long_stat("total number of functions", stats.s_nfunc);
+ long_stat("total number of function arguments", stats.s_nargs);
+ long_stat("maximum argument list length", stats.s_argmax);
+
+ if (stats.s_nfunc != 0) {
+ fp_stat("average argument list length",
+ (float)stats.s_nargs / (float)stats.s_nfunc);
+ }
+
+ (void) printf("\n");
+
+ long_stat("total number of types", stats.s_ntypes);
+ long_stat("total number of integers", stats.s_types[CTF_K_INTEGER]);
+ long_stat("total number of floats", stats.s_types[CTF_K_FLOAT]);
+ long_stat("total number of pointers", stats.s_types[CTF_K_POINTER]);
+ long_stat("total number of arrays", stats.s_types[CTF_K_ARRAY]);
+ long_stat("total number of func types", stats.s_types[CTF_K_FUNCTION]);
+ long_stat("total number of structs", stats.s_types[CTF_K_STRUCT]);
+ long_stat("total number of unions", stats.s_types[CTF_K_UNION]);
+ long_stat("total number of enums", stats.s_types[CTF_K_ENUM]);
+ long_stat("total number of forward tags", stats.s_types[CTF_K_FORWARD]);
+ long_stat("total number of typedefs", stats.s_types[CTF_K_TYPEDEF]);
+ long_stat("total number of volatile types",
+ stats.s_types[CTF_K_VOLATILE]);
+ long_stat("total number of const types", stats.s_types[CTF_K_CONST]);
+ long_stat("total number of restrict types",
+ stats.s_types[CTF_K_RESTRICT]);
+ long_stat("total number of unknowns (holes)",
+ stats.s_types[CTF_K_UNKNOWN]);
+
+ (void) printf("\n");
+
+ long_stat("total number of struct members", stats.s_nsmem);
+ long_stat("maximum number of struct members", stats.s_smmax);
+ long_stat("total size of all structs", stats.s_nsbytes);
+ long_stat("maximum size of a struct", stats.s_sbmax);
+
+ if (stats.s_types[CTF_K_STRUCT] != 0) {
+ fp_stat("average number of struct members",
+ (float)stats.s_nsmem / (float)stats.s_types[CTF_K_STRUCT]);
+ fp_stat("average size of a struct", (float)stats.s_nsbytes /
+ (float)stats.s_types[CTF_K_STRUCT]);
+ }
+
+ (void) printf("\n");
+
+ long_stat("total number of union members", stats.s_numem);
+ long_stat("maximum number of union members", stats.s_ummax);
+ long_stat("total size of all unions", stats.s_nubytes);
+ long_stat("maximum size of a union", stats.s_ubmax);
+
+ if (stats.s_types[CTF_K_UNION] != 0) {
+ fp_stat("average number of union members",
+ (float)stats.s_numem / (float)stats.s_types[CTF_K_UNION]);
+ fp_stat("average size of a union", (float)stats.s_nubytes /
+ (float)stats.s_types[CTF_K_UNION]);
+ }
+
+ (void) printf("\n");
+
+ long_stat("total number of enum members", stats.s_nemem);
+ long_stat("maximum number of enum members", stats.s_emmax);
+
+ if (stats.s_types[CTF_K_ENUM] != 0) {
+ fp_stat("average number of enum members",
+ (float)stats.s_nemem / (float)stats.s_types[CTF_K_ENUM]);
+ }
+
+ (void) printf("\n");
+
+ long_stat("total number of unique strings", stats.s_nstr);
+ long_stat("bytes of string data", stats.s_strlen);
+ long_stat("maximum string length", stats.s_strmax);
+
+ if (stats.s_nstr != 0) {
+ fp_stat("average string length",
+ (float)stats.s_strlen / (float)stats.s_nstr);
+ }
+
+ (void) printf("\n");
+ return (E_SUCCESS);
+}
+
+static int
+print_usage(FILE *fp, int verbose)
+{
+ (void) fprintf(fp, "Usage: %s [-dfhlsSt] [-u file] file\n", getpname());
+
+ if (verbose) {
+ (void) fprintf(fp,
+ "\t-d dump data object section\n"
+ "\t-f dump function section\n"
+ "\t-h dump file header\n"
+ "\t-l dump label table\n"
+ "\t-s dump string table\n"
+ "\t-S dump statistics\n"
+ "\t-t dump type section\n"
+ "\t-u save uncompressed CTF to a file\n");
+ }
+
+ return (E_USAGE);
+}
+
+static Elf_Scn *
+findelfscn(Elf *elf, GElf_Ehdr *ehdr, const char *secname)
+{
+ GElf_Shdr shdr;
+ Elf_Scn *scn;
+ char *name;
+
+ for (scn = NULL; (scn = elf_nextscn(elf, scn)) != NULL; ) {
+ if (gelf_getshdr(scn, &shdr) != NULL && (name =
+ elf_strptr(elf, ehdr->e_shstrndx, shdr.sh_name)) != NULL &&
+ strcmp(name, secname) == 0)
+ return (scn);
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *filename = NULL;
+ const char *ufile = NULL;
+ int error = 0;
+ int c, fd, ufd;
+
+ ctf_data_t cd;
+ const ctf_preamble_t *pp;
+ ctf_header_t *hp = NULL;
+ Elf *elf;
+ GElf_Ehdr ehdr;
+
+ (void) elf_version(EV_CURRENT);
+
+ for (opterr = 0; optind < argc; optind++) {
+ while ((c = getopt(argc, argv, "dfhlsStu:")) != (int)EOF) {
+ switch (c) {
+ case 'd':
+ flags |= F_DATA;
+ break;
+ case 'f':
+ flags |= F_FUNC;
+ break;
+ case 'h':
+ flags |= F_HDR;
+ break;
+ case 'l':
+ flags |= F_LABEL;
+ break;
+ case 's':
+ flags |= F_STR;
+ break;
+ case 'S':
+ flags |= F_STATS;
+ break;
+ case 't':
+ flags |= F_TYPES;
+ break;
+ case 'u':
+ ufile = optarg;
+ break;
+ default:
+ if (optopt == '?')
+ return (print_usage(stdout, 1));
+ warn("illegal option -- %c\n", optopt);
+ return (print_usage(stderr, 0));
+ }
+ }
+
+ if (optind < argc) {
+ if (filename != NULL)
+ return (print_usage(stderr, 0));
+ filename = argv[optind];
+ }
+ }
+
+ if (filename == NULL)
+ return (print_usage(stderr, 0));
+
+ if (flags == 0 && ufile == NULL)
+ flags = F_ALLMSK;
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ die("failed to open %s", filename);
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) != NULL &&
+ gelf_getehdr(elf, &ehdr) != NULL) {
+
+ Elf_Data *dp = NULL;
+ Elf_Scn *ctfscn = findelfscn(elf, &ehdr, ".SUNW_ctf");
+ Elf_Scn *symscn;
+ GElf_Shdr ctfshdr;
+
+ if (ctfscn == NULL || (dp = elf_getdata(ctfscn, NULL)) == NULL)
+ die("%s does not contain .SUNW_ctf data\n", filename);
+
+ cd.cd_ctfdata = dp->d_buf;
+ cd.cd_ctflen = dp->d_size;
+
+ /*
+ * If the sh_link field of the CTF section header is non-zero
+ * it indicates which section contains the symbol table that
+ * should be used. We default to the .symtab section if sh_link
+ * is zero or if there's an error reading the section header.
+ */
+ if (gelf_getshdr(ctfscn, &ctfshdr) != NULL &&
+ ctfshdr.sh_link != 0) {
+ symscn = elf_getscn(elf, ctfshdr.sh_link);
+ } else {
+ symscn = findelfscn(elf, &ehdr, ".symtab");
+ }
+
+ /* If we found a symbol table, find the corresponding strings */
+ if (symscn != NULL) {
+ GElf_Shdr shdr;
+ Elf_Scn *symstrscn;
+
+ if (gelf_getshdr(symscn, &shdr) != NULL) {
+ symstrscn = elf_getscn(elf, shdr.sh_link);
+
+ cd.cd_nsyms = shdr.sh_size / shdr.sh_entsize;
+ cd.cd_symdata = elf_getdata(symscn, NULL);
+ cd.cd_strdata = elf_getdata(symstrscn, NULL);
+ }
+ }
+ } else {
+ struct stat st;
+
+ if (fstat(fd, &st) == -1)
+ die("failed to fstat %s", filename);
+
+ cd.cd_ctflen = st.st_size;
+ cd.cd_ctfdata = mmap(NULL, cd.cd_ctflen, PROT_READ,
+ MAP_PRIVATE, fd, 0);
+ if (cd.cd_ctfdata == MAP_FAILED)
+ die("failed to mmap %s", filename);
+ }
+
+ /*
+ * Get a pointer to the CTF data buffer and interpret the first portion
+ * as a ctf_header_t. Validate the magic number and size.
+ */
+
+ if (cd.cd_ctflen < sizeof (ctf_preamble_t))
+ die("%s does not contain a CTF preamble\n", filename);
+
+ void *v = (void *) cd.cd_ctfdata;
+ pp = v;
+
+ if (pp->ctp_magic != CTF_MAGIC)
+ die("%s does not appear to contain CTF data\n", filename);
+
+ if (pp->ctp_version == CTF_VERSION) {
+ v = (void *) cd.cd_ctfdata;
+ hp = v;
+ cd.cd_ctfdata = (caddr_t)cd.cd_ctfdata + sizeof (ctf_header_t);
+
+ if (cd.cd_ctflen < sizeof (ctf_header_t)) {
+ die("%s does not contain a v%d CTF header\n", filename,
+ CTF_VERSION);
+ }
+
+ } else {
+ die("%s contains unsupported CTF version %d\n", filename,
+ pp->ctp_version);
+ }
+
+ /*
+ * If the data buffer is compressed, then malloc a buffer large enough
+ * to hold the decompressed data, and use zlib to decompress it.
+ */
+ if (hp->cth_flags & CTF_F_COMPRESS) {
+ z_stream zstr;
+ void *buf;
+ int rc;
+
+ if ((buf = malloc(hp->cth_stroff + hp->cth_strlen)) == NULL)
+ die("failed to allocate decompression buffer");
+
+ bzero(&zstr, sizeof (z_stream));
+ zstr.next_in = (void *)cd.cd_ctfdata;
+ zstr.avail_in = cd.cd_ctflen;
+ zstr.next_out = buf;
+ zstr.avail_out = hp->cth_stroff + hp->cth_strlen;
+
+ if ((rc = inflateInit(&zstr)) != Z_OK)
+ die("failed to initialize zlib: %s\n", zError(rc));
+
+ if ((rc = inflate(&zstr, Z_FINISH)) != Z_STREAM_END)
+ die("failed to decompress CTF data: %s\n", zError(rc));
+
+ if ((rc = inflateEnd(&zstr)) != Z_OK)
+ die("failed to finish decompression: %s\n", zError(rc));
+
+ if (zstr.total_out != hp->cth_stroff + hp->cth_strlen)
+ die("CTF data is corrupt -- short decompression\n");
+
+ cd.cd_ctfdata = buf;
+ cd.cd_ctflen = hp->cth_stroff + hp->cth_strlen;
+ }
+
+ if (flags & F_HDR)
+ error |= print_header(hp, &cd);
+ if (flags & (F_LABEL))
+ error |= print_labeltable(hp, &cd);
+ if (flags & (F_DATA | F_STATS))
+ error |= read_data(hp, &cd);
+ if (flags & (F_FUNC | F_STATS))
+ error |= read_funcs(hp, &cd);
+ if (flags & (F_TYPES | F_STATS))
+ error |= read_types(hp, &cd);
+ if (flags & (F_STR | F_STATS))
+ error |= read_strtab(hp, &cd);
+ if (flags & F_STATS)
+ error |= print_stats();
+
+ /*
+ * If the -u option is specified, write the uncompressed CTF data to a
+ * raw CTF file. CTF data can already be extracted compressed by
+ * applying elfdump -w -N .SUNW_ctf to an ELF file, so we don't bother.
+ */
+ if (ufile != NULL) {
+ ctf_header_t h;
+
+ bcopy(hp, &h, sizeof (h));
+ h.cth_flags &= ~CTF_F_COMPRESS;
+
+ if ((ufd = open(ufile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0 ||
+ write(ufd, &h, sizeof (h)) != sizeof (h) ||
+ write(ufd, cd.cd_ctfdata, cd.cd_ctflen) != (int) cd.cd_ctflen) {
+ warn("failed to write CTF data to '%s'", ufile);
+ error |= E_ERROR;
+ }
+
+ (void) close(ufd);
+ }
+
+ if (elf != NULL)
+ (void) elf_end(elf);
+
+ (void) close(fd);
+ return (error);
+}
OpenPOWER on IntegriCloud